UNPKG

kestrel.markets

Version:

A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.

165 lines 12 kB
/** * # frame/paradigm-ledger — the FOUR-STATE paradigm cell ledger (ADR-0041 §3, kestrel-wa0j.30) * * ADR-0041 §3 makes every `(pane × sort-value-bundle)` cell exactly one of four states: * • **ATTESTED** — materializes byte-identically today (and is monotone forever — the ratchet). * • **LATENT** — not yet, but a NAMED train will land it (a LATENT refusal names its train). * • **DEFECTIVE** — never, for a WRITTEN reason, with a SANCTIONED PERIPHRASIS. * • **UNATTESTED** — outside the closed roster (the closed-world default; never enumerated). * * This module is the SINGLE SOURCE of that table. It ships in `src/` (the package's `files` * excludes `tests/`), so production refusal constructors ({@link ./refusals.ts}) can read it — a * LATENT refusal pulls its train from HERE, never a second hand-kept list. The committed sidecar * `tests/golden/pane-paradigm.json` is this data SERIALIZED (generated by * `scripts/gen-paradigm-ledger.ts`, staleness-checked in `tests/frame.paradigm-ledger.test.ts`) — * the repo's generate-golden-from-source pattern (cf. `gen-detmath-golden.ts`), so the JSON can * never drift from this module. * * ## Totality (ADR-0041 §3: "a total function over a known grid") * {@link resolveCellState} is a TOTAL function over `pane × {@link PARADIGM_ROSTER}`: every cell * resolves to exactly one state. The listed {@link PARADIGM_CELLS} carry the non-UNATTESTED states; * every unlisted cell is UNATTESTED by the closed-world rule. `tests/frame.paradigm-ledger.test.ts` * asserts totality (no cell unclassified) and binds the ATTESTED rows to the live catalog signatures. * * ## Forward-compatibility with scheme conditioning (wa0j.44 — NOT implemented here) * A cell's state may later be CONDITIONED on a registry attribute (instrumentClass / SessionScheme): * `prior-context` is DEFECTIVE under a SessionScheme with no close boundary but ATTESTED under one * with a close — ONE paradigm, two conditioned cells (ADR-0041 §3). The cell KEY carries an OPTIONAL * {@link CellConditioning}; every current cell OMITS it (= unconditioned, applies to all schemes). * wa0j.44 adds scheme-conditioned cells by ADDING a more-specific conditioned cell — it NEVER * re-keys an existing unconditioned one. Pinning the optional field into the key shape NOW (while the * ledger is small) is the empty-ledger lesson (wa0j.52 / instrumentClass): an axis added to an * established key is an evidence-splitting migration; an optional axis reserved up front is additive. */ import { type BoundaryKind, type SessionScheme } from "./session-scheme.ts"; /** The four paradigm states (ADR-0041 §3). */ export declare const PARADIGM_STATES: readonly ["ATTESTED", "LATENT", "DEFECTIVE", "UNATTESTED"]; export type ParadigmState = (typeof PARADIGM_STATES)[number]; /** A state a LISTED cell may carry — UNATTESTED is the closed-world default and is NEVER listed * (listing it would enumerate the open world the closed-world rule exists to avoid). */ export type ListedState = Exclude<ParadigmState, "UNATTESTED">; /** * The CLOSED sort roster (ADR-0041 §1/§3) — the ground index sorts a pane argument may address. It * is closed at any instant and opened ONLY by the sort-introduction ceremony (five artifacts in one * commit). Train 1A's LIVE subset is {@link LIVE_SORTS}; the rest are pinned into the roster but * DEFERRED (their slots arrive with later trains). A value OUTSIDE this roster is UNATTESTED and * refused by name. */ export declare const PARADIGM_ROSTER: readonly ["Instrument", "LevelName", "Window", "Count", "SessionOrdinal", "ExpiryOrdinal", "Band"]; export type RosterSort = (typeof PARADIGM_ROSTER)[number]; /** The LIVE subset of {@link PARADIGM_ROSTER} the catalog materializes (has a catalog slot for). * Train 1A opened `LevelName` / `Window` / `Count`; Train 1B opened `SessionOrdinal` (`tape d-N`) and * `ExpiryOrdinal` (`chain e-N`) by the sort-introduction ceremony (ADR-0041 §3). */ export declare const LIVE_SORTS: readonly RosterSort[]; /** * A registry attribute a cell's paradigm state may be CONDITIONED on (ADR-0041 §3 / kestrel-wa0j.44). * ABSENT on every current cell (= unconditioned; the state holds for every instrumentClass / * SessionScheme). Reserved in the key shape NOW so wa0j.44 conditions cells additively — see the * module header. NOT populated here (wa0j.44 is explicitly out of scope for wa0j.30). */ export interface CellConditioning { readonly instrumentClass?: string; readonly sessionScheme?: string; } /** * One LISTED `(pane × sort)` cell of the ledger. UNATTESTED cells are never listed (closed-world). * Per-state required fields (enforced by {@link validateParadigmCell}): * • ATTESTED → `form` (the taught canonical View form that materializes it). * • LATENT → `train` (the named deferred train — ADR-0041 §3: a LATENT refusal names its train). * • DEFECTIVE → `reason` + `periphrasis` (the written reason + the sanctioned periphrasis). */ export interface ParadigmCell { readonly pane: string; readonly sort: RosterSort; readonly state: ListedState; readonly form?: string; readonly train?: string; readonly reason?: string; readonly periphrasis?: string; readonly conditioning?: CellConditioning; } /** Where the first production DEFECTIVE cell arrives (documented — ADR-0041 §3). It has LANDED with * kestrel-wa0j.44 as a SCHEME-CONDITIONED cell (see {@link SCHEME_CONDITIONED_CELLS}); no cell in the * UNCONDITIONED `(pane × sort)` space is DEFECTIVE (the ratchet's equity-rth bytes stay pinned). */ export declare const DEFECTIVE_FIRST_ARRIVAL: string; /** * The SessionOrdinal boundary each pane's read REQUIRES (ADR-0041 §3 conditioning). A pane listed here * is DEFECTIVE under any {@link ../frame/session-scheme.ts SessionScheme} that does NOT carry the * required boundary, and ATTESTED-as-today under one that does — ONE paradigm, conditioned on the * registry attribute (never two paradigms). * • `prior-context` anchors to the prior CLOSE (the `d-1` close boundary of the SessionOrdinal * stream), so it requires `close`. * • `tape` (Train 1B) addresses a PRIOR SESSION (`tape d-N`, N≥1); a prior session must be delimited * by a session `close`, so a scheme with no close (a perp's rolling UTC day) has no prior-session * address at all — `tape × SessionOrdinal` is scheme-conditioned DEFECTIVE there (the builder * renders the sanctioned periphrasis, anchor to the declared rolling extreme, never an invented * session), and ATTESTED-as-today under a close-bearing scheme (equity-rth, the default). Note this * is the CONDITIONED overlay on the UNCONDITIONED ATTESTED `tape × SessionOrdinal` cell — exactly * the prior-context pattern (one paradigm, two conditioned cells). * Flipping a declaration is the red-capability lever: retarget the required boundary and the conditioned * cell + the production refusal follow. This is the SINGLE SOURCE of the requirement — * {@link resolveCellState}, {@link schemeConditionedDefect}, and the census all read it. */ export declare const PANE_BOUNDARY_REQUIREMENT: Readonly<Record<string, BoundaryKind>>; /** The roster sort a boundary-conditioned cell is keyed on: `SessionOrdinal` — the monotone boundary * stream `d-N` indexes (ADR-0041 §1). A close/open boundary IS a SessionOrdinal address. */ export declare const CONDITIONED_SORT: RosterSort; /** The sanctioned periphrasis for a boundary-conditioned DEFECTIVE cell (ADR-0041 §3 exemplar). */ export declare const CONDITIONED_PERIPHRASIS = "anchor to the declared rolling extreme"; /** * The scheme-conditioned DEFECTIVE cell for `(pane × scheme)`, or `undefined` when the pane has no * boundary requirement OR the scheme CARRIES the required boundary (then the pane is ATTESTED-as-today, * not DEFECTIVE). Generated from {@link PANE_BOUNDARY_REQUIREMENT} × the scheme's boundary declaration — * the production refusal ({@link ./refusals.ts}) and the census both read this one function, so they * can never quote a different reason/periphrasis than the cell states. */ export declare function schemeConditionedDefect(pane: string, scheme: SessionScheme): ParadigmCell | undefined; /** * Every scheme-conditioned DEFECTIVE cell in the v1 grid (ADR-0041 §3) — the Cartesian product of the * boundary-requiring panes × the schemes that LACK their required boundary. This is the production * DEFECTIVE set (the census surfaces it); it is DELIBERATELY separate from {@link PARADIGM_CELLS} (the * unconditioned grid) so the unconditioned census + conformance ratchet keep the equity-rth bytes * pinned. Regenerating the sidecar re-derives this from the tables — it can never drift. */ export declare const SCHEME_CONDITIONED_CELLS: readonly ParadigmCell[]; /** Every LISTED cell (ATTESTED + LATENT + DEFECTIVE). Unlisted cells are UNATTESTED (closed-world). */ export declare const PARADIGM_CELLS: readonly ParadigmCell[]; /** * The LATENT train each `views.kestrel` destination pane form is waiting on (ADR-0041 §3), keyed by * pane id. This is the SINGLE SOURCE that `tests/frame.inflection-burndown.test.ts` reads — the * burn-down no longer keeps its own copy. Distinct projection from {@link PARADIGM_CELLS}: those * classify `(pane × roster-sort)`; this names the train for the destination-corpus FORMS (mostly * new, not-yet-admitted sorts — named level-SETs, tape style/overlay/strip, macro/vol sub-selectors). */ export declare const DESTINATION_BACKLOG: Readonly<Record<string, string>>; /** True iff `sort` is a member of the closed {@link PARADIGM_ROSTER}. */ export declare function isRosterSort(sort: string): sort is RosterSort; /** * The TOTAL four-state resolution (ADR-0041 §3). A listed unconditioned cell carries its state; every * other `(pane × sort)` is UNATTESTED by the closed-world rule. Total by construction: it returns a * {@link ParadigmState} for EVERY input, never throws, never `undefined` — the property the ledger * test asserts over the whole `pane × roster` grid. * * **Scheme conditioning (kestrel-wa0j.44).** When a {@link CellConditioning} supplying a * `sessionScheme` is passed AND the pane declares a {@link PANE_BOUNDARY_REQUIREMENT} on the * {@link CONDITIONED_SORT}, the state is conditioned on the registry attribute — ONE paradigm, two * conditioned cells: DEFECTIVE when the scheme LACKS the required boundary (a no-close perp), ATTESTED * (as-today) when it carries it (equity-rth). The UNCONDITIONED call (no `conditioning`) is unchanged — * the pane's conditioned axis is invisible to the unconditioned census + the conformance ratchet, so * the equity-rth bytes stay pinned. */ export declare function resolveCellState(pane: string, sort: string, conditioning?: CellConditioning): ParadigmState; /** The named LATENT train for a destination-corpus pane form, or `undefined` if the pane is not in * the backlog (ADR-0041 §3: a LATENT refusal names its train — pulled from HERE by the constructor). */ export declare function latentTrainFor(pane: string): string | undefined; /** The ATTESTED cells (the conformance-ratchet seed — monotone forever, ADR-0041 §3). */ export declare function attestedCells(): readonly ParadigmCell[]; /** * Validate ONE cell against the paradigm-cell schema, returning a list of human-readable errors * (empty ⇒ valid). Enforces the per-state required fields (ADR-0041 §3) so a DEFECTIVE cell can * never omit its reason/periphrasis, an ATTESTED cell can never omit its form, etc. Executable mirror * of `tests/golden/pane-paradigm.schema.json`; used by the totality test AND the DEFECTIVE * schema-example test (which proves the state is supported without a fake production entry). */ export declare function validateParadigmCell(cell: unknown): string[]; //# sourceMappingURL=paradigm-ledger.d.ts.map