import type { MemoryIdempotencyEntry, MemoryIdempotencyStore } from "../idempotency/index.js";
import type { MemoryMailDelivery, NormalizedMailMessage } from "../mail/index.js";
import type { MemoryNotificationDelivery } from "../notifications/index.js";
import type { DrainOutboxResult, OutboxErrorInfo, OutboxMessage, OutboxMessageKind, OutboxMessageStatus } from "../outbox/index.js";
import type { ProviderInstrumentationEventInput, ProviderInstrumentationPort } from "../providers/index.js";
import type { ScheduleDef, ScheduleRunnerPort, ScheduleRunOptions } from "../schedules/index.js";
import { type ActivityActor, type ActivityMetadata, type ActivityMetadataValue, type ActivityResource, type ActivityTenant, type AuditLogEntry, type AuditOutcome } from "./audit.js";
import type { EventBusPort, JobDef, JobDispatcherPort } from "./events.js";
import { type CreateGateOptions, type GateDecision, type GatePort, type PolicyContextFromDefinitions, type PolicyDefinition, type PolicyMapFromDefinitions, type PolicySubjectArgs } from "./policy.js";
import type { StorageObject, StoragePort, StorageVisibility } from "./storage.js";
/**
 * A recorded event entry from the recording event bus.
 */
export interface RecordedEvent {
    name: string;
    payload: unknown;
}
/**
 * Expected fields for a recorded event assertion.
 */
export interface RecordedEventExpectation {
    /**
     * Expected event name.
     */
    name?: string;
    /**
     * Expected event payload. Object values are matched as partial objects.
     */
    payload?: unknown;
}
/**
 * Create a recording event bus for testing.
 *
 * This bus records all published events for later assertion,
 * but does not support subscription (throws if called).
 *
 * @example
 * ```ts
 * const { bus, events } = createRecordingEventBus();
 *
 * // Inject bus into your use case
 * await createUser({ ports: { eventBus: bus } });
 *
 * // Assert on recorded events
 * expect(events).toHaveLength(1);
 * expect(events[0].name).toBe("user.registered");
 * expect(events[0].payload).toEqual({ userId: "123", email: "test@example.com" });
 * ```
 */
export declare function createRecordingEventBus(): {
    bus: EventBusPort;
    events: RecordedEvent[];
};
/**
 * A job dispatch captured by `createRecordingJobDispatcher(...)`.
 */
export interface RecordedJobDispatch {
    /**
     * Dispatched job name.
     */
    name: string;
    /**
     * Job definition supplied to the dispatcher.
     */
    job: JobDef;
    /**
     * Payload supplied to the dispatcher.
     */
    payload: unknown;
}
/**
 * Expected fields for a recorded job dispatch assertion.
 */
export interface RecordedJobDispatchExpectation {
    /**
     * Expected job name.
     */
    name?: string;
    /**
     * Expected job payload. Object values are matched as partial objects.
     */
    payload?: unknown;
}
/**
 * Create a recording job dispatcher for tests.
 *
 * The dispatcher records dispatch intent without running the job handler. Use
 * this when a use case or listener should enqueue work but the test does not
 * need to execute that work inline.
 *
 * @returns A job dispatcher plus its captured dispatches.
 */
export declare function createRecordingJobDispatcher(): {
    jobs: JobDispatcherPort;
    dispatchedJobs: RecordedJobDispatch[];
};
/**
 * A schedule run captured by `createRecordingScheduleRunner(...)`.
 */
export interface RecordedScheduleRun {
    /**
     * Schedule name.
     */
    name: string;
    /**
     * Schedule definition supplied to the runner.
     */
    schedule: ScheduleDef;
    /**
     * Payload supplied to the runner, when present.
     */
    payload?: unknown;
    /**
     * Run ID supplied by the provider or test, when present.
     */
    id?: string;
    /**
     * Provider or app source label, when present.
     */
    source?: string;
    /**
     * Scheduled timestamp supplied to the runner, when present.
     */
    scheduledAt?: ScheduleRunOptions["scheduledAt"];
    /**
     * Triggered timestamp supplied to the runner, when present.
     */
    triggeredAt?: ScheduleRunOptions["triggeredAt"];
}
/**
 * Expected fields for a recorded schedule run assertion.
 */
export interface RecordedScheduleRunExpectation {
    /**
     * Expected schedule name.
     */
    name?: string;
    /**
     * Expected schedule payload. Object values are matched as partial objects.
     */
    payload?: unknown;
    /**
     * Expected run ID.
     */
    id?: string;
    /**
     * Expected source label.
     */
    source?: string;
}
/**
 * Expected fields for a provider instrumentation event assertion.
 */
