Some checks failed
ci / check (push) Failing after 4s
H2 is ground-game's answer to our H1 reading — that a flat +1 to every seat is a solve-rate tax scaling with the number of Problems. Unclaimed Problems now tick only the seats in scope: global (all), personal (the owner), bond (the owner's Bond network over Bond edges only, degree 0 falling back to personal), assigned by hidden priority so 2p never has the bond card in play. T01: the package is vendored with digests, and H2's Problems.csv is r0's with one column added and NOTHING else changed — checked, not assumed, because the delta claims deal_and_thresholds unchanged and a silent difference would make every H2-vs-baseline comparison a comparison of two boards as well as two rule sets. Scopes are read from the column, not derived from the priority in Rust: F25 exists because we hardcoded numbers the edition already carried. T02: owner and scope are new ProblemState fields, both Option and both skipped when None, so a baseline state serialises without them and every recorded scenario's hash is untouched — asserted on the JSON, not assumed. with_variant() replaces the bare field write, because state.variant = v would leave owners unassigned: a silently wrong game rather than a failing one. T03: every named defect is mutation-proven — traversing Rivalry edges, applying stacking once, a degree-0 owner ticking everyone, personal hitting everyone. The degree-0 mutation MISSED first: the fallback lives inside bond_network and the mutation broke the None-owner arm instead, a different branch. It stayed green until aimed at the path the test exercises. A mutation that misses is not evidence the test works. T04: ownership is not a permission. Filtering SOLVE to the owner turns it red, which is the regression this task exists for — the engine had no owner concept before T02 added one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
204 lines
7.8 KiB
Markdown
204 lines
7.8 KiB
Markdown
---
|
|
id: CB-WP-0042
|
|
kind: product
|
|
title: "H2 — scoped problem stress"
|
|
status: active
|
|
state_hub_workstream_id: "8f11d55b-3452-49f3-9857-d0bf06752f68"
|
|
---
|
|
|
|
# Purpose
|
|
|
|
```
|
|
structural tier M (touches a canonical interface: edition loading
|
|
becomes variant-parameterised, and the kernel gains
|
|
per-Problem state)
|
|
chaos d8 = 4 → no override
|
|
declared tier M
|
|
```
|
|
|
|
**Declaration 2 of chaos window 4.**
|
|
|
|
## Why, and it is a direct answer to ours
|
|
|
|
We reported that H1-A behaves as a **solve-rate tax**: a flat +1 to every
|
|
seat while any Problem is unclaimed, so the pressure scales with the
|
|
number of Problems while the intended effect does not.
|
|
|
|
`ground-game` responded with **H2 — scoped problem stress**. Unclaimed
|
|
Problems now tick **only the seats in their scope**:
|
|
|
|
| scope | who takes the +1 |
|
|
|---|---|
|
|
| `global` | all seats |
|
|
| `personal` | the Problem's **owner** |
|
|
| `bond` | the owner's **Bond network** — owner plus every seat reachable over Bond edges only, never Rivalry; degree 0 falls back to personal |
|
|
|
|
Assigned by hidden priority: **0 (Surface) global, 1 personal, 2 personal,
|
|
3 bond, 4 personal** — which is a seat-band dial without a difficulty
|
|
card, since 2p never has the bond card in play.
|
|
|
|
**It does not stack with H1.** `replaces_experiments: [h1-problem-stress]`,
|
|
base is `ground-darvo-r0`, and there is **no ATTACK self-soothe**.
|
|
|
|
## Why this is bigger than H1 was
|
|
|
|
H1 was two arithmetic deltas on existing state. H2 needs three things we
|
|
do not have:
|
|
|
|
1. **Variant-scoped edition data.** H2 overrides `Problems.csv` with a
|
|
new `stress_scope` column. `edition.rs` `include_str!`s r0's copy at
|
|
compile time — **the data is currently a constant, not a parameter.**
|
|
2. **Per-Problem ownership**, assigned at setup. That is **new state**,
|
|
so it reaches the state hash and every recording.
|
|
3. **Bond-network reachability** — a graph traversal over Bond edges
|
|
only, with a degree-0 fallback.
|
|
|
|
## Task: variant-scoped edition data
|
|
|
|
```task
|
|
id: CB-WP-0042-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "37f9bc34-05d1-4a12-9a98-6c61ab3ec23f"
|
|
```
|
|
|
|
**Controls:**
|
|
- **the baseline's data is bit-for-bit what it was**, and its state hashes
|
|
do not move — the control that protected CB-WP-0038 and the one that
|
|
invalidates every prior measurement if it fails;
|
|
- the H2 package is **vendored with digests** like every other borrowed
|
|
file, and `edition-check` covers it — sibling discovery walks the disk
|
|
now, so an undigested file fails (CB-REV-0003 #8);
|
|
- **`stress_scope`'s assignment is read from the file, not hardcoded.**
|
|
The delta states the priority→scope mapping; **it is the edition's to
|
|
state and ours to read**, and F25 exists because we hardcoded numbers
|
|
the edition already carried.
|
|
|
|
**Done 2026-08-08.** Package vendored with digests; `edition-check` walks
|
|
it. `StressScope` and `stress_scopes()` read the column.
|
|
|
|
**H2's `Problems.csv` is r0's with one column added and nothing else
|
|
changed** — same rows, values, suits, visibilities and priorities. That is
|
|
**checked, not assumed**: the delta claims `deal_and_thresholds` unchanged,
|
|
and a silent difference would make every H2-vs-baseline comparison a
|
|
comparison of two boards as well as two rule sets.
|
|
|
|
## Task: ownership at setup
|
|
|
|
```task
|
|
id: CB-WP-0042-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "65b9b2b8-8160-488f-8cd4-b7f734d03b22"
|
|
```
|
|
|
|
`H2-OWN`: ascending hidden priority among in-play non-global Problems,
|
|
starting at Lead, stepping clockwise. Global Problems have no owner.
|
|
|
|
**Controls:**
|
|
- **deterministic**, and asserted so — the delta says "deterministic for
|
|
sims" and a seeded-but-unstated order would be untestable;
|
|
- **the baseline carries no owners and its hash does not move.** New
|
|
state that is `None` under baseline must serialise as it did before, or
|
|
every recorded scenario breaks;
|
|
- **exactly one owner per eligible Problem**, checked at every seat count,
|
|
because the assignment walks two sequences at once and off-by-one is
|
|
the obvious failure.
|
|
|
|
**Done 2026-08-08.** `owner` and `scope` on `ProblemState`, both
|
|
`Option`, both `skip_serializing_if = "Option::is_none"` — so a baseline
|
|
state serialises **without them** and every recorded scenario's hash is
|
|
untouched. Asserted directly, on the JSON.
|
|
|
|
**`with_variant()` replaces the bare field write.** `state.variant = v`
|
|
would leave owners unassigned — **a silently wrong game rather than a
|
|
failing one** — so the builder applies the variant's setup and every
|
|
driver path goes through it.
|
|
|
|
## Task: scoped pressure
|
|
|
|
```task
|
|
id: CB-WP-0042-T03
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "8426e79c-579e-4aba-a695-381020016206"
|
|
```
|
|
|
|
`H2-A`, at Round End, before the clamp and the DARVO arm check — the same
|
|
ordering H1-A needed, and the same trap.
|
|
|
|
**Controls:**
|
|
- **each scope fails on its own**, by mutation: global hitting only the
|
|
owner, personal hitting everyone, bond stopping at the owner;
|
|
- **`stacking: true` is tested** — two open bond Problems must tick the
|
|
network **twice**, and a careless implementation applies it once;
|
|
- **Rivalry edges are not traversed.** The delta says Bond only, and a
|
|
traversal that follows any relation is the single most likely defect;
|
|
- **degree 0 falls back to personal**, which is the branch a test forgets;
|
|
- ordering asserted as in CB-WP-0038: pressure before the arm check.
|
|
|
|
**Done 2026-08-08.** All four named defects mutation-proven:
|
|
|
|
| mutation | caught by |
|
|
|---|---|
|
|
| traverse Rivalry edges too | `h2_bond_scope_does_not_traverse_rivalry` |
|
|
| stacking applied once | `h2_pressure_stacks_per_problem` |
|
|
| degree-0 owner ticks everyone | `h2_a_bond_problem_with_no_bonds_is_personal` |
|
|
| personal hits everyone | `h2_pressure_reaches_only_the_scope` |
|
|
|
|
**The degree-0 mutation missed first**, and that is worth recording: the
|
|
fallback lives *inside* `bond_network`, and the first mutation broke the
|
|
`None`-owner arm instead — a different branch. It stayed green until the
|
|
mutation was aimed at the path the test actually exercises. **A mutation
|
|
that misses is not evidence the test works.**
|
|
|
|
## Task: SOLVE is not restricted by scope
|
|
|
|
```task
|
|
id: CB-WP-0042-T04
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "6606cb3b-733d-486c-9e46-37a2a2b0c2c9"
|
|
```
|
|
|
|
`H2-SOLVE`: any seat with a matching suit may claim; the owner need not be
|
|
the solver, and altruistic clearing is **intended**.
|
|
|
|
**Control:** our engine has no owner concept today, so this is already
|
|
true — which makes it a **regression test, not a feature**. T02 adds
|
|
ownership, and the risk is that ownership silently becomes a permission.
|
|
The test must fail if it does.
|
|
|
|
**Done 2026-08-08**, and it does: filtering SOLVE to the owner in
|
|
`legal_commands` turns it red.
|
|
|
|
## Task: measure, and report what fails
|
|
|
|
```task
|
|
id: CB-WP-0042-T05
|
|
status: todo
|
|
priority: high
|
|
state_hub_task_id: "0bcd97da-60b8-46b2-ae86-7a94f6af8dd5"
|
|
```
|
|
|
|
Same instrument as H1, same panel, both variants in one run.
|
|
|
|
**Controls:**
|
|
- **greedy and `reactive` both**, because H1's whole verdict turned on
|
|
which policy was asked (CB-EV-0031);
|
|
- **report against ground-game's own criteria** for H2, from their design
|
|
note — **read it, do not reuse H1's §3.2 from memory**;
|
|
- **the bond-scope hypothesis is the interesting one and must be measured
|
|
directly**: their claim is that a shared tick makes a Bond network
|
|
*jointly motivated* to solve that card. Whether a policy that does not
|
|
model other seats can express that at all is an open question, and the
|
|
honest answer may be "our panel cannot test this hypothesis";
|
|
- **`make panels` runs it**, or the figures come from an ungated binary
|
|
again (CB-REV-0002 #7).
|
|
|
|
## Not in this workplan
|
|
|
|
- **No stacking with H1.** The package forbids it explicitly.
|
|
- **No felt-play.** H2's central claim is about *motivation* — a bonded
|
|
pair caring about each other's card — and 200-game aggregates measure
|
|
dynamics, not that ([`Taxonomy.md`](../specs/Taxonomy.md) §4).
|