/** * SessionSummaryMaterializer — kernel terminalization primitive. * * The sole producer of {@link SessionSummaryRef}. No agent-callable surface * exists to bypass this (Convention #0 load-bearing — see * session-hierarchy.md §8.1). * * Atomicity contract (§8.1): the summary write and the owning session's * `non-terminal → idle` status flip commit as one logical unit. In the * InMemory store the two happen within the same method call under the store's * Map guard; in the Disk store they are two sequential write-tmp-renames * (summary.json first, then session.json). A mid-step crash leaves the * summary persisted but the session still active — `recover()` replays the * session-status flip idempotently on next boot. * * The class is function-call-style (no internal state beyond deps). Tests * inject a fake generator for deterministic IDs; production uses * `generateSummaryId` from `utils/id.ts`. */ import type { SessionId, TenantId } from '../../types/ids/index.js'; import type { SummaryId } from '../../types/session/ids.js'; import type { SessionStore } from '../../types/session/store.js'; import type { DeliverableRef } from '../../types/summary/deliverable.js'; import { type SessionSummaryKeyDecision, type SessionSummaryOutcome, type SessionSummaryRef } from '../../types/summary/ref.js'; /** * Dependencies for {@link SessionSummaryMaterializer}. The generator is * injected so tests can produce deterministic IDs; production code wires * `generateSummaryId` from `utils/id.ts`. */ export interface SessionSummaryMaterializerDeps { readonly store: SessionStore; readonly generateSummaryId: () => SummaryId; /** Clock hook — defaults to `new Date()` when omitted. */ readonly now?: () => Date; } /** * Caller-supplied payload for {@link SessionSummaryMaterializer.materialize}. * The materializer validates `agentSummary` length, constructs the * `SessionSummaryRef`, and delegates the atomic write to the store. */ export interface MaterializeInput { readonly sessionId: SessionId; readonly tenantId: TenantId; readonly finalOutcome: SessionSummaryOutcome; readonly agentSummary: string; readonly declaredDeliverables: readonly DeliverableRef[]; readonly keyDecisions: readonly SessionSummaryKeyDecision[]; } export declare class SessionSummaryMaterializer { private readonly deps; constructor(deps: SessionSummaryMaterializerDeps); /** * Kernel emission path. Validates, builds the immutable * {@link SessionSummaryRef}, and hands it to the store for atomic write + * status-flip. Rejects with: * * - {@link AgentSummaryTooLongError} — `agentSummary` exceeds the max char * cap ({@link AGENT_SUMMARY_MAX_CHARS}). * - `TenantIsolationError` — session is owned by a different tenant. * - {@link SessionAlreadySummarizedError} — the session already has a * persisted summary. Re-materialization would duplicate history; the * caller should instead open an intervention sub-session (§4.5). */ materialize(input: MaterializeInput): Promise; /** * Recovery path. Called at boot (or explicitly by the lifecycle manager) * for sessions whose `summary.json` is persisted but whose `session.json` * still reports a non-terminal status — the crash window between the two * atomic writes on disk. * * Idempotent: if the session is already `'idle'` (or another terminal * state), no write occurs; the existing summary is returned. If no summary * is persisted, returns `null` and no side effect occurs. This is the only * non-materialize path that may touch the stored summary — it does not * mint a new ID, only re-triggers the store's status flip via * `recordSummary` when it detects the dangling session. */ recover(sessionId: SessionId, tenantId: TenantId): Promise; private assertSummaryLength; private clock; } //# sourceMappingURL=materialize.d.ts.map