InnerLoop v1.7. The purpose is written first and the number follows from it: most spend on the task at hand, some on control, review and improving the process. make status prints it above the figure, because a threshold with no stated purpose is what let this number be argued three times. Soft 20% over a trailing 5, and the self-test enforces that the ratio and the window are a PAIR: META_SOFT_PCT == 100 / TRAILING_PASSES. One meta pass among n at parity cost reads 1/n, so 80/20 is one pass in five at normal cost -- a five-pass window. The same 20% over three would have silently also demanded the meta pass be half-price, which makes meta work rushed rather than rare. Moving the ratio without the window goes red. The phase setting is declared, argued and expiring in gates.toml, and reverts on review_by unless re-argued. Verified live at 35%. One with no reason or no expiry is refused rather than honoured, because a threshold anyone may move is not a threshold. Measured: the last five passes read 7% against the new line. InnerLoop.md crossed the 400-line limit three times while this was written and was fixed structurally each time -- the arithmetic, the cost-per-response basis and the two review case studies moved to InnerLoopReference.md. The limit was not raised. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
299 lines
15 KiB
Markdown
299 lines
15 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**.
|