ADR-0006 + CB-WP-0009: control gates are experiments
Some checks failed
ci / check (push) Failing after 4s
Some checks failed
ci / check (push) Failing after 4s
CB-EV-0007 found three defects in how gates are designed rather than in any one gate: the meta budget cannot see the pass it governs, it blocks its own repair, and nothing retires any gate. D1 budgets measure their own window. D2 a soft breach is a signal, and repairing the instrument that reports a breach is always in budget — a gate must never block its own remedy, which is the trap CB-RES-0005 §4 named for session shape and that got built anyway two tasks later. D3 every gate declares what would retire it and a date to argue it on. D4 loop work cashes out into something runnable in the pass that invents it, from the measured finding that cost per response tracks distance from a runnable check. D5 the tier table finally covers changes to the loop's own operation — CB-RES-0005 §6 said a second instance should trigger it, and this ADR is the second. The workplan is meta and above the budget line on recorded maintainer authorization, which is D2's first use. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
dc440e82c6
commit
3090935aac
2 changed files with 257 additions and 0 deletions
132
decisions/ADR-0006-adaptive-control-gates.md
Normal file
132
decisions/ADR-0006-adaptive-control-gates.md
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
# ADR-0006 — control gates are experiments, and they measure their own window
|
||||||
|
|
||||||
|
Status: **accepted** 2026-08-01
|
||||||
|
Tier: M (structural S by the letter of InnerLoop's table — no capability
|
||||||
|
port, no canonical interface, no dependency — declared **M** because it
|
||||||
|
changes how the loop constrains its own operation. This is the *second*
|
||||||
|
recorded instance of that gap, after CB-RES-0005 §6, which said a second
|
||||||
|
instance should trigger the change. D5 is that change. Chaos d4=3, no
|
||||||
|
override; declaration 4 of 12.)
|
||||||
|
|
||||||
|
Supersedes nothing. Amends InnerLoop v1.5 → **v1.6**.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Six passes of loop work produced five standing control mechanisms: the
|
||||||
|
cost budget (CB-01/CB-02), the session-shape budget (SH-1/2/3), the
|
||||||
|
mutation harness (M-D1-MUT), the DFD fact gate, and the meta budget
|
||||||
|
(v1.5). [CB-EV-0007](../evidence/CB-EV-0007-stage-0.md) measured what
|
||||||
|
they have been worth and found three defects in the *design of gates*,
|
||||||
|
not in any one gate:
|
||||||
|
|
||||||
|
1. **The meta budget could not see the pass it governed.** It aggregates
|
||||||
|
over every attributed task ever closed, so CB-WP-0008 — 100% product —
|
||||||
|
read `61% OVER`. This is the identical defect CB-RES-0005 §1 found in
|
||||||
|
SH-1/SH-2 and CB-WP-0007 T01 fixed for session shape. It was
|
||||||
|
*reintroduced two tasks later, by the person who had just fixed it*.
|
||||||
|
2. **The budget blocked its own repair.** v1.5 forbids opening meta work
|
||||||
|
above the line; the fix for the budget is meta work; the budget was
|
||||||
|
over. CB-RES-0005 §4 rejected build-gating session shape for exactly
|
||||||
|
this shape — *"a gate that blocks the remedy when the metric breaches
|
||||||
|
is not a gate, it is a trap"* — and the trap was then built elsewhere.
|
||||||
|
3. **Gates accumulate and nothing retires them.** Five mechanisms, no
|
||||||
|
expiry, no review. Three artifacts in this repo *do* carry one — the
|
||||||
|
chaos roll's 12-declaration window, AM-4c's withdrawal, and
|
||||||
|
`CommitWindow`'s delete-by 2026-12-31 — and all three came from
|
||||||
|
individual argument rather than from a rule.
|
||||||
|
|
||||||
|
The maintainer's instruction that opened this pass: *"experiment our way
|
||||||
|
to sensible, task- and context-specific control and review gates that
|
||||||
|
drive continuous and adaptive optimization."* These decisions are the
|
||||||
|
smallest step that makes gates experimental rather than permanent.
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
### D1 — A budget measures the window it governs
|
||||||
|
|
||||||
|
Every budget reports the window it constrains, and names it in its own
|
||||||
|
output. Cumulative figures are retained and labelled **history**.
|
||||||
|
|
||||||
|
The meta budget becomes **per-pass** (since the current workplan's first
|
||||||
|
commit), matching CB-01/CB-02's since-last-commit window and CB-RES-0005
|
||||||
|
D1's windowed session shape. Provenance: `adapted:sre-error-budget`, the
|
||||||
|
same rolling-window shape already adopted once here.
|
||||||
|
|
||||||
|
**Refuted if** the windowed figure and the cumulative figure stay within
|
||||||
|
20% of each other across two passes — in which case aggregation was not
|
||||||
|
the problem and the extra machinery should be deleted.
|
||||||
|
|
||||||
|
### D2 — A soft breach is a signal; repairing the instrument is exempt
|
||||||
|
|
||||||
|
Two changes to v1.5's meta budget:
|
||||||
|
|
||||||
|
- **Instrument repair is always in-budget.** Work that fixes the
|
||||||
|
instrument reporting a breach may be opened regardless of the reading.
|
||||||
|
A gate must never block its own remedy.
|
||||||
|
- **The maintainer may authorize above-line work explicitly**, recorded
|
||||||
|
in the workplan's frontmatter (`authorized_above_budget: <reason>`).
|
||||||
|
This pass carries the first one. Undocumented above-line meta work
|
||||||
|
remains a violation the evidence file must report.
|
||||||
|
|
||||||
|
The rest of v1.5 stands: soft, a started task may be finished, and a
|
||||||
|
breach is reported rather than enforced.
|
||||||
|
|
||||||
|
### D3 — Every control gate declares a review trigger
|
||||||
|
|
||||||
|
A gate without an expiry is a permanent tax justified once. Each entry in
|
||||||
|
`gates.toml` declares: what it checks, what it has **caught** (with
|
||||||
|
evidence pointers), a `review_by` date, and **what would retire it**.
|
||||||
|
|
||||||
|
`make gate-review` reports gates past their review date and gates that
|
||||||
|
have caught nothing since they were added. It **reports**; it does not
|
||||||
|
fail the build, for CB-RES-0005 §4's reason.
|
||||||
|
|
||||||
|
The trigger for actually retiring one is deliberately not automatic:
|
||||||
|
a gate that has caught nothing may be preventing rather than missing.
|
||||||
|
The report forces the argument to be made on a date, not never.
|
||||||
|
|
||||||
|
**Refuted if** a review cycle passes with no gate either retired,
|
||||||
|
tightened, or explicitly re-justified — that would make it a ritual, and
|
||||||
|
this document's own D4 says rituals cash out or go.
|
||||||
|
|
||||||
|
### D4 — Loop work cashes out into something runnable, in the same pass
|
||||||
|
|
||||||
|
From CB-EV-0007 §5: cost per response across five passes was 0.123,
|
||||||
|
0.228, 0.362, 0.298, 0.123 dollars, and the pattern 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.
|
||||||
|
|
||||||
|
So: a `meta` pass must ship at least one executable check, command, or
|
||||||
|
gate. Findings that remain prose are recorded as findings and do **not**
|
||||||
|
count as delivery.
|
||||||
|
|
||||||
|
**Refuted if** a prose-only meta pass demonstrably lowers cost per
|
||||||
|
response or catches a defect class no command could have. Stated because
|
||||||
|
it is the plausible counter-case: CB-WP-0003's conclusion that
|
||||||
|
class-by-class hardening does not converge was prose, and was correct.
|
||||||
|
|
||||||
|
### D5 — The tier table covers changes to the loop's own operation
|
||||||
|
|
||||||
|
CB-RES-0005 §6 recorded that InnerLoop's tier triggers are all *code*
|
||||||
|
properties ("new capability port", "canonical interface", "dependency"),
|
||||||
|
so a change to how the loop constrains itself scores **S** — one
|
||||||
|
paragraph in a commit message — however consequential. It declined to fix
|
||||||
|
this on one instance. This ADR is the second.
|
||||||
|
|
||||||
|
New trigger, at **M or above**: *changes whether or how the loop
|
||||||
|
constrains its own operation* — budgets, gates, review requirements, tier
|
||||||
|
rules themselves.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- `make status` reports a per-pass meta share; cumulative moves to
|
||||||
|
history. Existing readings are not comparable to new ones, and the
|
||||||
|
first output says so.
|
||||||
|
- A new `gates.toml` and `make gate-review`; `loop-lint` gains a check
|
||||||
|
that every gate in the Makefile has an entry, so the registry cannot
|
||||||
|
silently fall behind the gates it describes.
|
||||||
|
- InnerLoop → **v1.6**.
|
||||||
|
- One more thing to maintain. That is the honest cost, and D3's own
|
||||||
|
review trigger applies to `gate-review` itself: if it has retired
|
||||||
|
nothing by 2026-12-31, it is a ritual and goes.
|
||||||
125
workplans/CB-WP-0009-adaptive-gates.md
Normal file
125
workplans/CB-WP-0009-adaptive-gates.md
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
---
|
||||||
|
id: CB-WP-0009
|
||||||
|
kind: meta
|
||||||
|
title: "Make control gates experimental: window them, review them, cash them out"
|
||||||
|
status: proposed
|
||||||
|
authorized_above_budget: "maintainer, 2026-08-01 — 'improve our policies where it seems promising; we will experiment our way to sensible task- and context-specific control and review gates'. Meta read 59% at the time."
|
||||||
|
state_hub_workstream_id: ""
|
||||||
|
---
|
||||||
|
|
||||||
|
# Purpose
|
||||||
|
|
||||||
|
[ADR-0006](../decisions/ADR-0006-adaptive-control-gates.md) (tier M,
|
||||||
|
survey merged into the ADR from [CB-EV-0007](../evidence/CB-EV-0007-stage-0.md)
|
||||||
|
§3 and §5; chaos d4=3, no override, declaration 4 of 12).
|
||||||
|
|
||||||
|
Six passes produced five control mechanisms and no way to retire any of
|
||||||
|
them. CB-EV-0007 found three defects in how gates are *designed*:
|
||||||
|
|
||||||
|
1. the meta budget cannot see the pass it governs — the same cumulative
|
||||||
|
defect CB-WP-0007 T01 had just fixed for session shape, reintroduced
|
||||||
|
two tasks later by the same hand;
|
||||||
|
2. it blocks its own repair, which is the trap CB-RES-0005 §4 named and
|
||||||
|
rejected for session shape and then got built anyway;
|
||||||
|
3. nothing retires a gate.
|
||||||
|
|
||||||
|
This pass is **`kind: meta` and above the budget line**, on explicit
|
||||||
|
maintainer authorization recorded in the frontmatter — the first use of
|
||||||
|
ADR-0006 D2, and a deliberate exercise of it.
|
||||||
|
|
||||||
|
Per **D4**, every task here ships something runnable. A task that ends in
|
||||||
|
prose has not delivered.
|
||||||
|
|
||||||
|
## Task: the meta budget measures the pass it governs
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: CB-WP-0009-T01
|
||||||
|
status: todo
|
||||||
|
priority: high
|
||||||
|
state_hub_task_id: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
ADR-0006 **D1**. `make status` reports the meta share **for the current
|
||||||
|
pass** — the window since the active workplan's first commit — and keeps
|
||||||
|
the cumulative figure labelled *history*, exactly as `cb-cost`'s session
|
||||||
|
shape block does since CB-WP-0007 T01.
|
||||||
|
|
||||||
|
The instrument-repair exemption (**D2**) is what makes this task legal to
|
||||||
|
open at 59%, so the task must also *state* the exemption where the budget
|
||||||
|
prints, or the next reader will re-derive the same standoff.
|
||||||
|
|
||||||
|
**Predicted:** the windowed share for CB-WP-0008 reads at or near 0% —
|
||||||
|
it was a pure product pass — against 61% cumulative.
|
||||||
|
**Refuted if** the two land within 20% of each other, in which case D1 is
|
||||||
|
wrong and the machinery should be deleted rather than kept.
|
||||||
|
|
||||||
|
## Task: `gates.toml` and `make gate-review`
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: CB-WP-0009-T02
|
||||||
|
status: todo
|
||||||
|
priority: high
|
||||||
|
state_hub_task_id: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
ADR-0006 **D3**. A registry of every standing control gate: what it
|
||||||
|
checks, what it has caught (with pointers), `review_by`, and **what would
|
||||||
|
retire it**. `make gate-review` reports what is overdue and what has
|
||||||
|
caught nothing.
|
||||||
|
|
||||||
|
Seed it with the mechanisms that exist today — the cost budget, the
|
||||||
|
shape budget, mutation coverage, the DFD fact gate, the meta budget, the
|
||||||
|
chaos roll, the kernel spec→code gate, and `gate-review` itself, which is
|
||||||
|
not exempt from its own rule.
|
||||||
|
|
||||||
|
**The positive control this needs:** a registry that silently drifts
|
||||||
|
behind the Makefile is worse than none, so `loop-lint` gains a check that
|
||||||
|
every gate target has an entry and every entry names a real target. Its
|
||||||
|
own self-test must fail when an entry is removed.
|
||||||
|
|
||||||
|
## Task: InnerLoop v1.6
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: CB-WP-0009-T03
|
||||||
|
status: todo
|
||||||
|
priority: medium
|
||||||
|
state_hub_task_id: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
Fold **D2**, **D4** and **D5** into `specs/InnerLoop.md`:
|
||||||
|
|
||||||
|
- the breach-is-a-signal wording and the two exemptions (instrument
|
||||||
|
repair; recorded maintainer authorization);
|
||||||
|
- the cash-out rule, with its refutation condition;
|
||||||
|
- the tier trigger for changes to the loop's own operation, closing the
|
||||||
|
gap CB-RES-0005 §6 opened and this ADR's own tier declaration used.
|
||||||
|
|
||||||
|
`InnerLoop.md` is at its 400-line loadability limit, so this task
|
||||||
|
**displaces** as much as it adds: the chaos-roll rationale and the v1.1
|
||||||
|
→ v1.4 change log move to `InnerLoopReference.md`, leaving the rule and a
|
||||||
|
pointer. Loadability is itself a gate; growing the file to fit a rule
|
||||||
|
about gates would be the joke writing itself.
|
||||||
|
|
||||||
|
## Task: control loop — did the changes fire?
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: CB-WP-0009-T04
|
||||||
|
status: todo
|
||||||
|
priority: high
|
||||||
|
state_hub_task_id: ""
|
||||||
|
```
|
||||||
|
|
||||||
|
Commit `evidence/CB-EV-0008-adaptive-gates.md`. Four questions, all
|
||||||
|
answered from output, not argument:
|
||||||
|
|
||||||
|
1. **Does the windowed meta share differ from cumulative?** Against
|
||||||
|
T01's prediction; refuted within 20%.
|
||||||
|
2. **What does `gate-review` say on its first run?** A registry where
|
||||||
|
every gate is current and every gate has caught something is a
|
||||||
|
registry that was written to look good — say which entries are
|
||||||
|
uncomfortable.
|
||||||
|
3. **Did D4 hold for this pass?** Three of four tasks here ship a
|
||||||
|
command; T03 is prose. State whether the rule survives its own first
|
||||||
|
pass or needs the exception written down.
|
||||||
|
4. **Cost**, against the 0.123–0.362 per-response range, and the meta
|
||||||
|
share this pass itself consumed — reported under the rule it wrote.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue