/**
 * kestrel.markets/protocol — the incremental SESSION contract (protocol v0.2).
 *
 * This module is the L0 CONTRACT of the transport-neutral Session interaction
 * (djm.2 AC3/AC4; the schema the djm.4 controller and every face encode over).
 * It is the hash-chained transcript vocabulary of ONE agent-day: a genesis seals
 * the pure SessionSpec (SessionId = genesis hash); turn entries carry the binding
 * pentad `(sessionId, ordinal, parentHash, frameRoot)` plus the exact authored
 * bytes; a finalize seal closes the chain into a receipt root a CertifiedGrade
 * can pin. Idempotency IS content-addressing; a changed-bytes-same-slot turn
 * FAILS CLOSED. No face may reimplement Session progression — the wire verbs
 * deliberately omit an `advance`.
 *
 * HARD CONSTRAINTS (identical to src/protocol/index.ts — see its header):
 *  - ZERO RUNTIME dependencies. The ONLY import is intra-protocol
 *    (`./index.ts`, itself dependency-free); this module pulls in NO engine /
 *    session / blotter / fill / lang / grade / frame / render / ledger / cli
 *    code and must typecheck with `chdb` uninstalled. The import-graph boundary
 *    is an automated CI invariant (tests/protocol.boundary.test.ts).
 *  - DETERMINISM. Pure types + own constants; no wall clock, no RNG.
 *  - FAIL CLOSED. Unknown / changed-bytes-same-identity ⇒ a typed diagnostic,
 *    never a silent accept.
 *  - GENERIC ONLY. No founding-app tickers or strategy names in types, comments,
 *    or examples. Product identities ride INSIDE these fields at runtime.
 */
import type { EventCursor } from "./index.ts";
declare const OperationIdBrand: unique symbol;
declare const SessionIdBrand: unique symbol;
/**
 * CONTROL-PLANE identity (ADR-0004). One durable, resumable Operation carries a
 * canonical agent intent across the free boundary, machine settlement, human
 * completion, callbacks, and retries WITHOUT changing. It is minted by the
 * platform and is NOT derived from content — distinct in kind from a
 * {@link SessionId}. Branded so the two identities are never interchangeable.
 */
export type OperationId = string & {
    readonly [OperationIdBrand]: "OperationId";
};
/**
 * DETERMINISTIC identity: the genesis-entry hash of a Session's transcript. Same
 * SessionSpec ⇒ same genesis ⇒ same `SessionId`, on any host (a self-hosted
 * Kestrel and the managed backend agree). Branded distinctly from
 * {@link OperationId}: a deterministic Session identity is NOT a control-plane
 * handle, and the compiler refuses to substitute one for the other.
 */
export type SessionId = string & {
    readonly [SessionIdBrand]: "SessionId";
};
/**
 * Turn ordinal of the date-blind OPEN Frame — the author's first answer, before
 * any Wake. Reserved as `-1` so real Wake ordinals stay `0,1,2,…` and the OPEN
 * turn is never confused with a Wake turn.
 */
export declare const OPEN_ORDINAL: -1;
/**
 * Why a turn was recorded as a host failure (djm.4 fail semantics 3). A recorded
 * failure is FOREVER distinguishable from a judged STAND_DOWN — a closed
 * vocabulary so a downstream reader can dispatch exhaustively.
 */
export type FailureClass = "provider" | "timeout" | "malformed";
/** Runtime tuple of every {@link FailureClass}. Same both-ways guard as the index rdu vocabularies. */
export declare const FAILURE_CLASSES: readonly ["provider", "timeout", "malformed"];
/**
 * What an author actually produced for a turn — the three OUTCOMES kept forever
 * distinguishable (djm.4 fail semantics; the bead's distinguishability
 * criterion becomes a recorded fact):
 *  - `authored`   a Kestrel document was authored; `bytes` are the exact source.
 *  - `stand-down` the author EXPLICITLY stood down (a judgment, gradable) with a
 *                 stated reason — NOT a failure.
 *  - `failure`    the host recorded a provider/timeout/malformed failure — the
 *                 author never got to answer; never confused with a STAND_DOWN.
 */
export type TurnBody = {
    readonly kind: "authored";
    readonly bytes: string;
} | {
    readonly kind: "stand-down";
    readonly reason: string;
} | {
    readonly kind: "failure";
    readonly failureClass: FailureClass;
};
/**
 * One turn's transcript entry — the content-addressed record of an answer bound
 * to its SLOT. The BINDING PENTAD `(sessionId, ordinal, parentHash, frameRoot)`
 * is the turn's SEMANTIC-EFFECT IDENTITY: the position in the chain the author
 * answered. `authoredSha256` addresses the authored bytes; `entryHash` addresses
 * the whole entry (its content address — the next turn's `parentHash`).
 */