export interface ProviderInstrumentationEventExpectation {
    /**
     * Expected instrumentation event type.
     */
    type?: ProviderInstrumentationEventInput["type"];
    /**
     * Expected event ID.
     */
    id?: string;
    /**
     * Expected ISO timestamp.
     */
    timestamp?: string;
    /**
     * Expected request correlation ID.
     */
    requestId?: string;
    /**
     * Expected trace ID.
     */
    traceId?: string;
    /**
     * Expected span ID.
     */
    spanId?: string;
    /**
     * Expected parent span ID.
     */
    parentSpanId?: string;
    /**
     * Expected traceparent header value.
     */
    traceparent?: string;
    /**
     * Expected watcher name.
     */
    watcher?: string;
    /**
     * Expected provider name. Matches `providerName` on provider lifecycle events
     * and `details.providerName` on provider instrumentation events.
     */
    providerName?: string;
    /**
     * Expected structured details. Object values are matched as partial objects.
     */
    details?: unknown;
    /**
     * Expected request method.
     */
    method?: string;
    /**
     * Expected request path.
     */
    path?: string;
    /**
     * Expected contract name.
     */
    contractName?: string;
    /**
     * Expected status. This matches request status codes as well as job, outbox,
     * and schedule status strings.
     */
    status?: unknown;
    /**
     * Expected duration in milliseconds.
     */
    durationMs?: number;
    /**
     * Expected human-readable summary.
     */
    summary?: string;
    /**
     * Expected error message.
     */
    message?: string;
    /**
     * Expected stack trace.
     */
    stack?: string;
    /**
     * Expected use-case name on error events.
     */
    useCaseName?: string;
    /**
     * Expected use-case or custom event name.
     */
    name?: string;
    /**
     * Expected use-case kind.
     */
    kind?: "command" | "query";
    /**
     * Expected use-case phase.
     */
    phase?: "start" | "end" | "error";
    /**
     * Expected error summary.
     */
    error?: string;
    /**
     * Expected event bus event name.
     */
    eventName?: string;
    /**
     * Expected job name.
     */
    jobName?: string;
    /**
     * Expected outbox message ID.
     */
    messageId?: string;
    /**
     * Expected outbox message kind.
     */
    messageKind?: "event" | "job";
    /**
     * Expected outbox message name.
     */
    messageName?: string;
    /**
     * Expected schedule name.
     */
    scheduleName?: string;
    /**
     * Expected schedule cron expression.
     */
    cron?: string;
    /**
     * Expected schedule time zone.
     */
    timezone?: string;
    /**
     * Expected provider lifecycle action.
     */
    action?: "setup" | "start" | "stop";
    /**
     * Expected custom event label.
     */
    label?: string;
}
/**
 * Source accepted by provider instrumentation assertion helpers.
 */
export type ProviderInstrumentationAssertionSource = readonly ProviderInstrumentationEventInput[] | {
    /**
     * Recorded provider instrumentation events.
     */
    readonly events: readonly ProviderInstrumentationEventInput[];
};
/**
 * Create a recording schedule runner for tests.
 *
 * The runner records schedule run intent without executing the schedule
 * handler. Use `createInlineScheduleRunner(...)` when the test should run the
 * handler.
 *
 * @returns A schedule runner plus its captured runs.
 */
export declare function createRecordingScheduleRunner(): {
    runner: ScheduleRunnerPort;
    runs: RecordedScheduleRun[];
};
/**
 * Create a provider instrumentation port for tests.
 *
 * The port records every event and can optionally disable specific watchers.
 * Use the returned `events` array with provider instrumentation assertion
 * helpers.
 *
 * @returns A provider instrumentation port plus its captured events.
 */
export declare function createRecordingProviderInstrumentation(options?: {
    enabledWatchers?: readonly string[];
    disabledWatchers?: readonly string[];
}): {
    instrumentation: ProviderInstrumentationPort;
    events: ProviderInstrumentationEventInput[];
};
/**
 * Options for creating a test user actor.
 */
export interface CreateTestUserActorOptions extends Omit<ActivityActor, "type" | "id" | "metadata"> {
    /**
     * Optional role stored as `actor.metadata.role`.
     */
    role?: string;
    /**
     * Additional redaction-safe actor metadata.
     */
    metadata?: ActivityMetadata;
}
/**
 * Options for creating a test actor that represents impersonated user access.
 */
export interface CreateTestImpersonatedUserActorOptions extends CreateTestUserActorOptions {
    /**
     * Stable ID for the actor performing the impersonation.
     */
    impersonatorId: string;
}
/**
 * Options for creating a test tenant.
 */
