130 lines
5.7 KiB
Markdown
130 lines
5.7 KiB
Markdown
---
|
|
id: CB-WP-0046
|
|
kind: product
|
|
title: "The rule the placement encodes"
|
|
status: done
|
|
state_hub_workstream_id: "169242ac-024d-4001-aae2-d9bbf710fe2a"
|
|
---
|
|
|
|
# Purpose
|
|
|
|
```
|
|
structural tier S (one new edition reader, one rendered passage, one
|
|
marker attribute -- no rule, no dependency moved)
|
|
declared tier S
|
|
```
|
|
|
|
Closes the two gaps [CB-WP-0045](CB-WP-0045-the-table-names-what-it-shows.md)
|
|
named as *not done*.
|
|
|
|
## The gap, and the wrong reason given for it
|
|
|
|
CB-WP-0045 recorded:
|
|
|
|
> *"Nothing explains what a scope does … it is a `ground-game` question
|
|
> first: the scope rule is ours (Variant), not the edition's, so there is
|
|
> no vendored sentence to render."*
|
|
|
|
**The premise was false.** `editions/experiments/h2-scoped-problem-stress/`
|
|
ships `Rules_Text.csv`, and its `Problems / Stress scope` passage is the
|
|
rule verbatim:
|
|
|
|
> *"Each Problem has stress_scope. global: every seat. personal: the
|
|
> assigned owner only. bond: the owner and every seat connected to the
|
|
> owner through one or more Bonds (the Bond network). If the owner has no
|
|
> Bonds, bond scope behaves as personal. Rivalries do not expand bond
|
|
> scope. Multiple unclaimed Problems stack (+1 each) for seats in their
|
|
> scopes."*
|
|
|
|
**Nothing in clay-borg had ever read the file.** Twenty-two passages of
|
|
player-facing rules, in the repo, unreachable by a player — a whole
|
|
rulebook, where CB-WP-0045 found single columns.
|
|
|
|
**Third instance of F18's shape in two passes**, and the largest. The
|
|
pattern is now specific enough to name: *when a package adds a file rather
|
|
than a column, nothing notices.* `edition-check` verifies the digest and
|
|
freshness of files it knows; a file no reader mentions is not stale, it is
|
|
invisible. Recorded as a finding for `ground-game` rather than fixed here.
|
|
|
|
**The escalation is the part worth keeping.** CB-WP-0045 did not just
|
|
leave a gap; it *explained* the gap with an argument that would have
|
|
stopped the next reader from looking. A wrong reason for an open item is
|
|
worse than an open item, because it retires the question.
|
|
|
|
## The log said nothing about which rules were played
|
|
|
|
`2026-08-08-1734`: *"Well, i did not notice any difference, maybe i did
|
|
not start the H2 variation?"* **The log cannot answer that** — and neither
|
|
could we, a week later, from the file.
|
|
|
|
The variant rides the **begin marker**, not an eighth column:
|
|
|
|
```
|
|
<!-- trial-log:begin variant=h2-scoped-problem-stress -->
|
|
```
|
|
|
|
It is a property of the **session** (fixed at startup, constant across
|
|
`play again`), so a per-row column would repeat one fact on every line and
|
|
force a third accepted row width on a parser whose docstring is about
|
|
exactly that hazard (CB-WP-0032). The table shape is untouched.
|
|
|
|
**Stamped from `state.variant`, never from the `--variant` flag.** Three
|
|
call sites once wrote `state.variant = v` directly instead of
|
|
`with_variant()`, which leaves H2 inert; a log stamped from the flag would
|
|
have recorded `h2` for a session that played the baseline. **A false
|
|
provenance on real player words is worse than no provenance** — which is
|
|
also why an unstamped log reports `unrecorded` and not `ground-darvo-r0`.
|
|
|
|
## Task: render the rule, stamp the log
|
|
|
|
```task
|
|
id: CB-WP-0046-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "64b9e9bb-bcaa-45e5-975f-3527e4c95c05"
|
|
```
|
|
|
|
**Controls, all mutation-proven:**
|
|
|
|
| mutation | what went red |
|
|
|---|---|
|
|
| the scope rule never renders | *"Problems are placed by scope and nothing says what a scope does"* |
|
|
| it renders always, baseline included | *"the baseline table explains a scope distinction that is not in play"* |
|
|
| our paraphrase instead of the passage | *"the scope explanation is not the edition's own words"* |
|
|
| the writer drops the attribute | *"the log does not say which rules were played"* |
|
|
| unstamped parses as `ground-darvo-r0` | *"an unstamped log says NOTHING, not 'baseline'"* |
|
|
| `BEGIN` back to an exact match | *"the bytes hotseat.rs writes are the bytes this parses"* |
|
|
|
|
**The last mutation is the finding.** It went green the first time. Every
|
|
`trials.py` fixture composed its marker out of `BEGIN`, so all of them
|
|
**followed `BEGIN` wherever it went** — including away from what
|
|
`hotseat.rs` actually writes. Nine checks about the marker, and reverting
|
|
the marker broke every real stamped log with all nine still green.
|
|
|
|
The format is shared across two languages, so the control has to be a
|
|
**literal**: the exact bytes the writer emits, asserted from the reading
|
|
side, with the writer's own test asserting the same string from the other.
|
|
A fixture built from the constant under test cannot test the constant.
|
|
|
|
`stress_scope_rule()` matches on the **heading**, not on row 20 — a row
|
|
number is a property of today's file, a heading is a property of the rule
|
|
— and returns `None` if the edition stops carrying it (ADR-0018: an absent
|
|
explanation is reported absent, never replaced by ours).
|
|
|
|
**Done 2026-08-08.** `make all` green; `cargo test`: 80 render + 35 play;
|
|
24 `trials.py` checks. Verified on a live `make ground VARIANT=h2` page.
|
|
|
|
## Not done here
|
|
|
|
- **The other 21 passages are still unread.** `h2_rules_text()` returns
|
|
the whole rulebook and one caller uses one row of it. The Round-step
|
|
passages in particular are the account of the sequence the player is
|
|
standing in, and there is nowhere on the page that says it.
|
|
- **The baseline has no `Rules_Text.csv` at all**, so this explains only
|
|
the experiment. A baseline player still gets no rulebook — the reverse
|
|
of the usual gap, and a `ground-game` question.
|
|
- **The 11 existing notes stay `unrecorded` forever.** Their variant was
|
|
never written down; inventing one is the defect this pass exists to
|
|
avoid. `2026-08-08-1818`'s three notes are almost certainly H2 on the
|
|
internal evidence of what they say, and *almost certainly* is not a
|
|
provenance.
|