/**
 * kestrel.markets/protocol — the CANONICAL wire-protocol types (v0.1).
 *
 * This module is the open, versioned contract that the managed backend
 * implements (ADR-0010): the platform is the SERVER and imports these SHAPES.
 *
 * HARD CONSTRAINTS (do not violate):
 *  - ZERO runtime dependencies. This file imports NOTHING. It must typecheck
 *    with `chdb` uninstalled and pull in no engine / language / series / fill
 *    code. Keep it that way — it is the core side of the core-vs-local split.
 *  - SHAPES ONLY. No signing keys, no Stripe/commerce logic, no corpus/presence.
 *    Every signed, replayable artifact carries an opaque `*Ref` HANDLE, never a
 *    key or a signing routine (ADR-0010 open/closed seam).
 *  - GENERIC INSTRUMENTS ONLY. Order/Fill/Position/Blotter model instruments
 *    generically (opaque `symbol: string`). No founding-app tickers or strategy
 *    names appear in types, doc comments, or examples. Product tickers ride
 *    INSIDE these fields at runtime; they are not part of the published contract.
 *
 * Scope: v0.1 covered the trial→conversion (M1) surface — authority-continuation,
 * purchase, and grade receipts. v0.2 ADDS, non-breakingly, the content-addressed
 * catalog contract (./catalog.ts), the incremental Session transcript
 * (./session.ts) — both re-exported below — and the M2–M4 receipt roots
 * (input-admission, resource-value, promotion, live-activation), which the
 * CertifiedReceipt umbrella admits as non-breaking additions to AnyReceipt. No
 * existing v0.1 shape changed, so 0.2 stays a purely additive minor. v0.3 ADDS,
 * non-breakingly, the oversight contract (./oversight.ts) — the cross-repo seam
 * between the CLI and Web Renderings of the human PM/Pod oversight surface
 * (ADR-0035), re-exported below. No existing shape changed, so 0.3 stays a purely
 * additive minor.
 *
 * Under 0.3, further ADDITIVE-OPTIONAL shapes have landed without a minor bump —
 * the same rule `inputPin` (kestrel-m9i.27), the OfferTerms vocabulary
 * (PLAT-ADR-0028), the OSS-ADR-0046 wire shapes, and the h314 certified-evidence
 * fields all rode under. The ex-ante catalog PRICING block (kestrel-adge —
 * {@link import("./catalog.ts").CatalogPricing} on the optional
 * {@link import("./catalog.ts").CatalogPage}) is another: it adds an OPTIONAL field
 * to a wrapped catalog body (absent ⇒ today's bare listing) and touches no existing
 * shape, so it rides additive under 0.3. The MINOR moves only for a deliberate
 * milestone surface (as at 0.2 and 0.3), never for each additive-optional field.
 *
 * Version: `major.minor`. Bump the MAJOR on any breaking shape change; bump the
 * MINOR for a purely additive milestone (v0.2 = catalog + Session, additive to
 * every v0.1 shape — no existing field changed).
 */

import type { OfferTerms } from "./offer.ts";
import type { FillSupport } from "./support.ts";

/* ────────────────────────────── version ────────────────────────────────── */

/**
 * Canonical protocol version (`major.minor`). Bump the major on any breaking
 * shape change; bump the minor for a purely additive milestone. v0.2 adds the
 * catalog + incremental Session surface without touching any v0.1 shape.
 */
export const PROTOCOL_VERSION = "0.4" as const;

/**
 * @deprecated Alias of {@link PROTOCOL_VERSION} kept so existing consumers that
 * import `CONTRACT_VERSION` swap module specifiers without a rename. Remove once
 * all consumers migrate to PROTOCOL_VERSION.
 */
export const CONTRACT_VERSION = PROTOCOL_VERSION;

/* ─────────────────────────────── faces ─────────────────────────────────── */

/** The four faces every operation must project identically (ADR-0004). */
export const FACES = ["http", "sdk", "cli", "mcp"] as const;
export type Face = (typeof FACES)[number];

/* ──────────────────────────── scope + signers ──────────────────────────── */

/**
 * Authorization scopes (ADR-0003 two-signer rule). Ordered least→most
 * privileged. Treat as extensible: new scopes may be added, so consumers must
 * not exhaustively switch without a default. (Attestation is modeled separately
 * as {@link AttestationRole}, not as a Scope.)
 *
 * The trailing three are the FLEET/PM-tier scopes (OSS-ADR-0035 / PLAT-ADR-0031 §2),
 * neither wallet- nor per-act human-signable but granted as a whole PM/trader
 * ENVELOPE via the delegation handshake (PLAT-ADR-0031 §1):
 *  - `fleet-evidence:self`    — a trader reads its OWN blotter/journal/mandate/brief
 *    (PLAT-ADR-0026 §5's own-scope `fleet-evidence read`, adopted here by name).
 *  - `fleet-evidence:subtree` — a PM reads every child trader's evidence across its
 *    workspace subtree (the new PM reach; supersedes 0026's own-only term, split into
 *    `:self` == own and `:subtree` == subtree).
 *  - `fleet:write`            — a PM writes the population (hire/assign/allocate/arm on
 *    the paper path; live-arming still suspends to a human per PLAT-ADR-0003). Widening
 *    stays inexpressible in the algebra — a PM cannot mint authority it does not hold.
 */
export type Scope =
  | "data"
  | "sim"
  | "grade"
  | "paper"
  | "broker"
  | "live"
  | "fleet-evidence:self"
  | "fleet-evidence:subtree"
  | "fleet:write";

/**
 * Every authorization scope as a runtime tuple — the closed wire vocabulary of
 * {@link Scope}, ordered least→most privileged to match the type. The `satisfies`
 * proves the tuple stays a SUBSET of Scope; the paired exhaustiveness guard proves
 * it names EVERY member. Together they fail closed in BOTH directions: a scope
 * 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 const SCOPES = [
  "data",
  "sim",
  "grade",
  "paper",
  "broker",
  "live",
  "fleet-evidence:self",
  "fleet-evidence:subtree",
  "fleet:write",
] as const satisfies readonly Scope[];
/** Reverse-exhaustiveness proof: any `Scope` omitted from {@link SCOPES} makes `_Missing`'s default non-`never`, which violates its `never` constraint and fails to compile. */
type _ScopesExhaustive<_Missing extends never = Exclude<Scope, (typeof SCOPES)[number]>> = true;

/** Scopes a wallet may sign (reversible, commerce-only). The rest require a human. */
export const WALLET_SIGNABLE_SCOPES = ["data", "sim", "grade", "paper"] as const satisfies readonly Scope[];

/** True iff `scope` may be authorized by a wallet signature alone. */
export function isWalletSignable(scope: Scope): boolean {
  return (WALLET_SIGNABLE_SCOPES as readonly Scope[]).includes(scope);
}

