274 lines
14 KiB
Markdown
274 lines
14 KiB
Markdown
|
|
# ADR-0012: clay-borg is a design instrument, and §Underdetermined is the register
|
|||
|
|
|
|||
|
|
status: accepted
|
|||
|
|
date: 2026-08-05
|
|||
|
|
decided by: agent, under the standing loop authorization
|
|||
|
|
tier: L (structural L — named a high-leverage pass by the maintainer and it
|
|||
|
|
amends INTENT; chaos d8=6 → no override). Tier L requires a separate
|
|||
|
|
survey, an adversarial review, then this document.
|
|||
|
|
references: [CB-WP-0022](../workplans/CB-WP-0022-the-design-instrument.md),
|
|||
|
|
[CB-RES-0007](../research/CB-RES-0007-design-instrument.md),
|
|||
|
|
[challenge](../history/260805-design-instrument-challenge.md) /
|
|||
|
|
[response](../history/260805-design-instrument-response.md),
|
|||
|
|
[ADR-0007](ADR-0007-render-html-not-a-port.md) D3,
|
|||
|
|
GROUND-WP-0002, GROUND-WP-0004 T02 (ground-game's shape ruling)
|
|||
|
|
|
|||
|
|
## Context
|
|||
|
|
|
|||
|
|
Nineteen passes of building a rigorous simulator produced findings about
|
|||
|
|
*the game's rules* as a by-product, because an engine that refuses to
|
|||
|
|
proceed past an undecided rule cannot help but locate the undecided rules.
|
|||
|
|
Six such findings exist. They live in eleven files, no index, and one sat
|
|||
|
|
unread in an inbox for four days.
|
|||
|
|
|
|||
|
|
**The review changed what this ADR has to decide.** The survey proposed a
|
|||
|
|
new register governed by an existence rule — *a finding is not admissible
|
|||
|
|
without its reproduction*. C1 falsified the example that rule was built
|
|||
|
|
on, and C4 pointed out the incumbent was never evaluated. Both are
|
|||
|
|
load-bearing here, so both are answered before anything is built.
|
|||
|
|
|
|||
|
|
## The correction this ADR is built on
|
|||
|
|
|
|||
|
|
`CB-WP-0022:61` justified the rule with *"GR-E01 is admissible because
|
|||
|
|
4/6/9 against 5/7/9 is a computation anyone can rerun."* Commit `2da19a4`
|
|||
|
|
had already rerun it: **6/9/12 against 5/7/9**, and the scenario was
|
|||
|
|
renamed `-unreachable-` → `-reachable-`. The conclusion inverted.
|
|||
|
|
|
|||
|
|
That finding was **one of the two that passed the reproduction rule**. So:
|
|||
|
|
|
|||
|
|
| wrong premise | reached ground-game? | passed an existence test? |
|
|||
|
|
|---|---|---|
|
|||
|
|
| *"12 in the file"* — a sum with no deal table | yes | — |
|
|||
|
|
| *"SOLVE offered on a face-down Problem"* — wrong condition named | yes | — |
|
|||
|
|
| *"4/6/9, no dataset reconciles them"* | **stopped in flight, 2026-08-05** | **yes** |
|
|||
|
|
|
|||
|
|
**Existence is not the property that was missing.** Three findings went
|
|||
|
|
wrong on their *description*, and the one that carried an artifact carried
|
|||
|
|
a green one that no longer matched its prose. This ADR's rule is written
|
|||
|
|
against that, not against the survey's.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## D1 — INTENT gains a fourth property: the engine is an instrument
|
|||
|
|
|
|||
|
|
`INTENT.md` states three properties — Clay, Borg, product-driven
|
|||
|
|
evolution. It gains a fourth, and the wording is deliberately about a
|
|||
|
|
**mechanism**, not an ambition:
|
|||
|
|
|
|||
|
|
> 4. **Instrument** — the engine is rigorous enough that it cannot proceed
|
|||
|
|
> past a rule that does not decide. What it cannot execute, it reports:
|
|||
|
|
> findings about the *game's* design are a product of building the
|
|||
|
|
> simulator, not a side activity, and they are carried back to the game's
|
|||
|
|
> owner with the artifact that produced them.
|
|||
|
|
|
|||
|
|
**Why this is earned rather than aspirational.** It is a restatement of
|
|||
|
|
something that has already happened six times without anyone deciding it
|
|||
|
|
should. The alternative wording considered and rejected — *"clay-borg is a
|
|||
|
|
game design tool"* — claims a product we do not have and invites building
|
|||
|
|
one; this claims a property we already exhibit and makes it a duty.
|
|||
|
|
|
|||
|
|
**Falsifier, and it is real:** if a pass ships with the engine having
|
|||
|
|
tolerated an undecided rule by quietly picking a default and not raising
|
|||
|
|
it, property 4 is false and INTENT is lying. `provisional: true` plus its
|
|||
|
|
age report is what keeps it honest, and D2 puts the duty where that
|
|||
|
|
machinery already lives.
|
|||
|
|
|
|||
|
|
## D2 — `§Underdetermined` is the register. Nothing parallel is built.
|
|||
|
|
|
|||
|
|
C4 lands. `specs/GroundRules.md §Underdetermined` was never evaluated as a
|
|||
|
|
candidate, and against CB-RES-0007's own five benchmarks it already
|
|||
|
|
delivers four:
|
|||
|
|
|
|||
|
|
| benchmark | §Underdetermined today |
|
|||
|
|
|---|---|
|
|||
|
|
| findability — one register with an index | **yes**, U1–U10 in one section |
|
|||
|
|
| closure — the source changes, not an annotation | **yes**: *"a ruling flips the scenario, not the kernel"* (`:231-233`) |
|
|||
|
|
| time raised → read | **owner and raise date per item**, `make coverage` warns past 30 days |
|
|||
|
|
| taxonomy fits reality | untested either way |
|
|||
|
|
| reproducibility — 100% carry a replayable artifact | **no. This is the gap.** |
|
|||
|
|
|
|||
|
|
The survey went to Magic to discover the Oracle property. We had written
|
|||
|
|
it down ourselves eight days earlier, in our own words. **A second
|
|||
|
|
register would immediately disagree with the first**, and this project has
|
|||
|
|
a standing rule that a gate must cash out.
|
|||
|
|
|
|||
|
|
**Decision: extend, do not replace.** §Underdetermined becomes the finding
|
|||
|
|
register for all five kinds in D4, not only for dataset ambiguities. Its
|
|||
|
|
existing machinery — owner, raise date, `provisional: true`, the age
|
|||
|
|
warning — is the mechanism, unchanged. What is added is D3's admissibility
|
|||
|
|
rule, D4's `kind`, and D5's state.
|
|||
|
|
|
|||
|
|
**What this costs, stated plainly:** the register lives in a spec file
|
|||
|
|
about GROUND's rules, so a finding about the *engine's* behaviour sits in
|
|||
|
|
a document about the *game*. That is tolerable because every finding in
|
|||
|
|
scope is about the game by definition (D7), and it is the price of not
|
|||
|
|
running two registers that drift.
|
|||
|
|
|
|||
|
|
## D3 — admissibility: exists, has the ruled shape, and can fail
|
|||
|
|
|
|||
|
|
The survey's rule was one clause. It is now three, and **all three are
|
|||
|
|
required**:
|
|||
|
|
|
|||
|
|
> **1. It exists.** A scenario, an arithmetic check that prints the
|
|||
|
|
> contradiction, a recorded game the reader can replay, or a named test.
|
|||
|
|
>
|
|||
|
|
> **2. It has the ruled shape.** Per GROUND-WP-0004 T02, an arithmetic
|
|||
|
|
> finding ships a **row-level table** — Surface and each hidden priority
|
|||
|
|
> listed separately — **never a sum, never "deal depth N"**. Promoted here
|
|||
|
|
> from the T04 addendum it was, because two of three wrong premises were
|
|||
|
|
> quantities summed without a table.
|
|||
|
|
>
|
|||
|
|
> **3. It can fail.** The artifact must be capable of going red, and its
|
|||
|
|
> current colour is recorded. A reproduction that has gone **green is not a
|
|||
|
|
> closed finding** — it is a finding whose claim is now in question, and it
|
|||
|
|
> must be resolved to `applied` or `withdrawn` by a human reading it.
|
|||
|
|
|
|||
|
|
Clause 3 is the one the review bought. GR-E01's scenario went green when
|
|||
|
|
the edition landed, and the finding stayed admissible and stayed queued for
|
|||
|
|
transmission, because nothing in the rule said a passing artifact was a
|
|||
|
|
signal. **A green reproduction is an alarm, not a reassurance.**
|
|||
|
|
|
|||
|
|
**Falsifier for D3 as a whole:** if a finding reaches `ground-game` whose
|
|||
|
|
prose describes a quantity its own artifact does not compute, D3 has
|
|||
|
|
failed and the next revision needs the description generated *from* the
|
|||
|
|
artifact rather than written beside it.
|
|||
|
|
|
|||
|
|
## D4 — taxonomy, grounded in the six we have
|
|||
|
|
|
|||
|
|
Five kinds, each with the existing finding that forces it. **No kind is
|
|||
|
|
included that no finding of ours instantiates** — that is the whole
|
|||
|
|
discipline, and T05's backfill is its test.
|
|||
|
|
|
|||
|
|
| kind | means | our instance |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `underdetermined` | the rules do not say | U1–U10 |
|
|||
|
|
| `inconsistent` | the rules disagree with each other or with the dataset | GR-E01 as raised (now `withdrawn`) |
|
|||
|
|
| `inert` | a rule that cannot fire | SOLVE on a face-down Problem |
|
|||
|
|
| `degenerate` | fires, but collapses play | GR-A13 wasted SOLVE |
|
|||
|
|
| `unplayed` | implemented, never played to the end | GR-E03 / GR-E04 |
|
|||
|
|
|
|||
|
|
If backfill needs a sixth kind, **the taxonomy was invented rather than
|
|||
|
|
observed** and T07 must say so.
|
|||
|
|
|
|||
|
|
## D5 — lifecycle: a queue that empties, a log that does not
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
raised ──► reported ──► ruled ──► applied
|
|||
|
|
│
|
|||
|
|
└──────────► withdrawn ◄──────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
| state | means | owner |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `raised` | admissible under D3, in clay-borg | **clay-borg** |
|
|||
|
|
| `reported` | delivered to ground-game as a file under their workplan | **clay-borg** |
|
|||
|
|
| `ruled` | ground-game has answered | **ground-game** |
|
|||
|
|
| `applied` | **the source changed** — dataset or rules text — and our provisional default was deleted | **clay-borg** |
|
|||
|
|
| `withdrawn` | the finding was wrong, or dissolved | whoever finds it wrong |
|
|||
|
|
|
|||
|
|
`applied` means the source changed. It does **not** mean a ruling was
|
|||
|
|
recorded — Magic's Oracle property, and CB-RES-0007 §2 is right about it.
|
|||
|
|
|
|||
|
|
**The queue is `raised` + `reported`; the log is `applied` + `withdrawn`.**
|
|||
|
|
C6 asked whether keeping resolved findings contradicts "a queue that
|
|||
|
|
empties." It does not: the open queue empties, the closed log accumulates
|
|||
|
|
so a close rate can be computed. **Falsifier: if the default view shows
|
|||
|
|
closed findings mixed with open ones, the queue property is gone** — so
|
|||
|
|
`make design` reports the queue, and the log only on request.
|
|||
|
|
|
|||
|
|
**`withdrawn` is reported, not deleted.** GR-E01 is the reason: a claim
|
|||
|
|
retracted silently is how the first three survived. When a finding is
|
|||
|
|
withdrawn after being reported, the withdrawal goes downstream too.
|
|||
|
|
|
|||
|
|
## D6 — a finding without a reproduction is a `note`, and a note is not reportable
|
|||
|
|
|
|||
|
|
The survey left this open (§6) and the honest options were refusal or a
|
|||
|
|
note tier. **Notes are admitted, under three constraints that make the
|
|||
|
|
tier costly to sit in:**
|
|||
|
|
|
|||
|
|
1. A note **may not be reported to ground-game**. It has no `reported`
|
|||
|
|
state. This is the whole point: the unread-inbox failure was prose
|
|||
|
|
crossing a repo boundary.
|
|||
|
|
2. A note **expires at 30 days** and `make design` flags it, reusing
|
|||
|
|
§Underdetermined's existing age mechanism rather than adding one.
|
|||
|
|
3. A note that is promoted acquires a reproduction meeting D3 — there is
|
|||
|
|
no path from `note` to `reported` that skips it.
|
|||
|
|
|
|||
|
|
**Why not refusal.** A finding from *play* — the maintainer's *"I felt it
|
|||
|
|
was too easy but then we lost"* — is real, has no cheap artifact, and is
|
|||
|
|
the seed of CB-WP-0025. Refusing it would throw away the only class of
|
|||
|
|
finding the engine cannot produce by itself. **Why not silence.** A note
|
|||
|
|
that cannot expire ages into an apparent finding, which is the failure
|
|||
|
|
this register exists to stop.
|
|||
|
|
|
|||
|
|
## D7 — no engine-evolution register, on a corrected inventory
|
|||
|
|
|
|||
|
|
The declaration's judgment survives; **its argument did not, and the
|
|||
|
|
difference is recorded rather than smoothed over.** My inventory named
|
|||
|
|
`evidence/`, `decisions/`, `gates.toml` and workplans. C5 found two places
|
|||
|
|
it missed — `specs/InnerLoopReference.md`, 383 lines with sections headed
|
|||
|
|
*"moved from InnerLoop v1.6"*, and 769 lines of `history/` retrospectives.
|
|||
|
|
So the "third thing" the maintainer asked about **does exist and did find
|
|||
|
|
homes**, somewhat by accident.
|
|||
|
|
|
|||
|
|
Decision: **no new register**, because a third place to look for material
|
|||
|
|
currently in two makes it less findable, not more. This is argued and
|
|||
|
|
narrowed, **not settled** — if InnerLoopReference keeps absorbing content
|
|||
|
|
that is neither a decision nor a finding, that is the signal to revisit.
|
|||
|
|
|
|||
|
|
## D8 — `tools/design-baseline.py` is retired, not extended
|
|||
|
|
|
|||
|
|
C2 dismantled it: a hand-maintained dict counting itself (`:16-36`, `:89`),
|
|||
|
|
a `has_reproduction` that never checks the file exists (`:38-43`) so its
|
|||
|
|
own YES-control is green against a path `2da19a4` deleted (`:63`), date
|
|||
|
|
literals for the 4-day figure (`:96-98`), and `Makefile:127` running only
|
|||
|
|
`--self-test` so the reporting path has no CI at all.
|
|||
|
|
|
|||
|
|
**The 33% is withdrawn as a measured rate.** What survives is direction:
|
|||
|
|
eleven files with no index and 0 of 10 U-items ruled are both checkable
|
|||
|
|
without the tool.
|
|||
|
|
|
|||
|
|
`make design` (T05) reports **over the register**, which is real data with
|
|||
|
|
real files behind it, and its reproduction check **stats the file**. The
|
|||
|
|
baseline stays in the repo as the survey's dated snapshot, marked
|
|||
|
|
superseded — deleting it would erase the evidence for how the number got
|
|||
|
|
in.
|
|||
|
|
|
|||
|
|
## D9 — where a finding lives, and where it is delivered
|
|||
|
|
|
|||
|
|
The survey did not settle this. **Both, with distinct roles:**
|
|||
|
|
|
|||
|
|
- **clay-borg holds the finding and its reproduction**, in
|
|||
|
|
§Underdetermined. The artifact cannot leave — it only runs here.
|
|||
|
|
- **ground-game receives a generated report file under its own workplan**,
|
|||
|
|
not an inbox message. Per CB-WP-0022 T06: *the message that sat unread
|
|||
|
|
for four days is the baseline to beat, and the failure was not the
|
|||
|
|
message — it was that nothing pointed at it.*
|
|||
|
|
|
|||
|
|
The report **cites the reproduction by path**, which is the half of
|
|||
|
|
GROUND-WP-0004 T02's ruling that is theirs to keep, and makes the split
|
|||
|
|
survivable: they read a claim, we hold the thing that proves it.
|
|||
|
|
|
|||
|
|
## Consequences
|
|||
|
|
|
|||
|
|
- `INTENT.md` gains property 4 (D1) — the change with the longest
|
|||
|
|
half-life in this pass.
|
|||
|
|
- `specs/GroundRules.md §Underdetermined` becomes the register and gains
|
|||
|
|
`kind` and `state` per item (D2, D4, D5); **no new file, no new schema.**
|
|||
|
|
- T04's spec inherits D3 as a **rule**, not an addendum, and must say what
|
|||
|
|
a reproduction has to *show*.
|
|||
|
|
- T05 builds `make design` over the register and backfills all six. If a
|
|||
|
|
sixth kind is needed, the taxonomy was invented.
|
|||
|
|
- T06 reports the queue **and GR-E01's withdrawal**.
|
|||
|
|
- Notes carry a 30-day expiry (D6) on the existing age machinery.
|
|||
|
|
|
|||
|
|
## What was rejected
|
|||
|
|
|
|||
|
|
| rejected | why |
|
|||
|
|
|---|---|
|
|||
|
|
| a new register file with its own schema | C4 — the incumbent already delivers 4 of 5 benchmarks |
|
|||
|
|
| the existence-only admissibility rule | C1 — its own showcase finding passed it and was false |
|
|||
|
|
| refusing findings without reproductions | throws away findings from play, which is CB-WP-0025's entire input |
|
|||
|
|
| an engine-evolution register | D7 — a third home for material already in two |
|
|||
|
|
| extending `design-baseline.py` | C2 — it counts itself and its positive control is green against a deleted file |
|