import type { IdentityBinding, Person, ContentGrant, ConnectorGrant, PolicyAuditEvent, StudioRoleGrant } from '../policy/types.js'; import type { QuarantineRecord } from '../security/quarantine.js'; import type { ActorRef, StateRecord } from '../state-machine/types.js'; export type RecoveryStatus = 'clean' | 'snapshot_rebuilt' | 'tail_recovered' | 'failed'; export interface ScopedIdempotency { readonly namespace: string; readonly scopeId: string; readonly key: string; } export interface ExpectedAggregateRevision { readonly aggregateType: string; readonly aggregateId: string; readonly revision: number; } export interface DurableAuditInput { readonly eventId: string; readonly eventName: string; readonly actor: ActorRef; readonly reason: string; readonly correlationId: string; readonly occurredAt: string; readonly entityId?: string; readonly fromState?: string; readonly toState?: string; readonly fromRevision?: number; readonly toRevision?: number; readonly outcome?: 'applied' | 'denied' | 'retryable'; readonly denialReason?: string; readonly projectId?: string; readonly personId?: string; readonly role?: string; readonly capability?: string; readonly targetId?: string; } export interface DurableAuditRecord extends DurableAuditInput { readonly transactionId: string; readonly sequence: number; readonly recoveryStatus: RecoveryStatus; } export interface DurableOutboxMessage { readonly messageId: string; readonly topic: string; readonly payload: unknown; } export interface DurableOutboxRecord extends DurableOutboxMessage { readonly status: 'pending' | 'delivered'; readonly attemptCount: number; readonly createdSequence: number; readonly deliveredSequence?: number; readonly claim?: { readonly ownerId: string; readonly claimToken: string; readonly generation: number; readonly claimedAt: string; readonly expiresAt: string; }; readonly lastFailure?: { readonly failedAt: string; readonly generation: number; readonly reasonCode: 'DELIVERY_FAILED'; }; } export type DurableOperation = { readonly kind: 'machine.put'; readonly key: string; readonly record: StateRecord; } | { readonly kind: 'audit.append'; readonly event: DurableAuditInput; } | { readonly kind: 'identity.person.put'; readonly person: Person; } | { readonly kind: 'identity.binding.put'; readonly binding: IdentityBinding; } | { readonly kind: 'identity.binding.revoke'; readonly provider: string; readonly subject: string; readonly revokedAt: string; } | { readonly kind: 'policy.project.put'; readonly projectId: string; } | { readonly kind: 'policy.content.grant'; readonly grant: ContentGrant; } | { readonly kind: 'policy.content.revoke'; readonly grant: ContentGrant; } | { readonly kind: 'policy.connector.grant'; readonly grant: ConnectorGrant; } | { readonly kind: 'policy.connector.revoke'; readonly grant: ConnectorGrant; } | { readonly kind: 'policy.studio-admin.grant'; readonly personId: string; } | { readonly kind: 'policy.studio-admin.revoke'; readonly personId: string; } | { readonly kind: 'policy.studio-role.grant'; readonly grant: StudioRoleGrant; } | { readonly kind: 'policy.studio-role.revoke'; readonly grant: StudioRoleGrant; } | { readonly kind: 'policy.bootstrap.close'; } | { readonly kind: 'policy.audit.append'; readonly event: PolicyAuditEvent; } | { readonly kind: 'quarantine.put'; readonly record: QuarantineRecord; } | { readonly kind: 'outbox.enqueue'; readonly message: DurableOutboxMessage; } | { readonly kind: 'outbox.attempt'; readonly messageId: string; readonly ownerId: string; readonly claimToken: string; readonly generation: number; readonly attemptedAt: string; readonly expiresAt: string; } | { readonly kind: 'outbox.ack'; readonly messageId: string; readonly ownerId: string; readonly claimToken: string; readonly generation: number; readonly deliveredAt: string; } | { readonly kind: 'outbox.fail'; readonly messageId: string; readonly ownerId: string; readonly claimToken: string; readonly generation: number; readonly failedAt: string; readonly reasonCode: 'DELIVERY_FAILED'; } | { readonly kind: 'claim.put'; readonly namespace: string; readonly claimId: string; }; export interface DurableTransactionRequest { readonly transactionId: string; readonly occurredAt: string; readonly idempotency: ScopedIdempotency; readonly checkedRevisions: readonly ExpectedAggregateRevision[]; readonly mutatedRevisions: readonly ExpectedAggregateRevision[]; readonly operations: readonly DurableOperation[]; } export interface DurableJournalRecord extends DurableTransactionRequest { readonly schemaVersion: 1; readonly sequence: number; readonly timestamp: string; readonly recoveryStatus: Exclude; readonly previousHash: string | null; readonly domain: DurableJournalDomain; readonly signature: string; readonly checksum: string; } export interface DurableJournalDomain { readonly version: 1; readonly purpose: 'durable-journal-record'; readonly storeId: string; readonly rootDigest: string; readonly audience: string; readonly authorityDigest: string; readonly keyId: string; } export interface DurableBootstrapPlan { readonly version: 1; readonly purpose: 'durable-runtime-bootstrap'; readonly keyId: string; readonly storeId: string; readonly root: string; readonly rootDigest: string; readonly audience: string; readonly authorityDigest: string; readonly genesisRecordDigest: string; readonly authorizationId: string; readonly actor: ActorRef; readonly occurredAt: string; readonly expiresAt: string; readonly nonce: string; readonly people: readonly Person[]; readonly bindings: readonly IdentityBinding[]; readonly projects: readonly string[]; readonly adminSubject: { readonly provider: 'github' | 'slack' | 'email' | 'runtime'; readonly subject: string; }; readonly journalAuthority: { readonly keyId: string; readonly publicKey: string; }; readonly securityProvider: DurableSecurityProviderIdentity; } export interface SignedDurableBootstrapEnvelope { readonly payload: DurableBootstrapPlan; readonly signature: string; } export interface DurableJournalSigner { readonly keyId: string; readonly identity: DurableSecurityProviderIdentity; sign(request: { readonly domain: DurableJournalDomain; readonly payload: Uint8Array; }): Promise; } export interface DurableSecurityProviderIdentity { readonly id: string; readonly digest: string; readonly epoch: number; readonly protocolVersion: 1; } export interface DurableHead { readonly storeId: string; readonly sequence: number; readonly headHash: string; } export interface DurableHeadAdvance extends DurableHead { readonly expectedSequence: number; readonly expectedHeadHash: string; readonly nonceDigest?: string; } export interface DurableHeadAnchor { readonly identity: DurableSecurityProviderIdentity; read(storeId: string): Promise; readSync(storeId: string): DurableHead; compareAndSet(next: DurableHeadAdvance): Promise<'advanced' | 'conflict' | 'nonce-reused'>; } export interface BootstrapVerificationKey { readonly publicKey: string; readonly state: 'active' | 'retired' | 'revoked'; } export interface DurableJournalSecurity { readonly audience: string; readonly providerIdentity: DurableSecurityProviderIdentity; readonly bootstrapPublicKeys: Readonly>; readonly envelope: SignedDurableBootstrapEnvelope; readonly signer?: DurableJournalSigner; readonly headAnchor: DurableHeadAnchor; readonly now: () => string; } export interface DurableProjection { readonly aggregateRevisions: Record; readonly machines: Record>; readonly people: Person[]; readonly identityBindings: IdentityBinding[]; readonly projects: string[]; readonly contentGrants: ContentGrant[]; readonly connectorGrants: ConnectorGrant[]; readonly studioAdmins: string[]; readonly studioRoleGrants: StudioRoleGrant[]; readonly bootstrapClosed: boolean; readonly policyAudit: Array; readonly audit: DurableAuditRecord[]; readonly quarantine: Record; readonly outbox: Record; readonly claims: Record; readonly idempotency: Array; } export interface DurableSnapshot { readonly schemaVersion: 1; readonly throughSequence: number; readonly journalHeadHash: string; readonly storeRevision: number; readonly recoveryStatus: Exclude; readonly projection: DurableProjection; readonly checksum: string; } export interface DurableReadState extends DurableSnapshot { readonly forensicArtifacts: readonly string[]; } export type DurableTransactionResult = { readonly status: 'committed'; readonly sequence: number; readonly transactionId: string; } | { readonly status: 'duplicate'; readonly transactionId: string; readonly sequence: number; } | { readonly status: 'conflict'; }; export type DurableFaultPhase = 'before-journal-append' | 'after-journal-write' | 'after-journal-sync' | 'before-snapshot-temp' | 'after-snapshot-sync' | 'before-snapshot-rename'; export interface DurableStateAdapterOptions { readonly stateRoot: string; readonly security: DurableJournalSecurity; readonly maxRecordBytes?: number; readonly lock?: import('./lock.js').OperationLockOptions; readonly fault?: (phase: DurableFaultPhase) => void; }