/** Authority classes that can hold/sign a grant (ADR-0003). */
export type SignerClass = "wallet" | "human";

/** Runtime tuple of every {@link SignerClass}. Same both-ways closed-vocabulary guard as {@link SCOPES}. */
export const SIGNER_CLASSES = ["wallet", "human"] as const satisfies readonly SignerClass[];
type _SignerClassesExhaustive<_Missing extends never = Exclude<SignerClass, (typeof SIGNER_CLASSES)[number]>> = true;

/**
 * Conjunctive attestation roles layered ON TOP of an authority signature
 * (ADR-0003 refinement). A grade/executor attestation NEVER substitutes for a
 * human authority signature — it is required IN ADDITION.
 */
export type AttestationRole = "compute" | "executor";

/** Runtime tuple of every {@link AttestationRole}. Same both-ways closed-vocabulary guard as {@link SCOPES}. */
export const ATTESTATION_ROLES = ["compute", "executor"] as const satisfies readonly AttestationRole[];
type _AttestationRolesExhaustive<_Missing extends never = Exclude<AttestationRole, (typeof ATTESTATION_ROLES)[number]>> = true;

/**
 * Versioned result of resolving a requested scope set into the signatures and
 * attestations required to mint an Envelope. Conjunctive across roles.
 */
export interface SignerRequirementSet {
  readonly version: typeof PROTOCOL_VERSION;
  readonly scope: readonly Scope[];
  /** Authority signatures required (all must be present). */
  readonly requiredSigners: readonly SignerClass[];
  /** Attestation roles required in addition to the authority signatures. */
  readonly requiredAttestations: readonly AttestationRole[];
}

/**
 * Revocation / currentness coordinate for one Root subtree (ADR-0003). Distinct
 * from the live fencing epoch. Monotonic within a subtree; a higher epoch
 * supersedes lower ones.
 */
export type AuthorityEpoch = number;

/** Opaque identifier of a node in a workspace's pod/authority tree. */
export type NodeId = string;

/** Opaque handle to a revocation record; resolution is server-side. */
export type RevocationRef = string;

/**
 * Immutable, versioned top of a workspace authority tree (ADR-0003). Existing
 * children never widen; supersession re-derives a NARROWER grant.
 */
export interface RootGrant {
  readonly node: NodeId;
  readonly generation: number;
  readonly signerClass: SignerClass;
  readonly scope: readonly Scope[];
  readonly authorityEpoch: AuthorityEpoch;
}

/**
 * A signed grant bound to one node of the pod tree (ADR-0003). Narrowing-only
 * downward: a derived child's scope/budget/ceiling never exceed its parent's.
 * This is an invariant on how Envelopes relate, not a field.
 */
export interface Envelope {
  readonly node: NodeId;
  readonly scope: readonly Scope[];
  /** Cumulative spend cap granted (settlement asset minor units or abstract). */
  readonly budget?: number;
  /** Per-operation cap. */
  readonly ceiling?: number;
  /** ISO-8601 expiry; absent = no time bound. */
  readonly expiry?: string;
  /** Opaque handle to this Envelope's revocation record, if revocable. */
  readonly revocation?: RevocationRef;
}

/** Opaque handle to a minted/derived Envelope (used in receipts). */
export type EnvelopeRef = string;

/* ──────────────────────────────── offer ────────────────────────────────── */

/** How an Offer may be settled (ADR-0002/0003). Discriminated on `kind`. */
export type SettlementMethod =
  | { readonly kind: "stripe-mpp" }
  | { readonly kind: "x402"; readonly network?: string; readonly asset?: string }
  | { readonly kind: "human-claim"; readonly url: string };

/**
 * Platform-signed commercial proposal bound to exactly one Operation (ADR-0002).
 * Accepting an Offer can mint ONLY its named Envelope's scope; price never
 * supplies broker/live authority — those still require a human signature.
 */
export interface Offer {
  readonly offerId: string;
  readonly operationId: string;
  /** Hash of the canonical agent intent this Offer prices. */
  readonly intentHash: string;
  readonly scope: readonly Scope[];
  /** Spend ceiling of the Envelope this Offer would mint. */
  readonly ceiling: number;
  /** Amount to be settled to accept. */
  readonly amount: number;
  /** Settlement asset code (e.g. "usd"); opaque to the protocol. */
  readonly asset: string;
  /** Digest of the human-readable terms; full terms fetched by ref, not inlined. */
  readonly termsDigest: string;
  /** ISO-8601 expiry after which the Offer is void. */
  readonly expiry: string;
  /** Anti-replay nonce; one Offer accepts once. */
  readonly nonce: string;
  readonly settlementMethods: readonly SettlementMethod[];
  /**
   * The commercial terms this Offer prices ({@link OfferTerms}). Additive vocabulary
   * (PLAT-ADR-0028 A1): absent = the legacy implicit `one_shot` shape. Nouns only — no
   * billing/renewal/credit-burn SEMANTICS live on the protocol.
   */
  readonly terms?: OfferTerms;
}

/* ─────────────────────────── proof + the 402 body ──────────────────────── */

/**
 * Shareable evidence of a certified result earned under a trial capability —
 * the conversion-moment artifact (ADR-0002).
 */
export interface Proof {
  readonly proofUrl: string;
  /** The capability under which the result was earned. */
  readonly earnedUnder: string;
  /** Opaque handle to the certified result the proof points at. */
  readonly resultRef: string;
}

/**
 * The structured HTTP 402 body (ADR-0002/0004) — part of the CONTRACT, not a
 * transport error. Every face (http/sdk/cli/mcp) exposes it identically. Carries
 * the free result already earned plus BOTH continuations, scope-gated. This
 * wraps an {@link Offer}; it is not an Offer itself.
 */
export interface PaymentRequired {
  readonly operationId: string;
  /** The free result already earned, as shareable proof. */
  readonly proof: Proof;
  readonly offer: Offer;
  /**
   * The plural commercial alternatives on this 402 boundary (PLAT-ADR-0028 A1): e.g. a
   * `one_shot` beside a `recurring` or `committed_use_discount`, each a fully-formed
   * {@link Offer} carrying its own {@link OfferTerms}. Additive vocabulary — no
   * selection SEMANTICS here. INVARIANT (unenforced at this layer): when present it
   * includes the singular `offer` as its default/primary member.
   */
  readonly offers?: readonly Offer[];
  /**
   * Machine-settleable continuations. INVARIANT: a subset of the wrapped
   * `offer.settlementMethods` containing only the non-`human-claim` variants.
   */
  readonly machineSettlement: readonly SettlementMethod[];
  /**
   * The contextual human claim-and-fund continuation. INVARIANT: its `url`
   * equals the wrapped Offer's `human-claim` SettlementMethod url when present.
   */
  readonly humanAction: { readonly url: string };
}