export interface TurnEntry {
    readonly kind: "turn";
    /** The Session this turn belongs to (= genesis hash). */
    readonly sessionId: SessionId;
    /** Turn ordinal; {@link OPEN_ORDINAL} for the OPEN turn, `0,1,2,…` for Wakes. */
    readonly ordinal: number;
    /** Content address of the PRIOR entry (the chain link / prior cursor). */
    readonly parentHash: string;
    /** sha256 of the canonical delivered Frame this turn answers. */
    readonly frameRoot: string;
    /** sha256 of the exact authored bytes (idempotency address). */
    readonly authoredSha256: string;
    /** What the author produced. */
    readonly body: TurnBody;
    /** Content address of THIS whole entry (the next turn's `parentHash`). */
    readonly entryHash: string;
}
/**
 * The closed diagnostic vocabulary of the Session layer (djm.4 L0). Every
 * rejection is one of these typed reasons — never a crash, never a silent false:
 *  - `wrong-session`  the entry names a different Session.
 *  - `broken-chain`   the `parentHash`/ordinal does not continue the chain.
 *  - `turn-conflict`  changed bytes under the SAME semantic-effect slot (AC4).
 *  - `stale-frame`    the turn answers a superseded / non-current Frame.
 *  - `not-pending`    no turn is pending at this slot (phase gate; djm.4 L1).
 *  - `sealed`         the chain is finalized; no further turns admit (djm.4 L1).
 *  - `malformed-entry` the entry is structurally unreadable.
 */
export type SessionDiagnostic = "wrong-session" | "broken-chain" | "turn-conflict" | "stale-frame" | "not-pending" | "sealed" | "malformed-entry";
/**
 * Runtime tuple of every {@link SessionDiagnostic}, in the L0 order. Same
 * both-ways closed-vocabulary guard as the index rdu vocabularies: a diagnostic
 * added to (or removed from) the union without editing this tuple breaks the
 * build, so the runtime vocabulary can never silently drift from the type.
 */
export declare const SESSION_DIAGNOSTICS: readonly ["wrong-session", "broken-chain", "turn-conflict", "stale-frame", "not-pending", "sealed", "malformed-entry"];
/**
 * `session/open` — START: mint a Session against a sealed genesis. `sessionId`
 * (base) is the genesis hash; `genesisRoot` is the content root of the pure
 * SessionSpec the genesis seals. Optionally binds the control-plane
 * {@link OperationId} carrying this Session.
 */
export interface OpenMessage {
    readonly kind: "session/open";
    readonly sessionId: SessionId;
    readonly operationId?: OperationId;
    /** Content root of the sealed SessionSpec (pure data) the genesis pins. */
    readonly genesisRoot: string;
}
/**
 * `session/frame` — OPEN DELIVERY and WAKE-DELTA: deliver the Frame the author
 * must answer at `ordinal` ({@link OPEN_ORDINAL} for OPEN, `0,1,…` for a Wake
 * delta), carrying its content-addressed `frameRoot` and the `parentHash` (prior
 * cursor) the answer must bind to.
 */
export interface FrameMessage {
    readonly kind: "session/frame";
    readonly sessionId: SessionId;
    readonly ordinal: number;
    readonly frameRoot: string;
    readonly parentHash: string;
}
/**
 * `session/turn` — AUTHORED-OR-STAND-DOWN and REVISION: the author's answer to a
 * delivered slot. Carries the full binding pentad header plus the {@link TurnBody}.
 * A revision is another turn at the SAME slot; reconciliation ({@link reconcileTurn})
 * decides idempotent-duplicate vs. fail-closed conflict.
 */
export interface TurnMessage {
    readonly kind: "session/turn";
    readonly sessionId: SessionId;
    readonly ordinal: number;
    readonly parentHash: string;
    readonly frameRoot: string;
    readonly authoredSha256: string;
    readonly body: TurnBody;
}
/**
 * `session/events` — RESUME: replay graded events after a cursor. The SSE event
 * id IS the {@link EventCursor} token, so `Last-Event-ID` resume and this request
 * are one mechanism (ADR-0004 resumable cursors). Absent `after` ⇒ from genesis.
 */
export interface EventsMessage {
    readonly kind: "session/events";
    readonly sessionId: SessionId;
    readonly after?: EventCursor;
}
/**
 * `session/describe` — self-describe the Session's pinned catalog entry / spec.
 * `entryRoot` is the content root of the CatalogEntry (see ./catalog.ts) this
 * Session runs, so a client can fetch the full reproducibility surface.
 */
