CB-WP-0027 T05: evidence — and the one question this file cannot answer
CB-EV-0025. T05 asks whether a comment actually got written during play,
unprompted. It has not been, and that is the pass's real acceptance test.
Everything built here is evidence the mechanism works; none of it is
evidence it gets used. I exercised it myself, which proves the plumbing
and proves nothing about the ergonomics -- the person who wrote the
feature is the worst possible witness to whether it is worth using.
Stated plainly rather than answered optimistically, because CB-WP-0022
built a register whose first run found ten answers nobody had collected:
this project's failures are about whether things get READ.
ADR-0007 D5 turned out to be the easy part. PointerFact::parse already
refuses any unrecognised field, so a comment could not reach the command
path even by accident. That is strictness at a boundary paying off years
early, and the clearest instance in this project of it being cheaper than
vigilance across one.
esc() held against its first hostile input, and the test asserts the
harder half: the player's words are still READABLE after escaping. An
escaper that dropped the text would pass "no script tag in the output"
while destroying the note.
The reflow cost no coverage probe -- all 41 pre-existing render tests
passed through a full restructure into two columns. CB-WP-0024 saw the
opposite when a probe was tied to a rendering ("17 remaining"), and the
contrast is the useful part: a probe that names a FACT survives a reflow,
a probe that names a PRESENTATION does not.
Running it changed the design for the third pass running, after
CB-WP-0024's role column and CB-WP-0025's K=2 infeasibility. The pattern
is consistent enough to state: the ADRs in this project are good at
deciding and poor at predicting, and the loop's value comes
disproportionately from the code loop rather than from steps 1-3.
Chaos window 2 closes with zero overrides in twelve declarations, so its
retirement condition is untestable -- final now rather than projected. The
window's verdict should be that d8 made the mechanism unevaluable.
Also recorded rather than dismissed: make all failed once at env-test and
passed on re-run. A cb-play server and several cargo processes were
running concurrently, which is the likely cause -- but "likely" is doing
work in that sentence and I did not chase it. A gate that fails
intermittently and is re-run until green is a gate being trained not to
matter.
Not built, and named: promoting a comment to a register note is still
manual.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:39:12 +02:00
|
|
|
|
# CB-EV-0025 — the commentary track
|
|
|
|
|
|
|
|
|
|
|
|
CB-WP-0027 T05. Tier M (structural M — touches ADR-0007 D5's input
|
|
|
|
|
|
contract and the recorded-session format; chaos d8=7 → no override).
|
|
|
|
|
|
Declaration 10 of chaos window 2. Closed 2026-08-06.
|
|
|
|
|
|
|
|
|
|
|
|
**Delivered:** [ADR-0014](../decisions/ADR-0014-the-commentary-track.md),
|
|
|
|
|
|
a two-column page, a `/note` channel, `trials/<date>-<slug>.md`,
|
|
|
|
|
|
`tools/trials.py`, `make trials`, and `--trial` on `cb-play`.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. The question this file cannot answer
|
|
|
|
|
|
|
|
|
|
|
|
**T05 asks whether a comment actually got written during play, by the
|
|
|
|
|
|
maintainer, unprompted.** It has not been asked yet, and **that is the
|
|
|
|
|
|
pass's real acceptance test, not any of the tests below.**
|
|
|
|
|
|
|
|
|
|
|
|
The protocol's own claim is that it must cost almost nothing or it will
|
|
|
|
|
|
not be done. Everything here is evidence that the mechanism *works*;
|
|
|
|
|
|
none of it is evidence that it *gets used*. I exercised it myself, which
|
|
|
|
|
|
proves the plumbing and proves nothing about the ergonomics — the person
|
|
|
|
|
|
who wrote the feature is the worst possible witness to whether it is
|
|
|
|
|
|
worth using.
|
|
|
|
|
|
|
|
|
|
|
|
**Stated plainly rather than answered optimistically**, because
|
|
|
|
|
|
CB-WP-0022 built a register whose first run found ten answers nobody had
|
|
|
|
|
|
collected: this project's failures are about whether things get *read*,
|
|
|
|
|
|
not whether they get *built*.
|
|
|
|
|
|
|
|
|
|
|
|
## 2. What ADR-0007 D5 turned out to be
|
|
|
|
|
|
|
|
|
|
|
|
The workplan expected D5 — *JavaScript may not construct commands* — to
|
|
|
|
|
|
be the hard part. It was the easy part, for a reason worth recording:
|
|
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
|
_ => return Err(format!("unrecognised field in pointer fact: {pair:?}")),
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**`PointerFact::parse` refuses any unrecognised field**, so a comment
|
|
|
|
|
|
could not reach the command path even by accident. A parser that ignored
|
|
|
|
|
|
what it did not understand would have made this a real decision; one that
|
|
|
|
|
|
refuses made it a non-event.
|
|
|
|
|
|
|
|
|
|
|
|
**That is a control paying off two years of maintenance early**, and it is
|
|
|
|
|
|
the clearest instance in this project of strictness at a boundary being
|
|
|
|
|
|
cheaper than vigilance across one. D5 is **scoped, not amended**: the
|
|
|
|
|
|
command channel is untouched, and the note channel is a second one that
|
|
|
|
|
|
cannot become the first because `resolve` takes a `PointerFact` and
|
|
|
|
|
|
nothing converts a `Note` into one.
|
|
|
|
|
|
|
|
|
|
|
|
**The test asserts it anyway**, with a note whose text is a well-formed
|
|
|
|
|
|
pointer fact — because "the types don't connect" is a claim about code
|
|
|
|
|
|
layout until something checks the behaviour, and the inverse is asserted
|
|
|
|
|
|
too so the test is not vacuous.
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Running it changed the design, again
|
|
|
|
|
|
|
|
|
|
|
|
`make trials`'s first version called **any note without a recording an
|
|
|
|
|
|
orphan**. A recording is only written when the game ends, so **every note
|
|
|
|
|
|
in a live session reported as broken.**
|
|
|
|
|
|
|
|
|
|
|
|
A metric that cries wolf is one nobody reads — **which is the exact
|
|
|
|
|
|
failure this pass exists to prevent**, reproduced inside the tool built to
|
|
|
|
|
|
prevent it. Now three states: `ok`, `pending` (no recording yet), `orphan`
|
|
|
|
|
|
(the recording exists and the position is not in it). Only the third has a
|
|
|
|
|
|
target of zero.
|
|
|
|
|
|
|
|
|
|
|
|
**This is the third pass running where building or running the thing found
|
|
|
|
|
|
something the design did not.** CB-WP-0024's `role` column, CB-WP-0025's
|
|
|
|
|
|
`K=2` infeasibility, and this. The pattern is consistent enough to state:
|
|
|
|
|
|
**the ADRs in this project are good at deciding and poor at predicting**,
|
|
|
|
|
|
and the loop's value comes disproportionately from the code loop rather
|
|
|
|
|
|
than from steps 1–3.
|
|
|
|
|
|
|
|
|
|
|
|
## 4. A latent defect surfaced by a name collision
|
|
|
|
|
|
|
|
|
|
|
|
`make trials` did nothing. `trials` is also a *directory*, so Make saw an
|
|
|
|
|
|
up-to-date file and ran the recipe not at all.
|
|
|
|
|
|
|
|
|
|
|
|
Checking `.PHONY` found that **`design`, `difficulty` and `trials` — added
|
|
|
|
|
|
by CB-WP-0022, CB-WP-0025 and this pass — were all missing from it.** Two
|
|
|
|
|
|
of them work by luck: no file happens to share their name.
|
|
|
|
|
|
|
|
|
|
|
|
**Three passes added a target and none added it to `.PHONY`**, which is a
|
|
|
|
|
|
process observation rather than a bug: the Makefile has no control that a
|
|
|
|
|
|
new target is declared, and the failure is silent until a name collides.
|
|
|
|
|
|
Not fixed beyond declaring the three, because a gate for this would cost
|
|
|
|
|
|
more than it catches — but it is the kind of thing that is invisible until
|
|
|
|
|
|
it is not.
|
|
|
|
|
|
|
|
|
|
|
|
## 5. What the escaping test found
|
|
|
|
|
|
|
|
|
|
|
|
`esc()` has escaped suit names since CB-WP-0012. This is the first
|
|
|
|
|
|
user-authored free text the renderer has handled, and the source comment
|
|
|
|
|
|
— *"cannot currently carry a `<`" is how injection bugs are written* — was
|
|
|
|
|
|
written in anticipation of exactly this.
|
|
|
|
|
|
|
|
|
|
|
|
It held. `<script>alert(1)</script>` renders escaped.
|
|
|
|
|
|
|
|
|
|
|
|
**The test asserts something the obvious version would miss:** that the
|
|
|
|
|
|
player's words are *still readable* afterwards. An escaper that dropped
|
|
|
|
|
|
the text would pass "no script tag in the output" while destroying the
|
|
|
|
|
|
note. Escaping that eats what someone wrote is its own defect, and only
|
|
|
|
|
|
the positive half of the assertion catches it.
|
|
|
|
|
|
|
|
|
|
|
|
## 6. Coverage cost of the reflow
|
|
|
|
|
|
|
|
|
|
|
|
**None.** All 41 pre-existing `cb-render-html` tests passed unchanged
|
|
|
|
|
|
through a full restructure of the document into two columns, including the
|
|
|
|
|
|
coverage gate that asserts every view field appears in the *parsed*
|
|
|
|
|
|
document.
|
|
|
|
|
|
|
|
|
|
|
|
**That is a stronger result than it looks.** The gate is coupled to
|
|
|
|
|
|
tokens, not to layout — so moving every element into new containers did
|
|
|
|
|
|
not disturb it. CB-WP-0024 saw the opposite when a probe was tied to a
|
|
|
|
|
|
rendering (`17 remaining`), and the contrast is the useful part: **a probe
|
|
|
|
|
|
that names a fact survives a reflow; a probe that names a presentation
|
|
|
|
|
|
does not.**
|
|
|
|
|
|
|
|
|
|
|
|
## 7. Chaos window 2
|
|
|
|
|
|
|
ADR-0017: window 2's verdict — the mechanism worked, my account of it did
not
Tier M (changes how the loop constrains its own operation), declared at
d8 because the rate for window 3 is what this document decides and
declaring at a rate it invents would be circular. chaos d8 = 7, no
override.
I CLAIMED WINDOW 2 PRODUCED ZERO OVERRIDES, FIVE TIMES, AND IT IS FALSE.
Declaration 3 (CB-WP-0020) rolled d8 = 8, overrode, drew S against a
structural S, and changed nothing -- and CB-WP-0020 recorded it correctly
at the time, in those words: "the first override at d8... It changed
nothing... One."
Counting the workplans takes one command and I never ran it. CB-EV-0024
asserted "zero" without checking; CB-EV-0025, 0026, 0027 and CB-WP-0029
each cited the one before. A claim propagated five times by citation
rather than by measurement, in files whose subject was that exact failure.
facts-check catches a copied number that disagrees with its source;
nothing catches a number with NO source, asserted once and repeated.
Registered F23, and all four evidence files carry an in-place correction
rather than a silent edit (ADR-0012 D5).
THE ACTUAL VERDICT: THE RATE IS WORKING. Eleven rolls at d8 -- declaration
1 opened the window at the old d4 -- against 1.375 eights expected, 1
observed. Not a shortage of evidence; the design.
BUT THE RETIREMENT CONDITION GENUINELY CANNOT FIRE, and that took
computing to see. "An override changes nothing twice running" needs a
consecutive pair at P=1/3 each, so ~12 overrides expected, at ~1.4 per
window: ~9 windows, roughly 100 declarations. A gate that cannot cash out
on any realistic horizon is decoration, which ADR-0006 D3 forbids.
Restated to be evaluated PER WINDOW: retire if a full window's overrides
all change nothing, met in two consecutive windows. A window with no
overrides is inconclusive and advances nothing. ~24 declarations rather
than ~100. Window 2 counts as the first; window 3 opens at d8 and decides.
Recorded and deliberately not acted on: declarations 5-9 rolled six five
times running, ~1 in 370 for some run of five in eleven rolls. shuf tested
over 200 rapid successive calls looks uniform, longest run three. Found
post hoc, which is how coincidences become findings, so it is logged for a
future window to check rather than treated as evidence.
InnerLoop.md then crossed the loadability limit, and so did
InnerLoopReference.md. The window log moved to specs/ChaosRollHistory.md:
it grows by one entry per window, and a log inside a reference eventually
crowds out the reference.
make all: exit 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:55:54 +02:00
|
|
|
|
> **CORRECTED 2026-08-07 — this section is wrong.**
|
|
|
|
|
|
> Window 2 produced **one** override: declaration 3 (CB-WP-0020) rolled
|
|
|
|
|
|
> d8 = 8, drew S against a structural S, and **changed nothing** — which
|
|
|
|
|
|
> CB-WP-0020 recorded correctly at the time as *"One."* Eleven rolls at d8
|
|
|
|
|
|
> (declaration 1 opened the window at d4) against an expectation of 1.375
|
|
|
|
|
|
> eights. **The rate was working; I asserted "zero" without counting, and
|
|
|
|
|
|
> each later evidence file cited the one before it.**
|
|
|
|
|
|
> See [ADR-0017](../decisions/ADR-0017-chaos-window-2-verdict.md) and F23.
|
|
|
|
|
|
|
CB-WP-0027 T05: evidence — and the one question this file cannot answer
CB-EV-0025. T05 asks whether a comment actually got written during play,
unprompted. It has not been, and that is the pass's real acceptance test.
Everything built here is evidence the mechanism works; none of it is
evidence it gets used. I exercised it myself, which proves the plumbing
and proves nothing about the ergonomics -- the person who wrote the
feature is the worst possible witness to whether it is worth using.
Stated plainly rather than answered optimistically, because CB-WP-0022
built a register whose first run found ten answers nobody had collected:
this project's failures are about whether things get READ.
ADR-0007 D5 turned out to be the easy part. PointerFact::parse already
refuses any unrecognised field, so a comment could not reach the command
path even by accident. That is strictness at a boundary paying off years
early, and the clearest instance in this project of it being cheaper than
vigilance across one.
esc() held against its first hostile input, and the test asserts the
harder half: the player's words are still READABLE after escaping. An
escaper that dropped the text would pass "no script tag in the output"
while destroying the note.
The reflow cost no coverage probe -- all 41 pre-existing render tests
passed through a full restructure into two columns. CB-WP-0024 saw the
opposite when a probe was tied to a rendering ("17 remaining"), and the
contrast is the useful part: a probe that names a FACT survives a reflow,
a probe that names a PRESENTATION does not.
Running it changed the design for the third pass running, after
CB-WP-0024's role column and CB-WP-0025's K=2 infeasibility. The pattern
is consistent enough to state: the ADRs in this project are good at
deciding and poor at predicting, and the loop's value comes
disproportionately from the code loop rather than from steps 1-3.
Chaos window 2 closes with zero overrides in twelve declarations, so its
retirement condition is untestable -- final now rather than projected. The
window's verdict should be that d8 made the mechanism unevaluable.
Also recorded rather than dismissed: make all failed once at env-test and
passed on re-run. A cb-play server and several cargo processes were
running concurrently, which is the likely cause -- but "likely" is doing
work in that sentence and I did not chase it. A gate that fails
intermittently and is re-run until green is a gate being trained not to
matter.
Not built, and named: promoting a comment to a register note is still
manual.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:39:12 +02:00
|
|
|
|
**Declaration 10 of 12.** Structural M, d8 = 7, no override.
|
|
|
|
|
|
|
|
|
|
|
|
**Twelve declarations, no 8 rolled**, so the window closes with **zero
|
|
|
|
|
|
overrides** and its retirement condition — *retire if an override changes
|
|
|
|
|
|
nothing twice running* — is untestable. CB-EV-0024 §6 said this; it is now
|
|
|
|
|
|
final rather than projected.
|
|
|
|
|
|
|
|
|
|
|
|
**The window's own verdict should be that d8 made the mechanism
|
|
|
|
|
|
unevaluable**, and that the choice was between a rate that produces
|
|
|
|
|
|
evidence and a rate that produces rarity. Window 1 at d4 produced two
|
|
|
|
|
|
overrides and both changed the outcome; window 2 at d8 produced none.
|
|
|
|
|
|
|
|
|
|
|
|
## 8. One flaky gate, reported rather than dismissed
|
|
|
|
|
|
|
|
|
|
|
|
`make all` failed once at `env-test` and passed on re-run with zero
|
|
|
|
|
|
failures. A `cb-play` server and several `cargo` processes were running
|
|
|
|
|
|
concurrently during the failing run, which is the likely cause — but
|
|
|
|
|
|
**"likely" is doing work in that sentence and I did not chase it.**
|
|
|
|
|
|
|
|
|
|
|
|
Recorded because a gate that fails intermittently and is re-run until
|
|
|
|
|
|
green is a gate being trained not to matter, and this project has enough
|
|
|
|
|
|
instances of that class already.
|
|
|
|
|
|
|
|
|
|
|
|
## Open after this pass
|
|
|
|
|
|
|
|
|
|
|
|
- **Nobody has used it yet** (§1). Until a note is written in anger, the
|
|
|
|
|
|
ergonomic claim is unsupported.
|
|
|
|
|
|
- **Promotion is manual.** ADR-0014 D5 says a comment becomes a register
|
|
|
|
|
|
note by a human's judgement, and T04 reports comments but does not
|
|
|
|
|
|
offer a one-step promotion. That was in the workplan's controls and is
|
|
|
|
|
|
the part not built.
|
|
|
|
|
|
- **The narrow-viewport rule is asserted on the stylesheet**, not on a
|
|
|
|
|
|
layout. There is no browser in the test harness that can measure a
|
|
|
|
|
|
reflow, and saying the assertion is weaker than the claim is the honest
|
|
|
|
|
|
position.
|
|
|
|
|
|
- **The flaky `env-test`** (§8) has no explanation, only a plausible one.
|