/* ───────────────────────────── capabilities ────────────────────────────── */

/**
 * Ephemeral binding of an anonymous Operation's subject (ADR-0002/0009). Opaque
 * commitment; the platform resolves the real principal server-side.
 */
export type SubjectCommitment = string;

/** Base grant-token shape common to all capabilities. */
export interface Capability {
  readonly capabilityId: string;
  readonly scopes: readonly Scope[];
  /** ISO-8601 expiry. */
  readonly expiry: string;
}

/**
 * Anonymous, ephemeral, rate-limited capability (ADR-0002). Permits catalog
 * discovery, validation, free sim instances, certified grades/blotters,
 * temporary artifacts, and proof URLs. EXCLUDES commerce, paper, broker, wallet,
 * and live — its `scopes` are a subset of WALLET_SIGNABLE_SCOPES. May PRESENT
 * external settlement evidence but never controls a wallet until a new Envelope
 * is minted.
 */
export interface TrialCapability extends Capability {
  readonly kind: "trial";
  readonly subjectCommitment: SubjectCommitment;
  /** Requests-per-window budget; shape is server-defined, referenced opaquely. */
  readonly rateLimit: { readonly limit: number; readonly windowSeconds: number };
}

/* ───────────────────────────── operation ───────────────────────────────── */

/** Durable state of an Operation across the free→settle→complete lifecycle. */
export type OperationState =
  | "open"
  | "awaiting-settlement"
  | "awaiting-human"
  | "resumed"
  | "completed"
  | "failed";

/** Runtime tuple of every {@link OperationState}. Same both-ways closed-vocabulary guard as {@link SCOPES}. */
export const OPERATION_STATES = [
  "open",
  "awaiting-settlement",
  "awaiting-human",
  "resumed",
  "completed",
  "failed",
] as const satisfies readonly OperationState[];
type _OperationStatesExhaustive<_Missing extends never = Exclude<OperationState, (typeof OPERATION_STATES)[number]>> = true;

/** Resumable SSE event position (ADR-0004: resumable event cursors are canonical). */
export interface EventCursor {
  /** Monotonic event sequence number last delivered. */
  readonly sequence: number;
  /** Opaque resume token the server maps back to a stream offset. */
  readonly token: string;
}

/**
 * Durable, resumable control-plane unit for ONE canonical agent intent
 * (ADR-0004). Survives the free boundary, machine settlement, human completion,
 * callbacks, and retries WITHOUT changing `operationId`.
 */
export interface Operation {
  readonly operationId: string;
  readonly intentHash: string;
  readonly state: OperationState;
  readonly cursor: EventCursor;
  /** Opaque handle to the latest durable checkpoint, if any. */
  readonly checkpoint?: string;
  readonly authorityEpoch: AuthorityEpoch;
  /** Incremented each time the Operation is resumed after a boundary. */
  readonly resumeGeneration: number;
}

/* ───────────────────────────── receipts ────────────────────────────────── */

/**
 * Umbrella base for every platform-signed, replayable receipt (ADR-0004). The
 * signature is referenced by opaque handle — never the key or routine.
 * Concrete receipts compose this base.
 */
export interface CertifiedReceipt {
  readonly kind: string;
  /** Opaque handle to the platform's signature over this receipt. */
  readonly signatureRef: string;
  /** Root nodes whose authority this receipt is bound under. */
  readonly boundRoots: readonly NodeId[];
  /** ISO-8601 issuance time. */
  readonly issuedAt: string;
}

/**
 * Immutable record binding an Operation to its canonical intent, proposal,
 * qualification, checkpoint, successor Root, child-Envelope derivation, authority
 * epoch, resume generation, and first resumed event sequence (ADR-0004).
 * Idempotent on duplicate callbacks; cannot repeat a completed semantic-effect
 * slot.
 */
export interface AuthorityContinuationReceipt extends CertifiedReceipt {
  readonly kind: "authority-continuation";
  readonly operationId: string;
  readonly intentHash: string;
  readonly successorRoot: NodeId;
  readonly derivedEnvelope: EnvelopeRef;
  readonly authorityEpoch: AuthorityEpoch;
  readonly resumeGeneration: number;
  readonly firstResumedSequence: number;
}

/**
 * Settlement evidence on a {@link PurchaseReceipt}: either a provider payment id
 * or an on-chain transaction. Discriminated by presence.
 */
export type ProviderPayment =
  | { readonly provider: string; readonly paymentId: string }
  | { readonly chainTx: string };

/**
 * Record that an Offer was settled and an Envelope granted (ADR-0003). Each
 * provider payment id satisfies one Offer ONCE; duplicate callbacks are
 * idempotent; cross-Operation replay is refused (fail-closed).
 */
export interface PurchaseReceipt extends CertifiedReceipt {
  readonly kind: "purchase";
  readonly offerId: string;
  /** Opaque handle to the paying principal; resolution is server-side. */
  readonly payerPrincipal: string;
  readonly providerPayment: ProviderPayment;
  readonly acceptedTerms: { readonly termsDigest: string };
  readonly grantedEntitlement: EnvelopeRef;
  /** Opaque handle to the delivered artifact/stream. */
  readonly delivery: string;
}

/* ──────────────────────── generic instruments ──────────────────────────── */

/**
 * Generic instrument descriptor. Opaque `symbol` — NO founding-app tickers in
 * the contract; product symbols ride here at runtime. Covers equity/ETF and a
 * generic option leg; extend via `kind` without encoding any strategy.
 */
export type Instrument =
  | { readonly kind: "equity"; readonly symbol: string }
  | {
      readonly kind: "option";
      readonly symbol: string;
      readonly right: "call" | "put";
      readonly strike: number;
      /** ISO-8601 (date or datetime) expiry. */
      readonly expiry: string;
    };

export type Side = "buy" | "sell";

/** Runtime tuple of every {@link Side}. Same both-ways closed-vocabulary guard as {@link SCOPES}. */
export const SIDES = ["buy", "sell"] as const satisfies readonly Side[];
type _SidesExhaustive<_Missing extends never = Exclude<Side, (typeof SIDES)[number]>> = true;

/** A single order as recorded in a Blotter. Generic instrument fields only. */
export interface Order {
  readonly orderId: string;
  readonly instrument: Instrument;
  readonly side: Side;
  readonly qty: number;
  /** Limit price in the instrument's quote units. */
  readonly price: number;
  /** ISO-8601 time the order was placed. */
  readonly placedAt: string;
}