export type CreateTestTenantOptions = Omit<ActivityTenant, "id">;
/**
 * Context fields commonly shared by Beignet tests that exercise audit,
 * authorization, route hooks, and use cases.
 */
export interface TestActivityContext {
    /**
     * Actor under test.
     */
    actor: ActivityActor;
    /**
     * Tenant/account/workspace scope under test.
     */
    tenant?: ActivityTenant;
    /**
     * Stable request ID for assertions.
     */
    requestId: string;
    /**
     * Optional trace ID for assertions.
     */
    traceId?: string;
}
/**
 * Options for creating a test activity context.
 */
export interface CreateTestActivityContextOptions {
    /**
     * Actor under test.
     *
     * @default createTestUserActor()
     */
    actor?: ActivityActor;
    /**
     * Tenant under test. Pass `null` to omit tenant context.
     *
     * @default createTestTenant()
     */
    tenant?: ActivityTenant | null;
    /**
     * Request ID to expose on the context.
     *
     * @default "test-request"
     */
    requestId?: string;
    /**
     * Trace ID to expose on the context.
     *
     * @default "test-trace"
     */
    traceId?: string;
}
/**
 * Create a predictable user actor for tests.
 *
 * Use this when authorization or audit assertions need a stable actor shape
 * without repeating the `ActivityActor` object in every test.
 *
 * @param id - Stable user ID for the test actor.
 * @param options - Optional display name, role, and metadata.
 * @returns A user actor with `type: "user"`.
 */
export declare function createTestUserActor(id?: string, options?: CreateTestUserActorOptions): ActivityActor;
/**
 * Create a predictable user actor for tests that exercise impersonation.
 *
 * The returned actor remains the effective user, with `metadata.impersonatorId`
 * recording who initiated the impersonated access.
 *
 * @param id - Stable user ID being impersonated.
 * @param options - Impersonator ID plus optional display name, role, and metadata.
 * @returns A user actor with impersonation metadata.
 */
export declare function createTestImpersonatedUserActor(id: string, options: CreateTestImpersonatedUserActorOptions): ActivityActor;
/**
 * Create a predictable anonymous actor for tests.
 *
 * @param options - Optional display name or metadata.
 * @returns An anonymous actor with `type: "anonymous"`.
 */
export declare function createTestAnonymousActor(options?: Omit<ActivityActor, "type">): ActivityActor;
/**
 * Create a predictable service actor for tests.
 *
 * @param id - Stable service ID.
 * @param options - Optional display name or metadata.
 * @returns A service actor with `type: "service"`.
 */
export declare function createTestServiceActor(id?: string, options?: Omit<ActivityActor, "type" | "id">): ActivityActor;
/**
 * Create a predictable system actor for tests.
 *
 * @param id - Stable system actor ID.
 * @param options - Optional display name or metadata.
 * @returns A system actor with `type: "system"`.
 */
export declare function createTestSystemActor(id?: string, options?: Omit<ActivityActor, "type" | "id">): ActivityActor;
/**
 * Create a predictable tenant for tests.
 *
 * @param id - Stable tenant ID.
 * @param options - Optional slug or metadata.
 * @returns A tenant descriptor.
 */
export declare function createTestTenant(id?: string, options?: CreateTestTenantOptions): ActivityTenant;
/**
 * Create the activity fields commonly copied onto app test contexts.
 *
 * @param options - Optional actor, tenant, request ID, and trace ID overrides.
 * @returns Stable activity context fields for a test.
 */
export declare function createTestActivityContext(options?: CreateTestActivityContextOptions): TestActivityContext;
/**
 * Expected audit fields used by audit assertion helpers.
 */
export interface AuditLogEntryExpectation {
    /**
     * Expected action name.
     */
    action?: string;
    /**
     * Expected actor fields.
     */
    actor?: Partial<ActivityActor>;
    /**
     * Convenience matcher for `entry.actor.id`.
     */
    actorId?: string;
    /**
     * Convenience matcher for `entry.actor.type`.
     */
    actorType?: ActivityActor["type"];
    /**
     * Expected tenant fields.
     */
    tenant?: Partial<ActivityTenant>;
    /**
     * Convenience matcher for `entry.tenant.id`.
     */
    tenantId?: string;
    /**
     * Expected resource fields.
     */
    resource?: Partial<ActivityResource>;
    /**
     * Convenience matcher for `entry.resource.id`.
     */
    resourceId?: string;
    /**
     * Convenience matcher for `entry.resource.type`.
     */
    resourceType?: string;
    /**
     * Expected audit outcome.
     */
    outcome?: AuditOutcome;
    /**
     * Convenience matcher for `entry.metadata.severity`.
     */
    severity?: ActivityMetadataValue;
    /**
     * Expected request ID.
     */
    requestId?: string;
    /**
     * Expected trace ID.
     */
    traceId?: string;
    /**
     * Expected metadata fields. Object values are matched as partial objects.
     */
    metadata?: ActivityMetadata;
}
/**
 * Expected mail delivery fields used by mail assertion helpers.
 */
