Some checks failed
ci / check (push) Failing after 4s
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>
389 lines
19 KiB
Markdown
389 lines
19 KiB
Markdown
# The Inner Loop — Reference
|
||
|
||
Normative companion to **[InnerLoop.md](InnerLoop.md)**, which holds the
|
||
five steps, the tiers, and the chaos roll. Split from it on 2026-07-31 so
|
||
both files stay under the loop's own whole-file loadability limit.
|
||
|
||
Everything here binds exactly as the process document does.
|
||
|
||
## The four-dimension rubric
|
||
|
||
Every survey, ADR, and acceptance table is organized by these dimensions:
|
||
|
||
| Dimension | Question | Example measurable proxies |
|
||
|---|---|---|
|
||
| **D1 Ease of specification** | How simply can behavior be stated, tested, understood? | rules-to-scenario coverage %, spec lines per rule, time-to-first-correct-scenario for a fresh agent session |
|
||
| **D2 Efficiency of implementation** | How cheap to build and keep building? | source LOC, dependency count/weight, clean-build and incremental-build time, tokens-per-completed-task |
|
||
| **D3 Speed of execution** | How fast does it run? | benchmark wall-time vs baseline, events/sec, memory footprint, determinism overhead |
|
||
| **D4 Optionality** | How cleanly does it integrate, extend, get replaced? | public API surface size, count of leaked foreign types (must be 0), effort-to-swap measured by null/reference impl existence, WIT-expressibility |
|
||
|
||
Scoring is always **relative to the step-1 baseline**, never absolute:
|
||
`better / parity / worse / unmeasured` per proxy, with the number attached.
|
||
`unmeasured` is legal in a survey, illegal in an evidence file.
|
||
|
||
---
|
||
|
||
## Survey template (research/CB-RES-NNNN-<slug>.md)
|
||
|
||
```markdown
|
||
# CB-RES-NNNN: <capability>
|
||
capability: <canonical.capability.id>
|
||
status: draft | approved
|
||
|
||
## Candidates
|
||
Per candidate: origin, license, maturity, adoption; data model; mutation
|
||
mechanism; determinism/replay story; relevant performance (measured if
|
||
runnable locally, cited with source otherwise).
|
||
|
||
## Baselines (benchmark-to-beat)
|
||
| Dimension | Baseline holder | Metric | Value | Provenance |
|
||
(one row minimum per dimension; provenance = measured / cited / estimated)
|
||
|
||
## Verdict
|
||
Which candidate leads per dimension; what none of them do well
|
||
(the surpass opportunity); risks in the baselines themselves.
|
||
```
|
||
|
||
---
|
||
|
||
## Implementation rules the first pass earned
|
||
|
||
These are cheap, and each exists because its absence cost something in
|
||
CB-WP-0001. See `history/260731-inner-loop-retrospective.md`.
|
||
|
||
1. **No silently-ignored input.** A field that is parsed and then unused
|
||
is a defect, not a stub. Inputs are honoured or rejected with an
|
||
error — never dropped. *(A scenario `setup.patch` was parsed and
|
||
discarded; every scenario using it would have tested the wrong
|
||
initial state while passing.)*
|
||
2. **Decisions get commands, not defaults.** A rule that requires a
|
||
participant's choice is implemented as a command carrying that
|
||
choice. Until it is, **nothing claims coverage of it** — no tag, no
|
||
scenario, no acceptance row. Inventing a default to make a rule
|
||
"done" is the failure this prevents.
|
||
3. **Scaffolds are exercised or marked.** A scaffold's green gates are
|
||
not evidence. Any scaffold path no test reaches is marked as
|
||
unexercised. *(A compiling, fully-green scaffold shipped a state-hash
|
||
that would panic on any state holding a relation.)*
|
||
4. **Coverage gates that count tags say so.** A gate comparing rule IDs
|
||
against `covers:` lists proves no rule is unclaimed and no claimed
|
||
rule is invented. It does **not** prove a scenario exercises what it
|
||
names. Wherever such a number is reported, that limit is reported
|
||
with it.
|
||
|
||
---
|
||
|
||
## Agentic-efficiency requirements
|
||
|
||
The loop exists to be driven by agents. Therefore:
|
||
|
||
1. **Whole-file loadability** — every loop artifact stays under ~400 lines;
|
||
split before exceeding, link with relative paths.
|
||
2. **Structured over prose** *(guidance, not a requirement — nothing can
|
||
check it)* — tables and fenced blocks for anything a later step must
|
||
parse (baselines, acceptance metrics, evidence rows).
|
||
3. **One command surface** — all checks runnable through repo-root
|
||
commands (eventually `cb *`; until then, `make`/`cargo` aliases declared
|
||
in one place), each supporting deterministic, greppable output.
|
||
4. **Self-contained tasks** — a workplan task names its input artifacts and
|
||
output artifacts; a fresh session must be able to execute it from the
|
||
task text plus linked files alone.
|
||
5. **Evidence or it didn't happen** — claims of "better" live in committed
|
||
evidence files with numbers, never only in commit messages or chat.
|
||
6. ~~**Token discipline** — per the global budget policy, a loop iteration
|
||
that exceeds its budget without measurable progress is stopped and
|
||
decomposed, not pushed through.~~ **DEAD POLICY.** The 8k/10k per-task
|
||
token budget was never referenced or enforced, and CB-WP-0001 T08
|
||
exceeded it by orders of magnitude with no signal. It implies a control
|
||
that does not exist. Replacement in USD is CB-WP-0003 T05; until then
|
||
this is documentation of a gap, not a rule.
|
||
|
||
6a. **Live cost budget** *(replaces the above)* — spend since the last
|
||
commit, soft **$10.00**, hard **$22.00**, checked by `make cost-budget`.
|
||
Calibrated on the 32 commit intervals of CB-WP-0001 (p50 $1.40, p90
|
||
$9.36, max $10.80), so both thresholds bind on future work rather than
|
||
ratifying past work. Contract: [CostAccounting.md](CostAccounting.md)
|
||
§7 (CB-01, CB-02). It fires on the open remainder rather than per task
|
||
because per-task cost needs the commit that closes the task, and a
|
||
budget that can only report after the money is spent is the dead policy
|
||
this replaces.
|
||
|
||
**Enforcement status.** Rules above that a command can check are enforced
|
||
by `make loop-lint`; the full classification of every InnerLoop rule as
|
||
executable / checkable / decorative, with the failure class each catches,
|
||
is in `history/260731-inner-loop-rule-audit.md`. Rules marked *guidance*
|
||
or *dead* say so where they appear, so a reader can tell a requirement
|
||
from a preference without consulting the audit.
|
||
|
||
---
|
||
|
||
## Definition of done — one loop pass
|
||
|
||
A capability has completed the loop when all of the following are committed:
|
||
|
||
- [ ] research/CB-RES-NNNN with approved status and full baseline table
|
||
- [ ] decisions/ADR-NNNN with per-dimension expected advantage
|
||
- [ ] specs/<Capability>.md with acceptance-metrics table
|
||
- [ ] passing scenarios covering every numbered spec rule
|
||
- [ ] evidence/CB-EV-NNNN with final comparison vs baseline, no `unmeasured`
|
||
- [ ] every reported number produced by a harness with a positive
|
||
control; any metric that could not be instrumented is recorded as
|
||
uncomputable rather than estimated
|
||
- [ ] every unmet metric reported as unmet, with attribution and the
|
||
options for resolving it — a missed target is an output of the
|
||
loop, not a reason to move the target quietly
|
||
- [ ] **cost recorded**: `make cost` run for the pass, its composition
|
||
(not only its total) in the evidence file, and the per-task figures
|
||
pushed to the hub. M-D2-CST is no longer allowed to be
|
||
`uncomputable` — the instrument exists
|
||
([CostAccounting.md](CostAccounting.md))
|
||
- [ ] retrospective note (may be one paragraph appended to the evidence
|
||
file): what the loop itself should change
|
||
|
||
## Chaos roll — calibration (moved from InnerLoop v1.6)
|
||
|
||
> **Calibration window, opened 2026-07-31 (CB-WP-0003 T06).** The rate was
|
||
> d10 and the mechanism **never fired**: two rolls across two workplans
|
||
> (CB-WP-0001: 9, CB-WP-0002: 2), against ~0.2 expected firings. At d10 and
|
||
> ~2 tier decisions per workplan it would take roughly twenty workplans to
|
||
> observe four overrides, so the mechanism was set at a rate that prevented
|
||
> its own evaluation — the one option T06 ruled out.
|
||
>
|
||
> Raised to **d4 (25%) for the next 12 tier declarations**, then evaluated
|
||
> and either kept, returned to d10, or deleted. Expected ~3 firings in the
|
||
> window, which is enough to see whether an overridden tier produces a
|
||
> different outcome than the argued one.
|
||
>
|
||
> **Stated cost:** a chaos-L override on work that would have been S buys a
|
||
> full survey, adversarial review, and ADR. Measured comparable: CB-WP-0001
|
||
> T03 (a tier-L survey) cost **$9.91**. At 25% over 12 declarations the
|
||
> window is expected to cost **$20–30**. That is the price of finding out
|
||
> whether the mechanism is worth keeping, and it is cheaper than carrying an
|
||
> unevaluated ritual indefinitely. Both rolls are recorded in the tier declaration
|
||
(`tier: M (structural L, chaos 10→M)`). **Record the roll every time,
|
||
including when it changes nothing** (`tier: L (structural L, chaos 4)`),
|
||
so a mechanism that never fires is visible rather than assumed. Purpose:
|
||
an occasional random
|
||
reweighting keeps the classification honest — arguing everything into S
|
||
stops paying off when audits can compare argued tiers against the random
|
||
sample — and occasionally forces a deep look at something "obviously
|
||
trivial", which is where local optima hide.
|
||
|
||
|
||
## Change log — v1.0 to v1.3 (moved from InnerLoop v1.6)
|
||
|
||
v1.3 changed from v1.2: single source of fact is now executable
|
||
(`make facts-check`, CB-WP-0004 T04), giving the duplicated-fact-drift
|
||
class its first gate.
|
||
|
||
v1.2 changes from v1.1: single source of fact; review targets the
|
||
harness and states its sampling limit; correction vs retarget; the chaos
|
||
roll's calibration window; the live cost budget. The design goal is now
|
||
stated: **optimize for cheap correction, not for exhaustive prevention.**
|
||
Rationale: `history/260731-loop-hardening-retrospective.md`.
|
||
|
||
v1.1 — corrected from CB-WP-0002 (cost accounting) on
|
||
2026-07-31. Changes from v1.0: the instrument must exist and emit its own
|
||
target; inherited numbers are re-derived before use; every reporting tool
|
||
exposes `--self-test`; cost is in the definition of done. Rationale:
|
||
`history/260731-cost-accounting-retrospective.md`.
|
||
|
||
v1.0 — survived its first full pass (CB-WP-0001, the GROUND game kernel)
|
||
and was corrected from it on 2026-07-31. Changes from v0.2: measurement
|
||
validity (the positive control), metric feasibility and instrument naming,
|
||
four implementation rules the pass earned, and the requirement that
|
||
evidence state what it does not support. Rationale and the failures behind
|
||
each: `history/260731-inner-loop-retrospective.md`.
|
||
|
||
|
||
## Chaos roll — window 1's verdict and the d4 → d8 change
|
||
|
||
*(CB-WP-0018 T04, 2026-08-03. Full argument in `evidence/CB-EV-0015.md` §5
|
||
and `evidence/CB-EV-0016.md` §4.)*
|
||
|
||
Window 1 ran 2026-07-31 → 2026-08-02, twelve declarations, at d4 after an
|
||
earlier d10 that never fired and so prevented its own evaluation.
|
||
|
||
**Two overrides, one in each direction, and both changed the outcome**, so
|
||
window 1's retirement condition — *"the window closes with no overridden
|
||
tier producing a different outcome than the argued one"* — was not met:
|
||
|
||
| pass | roll | what the override bought |
|
||
|---|---|---|
|
||
| CB-WP-0011 | structural L → **S** | the deleted survey would have opened on 2D toolkits; the pass instead found the existing text renderer showing 24 of 41 view fields. Priced on the same subject: 0.099 $/response at S against 0.123 at L |
|
||
| CB-WP-0017 | structural S → **M** | ADR-0010. At tier S the page's script would have grown from *"it does one thing"* to holding a drag, following the pointer and marking other elements under a one-paragraph commit note, silently outgrowing ADR-0007 D5 |
|
||
|
||
**Why the rate fell.** Both were informative *because they were rare*. At
|
||
d4 the mechanism overrides a quarter of all declarations, at which point it
|
||
stops being a calibration on the tier table and becomes a second tier
|
||
table. d8 keeps the mechanism and restores its rarity.
|
||
|
||
**The weakest part of this decision, stated plainly:** it is a rate change
|
||
argued from **n=2**. The alternative — keep d4 for a second window and
|
||
decide with four data points — was live and was rejected only because a
|
||
quarter of declarations is a large standing tax to pay for evidence.
|
||
|
||
So window 2 carries a falsifier: **if it produces no override at all, that
|
||
is evidence the rate went too far**, not evidence the mechanism is
|
||
healthy. A window that cannot fire cannot be evaluated, which is the exact
|
||
failure d10 had.
|
||
|
||
## Meta budget — why 20% goes with a five-pass window
|
||
|
||
*(CB-WP-0019 T05, 2026-08-03, at the maintainer's instruction: "the main
|
||
budget should be spent on the task at hand while some of the budget should
|
||
be spent on control, review and improvement… 80/20 to start with".)*
|
||
|
||
The ratio and the window are a pair. With one meta pass among `n` at the
|
||
same cost `P` as each product pass, the measured share is `P / (n·P)`, so:
|
||
|
||
| window | one meta pass at parity reads | what a 20% line then demands |
|
||
|---:|---:|---|
|
||
| 3 | 33% | the meta pass must cost **half** a product pass |
|
||
| 4 | 25% | ~80% of one |
|
||
| **5** | **20%** | **parity — one pass in five, normal cost** |
|
||
| 6 | 17% | 20% is slack |
|
||
|
||
So 80/20 over a **trailing 5** is the literal reading of the instruction:
|
||
one pass in five is meta, and it may cost what a pass costs. The same 20%
|
||
over a trailing 3 would silently also require it to be half-price, which
|
||
does not make meta work rarer — it makes it rushed, and this project's
|
||
meta passes are where its instruments get repaired.
|
||
|
||
**Why not simply keep 25% over three?** Because 25% over three is *"one in
|
||
four at three-quarters cost"*, which is a ratio nobody chose; it was
|
||
inherited from ADR-0006 without the window being considered alongside it.
|
||
Stating the pair is the correction.
|
||
|
||
**The phase setting.** `meta_phase` in `gates.toml` carries `pct`,
|
||
`reason`, and `review_by`. It exists because stage 0 and a stabilisation
|
||
phase do not deserve the same ratio — but it expires, because a threshold
|
||
anyone may move is not a threshold. The failure it guards against is the
|
||
one this project has refused four times: raising a limit to pass a breach
|
||
rather than fixing the breach.
|
||
|
||
## Loop work cashes out — the measured basis
|
||
|
||
*(ADR-0006 D4, moved out of `InnerLoop.md` by CB-WP-0019 T05 when that file
|
||
crossed the loadability limit. Limits get fixed structurally here.)*
|
||
|
||
Cost per response across five passes ran **0.123, 0.228, 0.362, 0.298,
|
||
0.123** dollars. The reading that survived the data is that **cost tracks
|
||
distance from a runnable check**: the passes that shipped a command were
|
||
cheap; the passes that argued about what a number means were not
|
||
(CB-EV-0007 §5).
|
||
|
||
**Refuted if** a prose-only meta pass lowers cost per response, or catches
|
||
a class no command could.
|
||
|
||
## Why review is adversarial execution, not re-derivation
|
||
|
||
*(Moved out of `InnerLoop.md` by CB-WP-0019 T05 at the loadability limit.
|
||
Two cases, three passes apart, with the same shape.)*
|
||
|
||
**v1.1, from CB-WP-0002 — the same-sample blind spot (SSB).** The dedup
|
||
invariant was verified on the main transcript by the survey (206/206
|
||
groups) and independently re-verified by the reviewer, who used the same
|
||
transcript. It is **false** in the 8-response `subagents/` tree neither
|
||
examined. Two independent checks, one blind spot, because both sampled the
|
||
same way. Only an assertion running over all the data at execution time
|
||
caught it.
|
||
|
||
**v1.4, from CB-WP-0005 — re-derivation is not enough.**
|
||
`evidence/CB-EV-0001` reported `AM-7 replay | met, 2,290×` for a clause
|
||
that asserts nothing: the hash reaches only a `println!`. The reviewer
|
||
found it by opening a test out of curiosity and said so; **no systematic
|
||
step pointed there.** Mutating it settled it in one command.
|
||
|
||
Both are verification steps that inherited the author's blindness, and
|
||
both fixes replace re-derivation with **adversarial execution**.
|
||
|
||
## Quoting a cost — six for six, never high
|
||
|
||
*(CB-WP-0019 T03, 2026-08-03. The rule lived only in evidence files and
|
||
had been re-derived three times before it was written down.)*
|
||
|
||
| pass | reported mid-flight | settled | under by |
|
||
|---|---|---|---|
|
||
| CB-WP-0009 | $6.73 | $11.31 | 40% |
|
||
| CB-WP-0011 | $4.23 | $7.02 | 40% |
|
||
| CB-WP-0012 | $8.82 | $14.52 | 39% |
|
||
| CB-WP-0013 | $5.78 | $8.26 | 30% |
|
||
| CB-WP-0015 | $15.14 | $22.70 | 33% |
|
||
| CB-WP-0017 | $5.19 | $9.48 | 45% |
|
||
|
||
**Six for six, always low, never by less than 30%.** That is systematic
|
||
bias, not noise, and it has two causes — both of which must be fixed or
|
||
the rule does not hold:
|
||
|
||
1. **The boundary.** A pass's spend window runs to the **next** pass's
|
||
first commit, so a pass is not final until the one after it starts.
|
||
Quoting "the previous pass" is therefore still too early if the pass
|
||
after it has not been declared. (CB-EV-0013 §5.)
|
||
2. **The reading.** *A figure read earlier in a session is an in-flight
|
||
figure regardless of whose name is on it.* CB-EV-0014 quoted
|
||
CB-WP-0015 at $15.14/136 and called it settled; it had been read during
|
||
CB-WP-0015 itself and settled at $22.70/166 — 50% higher. Quoting from
|
||
memory defeats the rule even when the boundary is right.
|
||
(CB-EV-0015 §6.)
|
||
|
||
**Which is load bearing?** The second. CB-WP-0018 T04 applied it alone —
|
||
re-running `make status` at the moment of writing — and the figure it
|
||
quoted was correct. The boundary matters only because re-running early
|
||
still reads an open window; re-running *late* fixes both. So the
|
||
operative instruction is **re-run the instrument when you quote it**, and
|
||
the boundary rule is what tells you when "late enough" has arrived.
|
||
|
||
## Retargeting — the case, and the four corrections it must not forbid
|
||
|
||
*(v1.1, from CB-WP-0002/0003. Moved out of `InnerLoop.md` by CB-WP-0019
|
||
T03 at the loadability limit.)*
|
||
|
||
**The bad retarget.** AM-4's targets were measured at 246,250 and set at
|
||
250,000 in one commit, by the implementer, after seeing the number. That
|
||
is the structure the rule exists to stop: a target chosen to fit the
|
||
reading rather than a reading judged against a target.
|
||
|
||
**The four good corrections.** CB-WP-0002 then moved AC-1 three times —
|
||
$92.21 → $92.87 → $93.32 → $93.15 — each because a *new instrument*
|
||
disproved the old figure. A blanket prohibition on moving a target would
|
||
have forbidden all four to catch the one.
|
||
|
||
Hence the mechanical test rather than an appeal to intent: **a correction
|
||
is one where the target moves and the implementation does not.** If one
|
||
commit changes both the target and the code that target measures, it is a
|
||
retarget and needs an ADR.
|
||
|
||
CB-WP-0019 T01 is a worked example on the good side: AM-4b's target moved
|
||
745,000 while the code it measures did not change at all — only the
|
||
instrument's scope did, and its output is in the same commit.
|
||
|
||
## Numbers you inherit — two cases from CB-WP-0002
|
||
|
||
*(v1.1. Moved out of `InnerLoop.md` by CB-WP-0019 T03.)*
|
||
|
||
**A target set before its instrument existed.** `specs/CostAccounting.md`
|
||
AC-1 named `cb-cost --pin fc76445` before that tool was built, and set the
|
||
target to a hand-computed **$92.87**. When the tool existed it returned
|
||
**$93.32** — the hand computation carried a dedup bug the tool's own
|
||
positive control caught. *The metric satisfied v1.0's rule completely and
|
||
was still wrong.*
|
||
|
||
**A number quoted rather than measured.** The workplan opened with
|
||
**$248.46**, inherited from a prior pass. Re-derivation put it at
|
||
**$92.21**: the quoted figure double-counted transcript lines and priced a
|
||
three-model session at one model's rate.
|
||
|
||
Neither error was of the harness-does-nothing class — both sums ran over
|
||
real data, and a positive control would have passed them. That is why the
|
||
rule is *re-derive before using as a target, or cite as unverified*, and
|
||
not merely *add a control*.
|
||
|
||
**Quoting is not measuring** — the same sentence the cost-quoting rule
|
||
above rests on, learned here first and re-learned six times since.
|
||
|
||
## Chaos roll — window records
|
||
|
||
Moved to [`ChaosRollHistory.md`](ChaosRollHistory.md) on 2026-08-07: it is
|
||
a log that grows by one entry per window, and this file crossed the
|
||
loadability limit carrying it.
|