/** A single fill against an order. Generic instrument fields only. */
export interface Fill {
  readonly fillId: string;
  readonly orderId: string;
  readonly instrument: Instrument;
  readonly side: Side;
  readonly qty: number;
  readonly price: number;
  /** ISO-8601 time the fill occurred. */
  readonly filledAt: string;
}

/** A held position snapshot. Generic instrument fields only. */
export interface Position {
  readonly instrument: Instrument;
  /** Signed quantity (positive = long, negative = short). */
  readonly qty: number;
  /** Average entry price in quote units. */
  readonly avgPrice: number;
}

/** Terminal settlement summary of a Session run. */
export interface Settlement {
  /** Realized cash result in the settlement asset's minor units or abstract. */
  readonly realized: number;
  readonly asset: string;
  /** ISO-8601 settlement time. */
  readonly settledAt: string;
}

/* ─────────────────── certified evidence (kestrel-h314, additive) ─────────────────── */

/**
 * Which P&L channel a Blotter's headline number came from (CONTEXT "Headline"): the conservative
 * definite-fill `floor`, the probability-weighted `expected`, or a seeded causal `sampled`
 * realization. Mirrors the engine's channel vocabulary — the wire copy so an outsider recomputing a
 * grade reads the same channel identity without the runtime.
 */
export type PnlChannel = "floor" | "expected" | "sampled";

/**
 * The sampled-channel qualification-gate verdict carried on the headline (CONTEXT "Certified evidence"):
 * whether the sampled channel earned headline status and, when refused, the fail-closed `reasons`. A
 * verdict-only wire shape — no study internals, just the pass/fail + why.
 */
export interface SampledQualification {
  readonly qualified: boolean;
  readonly reasons: readonly string[];
}

/**
 * The headline record on a Blotter's totals (CONTEXT "Certified evidence"): WHICH `channel` is the
 * headline and its `usd` value, the qualification `gate` verdict that selected it, and the honesty
 * `tainted` bit (with `reasons`) — `true` when any non-zero expected contribution rode on extrapolated
 * support or the settle mark itself was untrustworthy. The number always travels with its taint attached,
 * never silently.
 */
export interface HeadlineFlag {
  readonly channel: PnlChannel;
  readonly usd: number;
  readonly gate: SampledQualification;
  readonly tainted: boolean;
  readonly reasons: readonly string[];
}

/**
 * The verdict-only projection of the engine's settle mark that crosses onto the public Blotter
 * (CONTEXT "SettleMarkVerdict"; kestrel-h314 D3, DESIGN §1.3 exposure boundary). The engine's rich
 * `SettleMarkRecord` — the raw vendor settle spot (`px`) plus its `as_of_ts` / `last_observed_ts` /
 * `age_ms` observation timestamps — is LICENSED data and stays private; only the derived staleness
 * VERDICT ships, so a Blotter can carry settle-mark honesty without redistributing vendor data.
 */
export interface SettleMarkVerdict {
  /** Was the mark stale at the settle instant (taints {@link HeadlineFlag})? */
  readonly stale: boolean;
  /** The mark's provenance: a live `market` print, a `parity`-recovered spot, or a retained `stale` value. */
  readonly source: "market" | "parity" | "stale";
  /** `true` when the mark could not be recovered (the loudest taint) — a non-bankable settle. */
  readonly mark_uncertain: boolean;
  /** The honest human annotation, when the recovery/staleness layer recorded one. */
  readonly note: string | null;
}

/**
 * The session totals the certified risk-honest metrics recompute from (CONTEXT "Certified evidence";
 * kestrel-h314 D2). Un-dropped from the rich engine Blotter — byte-stable and deterministic, NOT invented
 * arithmetic. `floor` and `expected` are always present; `sampled` only on a seeded run (ABSENT — never
 * `0` — when the channel is off). `settle_mark` is the verdict-only {@link SettleMarkVerdict}, absent on a
 * pre-staleness-provenance bus.
 */
export interface Totals {
  /** Definite-fill $ only — the conservative floor (`realized_floor_usd`). */
  readonly floor: number;
  /** E[$] weighted by `1 − survival` (`expected_usd`). */
  readonly expected: number;
  /** The seeded causal realization; ABSENT (not `0`) when the sampled channel is off. */
  readonly sampled?: number;
  readonly headline: HeadlineFlag;
  /** The settle mark's verdict-only staleness projection, when the bus recorded settle-mark provenance. */
  readonly settle_mark?: SettleMarkVerdict;
}

/**
 * One support class's slice of a Blotter's expected-$ (CONTEXT "Certified evidence"; kestrel-h314 D2,
 * ADR-0014). The certified `fill_claim` partitions `totals.expected` into the `calibrated` slice a grader
 * banks and the `extrapolated` slice it refuses to bank. SIGNED sub-cells (`gain ≥ 0`, `loss ≤ 0`,
 * `expected === gain + loss`) so a consumer that re-banks by SUBTRACTING the extrapolated slice removes
 * only its `gain` — extrapolated LOSSES survive (the `bankableEv` doctrine) and can never be zeroed. The
 * wire slice drops the engine record's per-slice `orders` count (not needed to recompute the metric).
 */
export interface FillClaim {
  /** The support class this slice aggregates (CONTEXT "Support flag"). */
  readonly support: FillSupport;
  /** Σ expected-$ over this slice's orders (on the grader's 1e-8 grid). Equals `gain + loss`. */
  readonly expected: number;
  /** The slice's GAINS: Σ non-negative expected-$ (≥ 0). A subtracting consumer removes ONLY this. */
  readonly gain: number;
  /** The slice's LOSSES: Σ negative expected-$ (≤ 0) — KEPT for extrapolated cells (never forgiven). */
  readonly loss: number;
}

/**
 * Certified execution record of a Session run (CONTEXT "Blotter") — the WHAT
 * HAPPENED, distinct from a Grade's judgment. Generic instruments only.
 *
 * CERTIFIED EVIDENCE (kestrel-h314, D2 — additive-optional): `totals` and `fill_claim` un-drop the
 * risk-honest accounting the rich engine Blotter already carries, so the risk-honest metric family
 * (bankable EV, realized floor, expected-$) is OUTSIDER-RECOMPUTABLE from the published artifact — not
 * only inside the private engine. Their ABSENCE on a pre-widening Blotter reads as UNKNOWN and fails the
 * risk-honest family CLOSED (never a silent zero — D6); the {@link ./grade.ts grade} Judge refuses to
 * certify those metrics for a Blotter that lacks the evidence.
 */