export interface MailDeliveryExpectation {
    /**
     * Expected memory delivery ID.
     */
    id?: string;
    /**
     * Expected subject.
     */
    subject?: string;
    /**
     * Expected recipients.
     */
    to?: NormalizedMailMessage["to"];
    /**
     * Expected sender.
     */
    from?: NormalizedMailMessage["from"];
    /**
     * Expected text body.
     */
    text?: string;
    /**
     * Expected HTML body.
     */
    html?: string;
    /**
     * Expected message headers.
     */
    headers?: Record<string, string>;
    /**
     * Expected normalized message fields.
     */
    message?: Partial<NormalizedMailMessage>;
}
/**
 * Expected notification delivery fields used by notification assertion helpers.
 */
export interface NotificationDeliveryExpectation {
    /**
     * Expected memory delivery ID.
     */
    id?: string;
    /**
     * Expected notification name.
     */
    notificationName?: string;
    /**
     * Expected parsed payload. Object values are matched as partial objects.
     */
    payload?: unknown;
    /**
     * Expected selected channels.
     */
    channels?: readonly string[];
    /**
     * Expected delivery metadata. Object values are matched as partial objects.
     */
    metadata?: Record<string, unknown>;
}
/**
 * Expected storage object fields used by storage assertion helpers.
 */
export interface StorageObjectExpectation {
    /**
     * Object key to look up.
     */
    key: string;
    /**
     * Expected size in bytes.
     */
    size?: number;
    /**
     * Expected content type.
     */
    contentType?: string;
    /**
     * Expected cache-control value.
     */
    cacheControl?: string;
    /**
     * Expected storage metadata.
     */
    metadata?: Record<string, string>;
    /**
     * Expected visibility.
     */
    visibility?: StorageVisibility;
    /**
     * Expected text body. Cannot be combined with `bytes`.
     */
    text?: string;
    /**
     * Expected object bytes. Cannot be combined with `text`.
     */
    bytes?: Uint8Array;
}
/**
 * Source accepted by outbox message assertion helpers.
 *
 * Use a `MemoryOutboxPort` or a snapshot returned by a test adapter. Durable
 * SQL adapters should expose app-owned snapshots rather than widening the
 * production `OutboxPort` read surface.
 */
export type OutboxMessageAssertionSource = readonly OutboxMessage[] | {
    /**
     * Current outbox message snapshots.
     */
    readonly messages: readonly OutboxMessage[];
};
/**
 * Expected outbox message fields used by outbox assertion helpers.
 */
export interface OutboxMessageExpectation {
    /**
     * Expected message ID.
     */
    id?: string;
    /**
     * Expected message kind.
     */
    kind?: OutboxMessageKind;
    /**
     * Expected event or job name.
     */
    name?: string;
    /**
     * Expected JSON payload. Object values are matched as partial objects.
     */
    payload?: unknown;
    /**
     * Expected delivery status.
     */
    status?: OutboxMessageStatus;
    /**
     * Expected claim attempt count.
     */
    attempts?: number;
    /**
     * Expected maximum delivery attempts.
     */
    maxAttempts?: number;
    /**
     * Expected delivery timestamp.
     */
    deliveredAt?: Date | null;
    /**
     * Expected serialized delivery error. Object values are matched as partial
     * objects. Pass `null` to assert no error has been recorded.
     */
    lastError?: Partial<OutboxErrorInfo> | null;
}
/**
 * Expected fields for one outbox drain result assertion.
 */
export interface OutboxDrainResultExpectation {
    /**
     * Expected claimed count.
     */
    claimed?: number;
    /**
     * Expected delivered count.
     */
    delivered?: number;
    /**
     * Expected retried count.
     */
    retried?: number;
    /**
     * Expected dead-lettered count.
     */
    deadLettered?: number;
}
/**
 * Source accepted by idempotency entry assertion helpers.
 *
 * Use a `MemoryIdempotencyStore` or a snapshot array from an app-owned adapter.
 * Durable SQL adapters should expose app-owned snapshots rather than widening
 * the production `IdempotencyPort` read surface.
 */
export type IdempotencyEntryAssertionSource = readonly MemoryIdempotencyEntry[] | Pick<MemoryIdempotencyStore, "entries">;
/**
 * Expected idempotency entry fields used by idempotency assertion helpers.
 */