export interface DescribeMessage {
    readonly kind: "session/describe";
    readonly sessionId: SessionId;
    readonly entryRoot: string;
}
/**
 * `session/finalize` — FINALIZATION and ARTIFACTS: seal the chain. `tipHash` is
 * the receipt root a CertifiedGrade can pin; `artifacts` are content-addressed
 * handles to the delivered Blotter/Grade/report artifacts.
 */
export interface FinalizeMessage {
    readonly kind: "session/finalize";
    readonly sessionId: SessionId;
    readonly tipHash: string;
    readonly artifacts: readonly string[];
}
/**
 * The incremental Session wire message union (djm.2 AC3). Discriminated on
 * `kind`. Every message binds the {@link SessionId}; turn/frame messages bind the
 * prior cursor and delivered Frame root. Deliberately NO `advance` verb: a face
 * is a pure encoder over the controller and structurally cannot reimplement
 * Session progression (djm.4 FACES).
 */
export type SessionMessage = OpenMessage | FrameMessage | TurnMessage | EventsMessage | DescribeMessage | FinalizeMessage;
/** The `kind` discriminant of {@link SessionMessage} — the frozen wire verb space. */
export type SessionMessageKind = SessionMessage["kind"];
/**
 * Every Session wire verb as a runtime tuple — the closed `kind` vocabulary of
 * {@link SessionMessage}. Driven by the union itself (`satisfies readonly
 * SessionMessage["kind"][]`) so adding a message forces this tuple to grow in
 * lockstep. Same both-ways closed-vocabulary guard as `RECEIPT_KINDS`: a `kind`
 * added to (or removed from) the union without editing this tuple breaks the
 * build. Fail-closed, no drift — and no `advance`.
 */
export declare const SESSION_MESSAGE_KINDS: readonly ["session/open", "session/turn", "session/frame", "session/events", "session/describe", "session/finalize"];
/**
 * The incremental interactions djm.2 AC3 enumerates, in lifecycle order. Each is
 * SERVED BY a wire verb via {@link INTERACTION_MESSAGE}; they are the lifecycle
 * STEPS, distinct from the {@link SessionMessageKind} VERBS that carry them.
 */
export type SessionInteraction = "start" | "open-delivery" | "authored-or-stand-down" | "wake-delta" | "revision" | "resume" | "finalization" | "artifacts";
/** Runtime tuple of every {@link SessionInteraction}, in lifecycle order. Same both-ways guard. */
export declare const SESSION_INTERACTIONS: readonly ["start", "open-delivery", "authored-or-stand-down", "wake-delta", "revision", "resume", "finalization", "artifacts"];
/**
 * The TOTAL map proving every required interaction is served by a real wire verb
 * — `Record<SessionInteraction, SessionMessageKind>`, so a missing interaction or
 * an unknown verb fails the build. Several interactions share a verb (the wire
 * vocabulary is intentionally smaller than the interaction set): authored /
 * revision both ride `session/turn`; OPEN delivery / Wake delta both ride
 * `session/frame`; finalization / artifacts both ride the `session/finalize`
 * seal. There is no bespoke verb per interaction — and still no `advance`.
 */
export declare const INTERACTION_MESSAGE: Record<SessionInteraction, SessionMessageKind>;
/**
 * The result of reconciling an incoming turn against the entry already recorded
 * at its slot. Either an idempotent admit (`ok: true`, `duplicate` says whether
 * the incoming was a byte-identical re-send) carrying the settled `entryHash`, or
 * a fail-closed rejection (`ok: false`) with a typed {@link SessionDiagnostic}.
 */
export type AdmitResult = {
    readonly ok: true;
    readonly duplicate: boolean;
    readonly entryHash: string;
} | {
    readonly ok: false;
    readonly diagnostic: SessionDiagnostic;
};
/**
 * Reconcile an `incoming` turn against the `prior` entry recorded at the same
 * intended slot — the idempotency + fail-closed primitive (djm.2 AC4; djm.4
 * "idempotency IS content-addressing"). Pure and synchronous; no crypto, no I/O.
 *
 * Ladder (fail-closed, most-specific first):
 *  1. structurally unreadable incoming        → `malformed-entry`
 *  2. names a different Session                → `wrong-session`
 *  3. does not continue the chain (parent/ord) → `broken-chain`
 *  4. answers a superseded Frame               → `stale-frame`
 *  5. SAME slot, SAME entry address            → idempotent duplicate (`ok`)
 *  6. SAME slot, CHANGED bytes                 → `turn-conflict` (the headline
 *     rule: a different-bytes-same-identity turn is NEVER silently accepted)
 *
 * (`not-pending` / `sealed` are phase diagnostics raised by the djm.4 L1 gate
 * that knows the Session's phase — not by this same-slot reconciler.)
 */
export declare function reconcileTurn(prior: TurnEntry, incoming: TurnEntry): AdmitResult;
export {};
//# sourceMappingURL=session.d.ts.map