export interface Blotter {
  readonly sessionId: string;
  readonly orders: readonly Order[];
  readonly fills: readonly Fill[];
  readonly positions: readonly Position[];
  readonly settlement: Settlement;
  /**
   * The session totals — the certified risk-honest accounting (kestrel-h314 D2). ADDITIVE-OPTIONAL:
   * ABSENT on a pre-widening Blotter, where its absence reads as UNKNOWN and fails the risk-honest
   * metrics closed (D6) — never a silent zero.
   */
  readonly totals?: Totals;
  /**
   * The session's expected-$ partitioned by fill support (kestrel-h314 D2): the `calibrated` slice a
   * grader banks and the `extrapolated` slice it refuses to bank. When present, always two entries in the
   * fixed order `[calibrated, extrapolated]` (deterministic, byte-stable). ADDITIVE-OPTIONAL: ABSENT on a
   * pre-widening Blotter (UNKNOWN, fails the risk-honest family closed — D6). Part of the certified
   * evidence alongside {@link totals} (the totals alone are not enough — CONTEXT "Certified evidence").
   */
  readonly fill_claim?: readonly FillClaim[];
}

/* ───────────────────────────── grade ───────────────────────────────────── */

/**
 * The judged verdict over one or more Blotters (CONTEXT "Certified grade"). The
 * COMPUTED numbers — portable: a self-hosted Kestrel produces the same values;
 * only the platform mints the trusted, signed receipt form ({@link CertifiedGrade}).
 * Metric keys are open (a string→number map) so new dimensions need no shape bump.
 */
export interface GradeResult {
  readonly subjectSessionId: string;
  /** Open metric map, e.g. { "bankable_ev": ..., "fill_support": ... }. */
  readonly metrics: Readonly<Record<string, number>>;
  /** Optional discrete verdict labels, e.g. flags an honest-fill judge sets. */
  readonly labels?: Readonly<Record<string, string>>;
}

/**
 * The signed, replayable receipt form of a {@link GradeResult}. Pins the data and
 * fill-model versions so anyone can replay to the identical numbers.
 */
export interface CertifiedGrade extends CertifiedReceipt {
  readonly kind: "grade";
  readonly result: GradeResult;
  /** Opaque handle to the pinned data snapshot the grade ran over. */
  readonly pinnedDataRef: string;
  /** Version tag of the fill model used. */
  readonly pinnedFillModelVersion: string;
  /** Opaque handle to the judge's signature. */
  readonly judgeSignatureRef: string;
  readonly replayable: true;
}

/* ─────────────────────── M2–M4 receipt roots (additive) ────────────────────── */

/**
 * Admission verdict for a purchased/delivered input (M2) — the fail-closed
 * trichotomy on the wire (18-operation-promotion-protocols.md):
 *  - `known`   a verified, complete delivery within scope — the ONLY admittable state.
 *  - `unknown` qualified, but delivery/schema/watermark/freshness/content/use could
 *              not be established — NOT presented as a known zero or neutral default.
 *  - `omitted` not acquired under any entitlement — NOT silently substituted.
 * This is the Kestrel KNOWN | UNKNOWN | OMITTED doctrine (fail closed) on the wire.
 */
export type AdmissionState = "known" | "unknown" | "omitted";

/** Runtime tuple of every {@link AdmissionState}. Same both-ways closed-vocabulary guard as {@link SCOPES}. */
export const ADMISSION_STATES = ["known", "unknown", "omitted"] as const satisfies readonly AdmissionState[];
type _AdmissionStatesExhaustive<_Missing extends never = Exclude<AdmissionState, (typeof ADMISSION_STATES)[number]>> = true;

/**
 * Receipt-gated admission of a purchased/delivered input into an Operation (M2).
 * Verifies the qualification receipt (entitlement + accepted terms) AND the
 * delivery receipt (what bytes/blocks/result were delivered), then binds the exact
 * Field identity, content root, source watermark, and consumer use scope. The
 * {@link AdmissionState} trichotomy fails closed: only a verified complete delivery
 * within scope is `known`. Source: 18-operation-promotion-protocols.md
 * `InputAdmissionReceipt`; the schema_version / receipt_id / canonical_digest /
 * signature patent fields fold into the {@link CertifiedReceipt} base.
 */
export interface InputAdmissionReceipt extends CertifiedReceipt {
  readonly kind: "input-admission";
  /** Opaque root of the purchased-input manifest. */
  readonly inputManifestRoot: string;
  /** Opaque root of the qualification receipt proving entitlement + accepted terms. */
  readonly qualificationReceiptRoot: string;
  /** Opaque root of the delivery receipt proving what was delivered. */
  readonly deliveryReceiptRoot: string;
  /** Opaque identity of the admitted Field. */
  readonly admittedFieldId: string;
  /** Opaque handle to the admitted Field's declared type/schema. */
  readonly admittedType: string;
  /** Opaque content root of the admitted value/content. */
  readonly admittedContentRoot: string;
  /** Opaque source-watermark handle bounding freshness/provenance. */
  readonly admittedSourceWatermark: string;
  /** Opaque handle to the consumer use scope the admission authorizes. */
  readonly admittedUseScope: string;
  /** Opaque root of the consumer artifact the input is admitted into. */
  readonly consumerArtifactRoot: string;
  /** The fail-closed admission verdict (KNOWN | UNKNOWN | OMITTED). */
  readonly resultingState: AdmissionState;
  /** Stated reason when `unknown`/`omitted`; absent on `known`. */
  readonly reason?: string;
  /** Opaque coordinate of the entitlement consumed, when one was. */
  readonly consumedEntitlementAt?: string;
}

/**
 * Metered marginal technical value of an admitted input (M3), measured by a
 * one-intervention baseline↔variant fork under a SHARED environment: the same
 * runtime/binding roots and named Judge grade both branches, isolating the single
 * admitted Field as the only change. The open `technicalEffectVector` carries the
 * named machine measures (decision agreement, indeterminate-decision count, token
 * consumption, latency, …) as a GradeResult-style string→number map, so a new
 * metric needs no shape bump. Binds acquisition cost WITHOUT claiming that a
 * favorable financial return proves technical validity. Source:
 * 18-operation-promotion-protocols.md `ResourceValueReceipt`.
 */