export interface IdempotencyEntryExpectation {
    /**
     * Expected operation namespace.
     */
    namespace?: string;
    /**
     * Expected client-provided idempotency key.
     */
    key?: string;
    /**
     * Expected normalized scope key.
     */
    scopeKey?: string;
    /**
     * Expected request fingerprint.
     */
    fingerprint?: string;
    /**
     * Expected reservation status.
     */
    status?: MemoryIdempotencyEntry["status"];
    /**
     * Expected replay result. Object values are matched as partial objects.
     */
    result?: unknown;
    /**
     * Expected reservation timestamp.
     */
    reservedAt?: Date;
    /**
     * Expected completion timestamp.
     */
    completedAt?: Date;
    /**
     * Expected expiration timestamp, or `null` when no expiration is set.
     */
    expiresAt?: Date | null;
}
/**
 * Find the first audit entry matching the expected fields.
 *
 * @param entries - Audit entries captured by a memory or fake audit port.
 * @param expectation - Partial audit fields to match.
 * @returns The first matching entry, or `undefined`.
 */
export declare function findAuditEntry(entries: readonly AuditLogEntry[], expectation: AuditLogEntryExpectation): AuditLogEntry | undefined;
/**
 * Assert that an audit entry exists and return the matching entry.
 *
 * The helper throws a plain `Error`, so it works with Bun, Vitest, Jest, and
 * other test runners.
 *
 * @param entries - Audit entries captured by a memory or fake audit port.
 * @param expectation - Partial audit fields to match.
 * @returns The matching audit entry.
 * @throws Error when no entry matches.
 */
export declare function assertAuditEntry(entries: readonly AuditLogEntry[], expectation: AuditLogEntryExpectation): AuditLogEntry;
/**
 * Assert that no audit entry matches the expected fields.
 *
 * @param entries - Audit entries captured by a memory or fake audit port.
 * @param expectation - Partial audit fields to reject.
 * @throws Error when a matching entry exists.
 */
export declare function assertNoAuditEntry(entries: readonly AuditLogEntry[], expectation: AuditLogEntryExpectation): void;
/**
 * Find the first recorded event matching the expected fields.
 *
 * @param events - Events captured by `createRecordingEventBus(...)`.
 * @param expectation - Partial event fields to match.
 * @returns The first matching event, or `undefined`.
 */
export declare function findRecordedEvent(events: readonly RecordedEvent[], expectation: RecordedEventExpectation): RecordedEvent | undefined;
/**
 * Assert that a recorded event exists and return the matching event.
 *
 * @param events - Events captured by `createRecordingEventBus(...)`.
 * @param expectation - Partial event fields to match.
 * @returns The matching event.
 * @throws Error when no event matches.
 */
export declare function assertRecordedEvent(events: readonly RecordedEvent[], expectation: RecordedEventExpectation): RecordedEvent;
/**
 * Assert that no recorded event matches the expected fields.
 *
 * @param events - Events captured by `createRecordingEventBus(...)`.
 * @param expectation - Partial event fields to reject.
 * @throws Error when a matching event exists.
 */
export declare function assertNoRecordedEvent(events: readonly RecordedEvent[], expectation: RecordedEventExpectation): void;
/**
 * Find the first recorded job dispatch matching the expected fields.
 *
 * @param jobs - Job dispatches captured by `createRecordingJobDispatcher(...)`.
 * @param expectation - Partial job fields to match.
 * @returns The first matching dispatch, or `undefined`.
 */
export declare function findDispatchedJob(jobs: readonly RecordedJobDispatch[], expectation: RecordedJobDispatchExpectation): RecordedJobDispatch | undefined;
/**
 * Assert that a job was dispatched and return the matching dispatch.
 *
 * @param jobs - Job dispatches captured by `createRecordingJobDispatcher(...)`.
 * @param expectation - Partial job fields to match.
 * @returns The matching dispatch.
 * @throws Error when no dispatch matches.
 */
export declare function assertDispatchedJob(jobs: readonly RecordedJobDispatch[], expectation: RecordedJobDispatchExpectation): RecordedJobDispatch;
/**
 * Assert that no job dispatch matches the expected fields.
 *
 * @param jobs - Job dispatches captured by `createRecordingJobDispatcher(...)`.
 * @param expectation - Partial job fields to reject.
 * @throws Error when a matching dispatch exists.
 */
export declare function assertNoDispatchedJob(jobs: readonly RecordedJobDispatch[], expectation: RecordedJobDispatchExpectation): void;
/**
 * Find the first recorded schedule run matching the expected fields.
 *
 * @param runs - Runs captured by `createRecordingScheduleRunner(...)`.
 * @param expectation - Partial schedule fields to match.
 * @returns The first matching schedule run, or `undefined`.
 */
