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.

106 lines 7.3 kB
/** * # frame/kernel-walk — the ONE cockpit-kernel walk + the shared kernel helpers (ADR-0052 §1) * * The SAFETY / CONTROL cockpit kernel has exactly ONE traversal: {@link walkKernel} visits the * optional mandate/brief prefix and then the 8 fixed-order {@link ./types.ts KERNEL_SECTION_LABELS} * sections, IN ORDER, calling a {@link KernelSink} method for each. Every section method is ALWAYS * called (absent-not-hidden is a structural property of the walk — a section can never be silently * skipped), and the SECTION ORDER lives here once. The two shipped renderers are format ADAPTERS * over this one walk: the canonical text sink ({@link ./render.ts}) materializes the delta-anchored * cell-lines, the token-optimal ARM sink ({@link ./render-arm.ts}) materializes the compact ASCII * lines. A new section, or a reordering, lands in BOTH renderers from a single edit here. * * This module also owns the kernel helpers both adapters share — the engine-log bucket set + * classification, the resting-order state label, and the action id token — parameterized by the * small vocabulary each adapter differs on, so the LOGIC is single-source while the BYTES stay each * adapter's own. PURE: no wall clock, no RNG (the whole render path is deterministic, RUNTIME §0). */ import type { Brief, Claim, EngineAction, EngineActionKind, Kernel, Mandate, OwnerAct, Position, RestingOrder, VehicleHealth, WakeRef } from "./types.ts"; /** * A format adapter for the cockpit kernel: {@link walkKernel} calls these in the fixed cockpit order * and each implementation accumulates its own line representation (canonical cell-lines, arm strings). * A section method is called EVEN WHEN its data is empty (absent-not-hidden) — the adapter renders the * explicit `none`/`UNKNOWN` placeholder, never a dropped section. The `mandate`/`brief` methods are * called ONLY when present (they are the optional standing-context prefix, not one of the 8 sections). */ export interface KernelSink { /** The lead block: the kernel sentinel (canonical) / the `#KERNEL <kind>` banner (arm). */ sentinel(frameKind: "OPEN" | "WAKE"): void; /** The `frame=<kind>` line (canonical only; the arm folds the kind into its sentinel). */ frameLine(frameKind: "OPEN" | "WAKE"): void; /** MANDATE — the hard, machine-checkable admission channel (ADR-0026). Present-only. */ mandate(mandate: Mandate): void; /** BRIEF — the soft, directional English channel; NOT an admission input (ADR-0026). Present-only. */ brief(brief: Brief): void; /** §1 WAKE — reason / severity / RELATIVE deadline. */ wake(wake: WakeRef | null | undefined): void; /** §2 DATA-HEALTH per vehicle + the NAMED unavailable capabilities. */ dataHealth(rows: readonly VehicleHealth[], unavailable: readonly string[]): void; /** §3 POSITIONS / INVENTORY-CLAIMS. */ positions(positions: readonly Position[]): void; /** §4 RESTING ORDERS. */ resting(resting: readonly RestingOrder[]): void; /** §5 BUDGET / REMAINING-R + the sizing headroom. */ budget(envelope: BudgetEnvelopeArg): void; /** §6 OWNER ENVELOPE + ACTS (the envelope echo reads the same budget as §5). */ ownerActs(envelope: BudgetEnvelopeArg, acts: readonly OwnerAct[]): void; /** §7 L0/L1 ENGINE LOG — bucketed fired | cancelled | rejected | clamped (+ catch-all `other`). */ engineLog(elog: readonly EngineAction[]): void; /** §8 PREDICTOR / REGIME CLAIMS. */ claims(claims: readonly Claim[]): void; } /** The budget-envelope argument §5 and §6 share (the cockpit risk envelope, or absent). */ export type BudgetEnvelopeArg = Kernel["budgetEnvelope"]; /** * The ONE cockpit-kernel traversal: mandate/brief prefix (present-only) then the 8 fixed-order * sections, each ALWAYS visited. This is the single source of the kernel's SECTION ORDER and its * absent-not-hidden completeness — both format adapters get an identical structure from it. PURE. */ export declare function walkKernel(kernel: Kernel, frameKind: "OPEN" | "WAKE", sink: KernelSink): void; /** The four engine-log buckets, in fixed render order — shared by both adapters. */ export declare const ENGINE_LOG_BUCKETS: readonly EngineActionKind[]; /** The engine log classified into the four fixed buckets (in order) + a catch-all `other` for any * kind outside the closed union (arrived across an untyped/JSON/`as` boundary — surfaced, never * dropped: absent-not-hidden). The classification is single-source; each adapter formats it. */ export interface EngineLogBuckets { readonly buckets: readonly { readonly kind: EngineActionKind; readonly items: readonly EngineAction[]; }[]; readonly other: readonly EngineAction[]; } /** Classify an engine log into the fixed buckets (order-preserving) + the catch-all `other`. PURE. */ export declare function bucketEngineLog(elog: readonly EngineAction[]): EngineLogBuckets; /** The per-adapter label vocabulary for {@link restingLabel} — `live` and `clamped` are INDEPENDENT * flags, so a live+clamped order surfaces BOTH (a `live` label can never mask a premium-band clamp). */ export interface RestingLabels { readonly live: string; readonly liveClamped: string; readonly clamped: string; readonly off: string; } /** The resting-order state label under an adapter's vocabulary. `live`/`clamped` independent * (fail-closed honesty: a clamped price is never hidden by a LIVE label). PURE. */ export declare function restingLabel(o: RestingOrder, labels: RestingLabels): string; /** The per-adapter shape of an engine action's id token (canonical `id@seqN (reason)`, arm * `id@N(reason)`). `seqPrefix` sits between `@` and the ordinal; `reasonSpace` inserts a space * before the `(reason)` group. Reason-when-present: no reason ⇒ byte-identical to the id@seq alone. */ export interface ActionTokenStyle { readonly seqPrefix: string; readonly reasonSpace: boolean; } /** An engine action's render token `id@<seqPrefix><ordinal>` plus `(reason)` WHEN present (the * engine-authored cause — never-naked / plan-budget / regime-UNKNOWN — that must not be silently * dropped at the render seam, kestrel-75n). PURE. */ export declare function actionToken(e: EngineAction, style: ActionTokenStyle): string; /** * A bucket's action tokens with each CONSECUTIVE RUN of items sharing an identical `(id, reason)` * collapsed to `<count>x <exemplar token>` instead of N near-duplicate tokens (kestrel-7bip). A plan * whose STATE trigger holds every tick emits the SAME refusal (`uncovered sell refused: never naked`) * once per tick — 24 byte-identical entries in one frame — flooding the very percept the token-optimal * renderer exists to conserve. The de-dup is a RENDER-time collapse ONLY (the engine still authors and * counts every action; the bucket's `items.length` count is unchanged): a run of one renders as the * bare token (byte-identical to pre-collapse, so no existing frame churns), and the exemplar keeps its * real `@seq` so the collapsed line stays a concrete, addressable receipt. Order-preserving; PURE. */ export declare function collapseActionTokens(items: readonly EngineAction[], style: ActionTokenStyle): string[]; //# sourceMappingURL=kernel-walk.d.ts.map