import { type NatsConnection } from "@nats-io/transport-node"; import { type EpCaller } from "./endpoint-subjects.js"; import { type AcceptanceFact } from "./endpoint-journal.js"; import { type AnchorResolver } from "./endpoint-signing.js"; /** A trusted, space-bonded receipt-store context: an OPAQUE token carrying only the space. Its * JS + JSM resources DERIVE from one binding-layer connection by the constructor and are held * in a module-private WeakMap keyed by this token, NEVER as reachable properties (distsys * c50817d MEDIUM): a caller holding the context cannot rebind its broker to split the publish * from the lost-CAS winner read. Every store seam takes this context. */ export interface ReceiptStoreContext { readonly space: string; } /** Bond the resources to one space by CONSTRUCTION (frozen token + WeakMap-private resources, * same discipline as the other store contexts): a hand-assembled structural look-alike is * rejected at every seam, and the broker cannot be rebound out from under a live operation. */ export declare function receiptStoreContext(nc: NatsConnection, space: string): Promise; /** Prove a context is store-branded (minted by {@link receiptStoreContext}) without touching the * broker: emission wiring is validated at seam ENTRY, so a hand-assembled store bundle refuses * BEFORE any terminal is committed against it, never as a post-commit emission failure. */ export declare function assertReceiptStoreContext(ctx: ReceiptStoreContext): void; /** Prove the store derives from EXACTLY this binding-layer connection (§13.4: "JS + JSM derive * from ONE connection by construction"): a same-space store built over a DIFFERENT connection * or broker passes any string-space compare, yet its publishes and lost-CAS winner reads land * on ANOTHER broker's streams - splicing one operation's authority across brokers. The bond is * connection IDENTITY, never a name. */ export declare function assertReceiptStoreConnection(ctx: ReceiptStoreContext, nc: unknown): void; /** One receipt's coordinates: the accepted execution's identity (§13.2). The subject caller is * the TRIPLE; the artifact's `caller` evidence carries `{id, lifecycleUid}`. */ export interface ReceiptRef { endpoint: string; caller: EpCaller; requestId: string; /** The accepted submission's stream sequence — the execution identity (§13.2/§13.10). */ sourceSeq: number; } /** The normative §13.10 Receipt artifact. */ export interface Receipt { v: 1; requestId: string; sourceSeq: number; space: string; endpoint: string; command: string; /** The EMITTING instance, recorded as EVIDENCE of who produced this attestation (a * post-crash reconciler records ITSELF here) - never proof of who executed the goal, and * never redemption authority. The executed outcome's authority is the committed terminal. */ instance: { id: string; instanceId: string; epoch: number; }; caller: { id: string; lifecycleUid: string; }; schemaDigests: { input: string; output: string; }; argsDigest: string; outcome: { ok: boolean; code?: string; }; resultDigest?: string; ts: number; signer: { keyId: string; }; sig: string; } /** The receipt-fact subject (`epf..receipt.....`, §13.2). */ export declare function receiptSubject(space: string, ref: ReceiptRef): string; /** Build and SIGN a receipt from the raw execution evidence: the digests are computed HERE from * the actual args/result (single source — an emitted digest can never mismatch what was * digested), the outcome is closed, and the artifact signs D28 over its canonical form. */ export declare function mintReceipt(args: { ref: ReceiptRef; space: string; command: string; instance: { id: string; instanceId: string; epoch: number; }; /** The caller's lifecycle evidence (`id` is the principal id, distinct from the request id). */ caller: { id: string; lifecycleUid: string; }; schemaDigests: { input: string; output: string; }; /** The accepted submission's raw args (digested here; `undefined` digests as null). */ args: unknown; outcome: { ok: boolean; code?: string; }; /** The raw result, when one exists (digested here). MUTUALLY EXCLUSIVE with `resultDigest`. */ result?: unknown; /** A pre-committed result digest, taken VERBATIM (the fact-derived path binds the terminal's * OWN `outcomeDigest`, never re-digesting a substitute payload). Mutually exclusive with * `result`. */ resultDigest?: string; ts: number; signer: { keyId: string; }; }, keyPair: { sign(input: Uint8Array): Uint8Array; }): Receipt; /** A receipt's OUTCOME, derived from the authoritative committed terminal (never a caller's free * claim): `ok` + optional catalog `code`, and the terminal's own `resultDigest` (already the * digest the terminal fact committed — a receipt re-attests it, it never re-digests a different * payload). {@link receiptOutcomeOfGoal} maps an action goal's terminal state onto this shape. */ export interface ReceiptOutcome { ok: boolean; code?: string; resultDigest?: string; } /** Map an action goal's committed terminal (`state` + its `outcomeDigest`) onto the receipt * outcome: only `succeeded` is `ok`; every other terminal state IS its own catalog code, so a * receipt's `outcome.code` can never disagree with the committed goal state. The digest is the * terminal fact's OWN `outcomeDigest` (the receipt attests the committed value, never re-digests * a substitute). Kept generic (state + digest, not the GoalResultFact type) so the receipt * module stays free of an action-composite dependency. */ export declare function receiptOutcomeOfGoal(state: string, outcomeDigest: string): ReceiptOutcome; /** Build and sign a receipt whose EVERY attestation field is DERIVED from the two authoritative * facts, never a caller's free parameter (distsys CF-1: an emitted receipt can no longer attest * an outcome or identity that disagrees with the committed record). Identity (requestId, * sourceSeq, caller, endpoint, command, schema digests, argsDigest) comes from the ACCEPTANCE * fact; the outcome (ok/code/resultDigest) comes from the committed TERMINAL. The only inputs * the caller supplies are the executing-instance EVIDENCE, the wall clock, the signer id, and * the key. A receipt minted here is reconstructable from the two facts, so a crash between * effect and emission is repaired by re-minting from the same facts (idempotent publish). */ export declare function mintReceiptFromFacts(args: { acceptance: AcceptanceFact; /** The caller triple from the acceptance's BROKER-AUTHENTICATED decision subject (§13.2): * the authoritative owner/actor/uid, cross-checked against the fact body here so a receipt * can never be subjected to a caller its acceptance body does not name. */ caller: EpCaller; space: string; /** The committed terminal outcome (from the authoritative terminal fact, via * {@link receiptOutcomeOfGoal} for goals, or a journaled command's own committed result). */ terminal: ReceiptOutcome; /** The EMITTING instance, recorded as EVIDENCE of who produced this attestation (a * post-crash reconciler records ITSELF here) - never proof of who executed the goal, and * never redemption authority. The executed outcome's authority is the committed terminal. */ instance: { id: string; instanceId: string; epoch: number; }; ts: number; signer: { keyId: string; }; }, keyPair: { sign(input: Uint8Array): Uint8Array; }): Receipt; /** Prove a RECORDED receipt attests the same facts as a freshly fact-derived candidate: every * attestation field (identity + outcome) must agree; only the emission evidence (instance, ts, * signer, sig) may differ, because two legitimate emitters — the inline commit path and the * reconciler — mint from the SAME facts at different moments. First-recorded-wins is the §13.10 * rule; a recorded receipt that DISAGREES with the facts is exactly the forged-attestation class * CF-1 closes and is a loud `conflict`, never silently adopted. */ export declare function assertReceiptAttestsSameFacts(recorded: Receipt, candidate: Receipt): void; /** Closed shape validation, IDENTITY-BOUND to the ref/subject it was read for (§13.4/§13.10): * a mis-subjected, cross-request, cross-caller, or garbled receipt never attests. The * artifact's caller EVIDENCE must name the subject's caller triple — a receipt whose body * names a different principal than its execution-scoped subject is forged attribution. */ export declare function parseReceipt(raw: unknown, ref: ReceiptRef, space: string): Receipt; /** Publish a receipt create-only on its execution-scoped subject, with EXPLICIT subject * coordinates (the artifact's caller evidence carries `{id, lifecycleUid}`, not the subject * triple, and a publisher never derives one by guessing). The receipt is SNAPSHOTTED to a * detached canonical candidate at entry: the identity binding ({@link parseReceipt}), the * published bytes, the lost-CAS winner comparison, and the returned value are all EXACTLY * that candidate — a caller mutating the receipt across the publish await can neither change * what is stored nor smuggle a "winner" past the equality proof. A lost CAS reads the winner * through the SAME bonded context and PROVES canonical identity — a DIFFERENT receipt already * on the subject is a loud `conflict` (one execution, one receipt, forever), never adopted. */ export declare function publishReceipt(ctx: ReceiptStoreContext, ref: ReceiptRef, receipt: Receipt): Promise<{ won: boolean; receipt: Receipt; }>; /** Read the execution's recorded receipt (`undefined` = none emitted yet), identity-bound. */ export declare function readReceipt(ctx: ReceiptStoreContext, ref: ReceiptRef): Promise; /** VERIFY a receipt (§13.10, fail loud, UNCONDITIONAL): D28 signature over the EXACT RAW * artifact against the FRESH-resolved anchor PLUS digest recomputation — both mandatory * ("signature against the anchor registry + digest recomputation", §13.10). The raw args * evidence is REQUIRED (undefined digests as null); the raw result evidence is REQUIRED * exactly when the receipt carries a resultDigest (a receipt attesting a result is only * verified against that result), and FORBIDDEN when it does not (a receipt with no * resultDigest cannot attest a presented result). The evidence is read ONCE and its digests * are computed at ENTRY, then compared BEFORE the anchor await — mutating the presented proof * values mid-verification changes nothing. A reader without raw evidence uses the explicitly * weaker {@link verifyReceiptSignature}. Returns the parsed receipt. */ export declare function verifyReceipt(raw: unknown, opts: { ref: ReceiptRef; space: string; resolveAnchor: AnchorResolver; /** The raw evidence to recompute against (MANDATORY, §13.10). `args` uses the * undefined→null rule; `result` is present exactly when the receipt digested one. */ recompute: { args: unknown; result?: unknown; }; /** Budget on the anchor resolution (default 5000ms): a stuck registry is a bounded * `unavailable`, never a hung verification. */ verifyBudgetMs?: number; }): Promise; /** The deliberately WEAKER, separately named authenticity read: closed identity-bound parse + * D28 signature against the fresh-resolved anchor, with NO digest attestation — for a reader * that does not hold the raw args/result. This is NOT the §13.10 verification (which is * unconditionally signature PLUS digest recomputation, {@link verifyReceipt}); it proves the * artifact is authentic and names these coordinates, nothing about what was executed. */ export declare function verifyReceiptSignature(raw: unknown, opts: { ref: ReceiptRef; space: string; resolveAnchor: AnchorResolver; verifyBudgetMs?: number; }): Promise; //# sourceMappingURL=endpoint-receipt.d.ts.map