export declare function findScheduleRun(runs: readonly RecordedScheduleRun[], expectation: RecordedScheduleRunExpectation): RecordedScheduleRun | undefined;
/**
 * Find the first provider instrumentation event matching the expected fields.
 *
 * @param source - Recording instrumentation result or event snapshot array.
 * @param expectation - Partial event fields to match.
 * @returns The first matching event, or `undefined`.
 */
export declare function findProviderInstrumentationEvent(source: ProviderInstrumentationAssertionSource, expectation: ProviderInstrumentationEventExpectation): ProviderInstrumentationEventInput | undefined;
/**
 * Assert that a provider instrumentation event exists and return it.
 *
 * @param source - Recording instrumentation result or event snapshot array.
 * @param expectation - Partial event fields to match.
 * @returns The matching event.
 * @throws Error when no event matches.
 */
export declare function assertProviderInstrumentationEvent(source: ProviderInstrumentationAssertionSource, expectation: ProviderInstrumentationEventExpectation): ProviderInstrumentationEventInput;
/**
 * Assert that no provider instrumentation event matches the expected fields.
 *
 * @param source - Recording instrumentation result or event snapshot array.
 * @param expectation - Partial event fields to reject.
 * @throws Error when a matching event exists.
 */
export declare function assertNoProviderInstrumentationEvent(source: ProviderInstrumentationAssertionSource, expectation: ProviderInstrumentationEventExpectation): void;
/**
 * Assert that a schedule run was recorded and return the matching run.
 *
 * @param runs - Runs captured by `createRecordingScheduleRunner(...)`.
 * @param expectation - Partial schedule fields to match.
 * @returns The matching schedule run.
 * @throws Error when no run matches.
 */
export declare function assertScheduleRun(runs: readonly RecordedScheduleRun[], expectation: RecordedScheduleRunExpectation): RecordedScheduleRun;
/**
 * Assert that no schedule run matches the expected fields.
 *
 * @param runs - Runs captured by `createRecordingScheduleRunner(...)`.
 * @param expectation - Partial schedule fields to reject.
 * @throws Error when a matching run exists.
 */
export declare function assertNoScheduleRun(runs: readonly RecordedScheduleRun[], expectation: RecordedScheduleRunExpectation): void;
/**
 * Find the first mail delivery matching the expected fields.
 *
 * @param deliveries - Deliveries captured by `createMemoryMailer(...)`.
 * @param expectation - Partial delivery or message fields to match.
 * @returns The first matching delivery, or `undefined`.
 */
export declare function findMailDelivery(deliveries: readonly MemoryMailDelivery[], expectation: MailDeliveryExpectation): MemoryMailDelivery | undefined;
/**
 * Assert that a mail delivery exists and return the matching delivery.
 *
 * @param deliveries - Deliveries captured by `createMemoryMailer(...)`.
 * @param expectation - Partial delivery or message fields to match.
 * @returns The matching delivery.
 * @throws Error when no delivery matches.
 */
export declare function assertMailDelivery(deliveries: readonly MemoryMailDelivery[], expectation: MailDeliveryExpectation): MemoryMailDelivery;
/**
 * Assert that no mail delivery matches the expected fields.
 *
 * @param deliveries - Deliveries captured by `createMemoryMailer(...)`.
 * @param expectation - Partial delivery or message fields to reject.
 * @throws Error when a matching delivery exists.
 */
export declare function assertNoMailDelivery(deliveries: readonly MemoryMailDelivery[], expectation: MailDeliveryExpectation): void;
/**
 * Find the first notification delivery matching the expected fields.
 *
 * @param deliveries - Deliveries captured by `createMemoryNotificationPort(...)`.
 * @param expectation - Partial delivery fields to match.
 * @returns The first matching delivery, or `undefined`.
 */
export declare function findNotificationDelivery(deliveries: readonly MemoryNotificationDelivery[], expectation: NotificationDeliveryExpectation): MemoryNotificationDelivery | undefined;
/**
 * Assert that a notification delivery exists and return the matching delivery.
 *
 * @param deliveries - Deliveries captured by `createMemoryNotificationPort(...)`.
 * @param expectation - Partial delivery fields to match.
 * @returns The matching delivery.
 * @throws Error when no delivery matches.
 */
export declare function assertNotificationDelivery(deliveries: readonly MemoryNotificationDelivery[], expectation: NotificationDeliveryExpectation): MemoryNotificationDelivery;
/**
 * Assert that no notification delivery matches the expected fields.
 *
 * @param deliveries - Deliveries captured by `createMemoryNotificationPort(...)`.
 * @param expectation - Partial delivery fields to reject.
 * @throws Error when a matching delivery exists.
 */
