CB-WP-0042 T01-T04: H2's scoped stress, with the named defects caught
Some checks failed
ci / check (push) Failing after 4s
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>
This commit is contained in:
parent
05d1a9aada
commit
04e26b3077
9 changed files with 900 additions and 7 deletions
|
|
@ -2,7 +2,7 @@
|
|||
id: CB-WP-0042
|
||||
kind: product
|
||||
title: "H2 — scoped problem stress"
|
||||
status: ready
|
||||
status: active
|
||||
state_hub_workstream_id: "8f11d55b-3452-49f3-9857-d0bf06752f68"
|
||||
---
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ do not have:
|
|||
|
||||
```task
|
||||
id: CB-WP-0042-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "37f9bc34-05d1-4a12-9a98-6c61ab3ec23f"
|
||||
```
|
||||
|
|
@ -74,11 +74,20 @@ state_hub_task_id: "37f9bc34-05d1-4a12-9a98-6c61ab3ec23f"
|
|||
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: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "65b9b2b8-8160-488f-8cd4-b7f734d03b22"
|
||||
```
|
||||
|
|
@ -96,11 +105,21 @@ starting at Lead, stepping clockwise. Global Problems have no owner.
|
|||
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: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "8426e79c-579e-4aba-a695-381020016206"
|
||||
```
|
||||
|
|
@ -118,11 +137,26 @@ ordering H1-A needed, and the same trap.
|
|||
- **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: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "6606cb3b-733d-486c-9e46-37a2a2b0c2c9"
|
||||
```
|
||||
|
|
@ -135,6 +169,9 @@ 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue