Scope cut first, on the maintainer's decision after a spend review: the project is 38% product / 62% loop-meta, cost per response is 2.9x worse than its best window, and INTENT stage 0 still lacks a CLI player and bots. CB-WP-0005 and CB-WP-0006 cost ~$74 — 31% of all spend — for zero measured efficiency gain. T02 and T04 are cancelled unstarted. T01: SH-1/SH-2/SH-3 now report over the window since the last commit, and the cumulative figure is retained but labelled "history, NOT the metric". The prediction held decisively — window 655,744 mean context against cumulative 255,307, a 2.6x gap against a 20% refutation threshold. A cumulative mean over 1,094 responses cannot detect a worsening trend because the history outvotes the present. T03: `make shape-budget`, modelled on CB-01/CB-02. Soft thresholds are the existing SessionShape targets; hard is 1.5x, set before the next measurement per §Step 4. Deliberately not in `make all` — failing the build on context would block committing, and committing is what closes the attribution window and is the natural point to compact, so a gate that blocks the remedy is a trap. It fires HARD on its first run: 656,574 against a 300,000 ceiling. InnerLoop v1.5 establishes the soft 25% meta budget. Workplans declare kind: product|meta|mixed and `make status` reports the share; mixed splits 50/50 and says so. Soft on purpose — a task already started may be finished, because stopping mid-task to satisfy a ratio wastes the work. What it forbids is opening new meta work above the line. A pass that exceeds it must say so in its evidence and name the product work displaced. First reading: 68% OVER, of $74.22 attributed. Product reads $0.00 because the only product workplan, CB-WP-0001, predates qualified task ids and its bare T## labels collide across passes — stated in the output rather than papered over. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
310 lines
13 KiB
Markdown
310 lines
13 KiB
Markdown
---
|
||
id: CB-WP-0006
|
||
kind: mixed
|
||
title: "Instrument the acceptance table, then implement what it exposes"
|
||
status: done
|
||
state_hub_workstream_id: "8a6327cc-fd5c-4e2c-a29b-b437c27d1e71"
|
||
---
|
||
|
||
# Purpose
|
||
|
||
CB-WP-0005 T02 measured M-D1-MUT for the first time:
|
||
|
||
```text
|
||
M-D1-MUT: 4/14 rows enforced
|
||
PARTIAL 2 (AM-7, AM-8 — some clauses live, some inert)
|
||
unmutatable 8 (no property to invert)
|
||
```
|
||
|
||
**4 of 14, against a predicted 10 of 14.** The prediction was wrong by
|
||
2.5×, and wrong about *what* as well as *how much*: CB-RES-0004 diagnosed
|
||
three absent kernel rules, and the measurement found that **more than half
|
||
the acceptance table has no instrument behind it at all**.
|
||
|
||
CB-WP-0005 Phase C was deferred before starting on that basis (T02's stop
|
||
condition, maintainer decision 2026-07-31). It was scoped to five rules —
|
||
K9, K10, K11, K14, K18 — which does not address the eight.
|
||
|
||
This workplan is scoped to what was measured rather than what was
|
||
predicted. **Phase A instruments the unmeasured rows; Phase B implements
|
||
the kernel work inherited from CB-WP-0005 T04–T06.** That order is the
|
||
whole point: the previous pass built a fix before its instrument existed,
|
||
and the instrument then contradicted the fix's premise.
|
||
|
||
Per InnerLoop §Step 4, no target moves in the commit that measures it.
|
||
|
||
## Phase A — instrument the rows that measure nothing
|
||
|
||
## Task: AM-6 — assert the throughput target
|
||
|
||
```task
|
||
id: CB-WP-0006-T01
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "a4513794-2f5f-480c-be30-56658711796f"
|
||
```
|
||
|
||
The sharpest single finding of CB-WP-0005. **Nothing in the workspace
|
||
compares any number to 100,000 events/s** — the project's headline
|
||
throughput claim, reported as `met, 16.5×`. The Criterion bench emits
|
||
throughput; the only asserts in `synthetic.rs` are the stress-gate shape
|
||
and the events-per-round pin.
|
||
|
||
Deliver a standing assertion — a test, not a bench — that measures applied
|
||
events/s on the synthetic workload and fails below the AM-6 target.
|
||
|
||
**The trap, stated up front:** a timing assertion in CI is flaky by
|
||
nature, and the usual response is to loosen it until it never fires, which
|
||
would reproduce exactly the defect being fixed. So the threshold is
|
||
**pinned well below the measured 1.65M/s** (AM-6 asks for 100k), the
|
||
assertion states its own headroom in the failure message, and a loosening
|
||
requires an ADR. A gate tuned until it cannot fire is a gate that counts
|
||
names.
|
||
|
||
**Verified by:** `make mutation-check --row AM-6` goes from `unmutatable`
|
||
to `red`.
|
||
|
||
**Delivered** — see [the delivery log](../history/260801-cb-wp-0006-log.md#cb-wp-0006-t01).
|
||
|
||
## Task: AM-2, AM-3 — instrument the size metrics
|
||
|
||
```task
|
||
id: CB-WP-0006-T02
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "d1572a4f-46e5-49dd-b1ec-7c371a780bb7"
|
||
```
|
||
|
||
AM-2 (≤40 spec lines per rule) and AM-3 (≤50 LOC for the synthetic
|
||
workload) are both `unmutatable` for the same reason: `make loc` prints
|
||
line counts and nothing divides, compares, or gates.
|
||
|
||
AM-2 is the **anti-gaming pair** for AM-1 — 100% rule coverage means
|
||
nothing if the rules are trivially small — so an uninstrumented AM-2
|
||
leaves AM-1 gameable, which is the specific risk MetricsAndScenarios §1
|
||
names when it introduces M-D1-SPL.
|
||
|
||
AM-3 depends on K18 (benches driven from scenario files); if K18 resolves
|
||
toward amending the spec rather than implementing it, AM-3 must be
|
||
restated or withdrawn with an argument rather than left unmeasured.
|
||
|
||
**Delivered** — see [the delivery log](../history/260801-cb-wp-0006-log.md#cb-wp-0006-t02).
|
||
|
||
## Task: AM-5, AM-9 — measure or withdraw, but stop leaving them blank
|
||
|
||
```task
|
||
id: CB-WP-0006-T03
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "6c84a220-cab3-40f1-b35f-b8df79106f6e"
|
||
```
|
||
|
||
AM-5 (clean build ≤60 s) is `recorded not gated` — and not recorded
|
||
either. AM-9 (peak RSS ≤64 MB) is declared "very unlikely to bind", which
|
||
CB-EV-0001 itself calls out as an unmeasured judgment call.
|
||
|
||
Both are cheap to measure: one `time` around a clean build, one
|
||
`/usr/bin/time -v` around the 100k-event run. **Or withdraw them with an
|
||
argument**, which is a legitimate outcome and possibly the right one for
|
||
AM-5 on a machine-dependent number. What is not legitimate is a third pass
|
||
leaving them blank while the scoreboard reports elsewhere.
|
||
|
||
**Delivered** — see [the delivery log](../history/260801-cb-wp-0006-log.md#cb-wp-0006-t03).
|
||
|
||
## Task: AM-4c — target it or drop it
|
||
|
||
```task
|
||
id: CB-WP-0006-T04
|
||
status: done
|
||
priority: low
|
||
state_hub_task_id: "a2571314-4c02-41cf-9473-96d3ae2d7b2b"
|
||
```
|
||
|
||
`reported, not targeted`, so there is no property to invert and it counts
|
||
against M-D1-MUT by ADR-0005 §1.
|
||
|
||
Two honest options, and the task must pick one with an argument: give it a
|
||
threshold (making it enforceable), or **remove it from the acceptance
|
||
table** and keep it as a reported diagnostic. A row in an acceptance table
|
||
that cannot fail is decoration, and this pass has learned to say so.
|
||
|
||
Note the incentive: ADR-0005 already predicts own-source growth from the
|
||
kernel work in Phase B, so AM-4c will move against us. Setting its
|
||
threshold *after* seeing that movement would be the retarget InnerLoop
|
||
§Step 4 forbids — so it is set here, before Phase B, or not at all.
|
||
|
||
**Delivered** — see [the delivery log](../history/260801-cb-wp-0006-log.md#cb-wp-0006-t04).
|
||
|
||
## Phase B — the kernel work inherited from CB-WP-0005
|
||
|
||
> These three were written in [CB-WP-0005](CB-WP-0005-assertion-coverage.md)
|
||
> Phase C and cancelled unstarted. Their analysis lives **here**, next to
|
||
> the work — CB-WP-0005 keeps only a forward pointer, so there is one copy.
|
||
> The normative controls are in
|
||
> [ADR-0005](../decisions/ADR-0005-assertion-coverage-and-replay.md) §6.
|
||
|
||
## Task: K9 and K11 — durable log, LogStore port, real conformance suite
|
||
|
||
```task
|
||
id: CB-WP-0006-T05
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "2a357dbf-3861-499d-a12e-f7682b7332f6"
|
||
```
|
||
|
||
**K9** — the acceptance property is *snapshot at seq N + events N+1..M ≡
|
||
genesis fold*, hash-compared, on `GroundState`. What exists instead is one
|
||
test round-tripping a `BTreeMap<String, u8>` with `EventSeq(17)` as a
|
||
literal: no game aggregate, no events applied, no from-genesis comparison.
|
||
Mutation-proven — making `Snapshot::take` discard its `EventSeq` leaves the
|
||
test green, so the half of K9 that says "+ the EventId it includes" is
|
||
unverified. `Snapshot` has no callers outside its own test.
|
||
|
||
**K11** — append-only, length-prefixed, versioned framing, with a truncated
|
||
tail **detected**; the operative clause is *detection*, so truncate-by-one-
|
||
byte and corrupt-length-prefix rejection are required, not optional.
|
||
Reimplemented rather than assimilated (ADR-0005 §2): ~100 lines against a
|
||
format Kafka and EventStore converged on independently, adding no
|
||
dependency, charged to **AM-4a** (shipped runtime, 1.5% headroom). The `LogStore` port with a shared
|
||
`fn conformance<S: LogStore>(…)`, retro-fitted to `KernelRng`, is what
|
||
finally earns **AM-11** — currently downgraded to unmet because the pair
|
||
exists and the suite does not.
|
||
|
||
**Verified by:** `make mutation-check --row AM-11` goes from
|
||
`unmutatable` to `red`.
|
||
|
||
## Task: K10 — the replay bundle and `--replay`
|
||
|
||
```task
|
||
id: CB-WP-0006-T06
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "d459444d-41be-40c5-9101-7a8420b42fb6"
|
||
```
|
||
|
||
INTENT design decision 8 of 10, unimplemented. `cb-sim` has no flag
|
||
parsing at all, so `--replay` has nowhere to go yet.
|
||
|
||
**This is not "a directory of four files"** — the D2 correction the
|
||
adversarial review forced. `scenario.rs` creates an `EventLog`, appends to
|
||
it and never reads it: the one production instantiation of the K11 log is a
|
||
write-only sink. `Pass` carries the *end* state, not an initial snapshot,
|
||
and failures are a formatted `String`, not structured expected-vs-actual.
|
||
Plumb the log out of `execute`, capture an initial snapshot, restructure
|
||
`RunOutcome::Failed`. The writer is **dev-only** behind the `scenarios`
|
||
feature and is charged to **AM-4b** (9.4% headroom), not AM-4a.
|
||
|
||
All four controls from ADR-0005 §6 are required verbatim, including the two
|
||
the reviewer supplied: truncate-by-one-byte rejection, and a mutated-seed
|
||
control so the round-trip is capable of failing.
|
||
|
||
Fixing this is also what lets **AM-7's withdrawn `hash-identical`
|
||
clause** be re-earned, since a real replay is what the clause was always
|
||
about.
|
||
|
||
## Task: K14 and K18 — implement, or amend the spec and say why
|
||
|
||
```task
|
||
id: CB-WP-0006-T07
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "d76ad893-520b-44bd-9b77-07dbfb651ce3"
|
||
```
|
||
|
||
Inherited from CB-WP-0005 T06. `CommitWindow` has zero non-test users;
|
||
the bench never touches `ScenarioFile`. Either wire them up or amend the
|
||
rules with a recorded argument. Deleting a rule to make a gate green is
|
||
forbidden; deleting one *with an argument* is legitimate and probably
|
||
right for K18.
|
||
|
||
## Phase C — measure, and answer the question this pass inherited
|
||
|
||
## Task: control loop — M-D1-MUT before and after
|
||
|
||
```task
|
||
id: CB-WP-0006-T08
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "1d4455c3-c642-47d8-916b-ab35bc512207"
|
||
```
|
||
|
||
Commit `evidence/CB-EV-0005` — **numbering corrected**, CB-EV-0004 was
|
||
already CB-WP-0005's. The baseline is **4 of 14**, committed and
|
||
reproducible via `make mutation-check`.
|
||
|
||
**Measured — [CB-EV-0005](../evidence/CB-EV-0005-instrument-the-table.md).
|
||
4 of 14 → 8 of 14** (8 of 10 enforceable; the 14 stays the headline and
|
||
AM-4c stays in it on purpose). Kernel link 15/18 → **18/18**, names only.
|
||
One row regressed to `SURVIVED` and was caught. **0 vacuous expects**
|
||
across 14 rows — test 3 is now mechanical, via a new `EXPECT-VACUOUS`
|
||
verdict. **The cost result refutes the pass:** mechanical share rose to
|
||
**50%**, the highest recorded.
|
||
|
||
Three tests, all reported:
|
||
|
||
1. **Did the enforced count rise, per row?** Against the per-task
|
||
predictions above, unmet reported as unmet.
|
||
2. **Did any row regress from `red` to `SURVIVED`?** The four currently
|
||
enforced rows are the ones with something to lose.
|
||
3. **Were the new mutations strong?** CB-WP-0005 T02 wrote two no-op
|
||
mutations on its first attempt, either of which would have published a
|
||
false accusation against working code. Every mutation added by this
|
||
pass must be shown to fail for the *stated* reason — record how that
|
||
was checked.
|
||
|
||
## Task: retrospective — is a weak mutation the new grep?
|
||
|
||
```task
|
||
id: CB-WP-0006-T09
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "4f291d5a-90f0-4f1f-bcaf-7ec28856bfcf"
|
||
```
|
||
|
||
The question CB-WP-0005 T08 raised and this pass is positioned to answer.
|
||
|
||
CB-WP-0004 concluded that tooling recovers capacity only where it removes
|
||
the manual path. M-D1-MUT does **not** remove a manual path — writing a
|
||
weak mutation is exactly as easy as writing a strong one, and the harness
|
||
cannot tell the difference. CB-WP-0005 produced two no-op mutations on its
|
||
first attempt, so the failure mode is demonstrated, not hypothetical.
|
||
|
||
**And it fails in the more dangerous direction:** a weak mutation does not
|
||
merely miss a defect, it *indicts working code*. A false `SURVIVED` sends
|
||
the next pass to fix something that is not broken.
|
||
|
||
So: is M-D1-MUT a real instrument, or a name-counter with extra steps? If
|
||
the latter, say so and propose what would actually bind — the candidate
|
||
being that the mutation must be written by someone other than the author
|
||
of the assertion, which is the adversarial-review principle applied one
|
||
level down.
|
||
|
||
**Answered — [260801-instrument-the-table-retrospective.md](../history/260801-instrument-the-table-retrospective.md).**
|
||
|
||
**A real instrument — but only because it was hardened three times in one
|
||
pass.** Five controls now stand between a mutation and a `red` verdict,
|
||
and every one exists because its failure actually occurred. The
|
||
generalizable finding: **an instrument that measures whether other
|
||
instruments work needs more controls than the instruments it measures** —
|
||
M-D1-MUT carries five, `dep-weight` and `rule-coverage` carry one each.
|
||
|
||
**A worse failure mode than predicted:** a mutation can become weak
|
||
**without anyone touching it**. AM-6's went `SURVIVED` when T04 moved its
|
||
gate from debug to release. Mutation strength is coupled to measurement
|
||
conditions, so a mutation is not a write-once artifact. CB-WP-0005 T08's
|
||
stronger remedy — mutations written by someone other than the author —
|
||
was **not tested** and should not be assumed unnecessary: `EXPECT-VACUOUS`
|
||
covers the cheap failure, not the expensive one AM-6 demonstrated.
|
||
|
||
**Prediction error collapsed** — 4–5×, then 2.5×, now small — because this
|
||
pass predicted **per task, as a mechanism, with the alternative named**.
|
||
Both branches are outcomes someone must defend, so the prediction cannot
|
||
be dodged; AM-3 and AM-4c took the second branch and are better resolved
|
||
for it.
|
||
|
||
**No InnerLoop change.** v1.4's mutation requirement is one pass old and
|
||
changing it before a second use would be the invention-in-isolation INTENT
|
||
warns about — the same argument used to amend K14. **The named next
|
||
candidate is `specs/SessionShape.md`**: SS-01…SS-05 have never been
|
||
enforced, and this pass ran at **2.5× the context ceiling its own spec
|
||
sets** without anything saying a word.
|