export interface ResourceValueReceipt extends CertifiedReceipt {
  readonly kind: "resource-value";
  /** Opaque root of the purchased-input manifest under valuation. */
  readonly purchasedInputManifestRoot: string;
  /** Opaque root of the qualification receipt for the purchased input. */
  readonly qualificationReceiptRoot: string;
  /** Opaque root of the {@link InputAdmissionReceipt} that admitted the input. */
  readonly inputAdmissionReceiptRoot: string;
  /** Opaque root of the one-intervention branch descriptor. */
  readonly branchDescriptorRoot: string;
  /** Opaque root of the baseline branch's output. */
  readonly baselineOutputRoot: string;
  /** Opaque root of the variant branch's output. */
  readonly variantOutputRoot: string;
  /** Opaque root of the baseline branch's grade receipt. */
  readonly baselineGradeReceiptRoot: string;
  /** Opaque root of the variant branch's grade receipt. */
  readonly variantGradeReceiptRoot: string;
  /** Opaque root of the environment inputs held identical across both branches. */
  readonly sharedEnvironmentInputRoot: string;
  /** Opaque root of the conserved semantic artifact under test. */
  readonly semanticArtifactRoot: string;
  /** Opaque roots pinning the runtime + binding held constant across branches. */
  readonly runtimeAndBindingRoots: readonly string[];
  /** Opaque identity of the named Judge that graded both branches. */
  readonly namedJudgeIdentity: string;
  /** Opaque handle to the acquisition amount / compute-cost measure. */
  readonly acquisitionMeasure: string;
  /** Open named machine-measure map (GradeResult-style); a new metric needs no shape bump. */
  readonly technicalEffectVector: Readonly<Record<string, number>>;
  /** The computed baseline↔variant comparison result. */
  readonly comparisonResult: string;
  /** Opaque root of the confidence / repetition manifest, when present. */
  readonly confidenceManifestRoot?: string;
}

/**
 * A candidate promoted per the promotion policy (M3/M4): the conserved semantic
 * artifact is carried unchanged while ONLY enumerated deployment dimensions change.
 * The policy verifies engine/Judge identities, input/output roots, receipt classes,
 * evidence freshness, semantic-root EQUALITY, thresholds, and approvals; it refuses
 * a rebuilt artifact lacking a semantic-equivalence proof or a report produced under
 * another Judge. Source: 18-operation-promotion-protocols.md `PromotionReceipt`.
 */
export interface PromotionReceipt extends CertifiedReceipt {
  readonly kind: "promotion";
  /** Opaque root of the promotion policy the promotion was verified against. */
  readonly promotionPolicyRoot: string;
  /** Opaque root of the evidence set the policy verified. */
  readonly promotionEvidenceSetRoot: string;
  /** Opaque root of the semantic artifact conserved across the promotion. */
  readonly conservedSemanticArtifactRoot: string;
  /** Opaque root of the prior deployment, when superseding one. */
  readonly priorDeploymentRoot?: string;
  /** Opaque root of the successor deployment. */
  readonly successorDeploymentRoot: string;
  /** The enumerated deployment dimensions permitted to change (mode/envelope/fence/…). */
  readonly changedDeploymentDimensions: readonly string[];
  /** Opaque handle to the supersession barrier, when one gates the promotion. */
  readonly supersessionBarrierRef?: string;
  /** Preconditions that must hold before live activation (e.g. human approval). */
  readonly activationPreconditions: readonly string[];
  /** The policy verification result. */
  readonly verificationResult: string;
}

/**
 * Live-activation state under the staged fencing protocol (M4). No live initiation
 * occurs before `active`:
 *  - `preparing`       a next fencing epoch is reserved.
 *  - `fence-confirmed` the epoch is installed and confirmed at the live Gate.
 *  - `active`          the candidate actuates; the prior holder is fenced out.
 *  - `refused`         activation was refused; the candidate stays non-actuating.
 * A failed fence leaves the candidate non-actuating — fail closed.
 */
export type ActivationState = "preparing" | "fence-confirmed" | "active" | "refused";

/** Runtime tuple of every {@link ActivationState}, in staged-fencing order. Same both-ways closed-vocabulary guard as {@link SCOPES}. */
export const ACTIVATION_STATES = ["preparing", "fence-confirmed", "active", "refused"] as const satisfies readonly ActivationState[];
type _ActivationStatesExhaustive<_Missing extends never = Exclude<ActivationState, (typeof ACTIVATION_STATES)[number]>> = true;

/**
 * A config/agent activated live (M4). The live execution module verifies the
 * control-plane signature, capsule digest, target-executor binding, Authority Head,
 * narrowing certificate, Envelope, approvals, expiry, and fencing epoch, then
 * follows the staged fencing protocol via {@link ActivationState}. Fencing epochs
 * are monotonic: the reserved epoch supersedes the prior. Possession of an old
 * capsule/artifact/credential reference is insufficient. Source:
 * 18-operation-promotion-protocols.md `LiveActivationReceipt`.
 */
export interface LiveActivationReceipt extends CertifiedReceipt {
  readonly kind: "live-activation";
  /** Opaque root of the Deployment Capsule being activated. */
  readonly deploymentCapsuleRoot: string;
  /** Opaque identity of the target executor bound to the capsule. */
  readonly targetExecutorIdentity: string;
  /** Opaque root of the ownership record for the activation. */
  readonly ownershipRecordRoot: string;
  /** The prior holder's fencing epoch (monotonic; superseded by the reserved one). */
  readonly priorFencingEpoch: number;
  /** The reserved successor fencing epoch. */
  readonly reservedFencingEpoch: number;
  /** Opaque root of the fence confirmation from the live Gate. */
  readonly fenceConfirmationRoot: string;
  /** The staged-fencing activation state (no live initiation before `active`). */
  readonly activationState: ActivationState;
  /** Opaque digest of the current Authority Head at activation. */
  readonly activeAuthorityHeadDigest: string;
  /** Event sequence at which the activation took effect. */
  readonly activatedAtSequence: number;
}

/**
 * Discriminated union of every concrete certified receipt. Switch on `.kind` for
 * exhaustive server-side dispatch. v0.1 minted the M1 trial→conversion roots
 * (authority-continuation, purchase, grade); v0.2 additively admits the M2–M4 roots
 * (input-admission, resource-value, promotion, live-activation) — the
 * CertifiedReceipt umbrella makes each a non-breaking addition.
 */
export type AnyReceipt =
  | AuthorityContinuationReceipt
  | PurchaseReceipt
  | CertifiedGrade
  | InputAdmissionReceipt
  | ResourceValueReceipt
  | PromotionReceipt
  | LiveActivationReceipt;

/**
 * Every concrete receipt discriminant as a runtime tuple — the closed `.kind`
 * wire vocabulary of {@link AnyReceipt}. Driven by the union itself (`satisfies
 * readonly AnyReceipt["kind"][]`) so extending {@link AnyReceipt} with a new
 * receipt root (M2–M4) forces this tuple to grow in lockstep. Same both-ways
 * closed-vocabulary guard as {@link SCOPES}: a `.kind` added to (or removed from)
 * the union without editing this tuple breaks the build. Fail-closed, no drift.
 */
export const RECEIPT_KINDS = [
  "authority-continuation",
  "purchase",
  "grade",
  "input-admission",
  "resource-value",
  "promotion",
  "live-activation",
] as const satisfies readonly AnyReceipt["kind"][];
type _ReceiptKindsExhaustive<_Missing extends never = Exclude<AnyReceipt["kind"], (typeof RECEIPT_KINDS)[number]>> = true;

