/** * # session/simulate — the frozen-at-wake Simulate driver (the Agent seam's companion to `./day.ts`) * * The **wake-driven, agent-in-loop** driver (RUNTIME §7). Where {@link import("./day.ts").runDaySession} * pauses at each wake and hands an external author a Frame through a FILE handshake, this drives the SAME * {@link SessionCore} — the same bus-stepping, the same {@link import("../engine").Gate}, the same * fills-before-sweep ordering — but hands the frozen vantage to the {@link Agent} seam IN-PROCESS and * consumes the {@link AgentTurn} it returns. Between wakes the standing Plans fire autonomously * (fire-then-inform); at a wake the driver freezes market time, assembles a date-blind {@link ActingFrame}, * `await`s `agent.decide(frame)`, and serializes every returned {@link Action} onto the graded Bus. * * ## Where the determinism boundary sits (RUNTIME §0, the whole point) * The single value that crosses the boundary is the returned {@link AgentTurn}; BELOW it everything is a * pure function of Bus bytes (ADR-0011). Every Action is stamped at the **injected wake ts** (no wall * clock, no unseeded RNG on the record path), so `project(gradedBus)` re-derives a byte-identical Blotter * and a captured run re-runs as a Backtest through {@link recordedAgent}. The delivered {@link ActingFrame} * (Rendering, model call, sampling) sits ABOVE the line — the recorded/fixed adapters ignore it entirely. * * ## Action → Bus routing (fail-closed, bounded-risk) * - `supersede` → parse the Kestrel document; the FIRST is the initial arm (no CONTROL, `day.ts` plans-0 * parity), a later one emits a CONTROL `supersede` + de-arm + arm. A parse escape de-arms * clean with a logged reason (never a crash — RUNTIME §8). * - `standDown` → a CONTROL `disarm` + de-arm clean (inventory rides its TP/EXIT — never liquidates). * - `journal` → a **pre-hoc** JOURNAL `author` record, emitted BEFORE the turn's other actions (provably * pre-hoc by `seq`). * - `scheduleWake` → recorded as a WAKE `scheduled` record AND unioned onto the agent-driven wake * frontier (kestrel-5zl.4): the agent's own cadence drives, floored (never replaced) by * the staleness backstop + optional structural cadence, coalesced/downgraded past the * attention budget (the squelch stays visible — never a silent drop). * - `placeOrder` / `cancelOrder` → routed through the **SAME Gate** a fired Plan uses (`core.gate`): an * order is expressed as a one-shot Plan and armed, so it crosses the identical * engine→Gate→fill path — SELL≥intrinsic, the budget clamp, and never-naked are enforced by * the engine, never re-implemented here (bounded risk by construction). * * Scope: this is the tracer-bullet slice — the thinnest deterministic Simulate path exercised by * {@link fixedPlanAgent} + {@link recordedAgent}. The live adapter body, the config matrix, and * wire-capture are later slices; the full Wake-grammar authoring (subscriptions/Views, the budget * algebra, per-session structural re-anchoring) is the b3l Wake-router epic — see `armStaleness`/ * `resolveWakeAt` for the conservative defaults taken here. */ import type { BusEvent, MetaEvent } from "../bus/index.ts"; import { readBus } from "../bus/index.ts"; import type { Right } from "../bus/types.ts"; import { intrinsic } from "../fair/index.ts"; import { assertNever, parse, print, type KestrelNode, type Module, type PlanStatement } from "../lang/index.ts"; import { armedPlanTermsOf, ENFORCED_PLAN_STATES } from "./armed-plan-terms.ts"; import { decisionControlFields, driverMeasurementVersions, type DecisionEmit } from "../grade/index.ts"; import type { InstrumentSpec } from "../engine/index.ts"; import type { EpisodeSigmoidParams } from "../fill/index.ts"; import { heldPositionAsOfGradedBus } from "../fill/index.ts"; import type { Blotter } from "../blotter/index.ts"; import { project } from "../blotter/index.ts"; import type { BriefingInput, EngineAction, FillRecord, FramePhase, FrameRight, InstrumentSpec as FrameInstrumentSpec, Kernel, Mandate, Brief, PlanStateEntry, Position, PriorSessionTape, PriorVantage, SizingHeadroom, RestingOrder, VehicleHealth, WakeRef, } from "../frame/types.ts"; import { expiryTauYears, etMinuteOfDay, etWallClockMs, type FairTauProvider } from "./clock.ts"; import { SessionCore, busSha256Of, fidelityOf, requireMeta, resolveSpecs, type FillModelName, type SessionReport } from "./sim.ts"; import { authorCutoffTs, briefingSnapshot, computeWakes, projectAuthorFrame, scanDateLeak, snapshotOf, type AuthorFrame, type TimeOfDay, } from "./day.ts"; import { OPEN_WAKE_KEY, assertHandlerResponseTimeless, wakeKeyOf, type Action, type ActingFrame, type Agent, type AgentConfig, type AgentTurn, type CapturedTurn, type CapturedTurns, type PlaceOrderAction, type WakeAt, type WakeKey, type WakeSource, } from "./agent.ts"; import { resolveView, windowServableBy, paneById, atmStraddleExtrinsic, type ViewSelection } from "../frame/pane-catalog.ts"; import type { OptionsAnalytics } from "../frame/options-analytics.ts"; import { canonicalizeConfig, cellConfigId as cellConfigIdOf, deriveConfigId, envelopeForConfig, fillSeedOf, sampledQualificationOf } from "./config.ts"; import { carryFrom, emptyCarry, type SessionCarry } from "./carry.ts"; // The stowaway concepts extracted from this driver into sibling modules (kestrel-z473.1) — this file // keeps ONLY the wake loop. Each is imported back for the loop's own use; the ones this file used to // export are re-exported below so the public surface is byte-identical. import { vehicleHealthOf, vehicleBookFromSpot, type VehicleBook } from "./vehicle-health.ts"; import { sizingHeadroomOf, budgetEnvelopeOf } from "./sizing.ts"; import { marketPaneOf, buildFrameOptions, SERVED_TAPE_BUCKET_MIN, type ChainFairContext, type OptionsOverlayConfig, } from "./market-pane.ts"; import { runOpenAuthoringLoop, viewSelectionOfDocument, DEFAULT_VIEW_REQUEST_CAP, DEFAULT_AUTHORING_TOKEN_BUDGET, type EmergenceRecord, } from "./authoring-loop.ts"; import { wakeFloorForBand, DAY_STALENESS_BACKSTOP_MIN, type FrontierWake, type WakeCtx } from "./wake-frontier.ts"; // Re-export the moved public symbols so `import { … } from ".../session/simulate.ts"` (and the // `src/session/index.ts` barrel) resolve exactly as before — the extraction is API-transparent. export { marketPaneOf, SERVED_TAPE_BUCKET_MIN, type ChainFairContext, type OptionsOverlayConfig } from "./market-pane.ts"; export { vehicleHealthOf, vehicleBookFromSpot, type VehicleBook } from "./vehicle-health.ts"; export { sizingHeadroomOf } from "./sizing.ts"; export { viewSelectionOfDocument, DEFAULT_VIEW_REQUEST_CAP, DEFAULT_AUTHORING_TOKEN_BUDGET, type EmergenceRecord, } from "./authoring-loop.ts"; export { type WakeCtx } from "./wake-frontier.ts"; // ───────────────────────────────────────────────────────────────────────────── // Public surface // ───────────────────────────────────────────────────────────────────────────── /** * The DAY-COMPAT side-channel (kestrel-5zl.3) — the narrow bridge the {@link import("./day.ts").runDaySession} * fileHandshakeAgent and the driver share so the day agent can render its inspectable artifacts + validate * revisions against the LIVE core WITHOUT a forked progression path. It carries NOTHING onto the graded * stream (it sits entirely ABOVE the determinism line): the driver sets `vantage` at each vantage BEFORE * calling `agent.open`/`agent.decide`, and binds `previewSupersede` once to the live engine's pure collision * preview. Present ONLY on the actual day file agent; a plain {@link dayCompat} run (e.g. a recordedAgent * replay) passes no bridge and the driver never touches it. */ export interface DayCompatBridge { /** The raw date-blind {@link AuthorFrame} for THIS vantage (OPEN briefing / each wake), set by the driver * before the corresponding `agent.open`/`agent.decide`. The day agent names each wake artifact from it * (`frame--.txt`) and serializes it as the `state-.json` machine channel; the TEXT frames * render through the canonical `src/frame` renderer over the driver's typed frames (kestrel-wa0j.2). */ vantage?: AuthorFrame; /** The engine's PURE supersede-then-arm collision preview ({@link import("../engine/index.ts").PlanEngine} * `supersedeArmRejection`), bound once by the driver to the live core: a rejection reason or `null`. The * day agent's reject-retry consults it so the standing book is NEVER torn down for a doomed revision * (fail-closed blast-radius, RUNTIME §8) — the collision preview guarantees the driver's subsequent * supersede+arm cannot reject. */ previewSupersede?: (mod: Module) => string | null; } /** Options for {@link runSimulateSession}. Exactly one of `busPath`/`events` supplies the bus; the * {@link Agent} seam supplies the decisions. The fill/tau/budget knobs mirror {@link import("./sim.ts").RunSimOptions}. */ export interface RunSimulateOptions { readonly busPath?: string; readonly events?: readonly BusEvent[]; /** The agent under test — live, recorded, fixed-plan, or file-handshake (the ONE seam). */ readonly agent: Agent; /** Authored wake vantages (ET times-of-day), strictly inside the driven window. */ readonly wakes?: readonly TimeOfDay[]; /** The author acting cutoff (an ET wall-clock time-of-day). The OPEN briefing is built ONLY from * observations watermarked at or before this instant; defaults to the canonical benchmark's T-5 * (09:25 ET). Injected + explicit so no post-cutoff print leaks to the agent (kestrel-m9i.11). */ readonly authorCutoff?: TimeOfDay; /** Present the OPEN authoring vantage as an INTRADAY keyframe carrying the observed range * (kestrel-1vw): when `true`, the OPEN briefing folds every exec observation at/before {@link * authorCutoff} into the range (`hod`/`lod`/`tape` + the current spot) instead of the pre-open * keyframe — so an ORB cell authoring at its opening-range close sees the range it must break out of. * The causal cutoff fence is unchanged (no post-cutoff print leaks); this ONLY changes whether the * admitted prefix is collapsed to the opening keyframe or presented as the range. Absent / `false` ⇒ * today's pre-open briefing, byte-identical. Set together with an intraday {@link authorCutoff}. */ readonly authorFromRange?: boolean; /** Add the structural cadence into the close (T-2h…T-5m) — see {@link computeWakes}. */ readonly structural?: boolean; readonly fillModel: FillModelName; readonly rUsd: number; /** The cell-sourced hard {@link Mandate} (ADR-0026) — the objective + R-definition + success * criterion + bounded-risk rule the agent is graded against. Rendered in the kernel; the ONLY * admission input. A GRADED run must declare one ({@link import("../frame/types.ts").assertGradedMandate}); * an ungraded/dev run may omit it (the frame renders unchanged). NOT hardcoded — the cell owns it. */ readonly mandate?: Mandate; /** The cell-sourced soft {@link Brief} (ADR-0026) — directional English (goal/approach/persona), * rendered as standing context, hashed + attributed, but NEVER an admission input (the hard guard). */ readonly brief?: Brief; readonly instruments?: readonly InstrumentSpec[]; readonly fairTauYears?: FairTauProvider; readonly makerFairParams?: EpisodeSigmoidParams; /** The prior session's {@link SessionCarry} (the multi-session horizon design, kestrel-5zl.16). Its `positions` seed this * session's opening book and its `document` is re-armed fresh (new plan-instance ids) BEFORE the OPEN * turn. Absent — or an `emptyCarry()` — is today's flat open, byte-identical. */ readonly openingCarry?: SessionCarry; /** `true` for a NON-final session of a multi-session Instance: settle carry-marks held inventory (it * survives into the returned {@link SimulateResult.carry}) instead of forcing it to intrinsic. Absent / * `false` — a standalone or the final session — is today's terminal intrinsic settle exactly. */ readonly carryClose?: boolean; /** This session's ordinal `k` in its Instance (the multi-session horizon design, kestrel-5zl.16.4) — the relative-day * coordinate `d{k}`. Absent for a standalone run ⇒ today's coordinate (no `d{k}` prefix), byte-identical. */ readonly sessionOrdinal?: number; /** The bounded OPEN authoring loop's dual budget (ADR-0029 §2). Consulted ONLY when the agent * exposes {@link Agent.authoringOpen} (the viewshop arm); a baseline/recorded/fixed run ignores it * entirely (single-shot open, byte-identical). Both fields are config axes — a different budget is a * different grid column. Absent ⇒ the conservative defaults ({@link DEFAULT_VIEW_REQUEST_CAP} / * {@link DEFAULT_AUTHORING_TOKEN_BUDGET}). */ readonly authoring?: { /** Max non-terminal iterations (view-requests + repairs, shared) before fail-closed standDown. */ readonly viewRequestCap?: number; /** Cumulative model-token ceiling (input + output + thinking, summed across iterations). */ readonly authoringTokenBudget?: number; }; /** The Percept v5 EMERGENCE LOG sink (ADR-0029 §5) — OFF the graded path. When supplied, the driver * appends one {@link EmergenceRecord} per non-terminal authoring iteration (BOTH view-requests AND * parse-error/repair events), keyed by `(OPEN_ORDINAL, iteration)`. Private application data (the raw * data for the emergence study AND the grammar-evolution signal, ADR-0030); never a graded input. */ readonly emergenceLog?: EmergenceRecord[]; /** * DAY-COMPAT MODE (kestrel-5zl.3 re-run) — the CALLER-OWNS-CADENCE path the {@link import("./day.ts").runDaySession} * fileHandshakeAgent refactor drives through. When the caller owns the wake cadence (the day's structural * offsets), the driver reproduces the STEPPED runner's cadence + byte stream EXACTLY: * - NO injected platform-default staleness/backstop wakes for this path — the day's own structural wakes * provide the coverage, so the delivered wake set is exactly `computeWakes(...)` (no 30-min DAY backstop * churn), reproducing the frozen day determinism_hash 44cf2cbf; * - CONTROL supersede carries the day's `{target:"wake-N", note:"revision-N"}` byte shape (not the bare * `{note?}` the agent-driven path emits), so `serializeEvent` bytes match the stepped runner. * * This is NARROW: it is NOT "silence the backstop". It never weakens the band fail-closed logic (16.7) for a * normal band run — {@link wakeFloorForBand}/{@link armStaleness} still floor every agent-driven session and * {@link tests/simulate.wake-band.test.ts} stays green. Absent / `false` ⇒ today's full agent-driven frontier, * byte-identical. (Threaded by the green step; declared here as the contract the TDD-red test targets.) */ readonly dayCompat?: boolean; /** The DAY-COMPAT {@link DayCompatBridge} (kestrel-5zl.3) — present ONLY when the caller is the * {@link import("./day.ts").runDaySession} file agent (it renders artifacts from `vantage` + validates * revisions through `previewSupersede`). Off the graded line: the driver sets `vantage` before each * `open`/`decide` and binds `previewSupersede` to the live core, but emits NOTHING from it. A plain * `dayCompat` run (a recordedAgent replay) omits it and the driver never touches it. */ readonly dayBridge?: DayCompatBridge; /** The options-analytics OVERLAY (kestrel-4gl.13.13) — the perception arm's OPRA surface, folded * causally into `market.options` at every frame cutoff so the `gex`/`iv-skew`/`implied-realized` * panes render in a LIVE run. **Config-gated: supplied ONLY for the perception arm** (a View that * selects the options-analytics panes). Absent — the minimal arm — leaves `market.options` * undefined and every frame byte-identical to before (the panes are off-default; the fold is never * paid). Folded per-cutoff with the T-5m guard (only events at/before the cutoff, no look-ahead) and * relabeled date-blind before it reaches the agent frame ({@link buildFrameOptions}). */ readonly optionsOverlay?: OptionsOverlayConfig; /** * THE MULTIDAY TAPE SEAM (kestrel-wa0j.20 — the DATA half of Train 1B's `tape d-N` address). The * PRIOR sessions' tapes (date-blind: relative ordinals + HH:MM clocks, NEVER dates), threaded onto * every frame this session serves so a View naming `tape d-N` (N ≥ 1) renders ordinal N's OWN * single-session block instead of the Train 1B absence line. Each ordinal renders SEPARATELY — no * cross-session folding (that is wa0j.20b, behind PR #194's render unification). * * INJECTABLE seam: the v1 single-day sim carries no multi-session tape state, so this is typically * ABSENT (honestly — `tape d-N` then renders absent-with-reason, byte-identical). A multi-day harness * (or a future day/backtest path that has the prior sessions' rows cheaply available) INJECTS them * here; the driver threads them, unchanged, into both the OPEN briefing and every wake frame. Absent * ⇒ no `priorSessions` field on any frame, byte-identical to today. */ readonly priorSessions?: readonly PriorSessionTape[]; /** * THE THETA GATE (theta-cell seam b, {@link import("../fill/held-position.ts").heldPositionAsOfGradedBus}). * When `true`, after settle the driver asks the held-position owner for the position held as of the * graded bus — it reconstructs the net HELD option legs + their blended basis, re-marks them against the * tape's own option book at every DELIVERED wake (theta decay between wakes), and returns ONE graded * `TELEMETRY theta_bleed` record carrying the stand-down floor (the mark at the LAST wake), which the * driver emits verbatim. The Blotter folds that into `totals.floor` (ADR-0011), so a watcher that STANDS PAT on a * bleeding straddle realizes a graded NEGATIVE floor instead of paying no running cost for doing nothing * — the whole point of the theta cell (it dissolves the doing-nothing-wins degenerate reward). * * Threaded from the FOMC-OPTIONS {@link import("./harness/plan-fixture.ts").FanFrame} `markToModel`. * Absent / `false` (every other cell) ⇒ no reconstruction, no record, no fold — every existing pinned * floor is byte-identical. Only binds when a position is actually HELD across ≥1 wake (a flat book, or a * watcher that closed out, emits nothing). CLEAN BOUNDARY: the bleed rides the graded Bus / Blotter as a * mark-to-model GRADING penalty; it is deliberately NOT folded into the engine-native SessionReport * `realized_floor_usd` or the multi-session carry cash (that report/ledger integration is separate work). */ readonly markToModel?: boolean; /** * The injectable wall clock the driver measures a clock-honest Seat turn with (ADR-0040 / * clock-honest wakes §7 — the ONE minting seam, the `opts.now ?? Date.now` idiom of `liveAgent`). * Consulted ONLY in a LIVE-shaped clock-honest run: a latency-blind session never measures (its * captures stay costless-deterministic), and a REPLAY (an agent exposing `recordedCostMs`) reads * recorded costs and never touches this — a replay path that reads a clock is a defect by * definition (the poisoned-clock fixture). Defaults to `Date.now`. */ readonly now?: () => number; /** * The session's DECLARED data rung (ADR-0040 data floor / clock-honest wakes §4) — the tape's * observability provenance (`"tick" | "second" | "minute" | "session"`, the `GradingFidelity` * lattice), declared on the run options / session catalog and carried with the tape like * `fill_model`. Typed loosely (injected provenance bytes) and VERIFIED fail-closed via the isRung * discipline: `tick`/`second` ⇒ clock-honest eligible; `minute`/`session` ⇒ latency-blind; an * off-lattice or ABSENT rung ⇒ latency-blind (an untrusted rung never compares as eligible). * Requesting `clockHonest: true` over an ineligible/undeclared rung REFUSES the run loudly at open — * never a silent downgrade to latency-blind. Irrelevant to a latency-blind run (may be omitted). */ readonly dataRung?: string; } /** The result of a Simulate session: the graded {@link Blotter} (a PURE projection of the graded Bus, * ADR-0011), the {@link CapturedTurns} the run consumed (the deterministic replay input for * {@link recordedAgent}), and the agent's {@link AgentConfig} (the comparison axis). */ export interface SimulateResult { readonly blotter: Blotter; /** * The native graded {@link SessionReport} of this run (kestrel-m9i.7.4) — the SAME `core.buildReport` * projection {@link import("./day.ts").runDaySession} returns, computed here from the finalized core so a * live/handshake Simulate run lands in the run {@link import("../ledger").ledger} WITHOUT a Blotter→report * bridge (the tournament runner records this verbatim; `session.settle_ts` is the injected `recorded_at`). * A PURE read of the finalized session — no wall clock, no RNG, and byte-identical to a `runDaySession` * report of the same graded bus (RUNTIME §0). */ readonly report: SessionReport; readonly captured: CapturedTurns; readonly config: AgentConfig; /** The canonical GRADED bus of this run (`core.gradedBus()` — the judge-stamped META + every emitted * engine reaction, re-stamped gap-free): the record itself, surfaced so a caller (and the w7la.1 * clocked fixtures) can assert bus-level facts — deliberation records, checkpoints, refusal * stamping — without any engine-state scrape (ADR-0010: the Bus is the truth). A PURE read of the * finalized core; `project(gradedBus)` is byte-identical to {@link SimulateResult.blotter}. */ readonly gradedBus: readonly BusEvent[]; /** The {@link SessionCarry} this session hands to the next (the multi-session horizon design, kestrel-5zl.16) — a PURE read of * the finalised session. On a final / standalone session (`carryClose` absent) its `positions` are * empty (inventory settled at intrinsic). The runner ({@link import("./instance.ts").runInstance}) * threads it into the next session's `openingCarry`. */ readonly carry: SessionCarry; } // ───────────────────────────────────────────────────────────────────────────── // Small helpers (pure, deterministic — no wall clock, no RNG) // ───────────────────────────────────────────────────────────────────────────── /** Normalize a parsed node into a module (a bare statement → a one-statement module) so it can be armed. */ function toModule(node: KestrelNode): Module { return node.kind === "module" ? node : { kind: "module", imports: [], statements: [node] }; } function msgOf(e: unknown): string { return e instanceof Error ? e.message : String(e); } // ───────────────────────────────────────────────────────────────────────────── // Clock-honest eligibility (ADR-0040 data floor / clock-honest wakes §4) — declared, verified, fail-closed // ───────────────────────────────────────────────────────────────────────────── /** The rungs of the observability lattice fine enough to ground a clock-honest session (ADR-0040: * sub-minute ground truth — 1s bars / event streams). The isRung discipline (`src/series/registry.ts`) * applied to THIS question: anything outside the closed lattice is untrusted and never compares as * eligible. */ const CLOCK_HONEST_ELIGIBLE_RUNGS: ReadonlySet = new Set(["tick", "second"]); const OBSERVABILITY_RUNGS: ReadonlySet = new Set(["tick", "second", "minute", "session"]); /** * Why a declared data rung CANNOT ground a clock-honest session, or `null` when it is eligible * (clock-honest wakes §4). PURE and fail-closed — declared-then-verified is not trust: * - `"tick"` / `"second"` → eligible (`null`); * - `"minute"` / `"session"` → too coarse (the ADR-0040 data floor) — such a session stays VALID but * latency-blind, and may never claim clock-honesty; * - absent → undeclared provenance — refuse (never a silent default); * - off-lattice → an untrusted rung — refuse (never compared as coarser/finer than anything). * The caller (the driver, at open) REFUSES a `clockHonest: true` run whose rung returns non-null — * never a silent downgrade to latency-blind (a producer must never *believe* it bought a * latency-honest result it didn't get). */ export function clockHonestIneligibility(declaredRung: string | undefined): string | null { if (declaredRung === undefined) { return "the session declares NO data rung (`dataRung`) — clock-honest requires sub-minute ground truth declared with the tape (ADR-0040 data floor); refused at open, never a silent default"; } if (!OBSERVABILITY_RUNGS.has(declaredRung)) { return `declared data rung ${JSON.stringify(declaredRung)} is not on the observability lattice (tick, second, minute, session) — an untrusted rung never compares as clock-honest eligible (fail-closed)`; } if (!CLOCK_HONEST_ELIGIBLE_RUNGS.has(declaredRung)) { return `declared data rung "${declaredRung}" is too coarse for clock-honest semantics (ADR-0040 data floor: tick/second only) — run it latency-blind or declare finer ground truth; refused at open, never a silent downgrade`; } return null; } // ───────────────────────────────────────────────────────────────────────────── // Schedule-time View validation (kestrel-wa0j.19 §1b) — the driver-side guard the wake loop applies // when a `scheduleWake` is accepted. (The bounded OPEN authoring loop itself + the View-document → // ViewSelection mapper live in `./authoring-loop.ts`; the wake floors + frontier shapes in // `./wake-frontier.ts`; extracted from this driver in kestrel-z473.1.) // ───────────────────────────────────────────────────────────────────────────── /** * SCHEDULE-TIME View value/budget validation (kestrel-wa0j.19 §1b): the checks that are KNOWABLE when a * `scheduleWake` is accepted — BEFORE the View ever reaches an (otherwise unguarded) delivery render. * Returns a refusal reason when the resolved View carries a defect the constant session context can prove * NOW, else `null`. Two checks, both mirroring the exact guards `materializePanes` applies at delivery so * the two can never drift: * • **window-arg value** — the served tape bucket is a session constant ({@link SERVED_TAPE_BUCKET_MIN}), * so a `tape ` that is sub-resolution or a non-multiple of it is refusable now via the SHARED * {@link windowServableBy} predicate (the same one the arged tape builder enforces at materialization). * • **budget sanity** — if the View declares a token budget already below the SUM of its selected panes' * catalog `tokenCostEstimate`s, it can never fit; refuse now. (The exact per-tokenizer measurement at * materialization stays the precise guard — the delivery seam §1a is the fail-closed backstop for a * View that fits the estimate yet overruns the real count.) * PURE. Distinct from the STRUCTURAL/date-leak refusals (unknown pane / reserved id / calendar leak), which * stay whole-wake refusals: a structurally-broken or unsafe View is nonsense to honor, whereas a sound View * that this session's resolution simply cannot serve drops to the default panes while the wake still fires. */ export function scheduleTimeViewDefect(sel: ViewSelection): string | null { for (const p of sel.panes) { for (const a of p.args ?? []) { if (a.kind === "arg-window" && p.name === "tape" && !windowServableBy(SERVED_TAPE_BUCKET_MIN, a.window)) { return ( `pane "tape" window "${a.window.value}${a.window.unit}" is not servable — the tape rows are served ` + `at ${SERVED_TAPE_BUCKET_MIN}m, so a renderable window must be a positive multiple of ${SERVED_TAPE_BUCKET_MIN}m` ); } } } if (sel.budget !== undefined) { let est = 0; for (const p of sel.panes) { const entry = paneById(p.name); if (entry !== undefined) est += entry.tokenCostEstimate; } if (est > sel.budget) { return `View "${sel.name}" is over its own token budget: the selected panes' estimated cost (~${est} tokens) exceeds the declared budget of ${sel.budget}`; } } return null; } /** `HH:MM` ET clock for a ts (dateless — a clock pins no calendar date). */ function clockOf(ts: number): string { const m = ((etMinuteOfDay(ts) % 1440) + 1440) % 1440; return `${String(Math.floor(m / 60)).padStart(2, "0")}:${String(m % 60).padStart(2, "0")}`; } const FRAME_PHASES = new Set(["pre", "open", "regular", "close", "post"]); /** Map the snapshot's phase string to a {@link FramePhase}, or `null` when unresolved (never a guess). */ function mapPhase(phase: string): FramePhase | null { return FRAME_PHASES.has(phase) ? (phase as FramePhase) : null; } // ───────────────────────────────────────────────────────────────────────────── // AuthorFrame → frame/types mappers (the acting Frame is assembled from the SAME date-blind projection // the stepped day emits — relative time + relative dte only, so no channel can re-leak the calendar) // ───────────────────────────────────────────────────────────────────────────── // ───────────────────────────────────────────────────────────────────────────── // Options-analytics overlay fold (kestrel-4gl.13.13) — the perception arm's live `market.options` // // The driver (the impure orchestrator) folds the OPRA overlay tape causally to each frame cutoff and // hands the pure frame builders the finished, date-blind {@link OptionsAnalytics}. Kept OUT of the // pure `projectWakeFrame`/`briefingInputOf` seams (they receive the built projection, never the tape), // so those stay pure functions of their inputs. // ───────────────────────────────────────────────────────────────────────────── /** Stream `events` up to and including `tsMax` — the causal T-5m cutoff (no look-ahead). A lazy * generator over a lazy source reads only the prefix (the fold stops at the first later event). */ function* untilTs(events: Iterable, tsMax: number): Generator { for (const e of events) { if (e.ts > tsMax) return; yield e; } } /** The plan-lifecycle HALF of the {@link Kernel} superset (positions / resting / fills / budget / * plan states), scraped from the date-blind snapshot. The WAKE frame layers the enriched 4gl.3 * cockpit lead block on top of this base ({@link enrichedKernelOf}); the OPEN briefing carries the * base alone (the enriched cockpit at OPEN is out of scope for this slice — m9i.11 briefing). */ /** The cell-sourced STANDING context (ADR-0026) layered onto every frame's kernel: the hard * {@link Mandate} (the only admission input) + the soft, directional {@link Brief}. Sourced from * the SESSION/CELL ({@link RunSimulateOptions}), NOT hardcoded — different cells declare different * objectives. Frame content sits ABOVE the determinism line, so this never perturbs the graded bus. */ export interface KernelStanding { readonly mandate?: Mandate; readonly brief?: Brief; } /** Roll same-(instrument, strike, right) fill legs into ONE net position line (kestrel-dd8): the fill * engine SETTLES these netted, so the pane must too — a GROSS per-leg render shows huge OFFSETTING marks * that misread as a phantom winner (`+$18,000` on a net-zero book) or invite a churn to "flatten" an * already-flat book. Net qty is the signed sum (a net-0 pair renders a single clearly-flat `0 …` line — * already flat, nothing to churn); the blended basis is the ABS-qty-weighted average of the leg bases * (always well-defined, even for a net-zero pair); the net `unrealUsd` is the SUM of the per-leg unreal * (which nets to the TRUE figure). If ANY grouped leg's mark is UNKNOWN (`null`) the net is `null` * (fail-closed — never sum a fabricated 0 into a real figure); if EVERY leg omits it the net omits it. * Grouping preserves each group's FIRST-APPEARANCE order (deterministic given the deterministic fills), * so a book with NO same-(strike,right) duplicates is BYTE-IDENTICAL to the un-netted projection. Pure. */ function netPositionLegs(legs: readonly Position[]): Position[] { const groups = new Map(); for (const p of legs) { const key = `${p.instrument}${p.strike}${p.right}`; const grp = groups.get(key); if (grp === undefined) groups.set(key, [p]); else grp.push(p); } const out: Position[] = []; for (const grp of groups.values()) { if (grp.length === 1) { out.push(grp[0]!); // the common case — passed through untouched (byte-identical) continue; } const first = grp[0]!; const qty = grp.reduce((n, p) => n + p.qty, 0); const absQty = grp.reduce((n, p) => n + Math.abs(p.qty), 0); const basis = absQty > 0 ? grp.reduce((s, p) => s + Math.abs(p.qty) * p.basis, 0) / absQty : first.basis; const anyUnknown = grp.some((p) => p.unrealUsd === null); const allAbsent = grp.every((p) => p.unrealUsd === undefined); const unrealUsd: number | null | undefined = allAbsent ? undefined : anyUnknown ? null : grp.reduce((s, p) => s + (p.unrealUsd ?? 0), 0); // Provenance survives only when every leg agrees; a mixed group has no single opener (drop it). const plan = grp.every((p) => p.plan === first.plan) ? first.plan : undefined; out.push({ instrument: first.instrument, // ADR-0017: an equity/spot leg carries NEITHER strike NOR right — preserve their absence through the // netting (a spot group nets under the `NVDA undefined undefined` key), so the frame renders it as // ` shares`, never a phantom strike. An option group carries both (byte-identical). ...(first.strike !== undefined ? { strike: first.strike } : {}), ...(first.right !== undefined ? { right: first.right } : {}), qty, basis, ...(plan !== undefined ? { plan } : {}), ...(unrealUsd !== undefined ? { unrealUsd } : {}), }); } return out; } export function kernelOf( af: AuthorFrame, instrument: string, standing: KernelStanding = {}, // kestrel-c11: the exec contract multiplier (equity/spot 1, option 100) — the SAME scaling the fill // engine's `pnl` applies (src/engine/orgfacts.ts), threaded so the surfaced P&L is in DOLLARS, never // per-contract points. Defaults to 1 (equity/spot); the OPEN briefing carries no fills so it is moot. multiplier: number = 1, ): Kernel { const spot = af.spot; const markKnown = spot !== null && Number.isFinite(spot); // Per-fill legs (kestrel-c11 running $ P&L each), then NETTED per (instrument, strike, right) so the // pane matches the engine's netted settle (kestrel-dd8) — a gross render misreads offsetting marks. const legs: Position[] = af.fills.map((f) => { const qty = f.side === "buy" ? f.qty : -f.qty; // kestrel-c11 — the position's running unrealized P&L in DOLLARS: `qty × (mark − basis) × multiplier`, // marked to spot (equity/spot, ADR-0017) or intrinsic (option), with the SAME dollar scaling the fill // engine's `pnl` uses. So the agent READS `unreal=-$25.97` instead of deriving it and mis-scaling // cents-for-dollars (the 100× abandon bug). `null` when the mark is UNKNOWN (no spot) — fail-closed to // `—`, never a fabricated 0. An option leg carries a finite strike + a real C/P right; equity does not. const isOption = Number.isFinite(f.strike) && (f.right === "C" || f.right === "P"); const mark = !markKnown ? null : isOption ? intrinsic(spot as number, f.strike, f.right as Right) : (spot as number); // single exec instrument per session (ADR-0017); a mixed-multiplier book would need a per-instrument multiplierOf like orgfacts. const unrealUsd = mark === null ? null : qty * (mark - f.px) * multiplier; return { instrument, strike: f.strike, right: f.right as FrameRight, qty, basis: f.px, plan: f.plan, unrealUsd, }; }); // kestrel-dd8: net same-(instrument, strike, right) legs into ONE line so the pane matches the engine's // netted settle — a book with no duplicates is byte-identical to the un-netted per-fill projection. const positions: Position[] = netPositionLegs(legs); const resting: RestingOrder[] = af.resting.map((r) => ({ // The AUTHORITATIVE Gate ref the fill engine rests this order under (kestrel-5zl.5): a `cancelOrder` // carrying this ref resolves to the real resting order through the SAME Gate a fired Plan cancels // through. (It was a synthetic `plan:role:strikeRight` handle that no Gate ref ever matched, so // cancel-by-ref silently no-op'd.) The kernel PRINTS it (`ref=o1`) — the ref is what a cancel names. ref: r.ref, side: r.side as "buy" | "sell", instrument, strike: r.strike, right: r.right as FrameRight, qty: r.qty, px: r.px, plan: r.plan, })); const plans: PlanStateEntry[] = af.plans.map((p) => ({ name: p.name, state: p.state as PlanStateEntry["state"], // kestrel-50w: carry the arm-time gate-block reason into the acting Frame so a plan stuck `authored` // on an unsatisfiable regime gate renders `authored (blocked: )`, never a bare (live-looking) // `authored`. Frame content, above the determinism line — the graded bus is untouched. ...(p.blockedReason !== undefined ? { blockedReason: p.blockedReason } : {}), })); return { // Cell-sourced standing context (ADR-0026) — present only when the cell declared it (absent ⇒ // the frame renders unchanged, byte-identical to pre-mandate). Never a fabricated default. ...(standing.mandate !== undefined ? { mandate: standing.mandate } : {}), ...(standing.brief !== undefined ? { brief: standing.brief } : {}), positions, resting, // Per-vantage fill deltas are a later refinement; the authoritative fill record is the graded Bus. fillsSinceLast: [] as FillRecord[], budget: { used: af.committedUsd, remaining: af.rUsd - af.committedUsd, total: af.rUsd }, plans, }; } /** The OPEN briefing input, mapped from the date-blind briefing {@link AuthorFrame}. */ function briefingInputOf( af: AuthorFrame, meta: MetaEvent, instrument: string, firstTs: number, lastTs: number, standing: KernelStanding = {}, options?: OptionsAnalytics, // kestrel-121: the chain-fair context evaluated at the OPEN author cutoff. Absent ⇒ the briefing // chain `fair` stays `—` (byte-identical to a pre-fair briefing). fairCtx?: ChainFairContext, // kestrel-wa0j.20: the injected prior-session tapes, threaded onto the OPEN briefing so `tape d-N` // serves ordinal N's block. Absent ⇒ no `priorSessions` field (byte-identical, Train 1B absence). priorSessions?: readonly PriorSessionTape[], ): BriefingInput { const instruments: FrameInstrumentSpec[] = meta.instruments.map((si) => ({ symbol: si.symbol, assetClass: si.assetClass, ...(si.role !== undefined ? { role: si.role } : {}), })); // The PRESENTED current-time is the frame's OWN vantage, reconstructed from its relative `sinceOpenMs` // (projected against this same `firstTs` origin) — NOT a re-assumption that the author acts at the // open. For the default (pre-open) briefing `sinceOpenMs === 0`, so `vantageTs === firstTs` and both // fields are byte-identical to before. For an intraday `authorFromRange` briefing the vantage is the // acting cutoff (kestrel far-cutoff clock), so the clock reads the cutoff and time-to-close shrinks // accordingly — the honest "it's 13:45, ~2h15m to close" a live FOMC author must reason over. const vantageTs = firstTs + af.sinceOpenMs; return { timeToCloseMin: Math.round((lastTs - vantageTs) / 60_000), phase: mapPhase(af.phase), clockET: clockOf(vantageTs), instruments, market: marketPaneOf(af, instrument, options, fairCtx), kernel: kernelOf(af, instrument, standing), ...(priorSessions !== undefined ? { priorSessions } : {}), }; } // ───────────────────────────────────────────────────────────────────────────── // The agent-driven wake frontier (kestrel-5zl.4) — constants + shape // // After the T-5 OPEN baseline (m9i.11) the AGENT drives its own monitoring cadence via `scheduleWake`; // the platform FLOORS it (never replaces it) with a staleness backstop + the optional structural close // cadence, and coalesces/downgrades past the attention budget. These are author-tunable config knobs, // NOT removable by the agent — safety can never be silenced (CLAUDE fail-closed). The budget algebra // proper and per-session structural re-anchoring are scoped to the b3l Wake-router epic. // ───────────────────────────────────────────────────────────────────────────── /** Total, deterministic frontier tiebreak when two wakes share a ts: the agent first, then the author * seed, then an own-fill management wake, then the structural cadence, then the staleness backstop (safety * sorts last, never masking an earlier authored intent). Same bus + same agent turns ⇒ identical frontier * order ⇒ identical Blotter. The `own-fill` wake exists only on a seeded (sampled-channel) run — a * fire-then-inform management prompt raised when the agent's order fills, ADR-0016 / kestrel-9gu.8.3. * `latency-fold` (ADR-0040 / clock-honest wakes §2.3) is a determinism-bearing tie-break PIN: no tie is * currently reachable — a frontier wake at exactly `returnTs` folds INTO the catch-up rather than sorting * beside it — but the rank is pinned anyway so the sort stays total (RUNTIME §0). */ const WAKE_SOURCE_RANK: Record = { agent: 0, seed: 1, "own-fill": 2, structural: 3, staleness: 4, "latency-fold": 5 }; // ───────────────────────────────────────────────────────────────────────────── // The SeqWindow + engine-actions-since-last-wake (kestrel-5zl.11 — the 4gl.3 cockpit engine log) // // The frame's L0/L1 engine log is the ACTIONS-SINCE-THE-LAST-WAKE, not the whole session: the // `[prevWakeSeq, thisWakeSeq)` slice of the graded Bus in **seq space** (every event carries a // monotonic `seq`, the determinism key — bus/types.ts EnvelopeBase). `prevWakeSeq`/`thisWakeSeq` // are the two adjacent WAKE-checkpoint seqs the driver stamps at each vantage. Reading only events // with `seq < thisWakeSeq` is frozen-at-wake by construction (no look-ahead), and an `asofSeq` is an // ORDINAL (date-blind), so the window is deterministic and replay-stable. // ───────────────────────────────────────────────────────────────────────────── /** The `[prevWakeSeq, thisWakeSeq)` bus-seq window the engine-actions-since-last-wake ride. Both are * WAKE-checkpoint `seq`s (an ordinal, never a wall-clock/date); the half-open window is the gap * between the previous vantage and this one. */ export interface SeqWindow { readonly prevWakeSeq: number; readonly thisWakeSeq: number; } /** The pure inputs {@link projectWakeFrame} consumes beyond the graded bus + the seq window: the * date-blind vantage projection (market pane + plan-lifecycle base), the exec instrument, the * per-vehicle books for the cockpit data-health, and the wake ctx (ordinal / reason / deadlines / * attention). Everything here is a pure derivation of the injected bus (no wall clock, no RNG). */ export interface WakeFrameConfig { readonly af: AuthorFrame; readonly instrument: string; /** The exec instrument's contract multiplier (kestrel-m9i.32) — `1` for equity/spot, `100` for a * listed option. Drives the cost-basis sizing headroom (equity basis = spot × mult; option basis = * premium × mult, ADR-0017). Absent ⇒ treated as `1` (equity/spot). */ readonly execMultiplier?: number; readonly vehicles: readonly VehicleBook[]; readonly ctx: WakeCtx; /** The cell-sourced standing context (ADR-0026 mandate + brief) layered onto the wake kernel. */ readonly standing?: KernelStanding; /** The options-analytics projection for THIS wake's cutoff (kestrel-4gl.13.13) — already folded * causally + date-blind by the driver ({@link buildFrameOptions}). Present only for the perception * arm; absent leaves `market.options` undefined (the minimal arm, byte-identical). */ readonly options?: OptionsAnalytics; /** The injected time-to-expiry resolver (`fairTauYears`) the chain's `fair` column is priced through * (kestrel-121) — the SAME source the fill engine prices `@fair` with, evaluated at THIS wake's cutoff * (`ctx.wakeTs`). Absent ⇒ the chain `fair` stays `—` (byte-identical to a pre-fair frame). */ readonly fairTauYears?: FairTauProvider; /** kestrel-wcnd: the exec chain's OWN expiry token at this wake (from the RAW snapshot — the * date-blind `af` cannot carry it). Feeds `fairTauYears`'s 2nd argument ONLY; never rendered. */ readonly fairExpiry?: string; /** The prior author vantage's SERVED values (kestrel-wa0j.48) — the typed snapshot the driver served * at the PREVIOUS vantage, so the `delta` pane can state what MOVED under stateless-redraw. Present * only on a wake AFTER the first (the driver captures it from the prior frame's served levels/book); * absent ⇒ the frame carries no `priorVantage` (byte-identical, and the delta pane fails closed). */ readonly priorVantage?: PriorVantage; /** The PRIOR sessions' tapes (kestrel-wa0j.20) — the injected multiday tape (`opts.priorSessions`), * threaded so `tape d-N` serves ordinal N's rows as its own block. Absent in the v1 single-day sim ⇒ * the frame carries no `priorSessions` (byte-identical, and `tape d-N` renders the Train 1B absence). */ readonly priorSessions?: readonly PriorSessionTape[]; /** Every armed plan STATEMENT the driver holds, in arm order (kestrel-wa0j.29) — the typed ASTs the * `armed-plan` pane's terms are captured from. The seam filters these to the plans in an ENFORCED * lifecycle state (per this wake's kernel plan set) and prints each clause through the canonical * printer. Absent (or no enforced plan) ⇒ the frame carries no `armedPlan` and the pane fails closed * to absent-with-reason, byte-identical to a frame without the field. */ readonly armedPlanAsts?: readonly PlanStatement[]; /** The tape's `session_date` (kestrel-wa0j.74) — the reference an ABSOLUTE per-leg `exp 2026-08-21` * is date-blinded to a relative `dte` against when the `armed-plan` pane captures the plan's terms. * Required so an authored iso-date tenor cannot leak into the acting Frame and trip {@link * assertFrameDateBlind}; unused when no plan carries an absolute per-leg expiry (byte-identical). */ readonly sessionDate: string; } /** Map ONE graded-bus event to its {@link EngineAction} bucket, or `null` when it is not an L0/L1 * engine action (RUNTIME §5–6): an `ORDER place` FIRED, an `ORDER cancel` (reason `cancelled`) * CANCELLED, an `ORDER reject` REJECTED, a `TELEMETRY guard` whose directional cap was `applied` * CLAMPED. An `ORDER fill` and an esc-reprice cancel (a non-`cancelled` reason) are not engine * actions on this SAFETY/CONTROL surface. `id` is the order ref; `asofSeq` is the event's ordinal. */ /** Refusal-reason markers (engine-authored constant strings) that promote a PLAN lifecycle record to a * `rejected` engine action so the acting agent sees WHY an order was refused (kestrel-7kt). A normal * lifecycle reason (`fired`, `superseded`, `ttl`, `invalidate`, `cancel-if`, `transferred`) is NOT a * refusal and stays out of the engine log. * * The list must cover EVERY reason `PlanEngine.#emitReject` authors (src/engine/plans.ts — the sole * producer of a PLAN refusal notice; a plain `#transition` reason is open-vocabulary lifecycle, which is * why this seam matches rather than inverts). Matching is the only discriminator the bus schema affords: * a reject notice and a transition are the same `PLAN lifecycle` shape, so an unlisted refusal is dropped * SILENTLY at the agent's only feedback loop (kestrel-x4j8). Adding an `#emitReject` reason means adding * its marker here — tests/simulate.engine-log-refusals.test.ts pins the vocabulary. */ const REFUSAL_MARKERS: readonly string[] = [ "never naked", "uncovered sell", "unfillable", "unresolvable", "exceeds plan budget", // kestrel-x4j8 — the fire-time refusals the 7kt list missed, each silently invisible until now: // the fail-closed far-OTM cap on unresolved moneyness (plans.ts, kestrel-9gu.6 — its call site asks // for it to be surfaced LOUDLY; `unresolvable` above never matched the engine's `unresolved`), the // budget-exhausted peg that can no longer chase, and the reprice dropped onto an already-filled intent. "unresolved", "fill-guard", "peg capped", "reprice dropped", // kestrel-ocyf — the arm-time regime activation-gate notices (`armDocument`): the definitive // dead-on-arrival verdict on a pre-scanned regime-less tape, and the conditional not-yet-written // block when the future is unknown. Both are #emitReject-authored and must reach the wake frame's // engine log, or the acting agent re-learns the phantom-position trap one wake late. "never written", "not yet written", ]; function isRefusalReason(reason: string | undefined): boolean { return reason !== undefined && REFUSAL_MARKERS.some((m) => reason.includes(m)); } function engineActionOf(e: BusEvent): EngineAction | null { if (e.stream === "ORDER") { switch (e.type) { case "place": return { id: e.order_id, kind: "fired", asofSeq: e.seq }; case "cancel": return e.reason === "cancelled" ? { id: e.order_id, kind: "cancelled", asofSeq: e.seq } : null; case "reject": return { id: e.order_id, kind: "rejected", asofSeq: e.seq, ...(e.reason !== undefined ? { reason: e.reason } : {}) }; default: return null; // fill — not an engine action bucket } } if (e.stream === "TELEMETRY" && e.type === "guard" && e.directional_cap === "applied") { return { id: e.order_id, kind: "clamped", asofSeq: e.seq }; } // A never-naked SELL refusal (or a synthesized-order de-arm) is a PLAN lifecycle record, not an ORDER // reject — no order was ever submitted. Surface the REFUSAL ones (only) as a `rejected` engine action // carrying the reason, so the agent can see why its order never rested (kestrel-7kt). if (e.stream === "PLAN" && e.type === "lifecycle" && isRefusalReason(e.reason)) { return { id: e.plan, kind: "rejected", asofSeq: e.seq, reason: e.reason! }; } // An agent order-action refuse (cancelOrder no-such-ref, scheduleWake unresolvable/past/beyond) is a // CONTROL record — surface it too, so a refused agent action is never invisible to the agent. if (e.stream === "CONTROL" && e.type === "refuse") { const note = e.note ?? "refused"; return { id: note.split(":")[0]!.trim(), kind: "rejected", asofSeq: e.seq, reason: note }; } return null; } /** The FILLS-SINCE-LAST-WAKE: the `[prevWakeSeq, thisWakeSeq)` slice of the graded stream's ORDER * `fill` events, mapped to {@link FillRecord}. Frozen-at-wake (only `seq < thisWakeSeq`) and scoped to * the gap (not cumulative-since-open), so an order that filled between vantages reaches the acting agent * (kestrel-fud — this was hard-coded `[]`). Pure + deterministic, a projection of the graded bus. */ function fillsInWindow(emitted: readonly BusEvent[], window: SeqWindow): FillRecord[] { const out: FillRecord[] = []; for (const e of emitted) { if (e.seq < window.prevWakeSeq || e.seq >= window.thisWakeSeq) continue; // outside [prev, this) if (e.stream !== "ORDER" || e.type !== "fill") continue; out.push({ side: e.side, instrument: e.instrument, // ADR-0017 (kestrel-1kp): an equity/spot fill carries NEITHER strike NOR right — PRESERVE their // absence, never substitute a phantom `0`/`"C"` zero-strike CALL. A concrete `0`/`"C"` defeats // {@link isSpotLeg} (which keys on presence), so the since-last fill line MISRENDERED the share leg // as `0C` instead of ` shares` (the same phantom-chrome class kestrel-orx fixed on the // kernel/positions surfaces). An OPTION fill carries BOTH — byte-identical to before. ...(e.strike !== undefined ? { strike: e.strike } : {}), ...(e.right !== undefined ? { right: e.right as FrameRight } : {}), qty: e.qty, px: e.px ?? 0, clock: clockOf(e.ts), ...(e.plan !== undefined ? { plan: e.plan } : {}), }); } return out; } /** The engine-actions-since-the-last-wake: the `[prevWakeSeq, thisWakeSeq)` slice of the graded * `emitted` stream, bucketed by {@link engineActionOf}. Frozen-at-wake (only events with * `seq < thisWakeSeq`) and scoped to the gap (not cumulative-since-open). Pure + deterministic. */ function engineActionsInWindow(emitted: readonly BusEvent[], window: SeqWindow): EngineAction[] { const out: EngineAction[] = []; for (const e of emitted) { if (e.seq < window.prevWakeSeq || e.seq >= window.thisWakeSeq) continue; // outside [prev, this) const a = engineActionOf(e); if (a !== null) out.push(a); } return out; } /** Layer the enriched 4gl.3 cockpit lead block onto the plan-lifecycle base {@link Kernel}: the wake * ref (RELATIVE `T-Nm` deadline), per-vehicle data-health, the (empty) unavailable set, the cockpit * budget envelope, owner acts, the engine-actions-since-last-wake, and predictor/regime claims. Every * section is always present (absent renders as an explicit `none`/`UNKNOWN`, never dropped). This is * the REAL kernel {@link renderKernel} consumes — not a partial stub. Pure + deterministic. */ function enrichedKernelOf( base: Kernel, dataHealth: readonly VehicleHealth[], engineLog: readonly EngineAction[], ctx: WakeCtx, sizing?: SizingHeadroom | null, ): Kernel { const minutesToClose = Math.round((ctx.lastTs - ctx.wakeTs) / 60_000); const wake: WakeRef = { reason: ctx.wakeReason, severity: "routine", deadline: Number.isFinite(minutesToClose) ? minutesToClose : null, }; return { ...base, // The extended cockpit lead block (4gl.3) — always present (absent-not-hidden). wake, dataHealth, // kestrel-wa0j.47: the v1 harness serves no macro/calendar capability, and the kernel's // unavailable-capabilities line is now that absence's ONE rendering (the `macro` pane left the // default OPEN set) — an empty list here would hide the absence entirely (absent-not-hidden). unavailable: ["macro calendar"], budgetEnvelope: budgetEnvelopeOf(base.budget, sizing), ownerActs: [], engineLog, claims: [], }; } /** * **The pure WAKE-frame builder** (kestrel-5zl.11): `(graded bus, seq window, config) → ActingFrame`. * Assembles the date-blind {@link ActingFrame} handed to the agent at one wake, whose `kernel` is the * REAL enriched 4gl.3 cockpit lead block — positions / resting / budget / data-health / owner-acts / * the engine-actions-since-last-wake / predictor-regime claims — that {@link renderKernel} consumes, * NOT the partial stub. The engine log is the `[prevWakeSeq, thisWakeSeq)` bus-window slice * ({@link engineActionsInWindow}), so it is the since-LAST-wake delta, frozen-at-wake (only * `seq < thisWakeSeq`) with no look-ahead. * * PURE: no wall clock, no unseeded RNG — the output is a byte-identical function of its inputs, so the * same bus + same seq window + same config projects an identical frame (the determinism the tracer's * replay rides on). Frame content sits ABOVE the determinism line (recorded/fixed adapters ignore it), * so it never perturbs the graded bus. DATE-BLIND: only relative time, the `HHMM` ET clock, and * ordinals reach the frame; {@link assertFrameDateBlind} is the fail-closed backstop at the seam. */ export function projectWakeFrame( emitted: readonly BusEvent[], window: SeqWindow, config: WakeFrameConfig, ): ActingFrame { const { af, instrument, vehicles, ctx, standing, options } = config; const minutesToClose = Math.round((ctx.lastTs - ctx.wakeTs) / 60_000); const dataHealth = vehicles.map((v) => vehicleHealthOf(v, ctx.wakeTs)); const engineLog = engineActionsInWindow(emitted, window); // The fills that happened since the last vantage — a graded-bus projection over the same seq window, // so an order that filled between wakes reaches the agent (kestrel-fud; the base `kernelOf` carries the // OPEN-briefing `[]`, which is correct pre-open). const fillsSinceLast = fillsInWindow(emitted, window); const base = kernelOf(af, instrument, standing ?? {}, config.execMultiplier ?? 1); // The sizing headroom (kestrel-m9i.32): the max fillable size the remaining-R budget admits for the // exec instrument, so a model sizes WITHIN the bounded-risk cost basis (ADR-0017) rather than into a // silent fire-time clamp. PURE — derived from the plan-lifecycle budget (`remaining $`) + the frame's // exec spot + the exec multiplier (equity 1 / option 100). An option's per-leg premium is not sourced // at this seam, so the option cue surfaces the remaining-$ ceiling + the basis rule (never a guess). const sizing = sizingHeadroomOf({ instrument, remainingUsd: base.budget?.remaining ?? null, spot: af.spot, multiplier: config.execMultiplier ?? 1, }); const kernel = { ...enrichedKernelOf(base, dataHealth, engineLog, ctx, sizing), fillsSinceLast }; // The ARMED plans' enforced terms for the `armed-plan` pane (kestrel-wa0j.29) — captured from the armed // ASTs the driver holds (`config.armedPlanAsts`), filtered to the plans this wake's kernel reports in an // ENFORCED lifecycle state (armed/fired/managing). The watcher manages plans whose document text it // never otherwise sees; the terms enter the frame THROUGH this typed input (the renderer invents none). // Absent config, or no enforced plan ⇒ `undefined` (absent-not-hidden: the field is unserialized and the // pane fails closed to absent-with-reason, byte-identical to a frame without it). const enforcedPlanNames = new Set(base.plans.filter((p) => ENFORCED_PLAN_STATES.has(p.state)).map((p) => p.name)); const armedPlan = config.armedPlanAsts !== undefined ? armedPlanTermsOf(config.armedPlanAsts, enforcedPlanNames, config.sessionDate) : undefined; return { // WakeDeltaInput wakeIndex: af.n, minutesSinceLast: Math.round((ctx.wakeTs - ctx.prevVantageTs) / 60_000), timeToCloseMin: minutesToClose, phase: mapPhase(af.phase), clockET: clockOf(ctx.wakeTs), wakeReason: ctx.wakeReason, // kestrel-121: price the chain `fair` column through the injected `fairTauYears` at this wake's cutoff // (`ctx.wakeTs`) — the SAME source the fill engine prices `@fair` with. Absent ⇒ `fair` stays `—`. market: marketPaneOf( af, instrument, options, config.fairTauYears !== undefined ? { tauYears: config.fairTauYears, nowTs: ctx.wakeTs, ...(config.fairExpiry !== undefined ? { expiry: config.fairExpiry } : {}) } : undefined, ), kernel, // The prior author vantage's served values (kestrel-wa0j.48) — threaded from the driver so the // `delta` pane states what MOVED under stateless-redraw (the renderer invents no value; the prior // data must enter through the frame input). Present only on a wake AFTER the first; absent ⇒ the // field is unserialized and the frame is byte-identical to today (the delta pane fails closed). ...(config.priorVantage !== undefined ? { priorVantage: config.priorVantage } : {}), // The prior sessions' tapes (kestrel-wa0j.20) — threaded from the driver so `tape d-N` serves // ordinal N's rows as its own single-session block. Present only when the run injects a multiday // tape; absent ⇒ the field is unserialized and the frame is byte-identical (Train 1B absence). ...(config.priorSessions !== undefined ? { priorSessions: config.priorSessions } : {}), // The armed plans' enforced terms (kestrel-wa0j.29) — threaded so the `armed-plan` pane renders the // WHEN/entries/exits/invalidation/size the watcher enforces. Present only on a wake with at least one // plan in an enforced state; absent ⇒ the field is unserialized and the frame is byte-identical. ...(armedPlan !== undefined ? { armedPlan } : {}), // acting-kernel strip wakeOrdinal: ctx.wakeOrdinal, // The stable replay identity (kestrel-5zl.19) — the source that raised this wake + its monotone // per-source ordinal, the two halves `wakeKeyOf` joins the captured turns on. wakeSource: ctx.wakeSource, wakeSourceOrdinal: ctx.wakeSourceOrdinal, // The relative-day coordinate (kestrel-5zl.16.4) — present ONLY for a multi-session run (it rides the // date-blind author projection), absent + unserialized for a standalone session (goldens unchanged). ...(af.sessionOrdinal !== undefined ? { sessionOrdinal: af.sessionOrdinal } : {}), severity: "routine", deadline: { minutesToClose, minutesToNextWake: ctx.nextWakeTs === null ? null : Math.round((ctx.nextWakeTs - ctx.wakeTs) / 60_000), }, dataHealth: { asOfClockET: clockOf(ctx.wakeTs), stale: [], unavailable: [] }, // The scheduled wake's stored View rides the delivery (kestrel-wa0j.4) — the adapter renders THIS // wake's panes under it; absent ⇒ the field is unserialized and the frame is byte-identical to today. ...(ctx.view !== undefined ? { view: ctx.view } : {}), attention: { wakesRemaining: ctx.wakesRemaining, coalesced: ctx.coalesced }, }; } /** Fail-closed date-blind fence over the assembled acting Frame (the agent boundary): serialize with the * SAME 1e-6 rounding the machine summary uses (so a raw float tail can't trip the epoch grep as a false * calendar signal), then run the SHARED {@link scanDateLeak}. A leak is REFUSED, never delivered. */ function assertFrameDateBlind(frame: ActingFrame): void { const body = JSON.stringify(frame, (_k, v) => typeof v === "number" && Number.isFinite(v) ? Math.round(v * 1e6) / 1e6 : v, ); const hit = scanDateLeak(body); if (hit !== null) { throw new Error( `simulate: acting Frame leaks a ${hit.name} (${JSON.stringify(hit.match)}) at the agent boundary ` + "(fail-closed, EVALUATION contamination fence)", ); } } // ───────────────────────────────────────────────────────────────────────────── // runSimulateSession // ───────────────────────────────────────────────────────────────────────────── /** * Drive one frozen-at-wake Simulate session through the {@link Agent} seam and return its graded * {@link Blotter} + the {@link CapturedTurns} it consumed. Reuses the SAME {@link SessionCore} the stepped * day drives (bus-stepping, Gate, `projectAuthorFrame`); the ONE behavioral change is that the wake set is * answered by `agent.decide` rather than a file handshake. `async` because the live loop is deliberately * non-deterministic; the recorded/fixed adapters resolve synchronously. */ export async function runSimulateSession(opts: RunSimulateOptions): Promise { if (opts.busPath === undefined && opts.events === undefined) { throw new Error("simulate: runSimulateSession needs either `busPath` or `events`"); } const events: BusEvent[] = opts.events !== undefined ? [...opts.events] : [...readBus(opts.busPath!)]; const meta = requireMeta(events); const specs = resolveSpecs(meta, opts.instruments); const fairTauYears = opts.fairTauYears ?? expiryTauYears(meta.session_date); const firstTs = events[0]?.ts ?? 0; const lastTs = events[events.length - 1]?.ts ?? firstTs; const sessionDate = meta.session_date; // ── Clock-honest session semantics (ADR-0040 / kestrel-w7la.1, clock-honest wakes §§2, 4, 7) ───── // The switch is the agent config's `clockHonest` (a ConfigId axis — a clocked run never shares a grid // column with an unclocked one). EVERY precondition refuses LOUDLY at open — never a silent default, // never a silent downgrade to latency-blind (§4). const clockHonest = opts.agent.config.clockHonest === true; if (clockHonest) { const buf = opts.agent.config.latencyBufferMs; if (typeof buf !== "number" || !Number.isInteger(buf) || buf < 0) { throw new Error( `simulate: clock-honest run refused at open — \`latencyBufferMs\` must be a non-negative integer (got ${JSON.stringify(buf)}); there is NO default (never a silent default — a designed default would be a judge-designed weighting, ADR-0030 spirit). \`0\` is legal: it declares a colocated seat.`, ); } // Eligibility: the ADR-0040 data floor, declared with the tape and verified fail-closed (§4). const ineligible = clockHonestIneligibility(opts.dataRung); if (ineligible !== null) { throw new Error(`simulate: clock-honest run refused at open — ${ineligible}`); } // A costless (pre-v6 / latency-blind) capture replays ONLY under latency-blind semantics (§7): // replaying it clocked would silently change what the run claims to be. Probed at the OPEN key — // the one entry every driver-captured recording holds. if (opts.agent.recordedCostMs !== undefined && opts.agent.recordedCostMs(OPEN_WAKE_KEY) === undefined) { throw new Error( "simulate: clock-honest run refused at open — the recorded capture is COSTLESS (it carries turns but no measured deliberation costs); a costless capture replays only latency-blind (ADR-0040 §7, never a silent downgrade)", ); } } /** The configured latency buffer, applied to every Seat-answered vantage (0 when latency-blind — * never read on that path). */ const bufferMs = clockHonest ? (opts.agent.config.latencyBufferMs as number) : 0; /** The injectable wall clock — consulted ONLY on the live clocked path (§7's one minting seam). */ const nowFn = opts.now ?? Date.now; /** * Measure — or, in replay, READ — one Seat turn's deliberation cost (§7: mint once, live-side, at * THIS seam; the only minting site). Replay mode (an agent exposing `recordedCostMs`) never touches * the clock — a replay path that re-times is a defect by definition (the poisoned-clock fixture). */ const clockedTurn = async ( key: WakeKey, call: () => Promise | AgentTurn, ): Promise<{ turn: AgentTurn; measuredMs: number; seatAnswered: boolean }> => { const costSource = opts.agent.recordedCostMs?.bind(opts.agent); if (costSource !== undefined) { const turn = assertHandlerResponseTimeless(await call()); const c = costSource(key); // `null` = the capture never held this key — the replay machinery SYNTHESIZED the turn // (divergence stand-down / inserted-vantage pass). Engine-minted, not Seat deliberation: // cost 0, no buffer, no record (§7 — charging tape for a turn no Seat took fabricates cost). if (c === null) return { turn, measuredMs: 0, seatAnswered: false }; if (c === undefined || !Number.isInteger(c) || c < 0) { throw new Error( `simulate: clock-honest replay hit a costless/malformed capture entry at wake ${key} — a costless capture replays only latency-blind (fail-closed, ADR-0040 §7)`, ); } return { turn, measuredMs: c, seatAnswered: true }; } const t0 = nowFn(); const turn = assertHandlerResponseTimeless(await call()); const t1 = nowFn(); return { turn, measuredMs: Math.max(0, Math.round(t1 - t0)), seatAnswered: true }; }; // Capture the a57.14 experimental envelope from the agent's config (kestrel-5zl.6) and stamp it on the // graded META at open — the CAPTURE side of a57.14. Only an authoring config declares one; a NO-LLM // Backtest (fixedPlan/recorded with BACKTEST_CONFIG) declares none ⇒ no stamp ⇒ the Blotter stays // certified (fail-closed by omission — never a fabricated identity). A declared-but-incomplete identity // is stamped so the projector fails the Blotter closed to PROVISIONAL (a57.14). The FULL ConfigId // rides alongside under the SAME condition (m9i.2 owner tweak): the grid CellKey keys on it, so // temperature-only config variants land in DISTINCT cells. const envelope = envelopeForConfig(opts.agent.config); const configId = envelope !== undefined ? deriveConfigId(canonicalizeConfig(opts.agent.config)) : undefined; // The cell config axis (fillSeed stripped — ADR-0016 §3): stamped ONLY when it DIVERGES from configId (the // config carried a fillSeed) — a seedless run's cell axis equals configId, so no stamp and the graded bus // stays byte-identical. Seed-only variants pool as replicates in ONE cell; configId keeps the seeded RUN id. const cellConfigId = envelope !== undefined ? cellConfigIdOf(opts.agent.config) : undefined; const cellConfigStamp = cellConfigId !== undefined && cellConfigId !== configId ? cellConfigId : undefined; // Arm the seeded sampled fill channel when the agent's config declares a fillSeed (kestrel-9gu.8.3, // ADR-0016); a Backtest config (or any omitting the seed) leaves the sampler OFF (fail-closed). const fillSeed = fillSeedOf(opts.agent.config); // The sampled-channel qualification claim (kestrel-9gu.12), read fail-closed off the config: absent — // every config until the 9gu.8.6 study passes — the headline gate resolves to the strict-cross floor. const sampledQualification = sampledQualificationOf(opts.agent.config); const openingCarry = opts.openingCarry; // The wake-frontier floor is a FUNCTION of the cell's timescale band (kestrel-5zl.16.7). Read the band // once from the opening carry (an absent carry — a standalone / flat open — is `emptyCarry().band` = // `day`, so this run is byte-identical to today), resolve the pure floor, and use its three controls // wherever the frontier gates a wake (`popNext` spacing/ceiling, `armStaleness` backstop, the own-fill // spacing). The DAY floor reproduces today's exact constants — no churn. const floor = wakeFloorForBand((openingCarry ?? emptyCarry()).band); const core = new SessionCore({ meta, specs, fillModel: opts.fillModel, rUsd: opts.rUsd, fairTauYears, firstTs, // NO `tapeRegimeScopes` pre-scan here, DELIBERATELY (kestrel-ocyf round 3): this is the // agent-interactive path (day.ts drives through it), and a whole-bus pre-scan is a LOOKAHEAD // ORACLE — a mid-session supersede→arm would receive a notice grade that is a function of // post-vantage events (definitive notice = "never written all day"; silence = "a REGIME write is // coming"), and the REFUSAL_MARKERS seam pipes that onto the acting agent's frame, letting it // read tomorrow's regime vocabulary through throwaway supersedes. Violates this file's own // charter (no post-cutoff leak / no look-ahead) and the eval contamination firewall. Interactive // sessions take the CONDITIONAL wording — derived only from `#tags` (events ingested so far), // causally honest at any vantage, still loud at arm. The batch-replay `runSimSession` (a post-hoc // report with no author to leak to) keeps the definitive pre-scan. ...(opts.makerFairParams !== undefined ? { makerFairParams: opts.makerFairParams } : {}), ...(envelope !== undefined ? { envelope } : {}), ...(configId !== undefined ? { configId } : {}), ...(cellConfigStamp !== undefined ? { cellConfigId: cellConfigStamp } : {}), ...(openingCarry !== undefined ? { openingCarry } : {}), ...(fillSeed !== undefined ? { fillSeed } : {}), ...(sampledQualification !== undefined ? { sampledQualification } : {}), // The clock-honest attestation input (ADR-0040 §5): every §4 precondition already held above (the // run refuses at open otherwise), so a constructed clocked core is an attested one. `true` or // absent — the driver NEVER stamps `false`. ...(clockHonest ? { clockHonest: true as const } : {}), }); const instrument = core.execSpec.symbol; const instruments = meta.instruments.map((i) => i.symbol); // DAY-COMPAT MODE (kestrel-5zl.3): the caller-owns-cadence path `runDaySession` drives through. When set, // the driver reproduces the stepped runner's cadence + byte stream EXACTLY — the day's own structural wakes // are the coverage, so NO platform staleness/backstop wake is injected (Divergence #1), and the CONTROL // supersede carries the day's `{target,note}` bytes (Divergence #2). NARROW + orthogonal to `band`: a normal // band run leaves it false, so `armStaleness`/`wakeFloorForBand` (16.7) are untouched and the wake-band // fail-closed invariant holds. `dayBridge` (present only for the actual day file agent) is bound to the live // core here so the agent can validate a revision against it (collision preview) with no forked path. const dayCompat = opts.dayCompat === true; if (opts.dayBridge !== undefined) { opts.dayBridge.previewSupersede = (mod: Module) => core.engine.supersedeArmRejection(mod); } const captured = new Map(); let armed = false; // the FIRST supersede is the initial arm (no CONTROL, `day.ts` plans-0 parity) let placeSeq = 0; // ── The date-blind seam for agent-authored free text (kestrel-auw) ──────────────────────────────── // Every agent free-text field that flows into a CONTROL event is a contamination vector: a CONTROL // `refuse` note is surfaced by `engineActionOf` into the NEXT wake's engine log, so a calendar token // (a month/weekday/date) in agent text re-renders into a later date-blind acting Frame and trips // `assertFrameDateBlind` UNCAUGHT — unwinding the whole session with no partial Blotter. So screen at // THIS seam (the same refuse-and-log `scheduleWake.reason` uses), NEVER echoing the matched token — // that token IS the leak, and the refuse note itself reaches the frame — and let the session continue. // `assertFrameDateBlind` stays the last-resort backstop; this is the belt that keeps it from firing. const DATE_BLIND_PLACEHOLDER = "[withheld: date-blind fence]"; /** Pure sanitizer for an agent string EMBEDDED into a runtime-built note (e.g. a `cancelOrder` ref in a * refuse note): the original when date-blind, else a fixed placeholder — never the matched calendar token. */ const dateBlindField = (text: string): string => (scanDateLeak(text) === null ? text : DATE_BLIND_PLACEHOLDER); /** Screen an agent free-text field that becomes (or rides in) its own CONTROL note (a `standDown` reason, * a `supersede`/`placeOrder` note). Date-blind → returned unchanged (byte-identical). A leak → an auditable * CONTROL `refuse` naming the leak CLASS ONLY (never the matched token) is emitted, and the field is * replaced with a date-blind placeholder so the originating CONTROL event stays date-blind. */ const dateBlindNote = (field: string, text: string, ts: number): string => { const leak = scanDateLeak(text); if (leak === null) return text; core.emit({ ts, stream: "CONTROL", type: "refuse", note: `${field} refused: leaks a ${leak.name} (date-blind fence)` }); return DATE_BLIND_PLACEHOLDER; }; // ── The agent-decision RECEIPT producer (kestrel-a57.18) ────────────────────────────────────── // The a57.5 projector (`grade/receipts`) lifts every agent PROPOSAL / DECLINE / STAND-DOWN off the bus // — but nothing WROTE them, so `projectReceipts()` returned `[]` on every real session and the // benchmark north star (measuring RESTRAINT: the declines and stand-downs) was inert in production. // These emits are that missing producer: the driver records what the agent DECIDED at the same three // sites it already records what the engine DID, on the unchanged CONTROL stream. // // The pairing with the arm record is EXACT by construction of `core.arm`, which is all-or-nothing (a // per-statement refusal comes back as DATA and is re-thrown as a whole-document `armRefusalError`): // • the arm SUCCEEDS ⇒ one `propose` per PLAN statement, `target` = the plan name the bus will arm; // • the arm ESCAPES (parse or engine refusal) ⇒ a `stand_down` carrying the text the agent left on // the table, and NOTHING armed — so the curation verdict's arm reconciliation stays clean rather // than reading a refused proposal as a phantom arm. // That is the driver's own fail-closed ladder ("parse escape → STAND_DOWN", extended to an ARM escape, // RUNTIME §8) mirrored onto the receipt channel — the escape is RECORDED, never dropped. const receiptMeasurement = driverMeasurementVersions({ fillModel: opts.fillModel, fidelity: fidelityOf(meta.mode) }); /** Write one agent decision receipt onto the CONTROL stream. `plan_text` rides the SAME date-blind * fence every other agent-authored note crosses: a leak is refused-and-placeholdered (never delivered), * and the placeholder then fails the projector CLOSED to a logged stand-down rather than banking a * scrubbed plan as if the agent had authored it. * * DAY-COMPAT (Divergence #3, kestrel-5zl.3): the caller-owns-cadence path exists to reproduce the * STEPPED runner's byte stream EXACTLY (the frozen day `44cf2cbf`), so it emits no receipt — a new * event on that path IS the churn it is defined to have none of. NARROW, and it is not "the producer is * optional": every agent-driven session (sim / bench / live — the graded line the benchmark ranks) * takes the branch below. The day handshake gets its receipts when it stops replaying frozen bytes. */ const emitDecision = (d: Omit, ts: number): void => { if (dayCompat) return; const plan_text = d.plan_text === null ? null : dateBlindNote(`${d.control} plan text`, d.plan_text, ts); core.emit({ ts, stream: "CONTROL", ...decisionControlFields({ ...d, plan_text, measurement_versions: receiptMeasurement }) }); }; /** The PLAN statements a module arms, each as its own canonical source text — one receipt row per plan * (a receipt is per-PLAN; `target` is the name the bus's arm record keys on). */ const planRows = (mod: Module): { name: string; text: string }[] => mod.statements.filter((st) => st.kind === "plan").map((st) => ({ name: st.name, text: print(st) })); /** One PROPOSE receipt per plan of a document the engine ACTUALLY armed (call only after a successful * `core.arm`, which is all-or-nothing). `novel_plan` is the honest kind for every arm on this surface: * the driver has no armory to accept FROM and no prior proposal to reparameterize — the agent authored * the document. The finer kinds arrive when the agent states its own (the a57.14 typed envelope). */ const emitProposals = (mod: Module, ts: number): void => { for (const row of planRows(mod)) { emitDecision({ control: "propose", target: row.name, decision_kind: "novel_plan", plan_text: row.text }, ts); } }; /** The RECEIPT of an ARM escape: the engine refused the document, so nothing armed and the agent's * decision produced no position. Recorded as a stand-down carrying the text it authored (curation * honesty), NOT as a proposal — a `propose` here would claim an arm the bus's arm record cannot back, * which the curation verdict would correctly read as a phantom arm. */ const emitArmEscape = (document: string, ts: number, e: unknown): void => { emitDecision({ control: "stand_down", decision_kind: "stand_down", plan_text: document, rationale: `arm escape → stand-down: ${msgOf(e)}` }, ts); }; // ── The agent-driven wake frontier (kestrel-5zl.4) ──────────────────────────────────────────── // A min-ordered set of pending wakes seeded from the agent's scheduleWake actions (open + each // decide) and the author/platform floor (authored vantages + optional structural cadence), advanced // turn-by-turn. Every ts is pure offset / ET-calendar arithmetic off the injected firstTs / // session_date (no wall clock, no RNG) — same bus + same agent turns ⇒ byte-identical evolution. const frontier: FrontierWake[] = []; let idx = 0; let prevVantageTs = firstTs; // the OPEN baseline (T-5, m9i.11) is the first vantage let delivered = 0; // The DELIVERED wake instants (theta-cell seam b) — the vantages a HELD position is marked-to-model at // when `markToModel` is on. Collected in delivery order; consumed once, after settle. Off the graded // path unless `markToModel` opts in (then folded into `totals.floor` via a `theta_bleed` record). const deliveredWakeTs: number[] = []; let coalesced = 0; // agent wakes folded since the last delivery — surfaced on the next retained frame /** Wakes RAISED per source so far — the monotone per-source counter each {@link FrontierWake}'s * {@link FrontierWake.sourceOrdinal} is minted from at the RAISE (kestrel-5zl.20), the stable half of * its {@link wakeKeyOf} replay identity. Counting RAISES not deliveries is the whole fix: a delivery * that later folds (an inserted own-fill advancing the budget/spacing, a probe skip) no longer shifts * the ordinal a subsequent same-source wake carries, so the replay join never depends on whether a * delivery survived folding. Deterministic (a pure count, no clock, no RNG). */ const raisedOrdinals = new Map(); /** Mint the next monotone per-source ordinal for a wake being RAISED (kestrel-5zl.20). */ const nextSourceOrdinal = (source: WakeSource): number => { const k = raisedOrdinals.get(source) ?? 0; raisedOrdinals.set(source, k + 1); return k; }; // ── The language-level WakeBudget (kestrel-wa0j.5) ──────────────────────────────────────────────── // `WAKE … BUDGET N wakes/day` on the ARMED standing document NARROWS the band's config wake ceiling // (min of the two — an authored budget may never widen config; budgets nest, authority only narrows). // It caps AGENT-cadence deliveries only: the safety floors (staleness/structural/own-fill) are never // capped away, and a wake folded past the budget is COALESCED — surfaced on the next retained // delivery's `attention.coalesced`, never a silent drop. The authored budget lives WITH the standing // document: a supersede replaces it, a de-arm clears it (back to the config floor alone). let authoredWakesPerDay: number | null = null; /** Reduce a module's WAKE statements to their authored wakes/day budget — the MIN across statements * (the narrowest authored bound wins). `M tokens/day` has NO enforceable meaning in this loop * (attention here is budgeted in wakes + coalescing, not a per-day token meter), so it REFUSES by * THROW — the arm sites route it through their fail-closed disarm/refuse ladder — rather than arm * an authored clause silently inert (kestrel-wa0j.5). */ const authoredWakeBudgetOf = (mod: Module): number | null => { let min: number | null = null; for (const s of mod.statements) { if (s.kind !== "wake" || s.budget === undefined) continue; if (s.budget.tokensPerDay !== undefined) { throw new Error( `WAKE ${s.name} BUDGET ${s.budget.tokensPerDay} tokens/day is unenforceable in this loop ` + `(attention is budgeted in wakes/day + coalescing, not tokens) — refused rather than armed inert`, ); } if (s.budget.wakesPerDay !== undefined) { min = min === null ? s.budget.wakesPerDay : Math.min(min, s.budget.wakesPerDay); } } return min; }; /** The effective per-session ceiling on delivered wakes: the band's config ceiling, NARROWED (never * widened) by the armed document's authored wakes/day. Absent authored budget ⇒ the config floor * alone — byte-identical to before the language-level budget was wired. */ const effectiveMaxWakes = (): number => authoredWakesPerDay === null ? floor.maxWakes : Math.min(floor.maxWakes, authoredWakesPerDay); /** ARM `mod` WITH its authored WakeBudget — the ONE place the arm side of the invariant "an * authored budget arms and de-arms WITH its document" lives (kestrel-wa0j.5). The budget reduces * BEFORE the arm (an unenforceable `tokens/day` clause THROWS here, into the caller's own * fail-closed disarm/refuse ladder — an authored budget is never armed silently inert) and binds * only when the arm itself succeeds; a throw from `core.arm` leaves the budget untouched. */ const armWithBudget = (mod: Module): void => { const wakesBudget = authoredWakeBudgetOf(mod); core.arm(mod); armed = true; authoredWakesPerDay = wakesBudget; }; /** The de-arm side of the same invariant (kestrel-wa0j.5): a de-armed/superseded document's * authored budget de-arms WITH it — back to the config floor alone. */ const clearAuthoredBudget = (): void => { authoredWakesPerDay = null; }; /** Dateless `HHMM` ET clock for a ts (a frontier wake's `label` + the WAKE checkpoint reason). */ const labelHHMM = (ts: number): string => { const m = ((etMinuteOfDay(ts) % 1440) + 1440) % 1440; return `${String(Math.floor(m / 60)).padStart(2, "0")}${String(m % 60).padStart(2, "0")}`; }; /** Resolve a {@link WakeAt} to epoch-ms, or `null` when structurally unresolvable (fail-closed). * `inMinutes` is an offset off the CURRENT vantage — so it spans ANY horizon natively (intraday or * multi-Session, e.g. `+1440` reaches the next session); `atClockET` anchors to `session_date` (the * conservative default taken here — per-session re-anchoring is scoped to b3l). */ const resolveWakeAt = (at: WakeAt, vantageTs: number): number | null => { if (at.kind === "inMinutes") return Number.isFinite(at.minutes) ? vantageTs + at.minutes * 60_000 : null; const m = /^(\d{1,2}):(\d{2})$/.exec(at.clockET.trim()); if (m === null) return null; const hh = Number(m[1]); const mm = Number(m[2]); if (hh > 23 || mm > 59) return null; return etWallClockMs(sessionDate, hh, mm); }; /** Union a pending wake onto the frontier, de-duplicated by ts (first-wins — deterministic by push * order: seed floor before agent before staleness). A same-ts collision keeps the earlier provenance. * The RAISED wake is minted its per-source ordinal HERE (kestrel-5zl.20) — the one place a wake enters * the frontier — so the identity is fixed at the raise, never at the delivery; a de-duplicated (dropped) * push mints nothing (it never becomes a wake). */ const pushFrontier = (w: Omit): void => { if (frontier.some((e) => e.ts === w.ts)) return; frontier.push({ ...w, sourceOrdinal: nextSourceOrdinal(w.source) }); }; /** Advance the frontier: pop the earliest pending wake in the open gap `(prevVantageTs, lastTs)`. An * agent wake within the band's `floor.minWakeSpacingMin` of the last vantage, or past * `floor.maxWakes`, is FOLDED (the coalesced counter is bumped, no separate delivery); the * staleness/structural floors are exempt and always delivered. Returns `undefined` when the gap holds * no further deliverable wake. */ const popNext = (): FrontierWake | undefined => { frontier.sort( (a, b) => a.ts - b.ts || WAKE_SOURCE_RANK[a.source] - WAKE_SOURCE_RANK[b.source] || (a.reason < b.reason ? -1 : a.reason > b.reason ? 1 : 0), ); while (frontier.length > 0) { const w = frontier.shift()!; if (w.ts <= prevVantageTs || w.ts >= lastTs) continue; // outside the open gap (defensive) // Safety-class wakes (structural cadence, staleness backstop, and an own-fill management wake) are // never folded by spacing/budget — a fill must be surfaced for management (fire-then-inform). const isSafety = w.source === "structural" || w.source === "staleness" || w.source === "own-fill"; if (!isSafety && (w.ts - prevVantageTs < floor.minWakeSpacingMin * 60_000 || delivered >= effectiveMaxWakes())) { coalesced++; // folded — surfaced on the next retained delivery's attention.coalesced continue; } return w; } return undefined; }; /** Whether the book is EXPOSED at the frontier — any net-nonzero option/spot inventory. A pure read of * the graded stream's ORDER `fill` events (the SAME source `armOwnFillWakes` and `af.fills` read; a * carried `openingCarry.positions` book is seeded as opening `place`+`fill`s BEFORE the first * `armStaleness`, so it reads exposed from `firstTs`). Nets buys against sells per instrument/strike/ * right: a closed round-trip nets to zero (flat), an open lot leaves a residual (held). Deterministic. */ const isExposed = (): boolean => { const net = new Map(); for (const e of core.emitted.events) { if (e.stream !== "ORDER" || e.type !== "fill") continue; const key = `${e.instrument}|${e.strike ?? ""}|${e.right ?? ""}`; net.set(key, (net.get(key) ?? 0) + (e.side === "buy" ? e.qty : -e.qty)); } for (const q of net.values()) if (q !== 0) return true; return false; }; /** Whether the cell's OWN staleness backstop lands PAST settle for THIS window (the WIDE-band regime — * swing/position on a short window). A session-level constant: when the band's backstop from `firstTs` * already overshoots `lastTs`, it overshoots from every later vantage too, so in this regime the band's * own backstop is NEVER in-window and every staleness wake `armStaleness` installs is a DAY-floor PROBE * (conditionally delivered — see the loop). For DAY/scalp this is `false` (their own backstop is * in-window), so no probe path is ever taken — those bands are byte-identical to today. */ const bandBackstopPastSettle = firstTs + floor.stalenessBackstopMin * 60_000 >= lastTs; /** Re-arm the staleness floor relative to `vantageTs`, parameterized by the cell's band * (kestrel-5zl.16.7). If no wake that will actually be DELIVERED lands within the band's backstop * deadline, insert a safety wake at `vantageTs + floor.stalenessBackstopMin`. A foldable agent wake * does NOT satisfy the floor, so the backstop can never be silenced by a sub-spacing (or capped) * schedule. There is no Action that removes this — the agent can never disable safety (fail-closed). * * FAIL-CLOSED while exposed. When a WIDE band's backstop lands PAST settle (`deadline >= lastTs` — the * position/swing regime on a short window), the band's own backstop can never cover the gap, so fall * back to the DAY backstop (the universal, most-conservative safety floor) and install it as a PROBE — * unconditionally, whatever the book reads NOW. Exposure can be acquired AFTER this vantage (a resting * order that fills between vantages — kestrel-5zl.16.7), and gating on a flat read HERE is exactly what * left a silent no-wake window while later HELD. The probe is DELIVERED only if the book is EXPOSED at * its frozen vantage (the loop's conditional-probe skip); a still-FLAT probe is not woken (widening to * settle is allowed for a flat book). For the DAY band `safeDeadline` equals `deadline` and lands past * settle, so this returns exactly as today (no probe, no churn — the no-churn anchor). */ const armStaleness = (vantageTs: number): void => { const willDeliver = (w: FrontierWake, effDeadline: number): boolean => w.ts > vantageTs && w.ts <= effDeadline && (w.source === "structural" || w.source === "staleness" || (w.ts - vantageTs >= floor.minWakeSpacingMin * 60_000 && delivered < effectiveMaxWakes())); const insertBackstop = (deadline: number): void => { if (!frontier.some((w) => willDeliver(w, deadline))) { pushFrontier({ ts: deadline, reason: "staleness-backstop", source: "staleness", label: labelHHMM(deadline) }); } }; const deadline = vantageTs + floor.stalenessBackstopMin * 60_000; if (deadline < lastTs) { insertBackstop(deadline); // the band's backstop lands inside the window — normal path return; } // The band's own backstop lands past settle. Install the DAY floor — the tightest universal safety net // — as a PROBE (delivery is gated on exposure in the loop, so a flat book is never woken). For the DAY // band `safeDeadline` equals `deadline` and also overshoots settle, so this returns here exactly as // today: no probe installed, no churn. If even the day floor lands past settle, settle IS the vantage. const safeDeadline = vantageTs + DAY_STALENESS_BACKSTOP_MIN * 60_000; if (safeDeadline >= lastTs) return; insertBackstop(safeDeadline); }; // Seed the frontier with the author/platform floor: authored vantages + (optional) structural cadence. // These are RETAINED as seed vantages (day.ts parity); the agent's scheduleWake set is unioned on top. for (const sw of computeWakes(sessionDate, opts.wakes ?? [], opts.structural ?? false, firstTs, lastTs)) { pushFrontier({ ts: sw.ts, reason: sw.label, source: sw.structural ? "structural" : "seed", label: sw.label }); } /** Express a placeOrder as a one-shot Plan and arm it — it then crosses the IDENTICAL engine→Gate→fill * path a fired Plan crosses (bounded risk enforced by the engine, never re-implemented). A synthesis/parse * escape (e.g. an unresolvable price form) is refused-and-logged. * * The synthesized Plan is **WHEN-less and ttl-less** so it is immediately satisfiable at the wake it * was submitted and then RESTS like a real limit order: * - **WHEN-less** — an armed plan with no `WHEN` fires unconditionally on the very next engine sweep * (it arms and fires in the SAME `onEvent`), so the order submits at once. The earlier `WHEN phase * open` was the bug: a placeOrder arrives at a WAKE during `phase regular`, so `phase open` never * evaluated true again and the order silently expired un-submitted (kestrel-5zl.5). * - **ttl-less** — a `ttl +1m` on the (now firing) plan would make the engine `#doTtlExpire` PULL the * still-unfilled resting order one minute after arm, i.e. before the agent's next wake could ever * see or `cancelOrder` it. A resting order instead rides until it fills, the agent cancels it, or the * session settles worthless-unfilled ($0 floor) — the honest "resting order" semantic. * `budget 1R` (bounded risk) and the engine's never-naked per-leg refusal still apply — an uncovered * SELL is refused-and-logged by the engine (no order rests), an unresolvable leg is skipped fail-closed. */ const routePlaceOrder = (action: PlaceOrderAction, ts: number): void => { const o = action.order; const priceExpr = o.price.trim().replace(/^@/, ""); // "@fair" → "fair" (the grammar's `@` is the separator) const name = `agent-order-${placeSeq++}`; // FAIL CLOSED, NARROWLY (kestrel-eywk). A synthesized one-shot inherits the standing document's risk // envelope, which now carries the author's OWN stated budget — so the ordinary case is ADMITTED and // bounded, and the never-naked / budget / intrinsic-floor checks in the engine still judge it. The one // case the engine cannot honestly serve is a standing document that states NO budget anywhere: there is // no authority to read, and the engine will not manufacture one. Refuse THIS action with a legible typed // reason on the author's channel (AX doctrine: no refusal without a reason) — the proportionate response // (ADR-0012), never a book-wide stand-down, never a silent clamp. Note: if nothing was ever opened (the // opening buy would hit this same refusal) there is no unstopped position to strand, so refusing even a // would-be SELL here never leaves inventory naked. if (!core.engine.synthesisEnvelopeBounded()) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `placeOrder ${name} refused (no-bounded-envelope): the standing document states no budget anywhere — no POD/BOOK and no plan \`budget NR\` — so a synthesized order would inherit no bound. State a budget (fail-closed, RUNTIME §8)`, }); // The refused order is a recorded stand-down (a57.18). No plan text: the driver refused BEFORE it // synthesized one, so there is no authored candidate to carry — it records what happened, not a // document that never existed. emitDecision({ control: "stand_down", target: name, decision_kind: "stand_down", plan_text: null, rationale: `placeOrder ${name} refused (no-bounded-envelope): the standing document states no budget anywhere` }, ts); return; } // The ADR-0017 leg convention: BOTH strike+right absent ⇒ an EQUITY/SPOT order, synthesized as an // equity leg (`USING exec ` + `DO buy N shares`) so it routes to the IDENTICAL spot-fill path a // fired plan's `DO buy N shares` crosses; else an OPTION leg (the option-chain fill path, unchanged). const isEquity = o.strike === undefined && o.right === undefined; const doc = isEquity ? `PLAN ${name} budget 1R\n USING exec ${o.instrument}\n DO ${o.side} ${o.qty} shares @ ${priceExpr}` : `PLAN ${name} budget 1R\n DO ${o.side} ${o.qty} ${o.strike} ${o.right} @ ${priceExpr}`; let mod: Module; try { mod = toModule(parse(doc)); } catch (e) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `placeOrder ${name} parse escape: ${msgOf(e)}` }); // Curation honesty (a57.18): the order the agent wanted and did not get is a recorded stand-down // carrying the text that escaped — never a dropped row. emitDecision({ control: "stand_down", target: name, decision_kind: "stand_down", plan_text: doc, rationale: `placeOrder ${name} parse escape: ${msgOf(e)}` }, ts); return; } core.emit({ ts, stream: "CONTROL", type: "author", target: name, ...(action.note !== undefined ? { note: dateBlindNote("placeOrder note", action.note, ts) } : {}) }); // `synthesizedOrder` — this is an agent placeOrder, not an authored document (kestrel-5zl.5): the engine // covers a SELL leg against the whole BOOK (the never-naked doctrine formula, since a one-shot has no // authored plan structure to scope to) and de-arms terminally-and-once if the leg is uncovered/unbuildable // (no per-sweep refusal storm). Authored plans keep the plan-scoped boundary (kestrel-22j.14). core.arm(mod, { synthesizedOrder: true }); // The PROPOSE receipt for the synthesized one-shot (a57.18). A placeOrder arms a real plan under a // real name, so it lands in the bus's arm record exactly like an authored plan — without this row it // would be an UNRECEIPTED ARM (the engine arming what the curation record does not own) and the // verdict would refuse to grade the whole session. `novel_plan`: the agent authored this order. emitProposals(mod, ts); armed = true; }; const routeAction = (action: Action, ts: number, dayOrdinal?: number): void => { switch (action.kind) { case "supersede": { let mod: Module; try { mod = toModule(parse(action.document)); } catch (e) { // Fail-closed: a parse escape at the driver de-arms clean with a logged reason (never a crash). core.emit({ ts, stream: "CONTROL", type: "disarm", note: `supersede parse escape: ${msgOf(e)}` }); // The RECEIPT of the same escape (a57.18): the agent decided something and it did not survive // the parse. The row is KEPT carrying the text it tried to author — the projector re-derives the // degrade itself ("parse escape → STAND_DOWN"), so the curation record cannot quietly lose the // decision that produced no arm. emitDecision({ control: "stand_down", decision_kind: "stand_down", plan_text: action.document, rationale: `supersede parse escape: ${msgOf(e)}` }, ts); if (armed) core.supersede(ts); clearAuthoredBudget(); // the de-armed document's authored budget de-arms with it return; } if (!armed) { try { // The authored WakeBudget reduces BEFORE the arm (kestrel-wa0j.5, `armWithBudget`): an // unenforceable `tokens/day` clause throws here and rides the SAME fail-closed disarm // ladder — an authored budget is never armed silently inert. armWithBudget(mod); // initial arm — no CONTROL record (matches the stepped day's plans-0) emitProposals(mod, ts); } catch (e) { // Fail-closed: an initial document the engine refuses to arm de-arms clean with a logged reason // (never a crash — the parse-escape ladder extended to an ARM escape, RUNTIME §8). core.emit({ ts, stream: "CONTROL", type: "disarm", note: `arm escape: ${msgOf(e)}` }); emitArmEscape(action.document, ts, e); } } else { if (dayCompat && dayOrdinal !== undefined) { // DAY-COMPAT (kestrel-5zl.3, Divergence #2): reproduce the stepped runner's CONTROL supersede // bytes EXACTLY — `{stream, type, target:"wake-N", note:"revision-N"}` (day.ts). `serializeEvent` // is `JSON.stringify` over all fields in insertion order, so the key order here // (ts, stream, type, target, note) MUST match `day.ts` for the frozen `44cf2cbf` to reproduce. core.emit({ ts, stream: "CONTROL", type: "supersede", target: `wake-${dayOrdinal}`, note: `revision-${dayOrdinal}` }); } else { core.emit({ ts, stream: "CONTROL", type: "supersede", ...(action.note !== undefined ? { note: dateBlindNote("supersede note", action.note, ts) } : {}) }); } core.supersede(ts); clearAuthoredBudget(); // the superseded document's authored budget de-arms with it try { // Same pre-arm WakeBudget reduction as the initial arm (kestrel-wa0j.5, `armWithBudget`): // the replacement's authored budget binds only when the replacement actually arms; // `tokens/day` refuses here. armWithBudget(mod); emitProposals(mod, ts); } catch (e) { // Fail-closed: a replacement the engine refuses to arm (e.g. a name still owned by a managing // lineage — names are lineage, ENGINE armDocument) leaves the just-superseded book riding its // TP/EXIT under its own record; a logged refuse, never a crash (RUNTIME §8). core.emit({ ts, stream: "CONTROL", type: "refuse", note: `supersede arm escape: ${msgOf(e)}` }); emitArmEscape(action.document, ts, e); } } return; } case "standDown": { // Fence ONCE and reuse: `dateBlindNote` emits the auditable `refuse` on a leak, so calling it // twice for the same field would double-log the same refusal. const reason = dateBlindNote("standDown reason", action.reason, ts); core.emit({ ts, stream: "CONTROL", type: "disarm", note: reason }); // The RESTRAINT row (a57.18) — the decision the benchmark north star is actually about. The agent // named no candidate (this surface's stand-down is a whole-book de-arm), so the plan is `null`: // the producer records the reason the agent gave and invents no plan it did not author. emitDecision({ control: "stand_down", decision_kind: "stand_down", plan_text: null, rationale: reason }, ts); if (armed) core.supersede(ts); // de-arm clean; inventory rides its TP/EXIT (never liquidates) clearAuthoredBudget(); // the de-armed document's authored budget de-arms with it return; } case "scheduleWake": { // Fail-closed at the seam. A reason that itself carries calendar identity would re-leak into the // date-blind acting Frame — refuse-and-log it (the book rides the floor), never deliver it. const leak = scanDateLeak(action.reason); if (leak !== null) { // Name the leak CLASS only — echoing `leak.match` would re-inject the calendar token into this // refuse note, which `engineActionOf` surfaces into the next date-blind Frame (kestrel-auw). core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake reason refused: leaks a ${leak.name} (date-blind fence)` }); return; } // Resolve the target; a past / beyond-window / unresolvable target is the PROPORTIONATE // refuse-that-action (the book stays armed on the staleness backstop), NOT a book-wide stand-down // and NEVER a forward peek past the driven window (agent.ts §Fail-closed; CLAUDE fail-closed). const at = resolveWakeAt(action.at, ts); if (at === null) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: unresolvable target` }); return; } if (at <= ts) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: target in the past (rides the staleness backstop)` }); return; } if (at >= lastTs) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: target beyond the driven window (no forward peek)` }); return; } // The stored View is validated AT SCHEDULE TIME, fail-closed (kestrel-wa0j.4 / kestrel-wa0j.19 §1b): // it rides the WAKE `scheduled` record and the delivered frame, so a defect is caught NOW — never // carried to an (otherwise unguarded) delivery render where it could crash the wake. TWO // dispositions, by defect class: // • date-leak / STRUCTURAL (unknown pane, reserved kernel id, un-understood args) — the View is // unsafe or nonsense; refuse the WHOLE scheduleWake (the book rides the floor), the existing // contract. Screened through the SAME date-blind fence as the reason, then `resolveView`. // • VALUE / BUDGET knowable now (a `tape ` the constant tape bucket can't serve, a View // already over its own token budget vs the catalog estimates) — the View is SOUND but this // session's resolution can't serve it; DROP the View and still fire the wake under the DEFAULT // panes, with a logged refuse (the proportionate disposition the delivery seam §1a reaches // anyway, moved earlier). The wake intent is honored; only the unrenderable lens is dropped. let scheduledView: ViewSelection | undefined; if (action.view !== undefined) { const viewLeak = scanDateLeak(action.view); if (viewLeak !== null) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: view refused — leaks a ${viewLeak.name} (date-blind fence)` }); return; } let sel: ViewSelection; try { sel = viewSelectionOfDocument(action.view); resolveView(sel, "WAKE"); // fail-closed: unknown pane id / reserved kernel id / refused args } catch (e) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: view refused — ${msgOf(e)}` }); return; } const defect = scheduleTimeViewDefect(sel); if (defect !== null) { // Sound View this session can't serve — drop it, keep the wake (default panes), log the refuse. core.emit({ ts, stream: "CONTROL", type: "refuse", note: `scheduleWake ${action.reason}: view dropped to default panes — ${defect}` }); } else { scheduledView = sel; } } // Record the request (the audit) AND union it onto the wake frontier (the mechanism). The `view` // rides the record ONLY when it was ACCEPTED — a dropped View is not advertised as if it will render. core.emit({ ts, stream: "WAKE", type: "wake", wake: "scheduled", reason: action.reason, ...(scheduledView !== undefined ? { view: action.view } : {}), }); pushFrontier({ ts: at, reason: action.reason, source: "agent", label: labelHHMM(at), ...(scheduledView !== undefined ? { view: scheduledView } : {}), }); return; } case "placeOrder": routePlaceOrder(action, ts); return; case "flatten": { // FLATTEN (bd if0 / 75n): the agent's first-class close. The engine cancels the managing plan's // resting orders for the instrument (neutralizing the rolling TP re-post) AND crosses a COVERED // close through the SAME Gate — never-naked holds (a flatten of a held long is a covered sell) and // it can NEVER create a naked position. A flat book is a clean no-op, surfaced (never silent). const sym = dateBlindField(action.instrument); const out = core.flatten(action.instrument, ts); core.emit({ ts, stream: "CONTROL", type: out.plansFlattened > 0 ? "disarm" : "refuse", note: out.plansFlattened > 0 ? `flatten ${sym}: closed ${out.closedQty} across ${out.plansFlattened} plan(s)${action.note !== undefined ? ` — ${dateBlindField(action.note)}` : ""}` : `flatten ${sym}: no held position to close (no-op)`, }); return; } case "cancelOrder": { try { // Route through the engine (kestrel-5zl.5 / #3c ow8): `core.cancelOrder` marks the engine child // cancelled AND drains the Gate's ORDER `cancel` in the SAME step, so the wake snapshot's // `resting[]` (an engine-dump scrape) and `engineLog` (a bus projection) AGREE within one // snapshot — never one wake late (the anomaly the capstone agent flagged). `cancel` returns // whether a resting order was actually removed; a ref that matches nothing currently resting // (unknown / already filled / already cancelled) is refused-and-logged — proportionate // fail-closed (never a stand-down, never a silent no-op), as CancelOrderAction specifies. if (!core.cancelOrder(action.ref, ts)) { // `action.ref` is agent free text that lands in this refuse note (→ next Frame via engineActionOf, // kestrel-auw) — sanitize a calendar token out of it so a bad ref can't trip the date-blind fence. core.emit({ ts, stream: "CONTROL", type: "refuse", note: `cancelOrder ${dateBlindField(action.ref)}: no resting order for ref` }); } } catch (e) { core.emit({ ts, stream: "CONTROL", type: "refuse", note: `cancelOrder ${dateBlindField(action.ref)}: ${msgOf(e)}` }); } return; } default: return assertNever(action, "simulate: unknown Action kind"); } }; /** Route one turn at the injected `ts`: the pre-hoc JOURNAL first (provably pre-hoc by `seq`), then the * actions in author order. An empty `actions[]` with no journal is a legitimate pass (emits nothing). */ const routeTurn = (turn: AgentTurn, ts: number, dayOrdinal?: number): void => { if (turn.journal !== undefined) core.emit({ ts, stream: "JOURNAL", kind: "author", body: turn.journal }); for (const action of turn.actions) routeAction(action, ts, dayOrdinal); }; // ── Clock-honest delivery machinery (ADR-0040 / clock-honest wakes §§2.1–2.6) ──────────────────── /** The segment tape carried between deliveries: exec SPOT/BOOK prints stepped since the last * delivered vantage — including a clocked OPEN overrun and each deliberation gap — drained into the * next delivery's snapshot. For a latency-blind run this is exactly the old per-wake segment. */ const segmentTapeCarry: { ts: number; px: number }[] = []; /** Step every input event with `ts < tsMax` through the core (fills-before-sweep — armed Plans keep * firing at machine speed in a deliberation gap; the armed plan governs the gap), collecting the * exec tape into the carry. */ const stepUntil = (tsMax: number): void => { while (idx < events.length && events[idx]!.ts < tsMax) { const ev = events[idx]!; if (ev.stream === "TICK" && ev.type === "SPOT" && ev.instrument === instrument) { segmentTapeCarry.push({ ts: ev.ts, px: ev.px }); } else if (ev.stream === "TICK" && ev.type === "BOOK" && ev.instrument === instrument) { segmentTapeCarry.push({ ts: ev.ts, px: ev.underlier_px }); } core.step(ev); idx++; } }; /** * The latency-fold (§2.3): remove every frontier entry inside the open deliberation window * `(fromTs, returnTs]` — half-open below, closed above; a zero-cost window is empty. Each folded * wake counts ONCE toward the visible squelch; a FLAT-BOOK staleness PROBE inside the window is * SKIPPED, not folded (rule d — a probe is not attention owed to the Seat; the next probe re-arms * from the return). This is the §2.3(g) guard REDIRECT made structural: in-window entries route * HERE (to the fold) before `popNext`'s defensive out-of-gap skip could ever silently discard a * safety-class wake. Returns the folded count — >0 ⇒ exactly ONE catch-up delivery at `returnTs`. */ const foldDeliberationWindow = (fromTs: number, returnTs: number): number => { let folded = 0; for (let i = frontier.length - 1; i >= 0; i--) { const e = frontier[i]!; if (e.ts <= fromTs || e.ts > returnTs) continue; // outside (fromTs, returnTs] frontier.splice(i, 1); if (bandBackstopPastSettle && e.source === "staleness" && !isExposed()) continue; // (d) probe skip folded++; } return folded; }; /** §2.5 — the past-settle tail: a control returning at/past the session's last tape instant has no * market left to execute against. It is NOT lapse-to-null (the Seat gains nothing from silence — it * holds whatever its standing authority held): each action is refused with the logged reason, * stamped at the TRUE `returnTs`; the journal (author metadata) still rides pre-hoc-by-seq. Settle * itself stamps later at `lastTs`, its normal ts — emission order record → refusals → settle. */ const refuseAfterSettle = (turn: AgentTurn, returnTs: number): void => { if (turn.journal !== undefined) core.emit({ ts: returnTs, stream: "JOURNAL", kind: "author", body: turn.journal }); for (const action of turn.actions) { core.emit({ ts: returnTs, stream: "CONTROL", type: "refuse", note: `${action.kind}: control returned after settle (no market left to execute against — ADR-0040 §2.5)`, }); } }; /** The pending latency-fold catch-up delivery (§2.3a): set when a deliberation window folded ≥1 * frontier wake — ONE normal frozen-at-wake delivery at the Seat's return time, consumed by the * next loop pass INSTEAD of `popNext` (safety-class by construction: it bypasses the spacing/budget * folds, yet still counts against `delivered` and the wake budget — §2.3b). */ let pendingCatchUp: FrontierWake | undefined; // 0. Multi-session re-arm (the multi-session horizon design, kestrel-5zl.16.2): re-arm the carried STANDING document fresh // BEFORE the OPEN turn, minting new plan-instance ids for this session (the engine mints per-arm, so // a fresh arm = fresh ids; a d0 `ttl 16:00` therefore CANNOT persist into d1 — it re-anchors to this // session's open). The agent's OPEN turn may still supersede it (a CONTROL supersede, since `armed`). // A session with no carried document opens exactly as today (`armed` stays false → the OPEN supersede // is the initial arm, plans-0 parity). Only a multi-session run reaches this branch. if (openingCarry?.document != null) { try { // The carried document's authored WakeBudget re-arms with it (kestrel-wa0j.5, `armWithBudget`). // An unenforceable `tokens/day` throws — unreachable for a carry that passed the arm-time guard // in its prior session, but not trusted: it rides the same disarm ladder as any arm escape. armWithBudget(openingCarry.document); } catch (e) { // Fail-closed: a carry the engine refuses to re-arm opens the session un-armed with a logged // reason (never a crash — the arm-escape ladder, RUNTIME §8); the OPEN turn may still arm fresh. core.emit({ ts: firstTs, stream: "CONTROL", type: "disarm", note: `carry re-arm escape: ${msgOf(e)}` }); } } // 1. OPEN — briefing (bounded by the author acting cutoff, T-5 by default — never a forward peek past // the cutoff, m9i.11) → agent.open → route the initial arm. const cutoffTs = authorCutoffTs(sessionDate, opts.authorCutoff); // kestrel-wcnd: hold the RAW briefing snapshot — `projectAuthorFrame` strips the chain's absolute // expiry (the date-blind seam keeps only a relative `dte`), but τ must be resolved against that // absolute expiry. It feeds the pricer only; the frame the agent reads is untouched. const briefingSnap = briefingSnapshot(meta, instrument, events, opts.rUsd, cutoffTs, { carryRange: opts.authorFromRange === true }); const briefingAf = projectAuthorFrame(briefingSnap, firstTs, sessionDate, opts.sessionOrdinal); const standing: KernelStanding = { ...(opts.mandate !== undefined ? { mandate: opts.mandate } : {}), ...(opts.brief !== undefined ? { brief: opts.brief } : {}), }; // Perception arm (kestrel-4gl.13.13): fold the options overlay to the OPEN author cutoff (T-5m // guard — only events at/before the cutoff). Absent overlay ⇒ undefined ⇒ minimal arm, byte-identical. const openOptions = opts.optionsOverlay !== undefined ? buildFrameOptions(opts.optionsOverlay, cutoffTs) : undefined; const briefingInput = briefingInputOf( briefingAf, meta, instrument, firstTs, lastTs, standing, openOptions, { // kestrel-121: price the OPEN briefing chain `fair` through the SAME `fairTauYears` the fill engine // uses, evaluated at the author cutoff `cutoffTs` (the T-5 baseline — no forward peek). tauYears: fairTauYears, nowTs: cutoffTs, // kestrel-wcnd: …and against the SAME chain expiry, so the briefing's `fair` is the contract's, // not the session close's. Absent ⇒ τ `null` ⇒ `fair` renders `—` (fail-closed). ...(briefingSnap.chain?.expiry !== undefined ? { expiry: briefingSnap.chain.expiry } : {}), }, // kestrel-wa0j.20: the injected prior-session tapes ride onto the OPEN briefing (absent ⇒ unchanged). opts.priorSessions, ); // DAY-COMPAT: hand the day file agent the raw OPEN {@link AuthorFrame} (kestrel-5zl.3) — the SAME // projection this driver's own `briefingInputOf` consumed; `briefing.txt` itself renders from the typed // BriefingInput through the canonical renderer (kestrel-wa0j.2). if (opts.dayBridge !== undefined) opts.dayBridge.vantage = briefingAf; // The OPEN turn: the bounded ADR-0029 authoring loop when the agent is viewshop-enabled (it exposes // `authoringOpen` — the driver's config gate), else the single-shot open() (baseline / recorded / // fixed-plan). Only the TERMINAL turn crosses to the Bus + CapturedTurns; the shopping/repair // iterations are evidence above the determinism line, so recordedAgent (no authoringOpen) replays // byte-identically whether the live run shopped/repaired N times or committed immediately. const callOpen = (): Promise | AgentTurn => opts.agent.authoringOpen !== undefined ? runOpenAuthoringLoop(opts.agent, briefingInput, { viewRequestCap: opts.authoring?.viewRequestCap ?? DEFAULT_VIEW_REQUEST_CAP, authoringTokenBudget: opts.authoring?.authoringTokenBudget ?? DEFAULT_AUTHORING_TOKEN_BUDGET, ...(opts.emergenceLog !== undefined ? { emergenceLog: opts.emergenceLog } : {}), model: opts.agent.config.model, }) : opts.agent.open(briefingInput); if (!clockHonest) { // Latency-blind (the default): byte-identical to before — no checkpoint, no measurement, no record. const openTurn = assertHandlerResponseTimeless(await callOpen()); routeTurn(openTurn, firstTs); captured.set(OPEN_WAKE_KEY, { turn: openTurn }); } else { // §2.6 — the OPEN turn is clocked, WITH the checkpoint it was missing: the OPEN vantage becomes a // real, named anchor on the bus at the author cutoff (exactly what the record's wake_seq needs). // The whole bounded authoring loop (view iterations AND repair retries) is inside ONE measured // window — one vantage, one record, cumulative cost (§2.7). const openCheckpoint = core.emit({ ts: cutoffTs, stream: "WAKE", type: "wake", wake: "checkpoint", reason: labelHHMM(cutoffTs) }); const { turn: openTurn, measuredMs, seatAnswered } = await clockedTurn(OPEN_WAKE_KEY, callOpen); const costMs = seatAnswered ? measuredMs + bufferMs : 0; const returnTs = cutoffTs + costMs; // the RECORD ts — the cost is truth, unclamped const landTs = Math.max(firstTs, returnTs); // where the OPEN control LANDS (§2.6 — a separate pin) // The overrun arm: a Seat that overruns its pre-open window arms late into a MOVING open — the // tape advances to the landing instant first (a within-window author steps nothing: no event // precedes firstTs). stepUntil(landTs); core.gate.now = landTs; if (seatAnswered) { core.emit({ ts: returnTs, stream: "WAKE", type: "deliberation", wake_seq: openCheckpoint.seq, measured_ms: measuredMs, buffer_ms: bufferMs, }); } if (returnTs >= lastTs) refuseAfterSettle(openTurn, returnTs); else routeTurn(openTurn, landTs); captured.set(OPEN_WAKE_KEY, seatAnswered ? { turn: openTurn, measuredMs } : { turn: openTurn }); prevVantageTs = landTs; // The OPEN-overrun fold: seed/structural wakes falling in (firstTs, landTs] were owed while the // Seat authored — they fold into ONE catch-up delivery at the landing instant, exactly §2.3. const folded = foldDeliberationWindow(firstTs, landTs); if (folded > 0 && landTs < lastTs) { coalesced = folded; pendingCatchUp = { ts: landTs, reason: "latency-fold", source: "latency-fold", label: labelHHMM(landTs), sourceOrdinal: nextSourceOrdinal("latency-fold") }; } } // The lower edge of the FIRST wake's engine-log window (kestrel-5zl.11): the seq the next emitted // event will carry, so the first `[prevWakeSeq, thisWakeSeq)` window is exactly the gap AFTER the // OPEN vantage (the OPEN arm's own PLAN records sit at/before this edge, never re-attributed as a // since-last engine action). Advanced to each delivered wake's checkpoint seq as the loop runs. let prevWakeSeq = core.emitted.events.length; // 2. The agent-driven wake frontier (frozen-at-wake), floored by the staleness backstop. The OPEN // baseline is the first vantage; from here the agent's scheduleWake cadence drives, the platform // floors (never replaces) it, and folds are surfaced on the retained delivery (never silently dropped). // DAY-COMPAT (kestrel-5zl.3, Divergence #1): the caller (the day driver) OWNS the cadence — its own // structural wakes ARE the coverage — so the platform injects NO staleness backstop on this path, // reproducing the stepped runner's sparse `{OPEN, authored/structural}` wake set (no 30-min DAY-band // churn → the frozen `44cf2cbf`). This is orthogonal to `band`: a normal band run leaves `dayCompat` // false, so the 16.7 fail-closed backstop below still floors every agent-driven session. // (Clock-honest: the floor re-arms from the OPEN control's LANDING instant — `prevVantageTs` is the // landTs a clocked OPEN advanced it to; latency-blind it still equals `firstTs`, byte-identical.) if (!dayCompat) armStaleness(prevVantageTs); // Own-fill management wake (kestrel-9gu.8.3, ADR-0016) — ONLY on a seeded (sampled-channel) run, so // this is purely additive to a Backtest (no fillSeed ⇒ never armed ⇒ byte-identical). When the agent's // resting order fills — a strict-cross floor OR a causal sampled draw — a management wake is armed a // spacing beyond the fill so the agent can react to owning the position (fire-then-inform). It is a // safety-class wake (never folded), floored by the staleness backstop just like the platform wake. let fillWatermark = core.emitted.events.length; // Arm a management wake a spacing beyond `afterTs` (the current vantage being delivered) for any own-fill // in the segment just stepped — floored to `afterTs` so the wake is always in a FUTURE gap (the frozen-at- // wake model only steps forward; a past ts would be dropped). Deduped by ts; deliverable next popNext. const armOwnFillWakes = (afterTs: number): void => { const fresh = core.emitted.events.slice(fillWatermark); fillWatermark = core.emitted.events.length; if (fillSeed === undefined) return; if (!fresh.some((e) => e.stream === "ORDER" && e.type === "fill")) return; const wakeTs = afterTs + floor.minWakeSpacingMin * 60_000; if (wakeTs > prevVantageTs && wakeTs < lastTs) { pushFrontier({ ts: wakeTs, reason: "own-fill-management", source: "own-fill", label: labelHHMM(wakeTs) }); } }; // The prior author vantage's SERVED values (kestrel-wa0j.48) — captured at the END of each wake from // the frame THIS driver served, and threaded into the NEXT wake so the `delta` pane can state what // MOVED under stateless-redraw. `undefined` on the first wake (no prior author vantage yet) ⇒ that // frame carries no `priorVantage` and the delta pane fails closed to absent-with-reason. let priorServedVantage: PriorVantage | undefined = undefined; let n = 0; for (;;) { // A pending latency-fold catch-up (§2.3a) delivers INSTEAD of the frontier pop: it is // safety-class (never itself spacing- or budget-folded), yet counts like any delivery below. const w = pendingCatchUp ?? popNext(); pendingCatchUp = undefined; if (w === undefined) break; // Drive events strictly before the wake, collecting the segment's underlier tape (day.ts parity; // the carry also holds anything a clocked OPEN overrun / deliberation gap already stepped). stepUntil(w.ts); const segmentTape = segmentTapeCarry.splice(0); armOwnFillWakes(w.ts); // seeded runs only — arm a management wake after any own-fill in this segment // Fail-closed conditional probe (kestrel-5zl.16.7): in a WIDE band whose own backstop lands past // settle, `armStaleness` installs a DAY-floor staleness PROBE at every vantage so exposure acquired // BETWEEN vantages (a resting order that fills after the last frontier evaluation — the marketable- // order-at-open case) is never left in a silent no-wake window while HELD. The probe is a REAL safety // wake only when the book is EXPOSED at this frozen vantage (segment fills are already stepped, so // `isExposed()` reads the book AT `w.ts`); a still-FLAT probe is not delivered (widening to settle is // allowed for a flat book) — skip it, re-arm the next DAY-floor probe from here, and step on. For // DAY/scalp this is unreachable (`bandBackstopPastSettle` is false — their own backstop is in-window, // never a probe), so those bands are byte-identical to today. if (bandBackstopPastSettle && w.source === "staleness" && !isExposed()) { armStaleness(w.ts); // re-arm the next probe from this point; a flat probe is never woken continue; } // Freeze market time at the wake ts and record the WAKE checkpoint (unconditional — part of freezing). // Its reason is the dateless HHMM clock (the unchanged bus contract); the wake's SEMANTIC reason rides // the acting Frame's wakeReason (agent reason / "staleness-backstop" / the seed HHMM label). core.gate.now = w.ts; const checkpoint = core.emit({ ts: w.ts, stream: "WAKE", type: "wake", wake: "checkpoint", reason: w.label }); // The upper edge of THIS wake's engine-log window — the checkpoint's own seq. Every engine action // in `[prevWakeSeq, thisWakeSeq)` happened strictly after the previous vantage and at/before this // one (frozen-at-wake by construction: only events with `seq < thisWakeSeq` are read). const thisWakeSeq = checkpoint.seq; // Project the frozen-at-wake acting Frame through the PURE `projectWakeFrame` seam: the date-blind // snapshot (market pane + plan-lifecycle base) + the enriched 4gl.3 cockpit kernel (per-vehicle // data-health + the `[prevWakeSeq, thisWakeSeq)` engine-actions-since-last-wake). The market/positions // half still derives from the SAME snapshot the stepped day renders; the cockpit engine log is a bus // projection (bus-as-truth, ADR-0010/0011). const snap = snapshotOf(core, "delta", n, w.label, w.ts, instruments, opts.rUsd, segmentTape); const af = projectAuthorFrame(snap, firstTs, sessionDate, opts.sessionOrdinal); const nextWakeTs = frontier.length > 0 ? Math.min(...frontier.map((e) => e.ts)) : null; // Perception arm (kestrel-4gl.13.13): fold the options overlay to this wake's cutoff `w.ts`. const wakeOptions = opts.optionsOverlay !== undefined ? buildFrameOptions(opts.optionsOverlay, w.ts) : undefined; const frame = projectWakeFrame( core.emitted.events, { prevWakeSeq, thisWakeSeq }, { af, instrument, // The exec contract multiplier drives the cost-basis sizing headroom (kestrel-m9i.32): equity 1, // listed option 100. Sourced from the live exec spec — never re-derived in the pure seam. execMultiplier: core.execSpec.multiplier, // The exec vehicle's data-health: an option instrument reads its chain book from `core.books`; // a plain EQUITY instrument has no chain book, so its liquidity is sourced from the live SPOT // NBBO `core.spotFill` tracks — the SAME quote pricing executes against (kestrel-710). Fail-closed. vehicles: [vehicleBookFromSpot(instrument, core.books.get(instrument), core.spotFill.currentQuote(instrument))], ctx: { wakeOrdinal: n, wakeSource: w.source, // The stable per-source ordinal minted at the RAISE (kestrel-5zl.20) — read straight off the // FrontierWake, so a folded delivery (own-fill/spacing/probe) never shifts this survivor's key. wakeSourceOrdinal: w.sourceOrdinal, wakeReason: w.reason, wakeTs: w.ts, prevVantageTs, nextWakeTs, lastTs, // Agent-driven with NO authored budget ⇒ open-ended (`null`, byte-identical to before). An // authored `BUDGET N wakes/day` (kestrel-wa0j.5) makes the narrowed remaining count VISIBLE // on every delivery — the attention accounting the squelch doctrine requires. THIS delivery // is already spent (`- 1`); a safety wake past the ceiling clamps at 0, never negative. wakesRemaining: authoredWakesPerDay === null ? null : Math.max(0, effectiveMaxWakes() - delivered - 1), coalesced, // The scheduled wake's stored View rides to the delivery it selects (kestrel-wa0j.4). ...(w.view !== undefined ? { view: w.view } : {}), }, standing, // Perception arm (kestrel-4gl.13.13): the options-analytics projection folded to THIS wake's // cutoff `w.ts` (causal, no look-ahead). Absent overlay (or an empty fold) ⇒ minimal arm. ...(wakeOptions !== undefined ? { options: wakeOptions } : {}), // kestrel-121: the SAME `fairTauYears` the fill engine prices `@fair` with, so the chain `fair` // column is anchored on ExecutionFair at this wake's cutoff (`w.ts`) — never a mid, never `—`. fairTauYears, // kestrel-wcnd: …resolved against the RAW snapshot chain's own expiry (the projected `af` is // date-blind and carries only a relative `dte`). Pricer-only — never served to the author. ...(snap.chain?.expiry !== undefined ? { fairExpiry: snap.chain.expiry } : {}), // The prior author vantage's served values (kestrel-wa0j.48) — captured below at the end of the // previous iteration; absent on the first wake (the delta pane fails closed there). ...(priorServedVantage !== undefined ? { priorVantage: priorServedVantage } : {}), // The injected prior-session tapes (kestrel-wa0j.20) — threaded onto every wake so `tape d-N` // serves ordinal N's block. Absent in the v1 single-day sim ⇒ byte-identical (Train 1B absence). ...(opts.priorSessions !== undefined ? { priorSessions: opts.priorSessions } : {}), // The armed plan ASTs the core currently holds (kestrel-wa0j.29) — the seam filters them to the // plans in an enforced state and captures their terms for the `armed-plan` pane. An empty set (no // plan armed yet) yields no `armedPlan` on the frame — byte-identical, the pane fails closed. armedPlanAsts: core.armedPlanStatements, // The tape's session_date (kestrel-wa0j.74) — the reference the `armed-plan` pane blinds an // absolute per-leg `exp ` to a relative `dte` against, so no calendar token leaks. sessionDate, }, ); assertFrameDateBlind(frame); // DAY-COMPAT: hand the day file agent the raw wake {@link AuthorFrame} (kestrel-5zl.3) — it names the // artifact (`frame--.txt`) and serializes `state-.json`; the TEXT frame renders from THIS // driver's typed ActingFrame through the canonical renderer (kestrel-wa0j.2). if (opts.dayBridge !== undefined) opts.dayBridge.vantage = af; // Key the capture on the SAME stable identity `recordedAgent` replays on (kestrel-5zl.19) — never the // global ordinal `n`, which any inserted vantage shifts. const key = wakeKeyOf(frame); /** Where this delivery leaves the vantage clock — `w.ts` latency-blind; `returnTs` clocked. */ let vantageEnd = w.ts; if (!clockHonest) { // Latency-blind (the default): byte-identical to before — decide free, land at the wake ts. const turn = assertHandlerResponseTimeless(await opts.agent.decide(frame)); // DAY-COMPAT: pass the wake ordinal `n` so `routeAction`'s supersede emits the day's `{target,note}` // CONTROL bytes (Divergence #2); ignored on the normal agent-driven path (`dayCompat` false). routeTurn(turn, w.ts, n); // re-seeds the frontier from this turn's scheduleWake actions (resolved off w.ts) captured.set(key, { turn }); } else { // §2.1 the clocked turn: the Seat still decides on the frozen-at-wake frame (ADR-0012 §2's honest // comparison basis — what changes is when its answer LANDS, not what it saw). Its measured cost + // the configured buffer advance the tape to `returnTs`; the record prices the vantage; the control // executes against the book as of the return — the strict-cross floor prices whatever the market // did during deliberation (no synthetic slippage model, §2.2). const { turn, measuredMs, seatAnswered } = await clockedTurn(key, () => opts.agent.decide(frame)); const costMs = seatAnswered ? measuredMs + bufferMs : 0; const returnTs = w.ts + costMs; stepUntil(returnTs); // fire-then-inform: the ARMED PLAN governs the gap at machine speed armOwnFillWakes(returnTs); // (f) an in-window own-fill manages forward from when the Seat can next look core.gate.now = returnTs; if (seatAnswered) { core.emit({ ts: returnTs, stream: "WAKE", type: "deliberation", wake_seq: checkpoint.seq, measured_ms: measuredMs, buffer_ms: bufferMs, }); } if (returnTs >= lastTs) refuseAfterSettle(turn, returnTs); // §2.5 — refused per action, still settles else routeTurn(turn, returnTs, n); // scheduleWake targets resolve off returnTs (§2.4) captured.set(key, seatAnswered ? { turn, measuredMs } : { turn }); vantageEnd = returnTs; } // (kestrel-5zl.20) the per-source ordinal is minted at the RAISE (`pushFrontier`), not counted here at // delivery — so a wake folded before delivery no longer shifts a later same-source wake's replay key. prevWakeSeq = thisWakeSeq; // advance the window's lower edge to this wake's checkpoint prevVantageTs = vantageEnd; // Capture the TYPED values THIS frame served (never the rendered bytes, ADR-0041 §1) as the prior // vantage the NEXT wake's `delta` pane diffs against (kestrel-wa0j.48). Off the served market pane: // spot/hod/lod/vwap from the levels, the ATM straddle extrinsic via the SAME shared helper the delta // pane reads with — so prior and current are computed identically. `baseSeq` is the wake ordinal // (relative, date-blind); `baseClockET` is the served HH:MM ET clock (date-blind). priorServedVantage = { baseSeq: n, ...(frame.clockET !== undefined ? { baseClockET: frame.clockET } : {}), spot: frame.market.levels.spot ?? null, hod: frame.market.levels.hod ?? null, lod: frame.market.levels.lod ?? null, vwap: frame.market.levels.vwap ?? null, atmExtrinsic: atmStraddleExtrinsic(frame.market), }; deliveredWakeTs.push(w.ts); // a vantage a held position is marked-to-model at (theta-cell seam b) delivered++; n++; coalesced = 0; // the folds gathered while finding w were surfaced on THIS delivery — reset for the next gap // The latency-fold (§2.3): frontier wakes inside the just-closed deliberation window (w.ts, // returnTs] coalesce — visibly — into ONE catch-up delivery at the Seat's return. Termination is // structural (§2.3e): a 0-cost window is empty, so the recursion only sustains while the Seat // keeps paying real cost against real frontier entries; past settle there is no market left and // §2.5 already graded the episode. if (clockHonest) { const folded = foldDeliberationWindow(w.ts, vantageEnd); if (folded > 0 && vantageEnd < lastTs) { coalesced = folded; // surfaced on the catch-up frame's attention.coalesced (§2.3c) — never silent pendingCatchUp = { ts: vantageEnd, reason: "latency-fold", source: "latency-fold", label: labelHHMM(vantageEnd), sourceOrdinal: nextSourceOrdinal("latency-fold") }; } } if (!dayCompat) armStaleness(vantageEnd); // re-arm the floor from the Seat's return (DAY-COMPAT owns its cadence) } // 3. Drive to settle. A non-final session of an Instance (`carryClose`) carry-marks held inventory to // close (it survives into the returned carry); a standalone / final session settles at intrinsic // (today's behaviour exactly). `settle()` with no carry is byte-identical to the pre-16.3 call. while (idx < events.length) { core.step(events[idx]!); idx++; } const settle = core.settle(opts.carryClose === true ? { carry: true } : undefined); // THETA-CELL seam b (kestrel theta-cell): ask the HELD-POSITION OWNER what the position held as of the // graded bus is worth — it reconstructs the net held legs + their blended basis, marks them against the // tape's option book at every DELIVERED wake (theta decay between wakes), and DECIDES the stand-down // floor. The driver adds no judgement of its own: it emits verbatim whatever `thetaBleed` the owner // returns (`null` ⇒ nothing at all), so the tested surface — not driver glue — decides the floor // (kestrel-pta5). Emitted HERE — after settle, BEFORE `core.blotter()`/`buildReport` project the // finalized stream — so the Blotter's `totals.floor` carries the bleed (ADR-0011). GATED + additive: a // cell that did not opt into `markToModel` (every cell but FOMC-OPTIONS) emits nothing ⇒ every existing // pinned floor is byte-identical. The bleed only binds when a position is actually HELD across ≥1 // delivered wake — a flat book, or a watcher that closed out (net-zero inventory), holds no legs and // emits nothing. CLEAN BOUNDARY: this rides the graded Bus / Blotter as a mark-to-model GRADING penalty, // distinct from realized settle cash — it is deliberately NOT folded into the engine-native // SessionReport `realized_floor_usd`, `settle.floorTotal`, or the carry cash (that report/ledger // integration is separate, out-of-scope work). const heldOpt = opts.markToModel === true ? { markToModel: true as const } : {}; const held = heldPositionAsOfGradedBus({ graded: core.emitted.events, tape: events, instrument, wakeTsList: deliveredWakeTs, recordTs: lastTs, ...heldOpt, }); if (held.thetaBleed !== null) { // `ts` FIRST so the serialized field order is canonical (seq, ts, stream, type, payload) — // SessionCore.emit prepends `seq` verbatim without re-canonicalizing (src/session/sim.ts), and // serializeEvent (src/bus/write.ts) is insertion-order-dependent, so a spread that left `ts` // after `type` put a non-canonical record onto the trust-substrate graded bus (kestrel-pta5, C3b). const { ts, ...rest } = held.thetaBleed; core.emit({ ts, stream: "TELEMETRY", type: "theta_bleed", ...rest }); } // The Blotter is a PURE projection of the graded Bus (ADR-0011) — no engine-state scrape. The carry is // a PURE read of the finalised session (the multi-session horizon design) — never a second writer onto bus or Blotter. const prior = openingCarry ?? emptyCarry(); const carry = carryFrom({ core, settle, prior, ordinal: opts.sessionOrdinal ?? prior.priorOrdinal + 1 }); // The native SessionReport, from the SAME finalized core `runDaySession` reports off (no Blotter→report // bridge): the ledger's record() consumes this verbatim, and its `session.settle_ts` is the deterministic // injected `recorded_at` (kestrel-m9i.7.4). Additive — the Blotter/carry above are byte-identical to before. // Always present (the tournament runner records it on every arm); this is also the frozen-basis report // `runDaySession` surfaces under DAY-COMPAT (kestrel-5zl.3) — `determinism_hash = emitted.hash()`, the // 0-based no-META basis the day reference `44cf2cbf` lives on — from this SAME single driver run. const report = core.buildReport(events.length, busSha256Of(events)); // The graded bus is surfaced BESIDE its projection (ADR-0010: the Bus is the truth; the Blotter its // regenerable projection) — one assembly feeds both, so they can never drift. const gradedBus = core.gradedBus(); return { blotter: project(gradedBus), report, captured, config: opts.agent.config, carry, gradedBus }; }