kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
35 lines (29 loc) • 2.36 kB
Markdown
# The Blotter is the sole Session projection — retire SessionReport; the Ledger records the Blotter
ADR-0011 made `project(bus) → Blotter` the pure, canonical projection of a Session. But
a second projection persists: the older `SessionReport`, reconstructed by scraping
engine/gate/fill state (`buildReport`), which the sqlite **Ledger** and the CLI `grade`
command still consume. The projector re-derives the totals / headline / settle-mark a second
time and pins parity to the report by comment ("byte-match the report's totals"). Two
projections of one Bus, kept in sync by hand, is the exact dual-truth ADR-0011 exists to
forbid — the code says so out loud ("the report→Blotter unification is a later cleanup").
Decision: the **Blotter is the sole projection of a Session**; `SessionReport` is retired.
The Ledger records from the Blotter; the CLI `grade` command reads the Blotter; any
human-legible report is a *rendering of* the Blotter (the a57.13 viewer), never a second
derivation. Sequenced, because the Ledger schema and CLI shape are bound to `SessionReport`
today:
1. Make the projector the **single fold** — the Blotter owns totals / headline / settle-mark;
`SessionReport` becomes a thin adapter *over* the Blotter. Pure internal move, no schema
change, no behaviour change.
2. Migrate the **Ledger to record from the Blotter** (the one schema-touching step). Gated
behind a Ledger regen — free by doctrine: the Ledger is a regenerable index rebuildable
from buses/Blotters (ADR-0010), delete-and-rebuild, not a migration script.
3. **Retire `SessionReport`** and its `buildReport` scrape once the Ledger and CLI read the
Blotter; `SessionRunResult` stops carrying both shapes.
Considered and rejected: leaving `SessionReport` as a permanent parallel shape (the status
quo — two writers, hand-synced parity, the dual truth), and a big-bang cutover (retire
before the Ledger migration — breaks `grade` and the leaderboard). The sequence above keeps
every step green.
Consequences: `buildReport`'s engine/gate/fill scrape is deleted (the anti-pattern
ADR-0011 forbids); the Ledger's regenerability makes step 2 a rebuild, not a migration;
nothing downstream reads two truths. Grade replays buses and reads Blotters, uniformly.
(Arch review C2; sequences the retirement ADR-0011 left as "a later cleanup.")