/* ─────────────────────────── arm refusals (OSS-ADR-0045) ─────────────────────────── */

/**
 * The closed, wire-stable vocabulary of reasons the plan engine REFUSES to arm a
 * statement (OSS-ADR-0045). A refusal is DATA, never a matched message string: a
 * consumer routes on `code`, and the human-readable `message`/`repair` are DISPLAY
 * only (a wording change is never a breaking change). Extensible — add a code here
 * and to {@link ARM_REFUSAL_CODES} in lockstep; consumers must not exhaustively
 * switch without a default. Two codes today:
 *  - `unknown-series` — a trigger names a series the FROZEN phonebook does not know:
 *    a case-variant of a known market fact (`VWAP` for `vwap`, `VELOCITY` for the
 *    windowed `velocity`), refused with a did-you-mean {@link ArmRefusal.repair}. The
 *    offending statement is refused AS DATA; its healthy siblings still arm. This
 *    reverts the 0.4.5 case-insensitive forgiveness AND the silent runtime de-arm (a
 *    plan that would have armed-then-never-fired): an unknown series is a LOUD,
 *    repairable refusal at arm, never a silent default (RUNTIME §8).
 *  - `plan-name-in-use` — a revision re-declares a plan NAME still owned by a LIVE
 *    (managing/inventory-holding) prior record. This one REMAINS a throw (an
 *    `ArmError`, whole-document): arming would clobber the by-name ledger and garble
 *    the merged lifecycle — names are lineage; author a new name.
 *  - `manages-nothing` — a plan carries a covered sell (`EXIT`/`TP`, both of which can
 *    only ever sell inventory the plan HOLDS) but NO way to ever hold inventory: no
 *    `DO`/`ALSO`/`RELOAD` entry to acquire, no `ARM … foreach|any held leg` to adopt a
 *    superseded plan's held leg, and no `foreach|any held leg` on the cover itself. Its
 *    exit can never cover, so the plan would arm and sit inert forever — the silent
 *    one-way door r866 fixed, one dropped keyword away (an EXIT-only revision that forgot
 *    the adoption binding). Refused AS DATA at arm — the offending statement never
 *    registers, its healthy siblings still arm — so `parse --arm`, `/validate`, and a
 *    real run all fail closed identically (kestrel-b4wx/kestrel-hcnj, RUNTIME §4/§8).
 *  - `opening-short-uncovered` — a MULTI-LEG opening structure: an ENTRY (`DO`/`ALSO`) SELL
 *    leg CO-EXISTS with an opening BUY leg on a plan that adopts NO inventory (no `ARM …
 *    foreach|any held leg`, no `EXIT`/`TP … foreach|any held leg`). An entry sell is covered
 *    ONLY by inventory the plan HOLDS at fire — and at the one entry fire nothing has filled
 *    yet (a same-fire entry BUY is still resting) and cross-strike structural coverage (a
 *    debit spread's long leg covering its short) needs ATOMIC combo execution the engine does
 *    not yet do (the AST `atomic` keyword is reserved-but-refused). So such a sell is DEAD ON
 *    ARRIVAL: never-naked refuses it at every fire while the plan's BUY leg fires ALONE,
 *    silently degrading a debit spread to a naked long whose proof is BYTE-IDENTICAL to the
 *    single long leg (kestrel-53gw). Refused AS DATA at arm — LOUD, never a silent per-leg
 *    drop — until atomic multi-leg structures land (kestrel-psn5). Scoped to that misleading-
 *    proof shape: a PURE naked opening sell (no opening buy) is NOT caught here — its proof is
 *    order_count=0 (distinguishable) and it keeps its fire-time never-naked diagnostic (ADR-0017).
 */
export type ArmRefusalCode = "unknown-series" | "plan-name-in-use" | "manages-nothing" | "opening-short-uncovered";

/**
 * Runtime tuple of every {@link ArmRefusalCode} — the closed wire vocabulary. Same
 * both-ways closed-vocabulary guard as {@link SCOPES}: a code 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 const ARM_REFUSAL_CODES = ["unknown-series", "plan-name-in-use", "manages-nothing", "opening-short-uncovered"] as const satisfies readonly ArmRefusalCode[];
/** Reverse-exhaustiveness proof: any `ArmRefusalCode` omitted from {@link ARM_REFUSAL_CODES} makes `_Missing`'s default non-`never`, which violates its `never` constraint and fails to compile. */
type _ArmRefusalCodesExhaustive<_Missing extends never = Exclude<ArmRefusalCode, (typeof ARM_REFUSAL_CODES)[number]>> = true;

/**
 * One coded arm-time refusal (OSS-ADR-0045). `statement` is the offending plan's
 * NAME; `code` is the wire-stable reason ({@link ArmRefusalCode}); `message` is the
 * human-readable diagnostic (DISPLAY only — NEVER matched as an interface); `repair`,
 * when present, is a concrete did-you-mean fix (e.g. the canonical lowercase series
 * name a case-variant meant).
 */
export interface ArmRefusal {
  readonly statement: string;
  readonly code: ArmRefusalCode;
  readonly message: string;
  readonly repair?: string;
}

/**
 * Every arm-time NOTICE code (kestrel-hk9u). A notice is NON-FATAL: unlike an
 * {@link ArmRefusal}, the statement still arms (it is a legal, integrity-clean
 * document) — the notice reports a condition that will keep the plan from ever
 * FIRING on the arming context, so an author is not silently handed a plan that
 * no-ops. Keep this union and {@link ARM_NOTICE_CODES} in lockstep. One code today:
 *  - `regime-unsatisfiable` — the plan carries a `regime {scope: value}` gate whose
 *    scope no REGIME writer on the arming context's tape will ever write, so the plan
 *    stays `authored (blocked)` for the whole session and never fires. This is the
 *    silent-gate the docs mistaught as an opaque author tag (the plan parses, arms,
 *    and then no-ops on every regime-less tape); the notice makes the dead-on-arrival
 *    verdict LEGIBLE at arm, identically across `parse --arm`, the hosted /validate
 *    route, and a real batch run (RUNTIME §8).
 *  - `adoption-bound-nothing` — the plan carries a valid `ARM … foreach|any held leg`
 *    adoption binding, but at arm it resolved to ZERO held legs (no superseded,
 *    inventory-holding sibling to adopt from). It arms and expires without ever covering,
 *    so its exit protection is inert — indistinguishable on the run report from a working
 *    adoption until this notice names it (kestrel-c25w; the run-tier sibling of the b4wx
 *    parse-tier manages-nothing refusal).
 */
export type ArmNoticeCode = "regime-unsatisfiable" | "adoption-bound-nothing";