export declare function assertNoNotificationDelivery(deliveries: readonly MemoryNotificationDelivery[], expectation: NotificationDeliveryExpectation): void;
/**
 * Assert that a storage object exists and optionally matches metadata/body
 * expectations.
 *
 * This helper works against any `StoragePort`, not only memory storage.
 *
 * @param storage - Storage port under test.
 * @param expectation - Object key and expected fields.
 * @returns The matching object metadata.
 * @throws Error when the object is missing or does not match.
 */
export declare function assertStorageObject(storage: StoragePort, expectation: StorageObjectExpectation): Promise<StorageObject>;
/**
 * Assert that a storage object does not exist.
 *
 * @param storage - Storage port under test.
 * @param key - Object key expected to be absent.
 * @throws Error when the object exists.
 */
export declare function assertNoStorageObject(storage: StoragePort, key: string): Promise<void>;
/**
 * Find the first outbox message matching expected fields.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Partial message fields to match.
 * @returns The first matching message, or `undefined`.
 */
export declare function findOutboxMessage(source: OutboxMessageAssertionSource, expectation: OutboxMessageExpectation): OutboxMessage | undefined;
/**
 * Find the first idempotency entry matching expected fields.
 *
 * @param source - Memory idempotency store or entry snapshot array.
 * @param expectation - Partial entry fields to match.
 * @returns The first matching entry, or `undefined`.
 */
export declare function findIdempotencyEntry(source: IdempotencyEntryAssertionSource, expectation: IdempotencyEntryExpectation): MemoryIdempotencyEntry | undefined;
/**
 * Assert that an idempotency entry exists and return it.
 *
 * @param source - Memory idempotency store or entry snapshot array.
 * @param expectation - Partial entry fields to match.
 * @returns The matching entry.
 * @throws Error when no entry matches.
 */
export declare function assertIdempotencyEntry(source: IdempotencyEntryAssertionSource, expectation: IdempotencyEntryExpectation): MemoryIdempotencyEntry;
/**
 * Assert that no idempotency entry matches expected fields.
 *
 * @param source - Memory idempotency store or entry snapshot array.
 * @param expectation - Partial entry fields to reject.
 * @throws Error when a matching entry exists.
 */
export declare function assertNoIdempotencyEntry(source: IdempotencyEntryAssertionSource, expectation: IdempotencyEntryExpectation): void;
/**
 * Assert that a matching idempotency entry is still in progress.
 *
 * @param source - Memory idempotency store or entry snapshot array.
 * @param expectation - Entry fields to match.
 * @returns The matching in-progress entry.
 */
export declare function assertIdempotencyInProgress(source: IdempotencyEntryAssertionSource, expectation?: Omit<IdempotencyEntryExpectation, "status">): MemoryIdempotencyEntry;
/**
 * Assert that a matching idempotency entry completed.
 *
 * @param source - Memory idempotency store or entry snapshot array.
 * @param expectation - Entry fields to match.
 * @returns The matching completed entry.
 */
export declare function assertIdempotencyCompleted(source: IdempotencyEntryAssertionSource, expectation?: Omit<IdempotencyEntryExpectation, "status">): MemoryIdempotencyEntry;
/**
 * Assert that an outbox message exists and return it.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Partial message fields to match.
 * @returns The matching message.
 * @throws Error when no message matches.
 */
export declare function assertOutboxMessage(source: OutboxMessageAssertionSource, expectation: OutboxMessageExpectation): OutboxMessage;
/**
 * Assert that no outbox message matches expected fields.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Partial message fields to reject.
 * @throws Error when a matching message exists.
 */
export declare function assertNoOutboxMessage(source: OutboxMessageAssertionSource, expectation: OutboxMessageExpectation): void;
/**
 * Assert that an outbox message is pending.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Message fields to match.
 * @returns The matching pending message.
 */
export declare function assertOutboxPending(source: OutboxMessageAssertionSource, expectation?: Omit<OutboxMessageExpectation, "status">): OutboxMessage;
/**
 * Assert that an outbox message was delivered.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Message fields to match.
 * @returns The matching delivered message.
 */
export declare function assertOutboxDelivered(source: OutboxMessageAssertionSource, expectation?: Omit<OutboxMessageExpectation, "status">): OutboxMessage;
/**
 * Assert that an outbox message is pending after at least one failed attempt.
 *
 * Use this for retry-scheduled assertions after `drainOutbox(...)` returns a
 * retried count.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Message fields to match.
 * @returns The matching retry-scheduled message.
 */
