clay-borg/specs/Taxonomy.md
tegwick 2806b3acb7
Some checks failed
ci / check (push) Failing after 3s
CB-WP-0041 done: ADR-0020 refuses the port, and T02 is why
T02 — all chance derives from one root seed. Three chance points, all
reading it: the setup deck shuffle, the setup Lead draw, and the reshuffle
permutation. The Problems deal is not chance at all. So in extensive-form
terms the tree has a single chance node at the root.

That test was wrong first, and the mutation caught it. It compared state
hashes — and GroundState carries `seed` as a field, so "different seeds
differ" was true by construction. Mutating the shuffle away left it green.
It now compares the dealt configuration, and the same mutation fails it: a
wrong-subject error inside the control written for T02.

The reshuffle is a pure function of (seed, round) because K5 requires
deterministic replay, where a real table reshuffles independently. That is
a modelling restriction, not a defect, and it is now pinned.

T03 — commit/reveal checked in both directions: before Reveal each seat
sees its own selection and no other; after Reveal the information sets
merge, because an encoding that hides forever is not commit/reveal either.

T04 — ADR-0020 refuses the EFG port, and the blocker is T02 rather than
T01, which inverts what the workplan expected. Perfect recall looked like
the risk and is a constraint with a known answer: key on observation
histories. Making chance explicit is the expensive one — the reshuffle
would become a real chance node and break the K5 purity that every
recording, replay bundle and trial-note hash depends on. A port would
trade the property this project is built on for one it has never needed.

Track B's first move is therefore a question, not a build: take "is
exploitability meaningful for a co-operative game with a shared threshold"
to OpenSpiel on a toy model, where answering it costs nothing. D4 states
what being wrong looks like — OpenSpiel settling on a toy what three
rounds of policy sweeps could not — and makes watching for it the next
action.

Taxonomy §4.1 records the EFG correspondence with the test that checks
each row, so a later pass starts from a specification rather than a memory.

Chaos window 4 at three declarations. Window 3's verdict is now two
windows behind and should be evaluated rather than restated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 15:35:03 +02:00

208 lines
10 KiB
Markdown

