import type { IControllerResourceDocument } from '../dist_ts/interfaces.projects.js'; import type { TControllerSessionId } from '../dist_ts_interfaces/index.js'; /** * The resource document as it was persisted while a resource had at most one attachment subject. * Frozen here rather than imported, because the live assertion now describes the set and would * reject every historical document. */ export interface IV31LegacyResourceDocument { id: string; controllerId: string; projectId: string; kind: 'terminal' | 'browser'; attachmentAuthorityId: string; attachmentRevision: number; sessionId: TControllerSessionId | null; sessionIdentityId?: string; terminalTarget?: { resourceId: string; agentSessionId?: string; }; updatedAt: Date; [key: string]: unknown; } export interface IV31ResourceMigrationResult { document: IControllerResourceDocument; migrated: boolean; } /** * A document that already carries the set must be left exactly as it is. * * `attachments` is the positive signal: the lift always writes it, including as an empty array * for a detached resource. Testing for an absent `sessionId` instead would read a detached legacy * document as already lifted and never migrate it. */ export declare const isV31AttachmentSetDocument: (valueArg: unknown) => valueArg is IControllerResourceDocument; /** * Lifts a single-subject resource document into the attachment set. * * The one subject it carried becomes a one-element set; a detached resource becomes an empty one. * `attachedAt` is the document's own `updatedAt`, which is the last moment the attachment can * have changed. A pending single-subject intent is dropped rather than translated: it is a * write-before-side-effect obligation whose side effect is re-driven by the coordinator's * recovery pass, and inventing an `op` for it would guess at an intent the document never stated. */ export declare const migrateV31ResourceDocument: (valueArg: IV31LegacyResourceDocument | IControllerResourceDocument) => IV31ResourceMigrationResult;