export declare function assertOutboxRetryScheduled(source: OutboxMessageAssertionSource, expectation?: Omit<OutboxMessageExpectation, "status">): OutboxMessage;
/**
 * Assert that an outbox message was dead-lettered.
 *
 * @param source - Memory outbox or message snapshot array.
 * @param expectation - Message fields to match.
 * @returns The matching dead-lettered message.
 */
export declare function assertOutboxDeadLettered(source: OutboxMessageAssertionSource, expectation?: Omit<OutboxMessageExpectation, "status">): OutboxMessage;
/**
 * Assert that a drain result matches expected counts.
 *
 * @param result - Result returned by `drainOutbox(...)`.
 * @param expectation - Partial count expectation.
 * @throws Error when any supplied count differs.
 */
export declare function assertOutboxDrainResult(result: DrainOutboxResult, expectation: OutboxDrainResultExpectation): void;
/**
 * Expected outcome for one policy matrix case.
 */
export type PolicyMatrixExpectation = "allow" | "deny";
type PolicyMatrixSubject<TResolver> = PolicySubjectArgs<TResolver> extends [subject: infer Subject] ? {
    subject: Subject;
} : {
    subject?: never;
};
/**
 * One typed authorization matrix case for a policy ability.
 */
export type PolicyMatrixCase<TContext, TPolicies extends readonly PolicyDefinition[] = readonly PolicyDefinition[]> = {
    [TAbility in keyof PolicyMapFromDefinitions<TPolicies> & string]: {
        name: string;
        ctx: TContext;
        ability: TAbility;
        expected: PolicyMatrixExpectation;
        reason?: string;
        code?: string;
    } & PolicyMatrixSubject<PolicyMapFromDefinitions<TPolicies>[TAbility]>;
}[keyof PolicyMapFromDefinitions<TPolicies> & string];
/**
 * Untyped policy matrix case used internally for failure reporting.
 */
export type UntypedPolicyMatrixCase<TContext> = {
    name: string;
    ctx: TContext;
    ability: string;
    subject?: unknown;
    expected: PolicyMatrixExpectation;
    reason?: string;
    code?: string;
};
/**
 * Result for one evaluated policy matrix case.
 */
export type PolicyMatrixResult<TContext, TPolicies extends readonly PolicyDefinition[] = readonly PolicyDefinition[]> = {
    case: PolicyMatrixCase<TContext, TPolicies>;
    decision: GateDecision;
    passed: boolean;
    message?: string;
};
/**
 * Test helper for evaluating authorization policies.
 */
export type PolicyTester<TContext, TPolicies extends readonly PolicyDefinition[]> = {
    /**
     * Gate created from the same policies, useful for direct assertions.
     */
    gate: GatePort<TContext, TPolicies>;
    /**
     * Evaluate cases and return structured pass/fail results.
     */
    evaluateMatrix(cases: readonly PolicyMatrixCase<TContext, TPolicies>[]): Promise<PolicyMatrixResult<TContext, TPolicies>[]>;
    /**
     * Evaluate cases and throw a combined assertion error when any fail.
     */
    assertMatrix(cases: readonly PolicyMatrixCase<TContext, TPolicies>[]): Promise<void>;
};
/**
 * Create a policy tester from the same options used by `createGate(...)`.
 *
 * Use this for table-driven authorization tests that document who can perform
 * each ability against which subject.
 *
 * @param options - Policy definitions and optional denial mapper.
 * @returns A policy tester with a gate plus matrix helpers.
 */
export declare function createPolicyTester<const TPolicies extends readonly PolicyDefinition[]>(options: CreateGateOptions<PolicyContextFromDefinitions<TPolicies>, TPolicies>): PolicyTester<PolicyContextFromDefinitions<TPolicies>, TPolicies>;
/**
 * Evaluate a table of policy cases without throwing.
 *
 * @param gate - Gate under test.
 * @param cases - Matrix cases to evaluate.
 * @returns Structured result for each case.
 */
export declare function evaluatePolicyMatrix<TContext, TPolicies extends readonly PolicyDefinition[]>(gate: GatePort<TContext, TPolicies>, cases: readonly PolicyMatrixCase<TContext, TPolicies>[]): Promise<PolicyMatrixResult<TContext, TPolicies>[]>;
/**
 * Assert that all policy matrix cases pass.
 *
 * @param gate - Gate under test.
 * @param cases - Matrix cases to evaluate.
 * @throws Combined error listing every failed case.
 */
export declare function assertPolicyMatrix<TContext, TPolicies extends readonly PolicyDefinition[]>(gate: GatePort<TContext, TPolicies>, cases: readonly PolicyMatrixCase<TContext, TPolicies>[]): Promise<void>;
export {};
//# sourceMappingURL=testing.d.ts.map