# Taxonomy — which system is a statement about?
Status: **draft**, normative for new work. Changes go through a decision
record in `decisions/`.
This document exists because the words were doing too much work. *"Error"*,
*"failure"*, *"finding"* and *"correction"* were each being used for the
game's design, our formalisation of it, the code, the measuring apparatus,
and the sentences we wrote — five different things, one vocabulary.
> **Every defect statement names a stratum before it names anything else.**
> "A bug in the simulator" and "a gap in the game" are not the same kind of
> claim, do not have the same owner, and are not fixed by the same person.
Grounded in existing practice rather than invented here: the
fault/error/failure chain from **Avizienis, Laprie, Randell & Landwehr**
(*Basic Concepts and Taxonomy of Dependable and Secure Computing*, IEEE
TDSC 1:1, 2004); the model strata and the verification/validation split
from **Sargent** (*Verification and Validation of Simulation Models*); and
**MDA** (Hunicke, LeBlanc & Zubek, 2004) for the game-facing layers.
---
## 1. The strata
| stratum | canon | what it is | who owns it |
|---|---|---|---|
| **GAME** | Sargent's *problem entity*; MDA *mechanics as designed* | the rules as the game's owner defines them — the edition, the printed text | **the game's owner**, not us |
| **MODEL** | Sargent's *conceptual model* | our formalisation: `GroundRules.md`, the rule ids, the state we chose to represent | us, answerable to the owner |
| **ENGINE** | Sargent's *computerized model* | the kernel that implements the model | us |
| **INSTRUMENT** | measurement apparatus | harnesses, policies, metrics, gates, the trial protocol | us |
| **ACCOUNT** | — | evidence files, register entries, messages, this document | us |
| **PRESENTATION** | MDA *aesthetics*-facing | the page, and everything [`Ornamentation.md`](Ornamentation.md) covers | us, later `clay-animate` |
### 1.1 The two relations that matter
> **GAME ↔ MODEL is validation.** *Did we formalise the right game?*
>
> **MODEL ↔ ENGINE is verification.** *Did we implement the formalisation
> correctly?*
This is Sargent's split and it is the one we kept losing. A statement that
the engine mis-scores a Bond is **verification**. A statement that the
rules do not say what happens when two Bonds break simultaneously is
**validation** — and it is not ours to answer.
**Sargent's third leg is `data validity`**, and it is where
`editions/` lives: the vendored CSVs, their digests, and the tripwires in
`edition.rs` are data validation, not verification.
### 1.2 What each stratum's defects look like
| stratum | a defect here looks like |
|---|---|
| GAME | a rule that does not decide; a dominant strategy; an action that earns its place nowhere |
| MODEL | we represented a rule the edition does not have, or omitted one it does |
| ENGINE | the code does not do what `GroundRules.md` says |
| INSTRUMENT | the measurement answers a different question than the one asked |
| ACCOUNT | the sentence claims more than the artifact shows |
| PRESENTATION | the player cannot see, or misreads, what the state says |
---
## 2. Fault, error, failure
Avizienis' chain, unchanged, applied **within** a stratum.
| term | definition | example, INSTRUMENT stratum |
|---|---|---|
| **fault** | the defect in the artifact — the wrong line, the wrong column, the wrong constant | `peak` maximised over `StressSet` payloads |
| **error** | the wrong internal state it produces | the metric holds 1 where the game held 2 |
| **failure** | the deviation visible at the interface | the evidence file says *"peak Stress was 1"* |
**A fault is dormant until activated.** `attack-value.rs`'s missing
assertion was a fault for weeks and produced no error, because no cell was
ever short.
### 2.1 The rule that explains our history
> **A failure in one stratum is a fault in the next.**
An INSTRUMENT failure (a metric reporting the wrong number) is an ACCOUNT
fault (a sentence built on it). An ACCOUNT failure that reaches the owner
is a fault in *their* decision-making. That is why
[`GameDesign.md`](GameDesign.md) §1 gates what may leave the repo: it is a
firebreak in this chain, not politeness.
### 2.2 The wrong-subject error, defined at last
[ADR-0018](../decisions/ADR-0018-a-number-that-does-not-move.md) named a
family and could not say precisely what it was. In this vocabulary:
> **A wrong-subject error is an ACCOUNT failure with no INSTRUMENT fault.**
> The measurement is correct about *its* subject; the sentence is about a
> different one.
`peak Stress was 1` — the metric correctly reported the maximum *assigned*
Stress. `Reactive is greedy with one preference changed` — the policy
correctly implemented what was written. **Nothing was miscomputed in
either case**, which is exactly why tests did not catch them and why the
fix is never "add a test to the engine".
---
## 3. The vocabulary, fixed
| word | means | does not mean |
|---|---|---|
| **finding** | a statement about the **GAME** stratum, admissible under GameDesign §1, addressed to the owner | any defect we happen to notice |
| **defect** | a fault in any stratum we own — MODEL, ENGINE, INSTRUMENT, ACCOUNT, PRESENTATION | a design question |
| **fix** | a change to the **artifact** that removes a fault | a change to what we said |
| **correction** | a change to the **ACCOUNT** — a claim withdrawn, restated or re-derived | a code change |
| **retraction** | a correction of something that has already **left the repo** | an internal edit |
| **regression** | a fault introduced by a change, in any stratum | any failure |
| **inert control** | a control that cannot fail, so proves nothing (ADR-0006 D3) | a control that happens to be green |
**The register carries findings.** Where an entry is really a defect in a
stratum we own — F18, F24, F25 are ENGINE/data — the row says so, because
"the engine has not read this file" and "the game does not decide this"
are different claims to a reader deciding what to act on.
---
## 4. What the layers measure, and what they cannot
MDA gives the game-facing split, and it maps onto instruments we already
have:
| MDA layer | where it lives here | what measures it |
|---|---|---|
| **Mechanics** | GAME → MODEL → ENGINE | the rule-coverage gate, the edition tripwires |
| **Dynamics** — the behaviour that emerges in play | what the ENGINE produces over many games | the policy panels: win rates, DARVO arm rates, action selection |
| **Aesthetics** — the player's response | not representable in state | **trial notes, and nothing else** |
> **Our panels measure dynamics. Our trial logs sample aesthetics. Neither
> substitutes for the other**, and the recurring temptation is to report a
> dynamics number as though it settled an aesthetics question — *"is the
> game fun at 5 seats"* is not answered by a win rate.
MDA's own directional insight is the reason: **the designer builds
mechanics upward hoping for a feeling; the player meets the feeling first
and infers the rules.** A simulator sits at the bottom of that arrow and
can only ever report upward.
---
## 4.1 The MODEL stratum has a formal name now
The **extensive-form game** is what our MODEL stratum corresponds to, and
the correspondence is established rather than assumed
([CB-WP-0041](../workplans/CB-WP-0041-the-extensive-form-foundation.md)):
| EFG component | ours | checked by |
|---|---|---|
| histories | the journal | — |
| actions | `bot::legal_commands` | — |
| **information sets** | the seat's **observation history**, *not* `project()` | `perfect-recall` |
| chance | **a single root node**; the reshuffle is correlated with it | `a_game_is_determined_by_its_seed` |
| simultaneity | commit/reveal, the textbook encoding | `a_pending_selection_is_hidden_until_reveal` |
| payoffs | `Outcome` / `score()` | — |
**`project()` is an observation, not an information state**, and the
distinction cost 22 measured violations to find. It is the same split
OpenSpiel draws between `ObservationString` and `InformationStateString`.
**No port was built** — [ADR-0020](../decisions/ADR-0020-we-do-not-build-the-port.md)
refuses it, because making chance explicit would break the replay purity
the evidence discipline rests on.
## 5. Worked examples from this repo
Because a taxonomy with no instances was invented rather than observed
(GameDesign §2).
| what happened | stratum | fault / error / failure |
|---|---|---|
| `solution_deck()` is a Rust literal that never reads `Solutions.csv` | ENGINE (data validity) | dormant **fault**; no error, because the literal agrees |
| `score()` read `self` while H1's pressure went into `work` | ENGINE | **fault**; error only at round 5; no measured failure |
| GR-P05 — SOLVE offered where it could not act | MODEL, then GAME | our **failure**, escalated to a GAME finding, ruled by the owner |
| ATTACK earns its place in no mode (F17) | **GAME** | a finding — not a defect at all |
| `peak Stress was 1` | ACCOUNT | **failure** with no instrument fault (§2.2) |
| the panels ran under no gate | INSTRUMENT | **fault** — every published figure came from an ungated binary |
| the note channel closed when the game ended | PRESENTATION | **failure**; the state was right, the player could not reach it |
**Read the stratum column.** Six rows, six different owners and six
different fixes, and every one of them was called "an error" at the time.
---
## 6. Falsifier
If a defect arises that cannot be placed in exactly one stratum, the
strata are wrong — either too few, or cut in the wrong place. **Record the
instance rather than widening a definition to swallow it**, which is how a
taxonomy stops distinguishing anything.
A second falsifier, from §2.2: if a wrong-subject error is ever found that
*did* have an instrument fault, then the family is not what ADR-0018 and
this document say it is.
## Sources
- Avizienis, Laprie, Randell & Landwehr, *Basic Concepts and Taxonomy of
Dependable and Secure Computing*, IEEE TDSC 1(1), 2004.
- Sargent, *Verification and Validation of Simulation Models*, Winter
Simulation Conference.
- Hunicke, LeBlanc & Zubek, *MDA: A Formal Approach to Game Design and
Game Research*, AAAI Workshop, 2004.