/**
 * Runtime tuple of every {@link ArmNoticeCode} — the closed wire vocabulary, guarded
 * both ways exactly like {@link ARM_REFUSAL_CODES}: adding a code to (or removing one
 * from) the union without editing this tuple breaks the build.
 */
export const ARM_NOTICE_CODES = ["regime-unsatisfiable", "adoption-bound-nothing"] as const satisfies readonly ArmNoticeCode[];
/** Reverse-exhaustiveness proof: any `ArmNoticeCode` omitted from {@link ARM_NOTICE_CODES} makes `_Missing`'s default non-`never`, which violates its `never` constraint and fails to compile. */
type _ArmNoticeCodesExhaustive<_Missing extends never = Exclude<ArmNoticeCode, (typeof ARM_NOTICE_CODES)[number]>> = true;

/**
 * One coded arm-time NOTICE (kestrel-hk9u). `statement` is the plan's NAME; `code` is
 * the wire-stable reason ({@link ArmNoticeCode}); `message` is the human-readable
 * diagnostic (DISPLAY only — NEVER matched as an interface). A notice never sets the
 * plan un-armed: it is surfaced ALONGSIDE a successful arm.
 */
export interface ArmNotice {
  readonly statement: string;
  readonly code: ArmNoticeCode;
  readonly message: string;
}

/**
 * The result of arming a document (OSS-ADR-0045): the NAMES of the plans that armed,
 * the coded {@link ArmRefusal}s for the statements that did not — nothing healthy
 * is aborted by a bad sibling, and nothing is silently dropped — and the non-fatal
 * {@link ArmNotice}s for plans that armed but can never FIRE on this tape
 * (kestrel-hk9u). A refusal that MUST halt the WHOLE document (a live-name collision,
 * `plan-name-in-use`) is thrown as an `ArmError` carrying its `.code` instead of being
 * returned here. `notices` is additive and optional — a report without regime notices
 * omits it, so existing consumers are unaffected.
 */
export interface ArmReport {
  readonly armed: readonly string[];
  readonly refusals: readonly ArmRefusal[];
  readonly notices?: readonly ArmNotice[];
}

/* ─────────────────────────── v0.2 additive surface ─────────────────────────── */

/**
 * The v0.2 additions, re-exported so the published `kestrel.markets/protocol`
 * entrypoint carries the whole contract. Both modules are intra-protocol and
 * dependency-free (asserted by tests/protocol.boundary.test.ts):
 *  - ./catalog.ts — the content-addressed {@link import("./catalog.ts").CatalogEntry}.
 *  - ./session.ts — the incremental Session transcript + Operation/Session
 *    identity split + the idempotency/fail-closed reconciler.
 */
export * from "./catalog.ts";
export * from "./session.ts";

/* ─────────────────────────── v0.3 additive surface (oversight) ─────────────────────────── */

/**
 * The v0.3 addition: the OVERSIGHT contract — the cross-repo seam between the CLI
 * (`ascii`/Ink) and Web (`html`) Renderings of the human PM/Pod oversight surface
 * (ADR-0035). Re-exported so the published `kestrel.markets/protocol` entrypoint
 * carries the whole contract. Intra-protocol and dependency-free (asserted by
 * tests/protocol.boundary.test.ts): the acting Kernel is a STRUCTURAL MIRROR of
 * `src/frame/types.ts`, never an import. PURELY ADDITIVE — 0.2 → 0.3 touches no
 * existing shape (same rule catalog.ts and session.ts landed under).
 *  - ./oversight.ts — Caller / OversightIdentity, the acting Kernel as a protocol
 *    shape, the Book/Pod org, OversightFrame, the turn-stream, typed owner acts,
 *    the human-message channel, input resolution, the closed OversightEvent enum,
 *    and the OversightBackend seam.
 */
export * from "./oversight.ts";

/* ─────────────────────────── offer terms (PLAT-ADR-0028 A1) ─────────────────────────── */

/**
 * The OfferTerms commercial-terms vocabulary, re-exported so the published
 * `kestrel.markets/protocol` entrypoint carries it (the {@link Offer.terms} field and the
 * plural {@link PaymentRequired.offers} alternatives reference it). Pure nouns/enums,
 * intra-protocol and dependency-free (asserted by tests/protocol.boundary.test.ts).
 */
export * from "./offer.ts";

/* ─────────────────────────── wire shapes (OSS-ADR-0046) ─────────────────────────── */

/**
 * The hosted-service HTTP/SSE wire shapes, re-exported so `src/protocol` is the ONE
 * home for every wire shape this repo speaks (OSS-ADR-0046). Pure snake_case types +
 * the SSE `operation.*` const vocabulary + fail-closed decoders; intra-protocol and
 * dependency-free (asserted by tests/protocol.boundary.test.ts). The CLI transport
 * (`src/cli/backend/wire.ts`) re-exports THIS module rather than hand-copying it.
 */
export * from "./wire.ts";

/* ─────────────────────────── attestation wire constants (OSS-ADR-0046, kestrel-s67u) ─────────────────────────── */

/**
 * The load-bearing WIRE constants of the signed grade root + receipt attestation label
 * (`GRADE_SIGN_PREFIX`, `JUDGE_ID`, `JUDGE_VERSION`, `FILL_MODEL_VERSION`, `ROOT_HASH_PREFIX`,
 * `VERIFY_KEYS_PATH`), the ONE dependency-free home both the platform signer and the OSS CLI
 * verifier import instead of re-declaring literals (OSS-ADR-0046 §2). Deliberately NOT gated on
 * `PROTOCOL_VERSION` — see the versioning note in `./attestation.ts`. A drift of any copy is a RED
 * conformance run, never a silent cross-repo verify break.
 */
export * from "./attestation.ts";

/* ─────────────────────────── certified evidence + Judge (kestrel-h314) ─────────────────────────── */

/**
 * The fill-support partition + banking policy (kestrel-dpy / ADR-0014), PROMOTED onto the protocol
 * surface (kestrel-h314 D5) — `FillSupport`, `SupportPartition`, `partition`, `rawEv`, `bankableEvOf`,
 * `bankableEv`, `isCalibratedSupport`. Pure, intra-protocol, dependency-free. One source: the runtime's
 * `src/support/index.ts` and any self-hosted outsider read the SAME policy from here.
 */
export * from "./support.ts";

/**
 * The one OSS-exported deterministic Judge (kestrel-h314 D4, CONTEXT "Judge"):
 * `grade(blotters) → GradeResult` over the PROTOCOL Blotter, emitting BOTH metric families over a shared
 * 1e-8 rounding grid. Fail-closed: a Blotter lacking the certified evidence is REFUSED the risk-honest
 * family (UNKNOWN + logged reason), never a silent zero.
 */
export * from "./grade.ts";
