Overview
Measured value
What the ledger is worth, measured by asking the same questions twice in real Claude Code sessions — once with the ledger available, once with the ordinary toolset and no ledger — with your actual prompt caching in both arms. The case is turns and answer quality, not tokens. The ledger arm reaches an answer in 27% fewer turns and scores higher where a written reference answer exists. On cost and tokens the confidence interval spans zero: this measurement does not settle them, and the page says so rather than picking the flattering side.
/tmp/real-bench-combined— run20260807T144905Z, 21 questions, 42 sessions, both arms fresh and interleaved. The report is regenerated read-only from the stored session ids withtools/real-session-bench-report.py --dir./tmp/real-bench/grades-3pass.json— the graded answers, judgeclaude-opus-5, 3 passes per answer, median aggregated, 117 judge calls./root/ledger-baselines/runs/*— the retrieval eval, caller-recall and latency instruments, each with its own raw JSON and console log.
possibly cheaper
20260807T144905Z measured turns, wall clock, tokens and cost, and spent $0 on judges.
The quality figures come from grading the stored answers of the earlier
2026-08-06 session runs. They are two different measurements of two different builds and
are reported separately below — they are never combined into a single score.The one defensible sentence
On the same questions, the ledger arm reaches an answer in about a quarter fewer agent turns and scores slightly higher where ground truth exists, at a token and cost bill that is statistically indistinguishable from working without it. It buys steps and accuracy, not tokens.
Which claims are settled and which are not
They are not equally strong and must never be quoted as though they were. Turns and wall clock are counted from the session transcripts. Cost and tokens carry a confidence interval that includes zero. Quality is one language model's opinion of another's answer.
| Claim | Basis | Status |
|---|---|---|
| −27% agent turns (7.00 vs 9.57) | turn count per session transcript, 42 sessions | Settled |
| −8.9% wall clock | first-to-last timestamp per session | Settled |
| 0.884 vs 0.841 answer quality | LLM judge vs written reference, 3 passes, median | Judged, n=16 |
| Cheaper per question | geomean cost ratio, bootstrap CI | Unsettled — CI spans zero |
| Fewer tokens | ratio of sums + leave-one-out | Unsettled — sign flips |
| 91.6–93.7% fewer tokens | cold-API harness, no caching, stripped control | Superseded |
| $2.7 against $26–34 | same cold-API harness | Superseded |
Turns: the primary result
A turn is one model round trip in the session — the unit the user actually waits through, and the one thing neither prompt caching nor a generous toolset can disguise. Both arms answered the same 21 questions in fresh sessions, interleaved so neither arm owns a time slot, all under a single run id.
| ledger | control | delta | |
|---|---|---|---|
| turns, total | 147 | 201 | −54 |
| turns per question | 7.00 | 9.57 | −2.57 (−27%) |
| wall clock, total | 1,569 s | 1,722 s | −8.9% |
| wall clock per question | 75 s | 82 s | −7 s |
| questions where the arm used fewer turns | 13 | 4 | 4 tied |
The turn saving is four times the time saving, and that is the finding, not a defect. The ledger arm takes fewer, larger turns: it asks one question of the index and gets a paragraph of code back, where the control arm walks a directory, greps, reads, greps again. Anyone quoting this as a speed result should quote −8.9%, not −27%.
Every question, both arms
Reproduce with python3 tools/real-session-bench-report.py --dir /tmp/real-bench-combined.
Negative red% means the ledger arm used more tokens on that question.
| question | L turns | C turns | ledger tok | control tok | red% |
|---|---|---|---|---|---|
| 1a842926 | 8 | 11 | 586,871 | 537,783 | −9.1% |
| 221e2738 | 7 | 12 | 525,640 | 652,671 | 19.5% |
| 37615872 | 5 | 8 | 323,094 | 331,880 | 2.6% |
| 37d7c7a4 | 5 | 8 | 359,103 | 435,356 | 17.5% |
| 3f3bc7a4 | 2 | 4 | 112,779 | 125,278 | 10.0% |
| 419be480 | 6 | 9 | 415,198 | 372,364 | −11.5% |
| 5a754efe | 14 | 10 | 1,350,632 | 593,391 | −127.6% |
| 6f9e09d3 | 5 | 5 | 324,572 | 190,841 | −70.1% |
| 7aaa6682 | 9 | 21 | 738,922 | 1,142,774 | 35.3% |
| 942e1931 | 6 | 6 | 428,768 | 286,160 | −49.8% |
| 993c9787 | 9 | 15 | 722,003 | 963,107 | 25.0% |
| ab42c45b | 22 | 18 | 1,812,365 | 1,158,018 | −56.5% |
| af2c8aed | 5 | 8 | 382,935 | 530,427 | 27.8% |
| b784b511 | 5 | 4 | 307,127 | 145,189 | −111.5% |
| ba12d65e | 4 | 11 | 257,588 | 567,446 | 54.6% |
| bffbb4ec | 5 | 8 | 362,630 | 437,963 | 17.2% |
| cc9403ec | 7 | 7 | 571,607 | 387,491 | −47.5% |
| e7a7127c | 7 | 7 | 534,181 | 311,674 | −71.4% |
| f11df952 | 7 | 5 | 508,566 | 226,403 | −124.6% |
| f78a2653 | 3 | 7 | 196,108 | 320,772 | 38.9% |
| fb8160dd | 6 | 17 | 463,641 | 1,089,661 | 57.5% |
| total | 147 | 201 | 11,284,330 | 10,806,649 | −4.4% |
Cost and tokens: measured, and not settled
The primary cost statistic is the per-question cost ratio, aggregated as a geometric mean and given a 95% confidence interval from 10,000 bootstrap resamples of the question set. It is reported that way because a total is hostage to whichever question happened to go long.
| statistic | value | reading |
|---|---|---|
| cost, median question (geomean) | 9.2% less, 95% CI 4.9% more … 20.7% less | spans zero — unsettled |
| tokens, median question (geomean) | 4.7% more, 95% CI 28.9% more … 14.9% less | spans zero — unsettled |
| tokens, ratio of sums | −4.4% (11,284,330 vs 10,806,649) | ledger used more, in total |
| cost, ratio of sums | 7.1% less ($12.7425 vs $13.7164) | ledger cost less, in total |
| leave-one-out, tokens | −11.4% … +2.7% | one question flips the sign |
| leave-one-out, cost | +3.3% … +13.7% | direction holds, size does not |
| cache hit | 100.0% ledger, 100.0% control | both arms cached; the old cold-API harness cached neither |
One question dominates. 5a754efe — “how is the Wiki front end built”
— cost the ledger arm 1.35 M tokens against the control's 0.59 M. Dropping it alone moves the
token total 7.2 points, from −4.4% to +2.7%, and the cost total 6.6 points. A headline
that one question out of 21 can invert is not a headline.
Answer quality
Every stored answer from the 2026-08-06 session runs was graded three times by
claude-opus-5 against the written reference answer, and the median of the three passes
taken. 117 judge calls. Judge sd across passes: mean 0.028, max 0.116 — small
enough that the aggregate is not a sampling artefact.
| question set | n | ledger | control | delta |
|---|---|---|---|---|
| reference-backed, clean | 16 | 0.884 | 0.841 | +0.044 |
| of which cleared the 0.6 pass mark | 16 | 15 | 13 | +2 |
| all clean questions, including the 2 with no reference | 18 | 0.836 | 0.849 | −0.013 |
Both rows are true and the difference between them is the whole story. Two of the
21 questions have no written reference answer, so the judge grades against its own priors about a
codebase it has never seen. On one of them (5a754efe) the same answer scored 0.8 under
single-pass grading and 0/0/0 under three passes — the judge invented a premise and then marked
against it. Those two questions carry the entire sign change between the 18-question and 16-question
rows. Where ground truth exists, the result is stable and the ledger leads by 0.044; where it does not,
the instrument has no resolution in either direction. Writing the two missing references is an open
item (c80dfcc1).
20260806T055131Z with ledger answers from run
20260806T090845Z — arms measured up to 3.3 h apart. The report tool refuses to
publish that snapshot's timing and cost for exactly that reason, and those numbers are not
quoted here. The answer text is unaffected by when it was produced, so the grading stands; but note
that the ledger answers graded here come from the older build (8.29 turns per question), not
from the build that produced the 7.00 headline above. Three further questions were dropped from the
quality aggregate because one arm cited the benchmark's own answer key.The contamination on the turns run
The ledger arm was served the benchmark's own answer key in 6 of 21 sessions. The
report tool emitted “0 contaminated”, and that is technically correct — it only
inspects the final stored answer for a citation of a bench-owned document, and no arm cited one. But
docs/BENCH_REFERENCE_ANSWERS.md had been deleted from disk without its Qdrant chunks
being tombstoned, so stale copies were still returned as ranked query_ledger hits, with
the graded answers verbatim in the snippet, on 1a842926 (rank 3),
419be480 (rank 3), ba12d65e (rank 8), bffbb4ec (rank 8),
fb8160dd (rank 9) and 37d7c7a4 (rank 10). The control arm received none.
Read those six questions as not clean. They are not uniformly flattering — two of the six used more ledger turns than the older baseline, and the contamination cost the ledger arm tokens it would not otherwise have spent — but the honest position is that the 7.00 figure carries six questions that a stricter run would have to redo.
The fix is in flight as
PR #137 on branch
feat/answer-key-purge — “the answer key was never actually excluded —
make it a server rule, then delete it” — and is tracked as open items
4933580f (purge the stale chunks and filter the retrieval path),
f891960b (19 stale chunks still served for a file that no longer exists),
12897e98 (the benchmark can retrieve its own answer key),
7ddecd92 (move the exclusion server-side, off the caller) and
7fc66cb9 (the contamination check is answer-only). This page will not carry a clean
contamination claim until that work lands and the run is repeated.
What else is measured, and holds
These are instrument readings on the ledger itself rather than agent A/B results, and they are reproducible on demand for $0.
Retrieval — golden-set eval
80 questions with known answer files, scored against the live hybrid retrieval of build
04a9e15.
| split | n | recall@1 | recall@5 | MRR |
|---|---|---|---|---|
| overall | 80 | 0.6000 | 0.8875 | 0.7196 |
| tuning half (questions the priors were tuned on) | 44 | 0.5682 | 0.8864 | 0.6965 |
| held out | 36 | 0.6389 | 0.8889 | 0.7479 |
The held-out half is the number to trust; it is quoted alongside the overall figure because a
tuning-half-only headline is how this project previously talked itself into a retrieval win that did
not generalise. Corpus at the time: 26,458 live chunks. This build did not reproduce
the 0.6625 recall@1 measured on an earlier corpus — the reading is bit-identical across two
runs, and the cause is five rank-1 displacements by the build's own freshly ingested files, i.e.
corpus drift rather than a configuration regression. The honest number travels with the build
(open item b62b432f).
Source: /root/ledger-baselines/runs/phaseB-combined/eval-summary.txt,
raw eval-relevance.json; re-run at phaseB-combined-run2/. The build
attribution is by timestamp — the instrument artefacts carry no build sha.
Caller recall — who calls this?
The refactoring question the alternative cannot answer at all. Recall is measured over a frozen 30-symbol set by comparing the graph's inbound edges against a deterministic textual sweep of the same tree.
| round | before | after | delta |
|---|---|---|---|
| round 1 (tree md5 b6114c13…, 4,745 files) | 0.6173 | 0.8064 | +0.1890 |
| round 2 (tree md5 79a6085f…, 4,739 files) | 0.6176 | 0.8065 | +0.1889 |
Two independent same-tree rounds, the tree fingerprinted at both ends of each so a shifting
denominator could not manufacture the gain; the delta reproduces to ±0.0002. Per repo:
scout 0.398→0.725, wiki 0.573→0.918, motlogs 0.900→1.000, agent 0.570→0.698,
openbrain 0.647→0.692. +6,648 reference edges, from markdown code regions, Razor attributes and
<see cref>. Precision was hand-checked at source: 0 false positives out of
20 — with the caveat that 2 of the 20 are mentions in a changelog and an auto-generated
table, real but useless to a refactorer. The gain is not durable unless
Recall:ExtendedUsageForms is set in the live configuration; without it an ordinary
auto-ingest reverts the edge set.
Source: /root/ledger-baselines/runs/t3-SUMMARY.txt, with
t3-precision-sample.txt, t3-comparison.txt,
t3-round2-comparison.txt.
Latency — two pathologies, fixed
| path | before | after | mechanism |
|---|---|---|---|
| first search after an idle period | 7,371.6 ms | 38.9 ms | BM25 index was rebuilt on the request path; a background warmup now owns it (rebuild-on-request-path True→False) |
/api/stats | 6,804.1 ms | 1.9 ms | the endpoint scrolled the whole collection on every call; now served from cache |
Both were measured with an idle interval of 330 s before the cold probe. The cold-start figure was re-checked after the later deploy and held: 33.1 ms cold against 27.0 ms warm.
979aeb4e). A 3,500× difference
is far outside anything concurrent ingest can explain, but the warning is part of the record and is
printed here rather than filtered out.Source: /root/ledger-baselines/runs/t2-noop/ (before),
t2-warmup-on/coldstart-summary.txt and t2-invcache-on/latency-summary.txt
(after), phaseB-combined/coldstart-summary.txt (re-check).
2026-09-12/13 measurements — the scale plan's own evidence
A separate work of measurement, from docs/LEDGER_SCALE_PLAN.md and its
docs/evidence/ artefacts, dated and sourced individually below. None of it updates the
turns/cost headline above — that headline is a specific run (20260807T144905Z) this
work did not repeat. The one explicit claim this section does not make is a new cost or turns number:
that measurement is WP5.2, and it has not run (see below).
New retrieval baseline (WP0.6)
Merged 600b92b (PR #149), measured 2026-09-12: golden-set recall@1
0.5125, recall@5 0.75; latency p50 25 ms uncached. This is a
different measurement occasion from the 80-question / build-04a9e15 figures earlier on this
page (recall@1 0.6000 / recall@5 0.8875) — corpus and build differ between the two, and neither supersedes
the other; both are dated.
Source: docs/LEDGER_SCALE_PLAN.md §10 (WP0.6 row) and §12 (2026-09-12 afternoon
entry).
Change-safety re-tests — text lane, then compiler lane
Two five-task re-runs of the same change-plan suite (CP01–CP05), deterministic scoring, no judge model, stated here exactly as their evidence READMEs state them.
| run | arm | n | recall | precision | tp/plan | turns |
|---|---|---|---|---|---|---|
change-safety-retest-2026-09-12text-lane tools visible; Precise:Enabled=false |
ledger | 5 | 0.721 | 0.395 | 17.2 | 7.4 |
| control | 5 | 0.765 | 0.523 | 16.0 | 6.4 | |
change-safety-precise-2026-09-13compiler lane on; Precise:Enabled=true |
ledger (precise lane on) | 5 | 0.651 | 0.517 | 11.2 | 7.0 |
| control | 5 | 0.670 | 0.687 | 13.6 | 6.0 |
Tools used, when visible: in the text-lane run the ledger arm made 88 ledger calls across
10 transcripts, dominated by read_span (53) and reference_set (16, up from 0 when
the tool was hidden). In the compiler-lane run the ledger arm made only 16 ledger calls, of which
find_references (4) and find_implementations (1) were the compiler-backed tools —
agents do pick them up once advertised and enabled.
n=5 cannot resolve this. Between the two runs, the control arm — which never touched the ledger — moved from recall 0.765 to 0.670: a 0.765 → 0.670 drift on identical tasks with nothing about the ledger changing. That run-to-run swing is larger than any ledger-vs-control difference measured in either run, so at n=5 the suite cannot distinguish the compiler lane from the text lane from no ledger at all, in either direction. Neither run is evidence for or against the precise lane; the usable signal is only that the tools get used once visible, and that the precision gap has the same mechanism in both runs (plans copying every candidate file the reference tool named).
Source: docs/evidence/change-safety-retest-2026-09-12/README.md,
docs/evidence/change-safety-precise-2026-09-13/README.md.
efcore large-codebase scale trial (WP5.1)
A real 79,633-chunk corpus (the efcore repo, pinned a3381523, 5,773 .cs files),
ingested through production isolation checks (Qdrant's 49 collections unchanged before/after; the live
sources/current symlink untouched).
| metric | value | target |
|---|---|---|
| recall@5 | 0.950 | ≥ 0.80 ✅ |
| recall@1 | 0.825 | — |
| MRR | 0.8865 | — |
| latency p95 | 43.8 ms | ≤ 1.5 s ✅ |
| latency p50 | 32.2 ms | — |
| ingest wall-clock | 9.81 h | — |
| ingest cost | $49.44 ($0.000621/chunk) | — |
| RAM per 100k chunks | 1.543 GiB (Qdrant 1.229 GiB) | — |
Both Phase-5 gates (recall@5 and p95) were met. The precise lane was NOT measured in this trial — MSBuildWorkspace loaded 0 csprojs because efcore is unrestored and its pinned preview SDK is absent, and it failed silently at the time (the fail-loud fix landed the next day, #191).
Source: docs/evidence/efcore-trial-2026-09-12/RESULTS.md;
docs/LEDGER_SCALE_PLAN.md §10 (WP5.1 row) and §12.
Groq ingest cost per 100k chunks
From the efcore trial's own throughput: ≈ $62 per 100k fresh chunks, close to the
≈ $60 modelled independently in WP5.3's capacity plan before this trial ran.
Source: docs/LEDGER_SCALE_PLAN.md §12 ("Groq per 100k fresh chunks" row).
No new cost or turns claim exists yet
Superseded measurements
Four generations of headline have been published by this project, and three of them were wrong in a way that flattered the ledger. They stay on the page. A value page that quietly replaces its numbers is indistinguishable from one that invents them, and every figure below was retired for a reason that is itself worth knowing.
1 — “63.3% fewer tokens, cheaper on 20 of 20” (June 2026)
−63.3% tokens · ledger 41,406 vs direct 112,756 · 20/20
Why it was wrong: nobody ran two agents. A single session role-played
both paths and reported its own token usage — what the code still calls
BenchMethod.Estimated: “in-session subagent drain: self-reported usage, tool
separation not enforced”. Nothing stopped the “direct” path using what it had
already learned from the ledger path, and no prompt-caching economics applied to either. It measured
a story about two paths, not two paths.
No run artefact survives on disk; quoted from the recorded bench history. It is history, not evidence, and is not comparable with anything below.
2 — “91.6–93.7% fewer tokens, $2.7 against $26–34” (cold-API harness, runs 20260806T002520Z / 20260806T010417Z)
91.6–93.7% tokens · $2.69–2.75 vs $26.33–34.27 · 60–66% wall clock · 60 vs 261–289 turns
Why it was wrong: both sides of the comparison were rigged, without anyone
intending it. First, prompt caching was never switched on — it is opt-in, the
harness never set cache_control, and all four cache counters read zero. Input is where
the control's bill lives (98.7% of that arm's tokens), and input is exactly what caching discounts;
in real sessions both arms cache at ~100%. Second, the control was a deliberately stripped grep:
grep -rIn --max-count=20, output truncated at 6,000 characters, file reads at 12,000, a
fixed --include list, no ripgrep, no context lines, no globbing — which inflated
its turn count, and the turn count is the sole stated cause of the token and time gaps. Third, that
grep arm could read the benchmark's own answer key, and demonstrably did. The 1/18th-the-tokens
claim built on these runs is withdrawn in full.
Published in the previous revision of this page; recoverable from this file's git history. Re-measured on real sessions, the same 21 questions come out token-flat.
3 — “+7.0% fewer tokens”, then “−4.9%” (first real-session runs, 2026-08-06)
baseline −8.4% · trimmed +7.0% · full-tools −4.9%
Why they were wrong: two artefacts of the harness, and one whale.
The baseline snapshot ran with a broken tool gate that only the control arm bypassed. The
trimmed snapshot advertised a narrower tool surface than the full-tools one —
14 tools against the server's full list — which moved the headline 12 points by changing the
agent's tool choice, with nothing about the ledger changing at all. Worse,
both the trimmed and full-tools snapshots are mixed-run: their control arms come from run
20260806T055131Z and their ledger arms from 20260806T090845Z /
20260806T095156Z, every question with its two arms 3.3–4.0 h apart. The report
tool now prints NOT PUBLISHABLE — mixed-run comparison across the top of both
and refuses to post them. And all three are dominated by the same single question, which moves the
token headline 14.6–15.8 points on its own.
What those runs did establish, and what still stands, is the honest baseline the current result is measured against: on 2026-08-06 the ledger arm was not ahead — on the one snapshot with clean provenance it used 9.3 turns per question against the control's 8.8 and took 14.4% more wall clock. The 7.00 result a day later came from the schema-preload, span-first and inlining changes, not from a change of instrument.
All three snapshots survive and regenerate:
/tmp/real-bench-baseline, /tmp/real-bench-trimmed,
/tmp/real-bench-fulltools.
4 — the correctness claims, in order
“15 correct vs 1” · “9 vs 10 of 15” · “15–15 then 13–16”
Why they were wrong. “15 vs 1” counted truncated control paths as wrong answers rather than as never finished; once the control was allowed to complete it became 9 vs 10 and the advantage vanished. The 15–15 / 13–16 pair came from two identical configurations disagreeing by three questions, i.e. entirely within the noise of a single judge over 21 questions. The current quality figure is not a fourth attempt at the same measurement: it grades three times per answer, reports the judge's own sd, and separates the questions that have a written reference from the two that do not.
How the current run was made
- Two fresh sessions per question. One with the ledger MCP available, one without it and with the ordinary toolset. Real Claude Code sessions, real prompt caching — not a synthetic harness.
- Interleaved, single run id. Arms alternate which goes first, and every one of
the 42 session ids derives deterministically from
md5(qid-arm-RUN_ID), so a mixed-run comparison cannot be assembled by accident. The report refuses to publish if it finds one. - Arm isolation is checked, not assumed. 0 MCP calls appear in the control arm's transcripts against 177 in the ledger arm's.
- The tool surface is the trimmed one, and that must be said out loud. The ledger
arm was allowed the 14 ledger tools this build advertises — checked against the build's own
tools/listcapture, which returns exactly those 14 and no more — plusRead,GrepandGlob, the same file tools the control gets. That is the same 14-tool surface as the superseded trimmed snapshot below, not the wider surface of the full-tools one. (How much wider is not stamped in any artefact from that day; what is provable from the transcripts is that the wider runs reached at least one tool the 14 does not contain —reference_set, called once in each. The trim itself is a config flag on the same server, not a code deletion.) The surface is held constant across both arms inside this run, so it cannot manufacture the turn gap; but it is a limitation this run shares with that superseded setup rather than one that has been fixed, and a build advertising a different surface could measure differently. The criticism levelled at the trimmed snapshot below stands for the reason given there — the surface changed between snapshots and moved the headline 12 points with nothing about the ledger changing — not because 14 is the wrong number of tools. - One intervention is applied to the ledger arm only, deliberately. MCP tool
schemas are deferred by default, so the ledger arm used to spend its opening turn on a
ToolSearchcall to fetch them — a fixed startup tax on the only arm that has MCP tools at all. In the older run that is 24 such calls across 21 sessions, every session opening with one; the control, which loads no MCP server, made zero. Preloading the schemas removes it, and this run records 0. So of the 1.29 turns per question the ledger arm improved on its own earlier baseline, roughly 1.14 is that tax being removed rather than search getting better. The ledger-versus-control gap of 2.57 turns is a different comparison — the control never paid the tax — but anyone reading this page as “retrieval got much better overnight” is reading it wrong. - Turns are counted from the transcripts, deduplicated by message id — without that deduplication the same run reads 2.68× higher.
- Cost is aggregated per question, not as a total, with a bootstrap confidence interval, so a single long question cannot become the headline.
- Grading is separate, three-pass, and median-aggregated, against reference answers written by hand from the source tree rather than taken from the ledger's own output.
What this page does not establish
- That the ledger saves tokens or money. Both intervals span zero. On this evidence it is cost-neutral; it may be cheaper, and it may not be.
- A quality advantage at any useful confidence. 16 questions, one judge model, +0.044. It is the right direction and it is stable across grading schemes; it is not significance.
- Judge independence.
claude-opus-5gradingclaude-opus-5. - That six of the turns questions were clean. They were served the answer key; see above.
- Anything about a developer mid-task. Every question is one cold question in a fresh session. That is the measurable case, not the normal one, and a warm session with accumulated context may behave differently in either direction.
- That the questions are neutral ground. They were harvested from what agents actually asked the ledger, so the sample is selected on the ledger's own turf.
- A retrieval improvement from the corpus change. Method-level chunking took the corpus past 23,000 chunks at full enrichment coverage, and golden-set recall landed at parity, not ahead — see the retrieval tuning log.
The full experiment log — every trial, its plan, its result and its corrections — is in
docs/REINGEST_TRIALS.md in the repository. The retrieval-side measurements are on the
retrieval tuning log.
Open Brain — the MOTMaster Architectural Ledger · measured value · turns and cost
from run 20260807T144905Z, quality from the graded 2026-08-06 session answers,
instruments from ledger-baselines/runs · page rewritten 2026-08-09