/** * Owner-scoped registry for interactive sessions. * * Records carry no command, input, environment value, prompt, or output — only * opaque identity, state, cursors, and outcome metadata. Interactive records are * intentionally separate from `JobManager` records: the two domains have * different ownership, policy, and cleanup contracts. */ import { type InteractiveSessionRecord, type ProcessOutcome, type SessionState, type SessionSummary, type TerminationReason } from "./types.js"; export declare function canTransition(from: SessionState, to: SessionState): boolean; export declare class SessionRegistry { private readonly records; private readonly byOwner; /** Process-lifetime issued ids: never reused, even after removal. */ private readonly issuedIds; private readonly ownerLocks; private readonly fencedOwners; /** * Serialize id issuance and live-slot reservation for one owner so two * concurrent starts cannot both pass the live limit. */ withOwnerLock(ownerId: string, fn: () => Promise | T): Promise; mintId(): string; liveCount(ownerId: string): number; insert(record: InteractiveSessionRecord): void; /** * Owner mismatch is indistinguishable from a missing id: callers must not be * able to use this lookup as an existence oracle for another conversation. */ get(ownerId: string, id: string): InteractiveSessionRecord | undefined; /** Unscoped access for cleanup/lifecycle paths that already own the record. */ getUnscoped(id: string): InteractiveSessionRecord | undefined; liveRecords(ownerId: string): InteractiveSessionRecord[]; allLiveRecords(): InteractiveSessionRecord[]; owners(): string[]; /** Live first, then descending start time, capped for model consumption. */ list(ownerId: string): SessionSummary[]; /** * Compare-and-transition. Returns false when the transition is not allowed, * which is how a late exit observation loses to a committed terminal state. */ transition(record: InteractiveSessionRecord, to: SessionState, patch?: { terminationReason?: TerminationReason | undefined; processOutcome?: ProcessOutcome | undefined; cleanupVerified?: boolean | undefined; now?: number | undefined; }): boolean; /** Add outcome facts without replacing a chosen terminal state. */ enrich(record: InteractiveSessionRecord, patch: { terminationReason?: TerminationReason | undefined; processOutcome?: ProcessOutcome | undefined; cleanupVerified?: boolean | undefined; }): void; /** Fence an owner before its id is rebound so no new operation can enter. */ fenceOwner(ownerId: string): void; unfenceOwner(ownerId: string): void; isFenced(ownerId: string): boolean; private pruneTerminal; }