Apply ground-game's rulings: mastery in points, four boards, and a
Some checks failed
ci / check (push) Failing after 4s
Some checks failed
ci / check (push) Failing after 4s
vendor tool that covers what the gate checks
They ruled on all seven items the same day. Two were actionable here.
F28 RULED: points. Modes.csv MODE_COOP clarified upstream to say
"penalties apply to points, not card count"; mastery is now
total - blame - denied. A recorded scenario went red on it --
gr-e02-shared-ground pinned 0 (2 claimed CARDS - 1 - 1) and now expects
2 (4 POINTS - 1 - 1). The number moved because the rule was decided, not
because the engine drifted, and the scenario records both rulings; its
schema has no field for a second one, so both live in ruled_note with
`ruled` carrying the LATEST date.
F29 RULED not-intended and APPLIED upstream: SCN_02's suits re-tuned the
same day. The characterisation test is how we found out -- it pinned the
duplication, went red on the re-tune, and that red WAS the notification.
It now asserts every pair distinct, the stronger statement the
duplication had made unavailable. SCN_02 re-measures at 73 at 2p, not
67: its own board now.
F26/F30 ruled and recorded. F30's ruling incidentally confirms our
reading -- they name priority-2's suit as the first lever, which is the
difference we identified without having measured causation.
vendor-editions grew twice, both times because it covered less than the
gate it exists to satisfy:
- It refused to touch ground-darvo-r0/ on the reasoning that the
baseline is "a separate record". That was wrong within the hour:
ground-game clarified Modes.csv and `make vendor` reported a clean
sync while edition-check went red. A sync tool that covers less than
its check reports success into a red gate.
- Its two-block rewrite DETECTED which fence held which set and
preserved the arrangement -- faithfully preserving a swap an earlier
write had introduced, leaving each fence under a heading describing
the other. edition-check reads every sha256 line flat and passed
throughout: a document can be self-consistently wrong and green.
Order is now asserted, with a control that goes red on a swap.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
98f600b1d3
commit
704b99975b
15 changed files with 373 additions and 154 deletions
|
|
@ -55,8 +55,8 @@
|
|||
| workplan | CB-WP-0045 | done | — | workplans/CB-WP-0045-the-table-names-what-it-shows.md |
|
||||
| workplan | CB-WP-0046 | done | — | workplans/CB-WP-0046-the-rule-the-placement-encodes.md |
|
||||
| workplan | CB-WP-0047 | done | — | workplans/CB-WP-0047-all-four-boards-and-all-three-modes.md |
|
||||
| workplan | CB-WP-0048 | in_progress | — | workplans/CB-WP-0048-a-configuration-not-a-variant.md |
|
||||
| workplan | CB-WP-0049 | in_progress | — | workplans/CB-WP-0049-a-seat-that-plays-its-own-objective.md |
|
||||
| workplan | CB-WP-0048 | active | — | workplans/CB-WP-0048-a-configuration-not-a-variant.md |
|
||||
| workplan | CB-WP-0049 | active | — | workplans/CB-WP-0049-a-seat-that-plays-its-own-objective.md |
|
||||
| task | CB-WP-0001-T01 | done | — | workplans/CB-WP-0001-inner-loop.md |
|
||||
| task | CB-WP-0001-T02 | done | — | workplans/CB-WP-0001-inner-loop.md |
|
||||
| task | CB-WP-0001-T03 | done | — | workplans/CB-WP-0001-inner-loop.md |
|
||||
|
|
|
|||
|
|
@ -93,6 +93,11 @@ profile: scoped_plus_attack_soothe
|
|||
- Each module: apply `rules_delta` + optional `data_overlays` from its `path`.
|
||||
- Apply modules in **aspect order** listed in `catalog.yaml` `aspects:` (stable, documented).
|
||||
- Conflict: refuse composition rather than last-write-wins.
|
||||
- **`consumed_files` (RPT-0006):** when present on a module, a consumer that
|
||||
has not read those paths is in a **detectable** incomplete state — not
|
||||
silence. Freshness/edition-check should fail or warn if a listed file is
|
||||
unread or undigested. Modules without the field still work; new modules
|
||||
should list it.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
schema_version: 2
|
||||
# terminology: aspect (human) = former axis; modules remain module_id
|
||||
# packages declare files consumers must read (consumed_files / data_overlays)
|
||||
updated: "2026-08-08"
|
||||
default_baseline: ground-darvo-r0
|
||||
default_profile: baseline
|
||||
|
|
@ -97,6 +98,12 @@ modules:
|
|||
status: measured
|
||||
rules_delta: editions/modules/problem_stress/scoped/rules_delta.yaml
|
||||
data_overlays: [Problems.csv, Rules_Text.csv]
|
||||
# files a consumer must open to implement this module (RPT-0006 §5b)
|
||||
consumed_files:
|
||||
- editions/modules/problem_stress/scoped/rules_delta.yaml
|
||||
- editions/modules/problem_stress/scoped/Problems.csv
|
||||
- editions/modules/problem_stress/scoped/Rules_Text.csv
|
||||
- editions/modules/problem_stress/scoped/MODULE.md
|
||||
legacy_experiment_ids: [h2-scoped-problem-stress]
|
||||
measurement_ref: reports/260808-clay-borg-h2-measured.md
|
||||
hypothesis_ref: history/260808-h2-scoped-problem-stress.md
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ PRB_01_2,SCN_01,Hidden,personal,2,Unspoken Overload,The work required more capac
|
|||
PRB_01_3,SCN_01,Hidden,bond,3,Bad News Was Delayed,A warning was withheld until the remaining options became worse.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=bond (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_01_4,SCN_01,Hidden,personal,4,No Checkpoint Process,The group had no reliable moment for testing progress and changing course.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_S,SCN_02,Surface,global,0,Shared Task Left Undone,"A recurring responsibility was not completed, and others absorbed the impact.",Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=global (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM_SURFACE
|
||||
PRB_02_1,SCN_02,Hidden,personal,1,Different Standards,"Players were using different definitions of complete, timely, or fair.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_2,SCN_02,Hidden,personal,2,Invisible Workload,Some contributions and constraints were not visible to the group.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_3,SCN_02,Hidden,bond,3,Resentment Never Raised,Frustration accumulated without a direct request or acknowledgement.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=bond (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_4,SCN_02,Hidden,personal,4,No Ownership Routine,The group relied on goodwill instead of a dependable allocation method.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_1,SCN_02,Hidden,personal,1,Different Standards,"Players were using different definitions of complete, timely, or fair.",Change,SYM_CHANGE,2,Resolve with Change. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_2,SCN_02,Hidden,personal,2,Invisible Workload,Some contributions and constraints were not visible to the group.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_3,SCN_02,Hidden,bond,3,Resentment Never Raised,Frustration accumulated without a direct request or acknowledgement.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=bond (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_4,SCN_02,Hidden,personal,4,No Ownership Routine,The group relied on goodwill instead of a dependable allocation method.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_03_S,SCN_03,Surface,global,0,Decision Announced as Settled,A group-affecting choice was presented as final before meaningful agreement.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=global (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM_SURFACE
|
||||
PRB_03_1,SCN_03,Hidden,personal,1,Mandate Was Ambiguous,"It was unclear who could decide, advise, consent, or veto.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_03_2,SCN_03,Hidden,personal,2,Contributions Were Dismissed,Relevant input was ignored or treated as less legitimate.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
|
|
|
|||
|
|
|
@ -1,4 +1,4 @@
|
|||
mode_id,title,mode_type,tagline,rules_text,scoring_tiebreak,back_design_id
|
||||
MODE_COOP,SHARED GROUND,Cooperative,The group succeeds or fails together.,"All claimed Problem cards form one shared score. Meet the Scenario threshold by the end of Round 5. Playable at 2–6 players — not a high-seat-only mode. No individual winner is declared. For a mastery rating, subtract 1 for each Blame token still in play and 1 for each Denied Problem.",Not applicable.,BACK_MODE
|
||||
MODE_COOP,SHARED GROUND,Cooperative,The group succeeds or fails together.,"All claimed Problem cards form one shared score equal to the sum of their point values. Meet the Scenario threshold by the end of Round 5. Playable at 2–6 players — not a high-seat-only mode. No individual winner is declared. For a mastery rating, start from that shared point total and subtract 1 point for each Blame token still in play and 1 point for each Denied Problem (penalties apply to points, not card count).",Not applicable.,BACK_MODE
|
||||
MODE_SEMI,"COMMON PROBLEM, PERSONAL EDGE",Semi-cooperative,The group must succeed before anyone can win.,"The group succeeds only if the total value of all claimed Problems meets the Scenario threshold (always ≤ available points for the seat band). If it succeeds, each player scores the value of Problems they claimed minus 1 per Blame token they hold. Highest score wins.","Lower Stress, then more Bonds, then shared victory.",BACK_MODE
|
||||
MODE_COALITION,BONDED COALITIONS,Dynamic teams,Bonds decide the sides at the end.,"The group must first meet the Scenario threshold (always ≤ available points for the seat band). At game end, each connected network of Bonds is a coalition; unbonded players are one-player coalitions. Sum the personal scores of coalition members. The highest-scoring coalition wins. Rivalries do not connect players.","Lower combined Stress, then fewer Blame tokens, then shared victory.",BACK_MODE
|
||||
|
|
|
|||
|
|
|
@ -57,16 +57,42 @@ Vendored 2026-08-08 from `ground-game` `8886543` (CB-WP-0038). These are
|
|||
the adversarial review ([CB-REV-0001](../../reviews/CB-REV-0001-h1.md))
|
||||
reported it unverified and it was a real gap.
|
||||
|
||||
```
|
||||
sha256 7a7a302aabecdeb419c562a029bec3e3576a306b0bd1175d1200de60d9530073 Actions.csv
|
||||
sha256 0afb882dc8001f03bc48a152c9d8c36ad492ceeff2d30ef6a3a690937317f77b DARVO.csv
|
||||
sha256 d06924a19f805feb9e2557fd5c06254ae2054e1f865265f45c26eb293f53bf12 Glossary.csv
|
||||
sha256 4b8e795fbbc93646230f666f8c139dfbd3375af7a12c2968f1674ec83b05b21d Modes.csv
|
||||
sha256 ad2bfbf897bbb3878691cbdbfec739adc58d28cad3923a989dd46b426cce1395 Player_Mats.csv
|
||||
sha256 62e4ae3f4a3c29cf8bdd13f09d3a8866aa98b1716b8e72e49a4aba874c9e9fcb Problems.csv
|
||||
sha256 cd84c3b131c1b7a541e9e42529fdce2b7911f0832cce8c50cfcb8462d01dc551 Relations.csv
|
||||
sha256 f830de9ca44417a7510e04a39ea24a070a81969b33a31fa68361fba132ad40cd Scenarios.csv
|
||||
sha256 0bda1ee97de726b5e8c4404ab15ecc53a359e6c23db74fb41ecb51d78f9884ad Solutions.csv
|
||||
sha256 25273bb6e74c9ad545c5e89dfe0f76b294d0a6cbef51f80d548039d5f0943484 Tokens.csv
|
||||
```
|
||||
|
||||
**H2 vendored 2026-08-08** (CB-WP-0042). Its `Problems.csv` is r0's with
|
||||
**one column added** — `stress_scope` — and **nothing else changed**: same
|
||||
rows, same `point_value`, `required_solution`, `visibility` and
|
||||
`hidden_priority`. That is checked, not assumed, because the delta's
|
||||
`unchanged:` list claims `deal_and_thresholds` and a silent change there
|
||||
would move every baseline hash.
|
||||
|
||||
**`rules_delta.yaml` is the load-bearing one**: it is the executable
|
||||
statement of H1, and the kernel implements it. A silent change there is a
|
||||
silent change to what we measured.
|
||||
|
||||
## Digests
|
||||
|
||||
```
|
||||
sha256 536ad836991804e8d96eff20ae549654ecb82e28cdd884914730b70e3c387ee3 ../ASPECTS.md
|
||||
sha256 5b5f1b73a6fa0f7a8d9ef2061670efc1c309d69774dea9e0deeb3fbce0a399b9 ../CATALOG.md
|
||||
sha256 2adedb8c28570c33e126484c472d8b097067f50358f2ac523f1b3c976e66947a ../catalog.yaml
|
||||
sha256 269db010edfbf9331a3e3bc07fa3949138b2f20adf77ba2c11925bcb8579f997 ../CATALOG.md
|
||||
sha256 5f12bbdc180efd89a5a27750a01d763018044309a629e8437bf8b65373a685ca ../catalog.yaml
|
||||
sha256 7b1cc0149122b855e827bc930576ed165bf7dd8d62707e845a9e514ce3521f8e ../experiments/h1-problem-stress/Actions.csv
|
||||
sha256 62785f5e7e245c60171624d15de2f40187a44fec54f93c7d9705cf52584b1078 ../experiments/h1-problem-stress/Rules_Text.csv
|
||||
sha256 49897a68056643a8cfccff32c9e4a9811018b4e4689b90a85124a487f2318369 ../experiments/h1-problem-stress/VARIANT.md
|
||||
sha256 443199db94601cc889557e5e86823f374dbfdf875962fc84f95c01865605101c ../experiments/h1-problem-stress/metadata.json
|
||||
sha256 f58e81f84ea2b0d16e39932261eb3f3d9890345cdf37ad6f0b3abc00636840be ../experiments/h1-problem-stress/rules_delta.yaml
|
||||
sha256 4c81bae21d2ecb70c7424fa17445246a9b551b10e258d448634816c564e28f09 ../experiments/h2-scoped-problem-stress/Problems.csv
|
||||
sha256 959872910d7824629afe34fb7135a2670d699444001f2eb72b33ba3102c3b82f ../experiments/h2-scoped-problem-stress/Problems.csv
|
||||
sha256 8ed8deb7ad142de1bda70dc11add339f742e8c12ac1f02d5f7c7ec8f17f77b1d ../experiments/h2-scoped-problem-stress/Rules_Text.csv
|
||||
sha256 b0ffea41820ef35960d8c75ff0a734370a29a738e49fda74851fe5c2daafe53e ../experiments/h2-scoped-problem-stress/VARIANT.md
|
||||
sha256 abf994f585fdfa9b2822614a7961e98141cded6a91c446916ff7fd48642de0a7 ../experiments/h2-scoped-problem-stress/metadata.json
|
||||
|
|
@ -84,37 +110,11 @@ sha256 a5e66fd60abef1cf965b0b20892548c65f4005c45f4d44c025e4756eff579897 ../mod
|
|||
sha256 95fa5d4ad811407eda1cf31d99d5dd984e9d1d9af8c284e10df598874d0f06e3 ../modules/problem_stress/flat_any_open/rules_delta.yaml
|
||||
sha256 1e9cb6e2dac046a9f48beccb0ddc09c41608306711320159ecdce3572562e454 ../modules/problem_stress/none/MODULE.md
|
||||
sha256 aae98322a70e51b639b8c39ac45604807f5311ae55edc75b47199056a483c963 ../modules/problem_stress/scoped/MODULE.md
|
||||
sha256 4c81bae21d2ecb70c7424fa17445246a9b551b10e258d448634816c564e28f09 ../modules/problem_stress/scoped/Problems.csv
|
||||
sha256 959872910d7824629afe34fb7135a2670d699444001f2eb72b33ba3102c3b82f ../modules/problem_stress/scoped/Problems.csv
|
||||
sha256 8ed8deb7ad142de1bda70dc11add339f742e8c12ac1f02d5f7c7ec8f17f77b1d ../modules/problem_stress/scoped/Rules_Text.csv
|
||||
sha256 960e8a35f5f214ff9936ea95c4ca9a9145e2a01a8258b1c873251b89ee23972f ../modules/problem_stress/scoped/rules_delta.yaml
|
||||
```
|
||||
|
||||
**H2 vendored 2026-08-08** (CB-WP-0042). Its `Problems.csv` is r0's with
|
||||
**one column added** — `stress_scope` — and **nothing else changed**: same
|
||||
rows, same `point_value`, `required_solution`, `visibility` and
|
||||
`hidden_priority`. That is checked, not assumed, because the delta's
|
||||
`unchanged:` list claims `deal_and_thresholds` and a silent change there
|
||||
would move every baseline hash.
|
||||
|
||||
**`rules_delta.yaml` is the load-bearing one**: it is the executable
|
||||
statement of H1, and the kernel implements it. A silent change there is a
|
||||
silent change to what we measured.
|
||||
|
||||
## Digests
|
||||
|
||||
```
|
||||
sha256 7a7a302aabecdeb419c562a029bec3e3576a306b0bd1175d1200de60d9530073 Actions.csv
|
||||
sha256 0afb882dc8001f03bc48a152c9d8c36ad492ceeff2d30ef6a3a690937317f77b DARVO.csv
|
||||
sha256 d06924a19f805feb9e2557fd5c06254ae2054e1f865265f45c26eb293f53bf12 Glossary.csv
|
||||
sha256 565431571bc06adafb67edefd4b368839b6b94134c2289877384688cc643390b Modes.csv
|
||||
sha256 ad2bfbf897bbb3878691cbdbfec739adc58d28cad3923a989dd46b426cce1395 Player_Mats.csv
|
||||
sha256 0a04830c93b62dcb2f4411a9fbde576368a7427fe9e63c5015e606e4d42d23a0 Problems.csv
|
||||
sha256 cd84c3b131c1b7a541e9e42529fdce2b7911f0832cce8c50cfcb8462d01dc551 Relations.csv
|
||||
sha256 f830de9ca44417a7510e04a39ea24a070a81969b33a31fa68361fba132ad40cd Scenarios.csv
|
||||
sha256 0bda1ee97de726b5e8c4404ab15ecc53a359e6c23db74fb41ecb51d78f9884ad Solutions.csv
|
||||
sha256 25273bb6e74c9ad545c5e89dfe0f76b294d0a6cbef51f80d548039d5f0943484 Tokens.csv
|
||||
```
|
||||
|
||||
`make edition-check` compares this against `../ground-game` when that
|
||||
repository is present, and reports **`upstream not checked out`** as a
|
||||
distinct outcome when it is not — never a pass. An absent check is
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
problem_id,scenario_id,visibility,hidden_priority,title,problem_text,required_solution,symbol_id,point_value,front_rules,reveal_effect,unresolved_effect,back_design_id
|
||||
PRB_01_S,SCN_01,Surface,0,Deadline Missed,A promised result was not delivered when expected.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_01_1,SCN_01,Hidden,1,Unclear Ownership,Responsibility for the commitment and the work was never made explicit.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_01_2,SCN_01,Hidden,2,Unspoken Overload,The work required more capacity than someone could safely or fairly provide.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_01_3,SCN_01,Hidden,3,Bad News Was Delayed,A warning was withheld until the remaining options became worse.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_01_4,SCN_01,Hidden,4,No Checkpoint Process,The group had no reliable moment for testing progress and changing course.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_S,SCN_02,Surface,0,Shared Task Left Undone,"A recurring responsibility was not completed, and others absorbed the impact.",Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_02_1,SCN_02,Hidden,1,Different Standards,"Players were using different definitions of complete, timely, or fair.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_2,SCN_02,Hidden,2,Invisible Workload,Some contributions and constraints were not visible to the group.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_3,SCN_02,Hidden,3,Resentment Never Raised,Frustration accumulated without a direct request or acknowledgement.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_4,SCN_02,Hidden,4,No Ownership Routine,The group relied on goodwill instead of a dependable allocation method.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_S,SCN_03,Surface,0,Decision Announced as Settled,A group-affecting choice was presented as final before meaningful agreement.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_03_1,SCN_03,Hidden,1,Mandate Was Ambiguous,"It was unclear who could decide, advise, consent, or veto.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_2,SCN_03,Hidden,2,Contributions Were Dismissed,Relevant input was ignored or treated as less legitimate.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_3,SCN_03,Hidden,3,One Voice Spoke for Others,A player claimed authority to represent people who had not agreed.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_4,SCN_03,Hidden,4,No Decision Rule,The group had no shared method for turning discussion into a legitimate choice.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_S,SCN_04,Surface,0,Private Information Spread,Information moved beyond the circle in which it was originally shared.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_04_1,SCN_04,Hidden,1,Confidentiality Was Assumed,The players never made the scope of confidentiality explicit.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_2,SCN_04,Hidden,2,Exposure Caused Harm,"The sharing changed another player's safety, reputation, or freedom to choose.",Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_3,SCN_04,Hidden,3,Consent Boundary Was Ignored,A clear or reasonably expected limit on sharing was crossed.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_4,SCN_04,Hidden,4,No Sharing Protocol,"The group lacked a repeatable rule for consent, need-to-know, and escalation.",Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
problem_id,scenario_id,visibility,hidden_priority,title,problem_text,required_solution,symbol_id,point_value,front_rules,reveal_effect,unresolved_effect,back_design_id
|
||||
PRB_01_S,SCN_01,Surface,0,Deadline Missed,A promised result was not delivered when expected.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_01_1,SCN_01,Hidden,1,Unclear Ownership,Responsibility for the commitment and the work was never made explicit.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_01_2,SCN_01,Hidden,2,Unspoken Overload,The work required more capacity than someone could safely or fairly provide.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_01_3,SCN_01,Hidden,3,Bad News Was Delayed,A warning was withheld until the remaining options became worse.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_01_4,SCN_01,Hidden,4,No Checkpoint Process,The group had no reliable moment for testing progress and changing course.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_S,SCN_02,Surface,0,Shared Task Left Undone,"A recurring responsibility was not completed, and others absorbed the impact.",Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_02_1,SCN_02,Hidden,1,Different Standards,"Players were using different definitions of complete, timely, or fair.",Change,SYM_CHANGE,2,Resolve with Change. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_2,SCN_02,Hidden,2,Invisible Workload,Some contributions and constraints were not visible to the group.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_3,SCN_02,Hidden,3,Resentment Never Raised,Frustration accumulated without a direct request or acknowledgement.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_02_4,SCN_02,Hidden,4,No Ownership Routine,The group relied on goodwill instead of a dependable allocation method.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_S,SCN_03,Surface,0,Decision Announced as Settled,A group-affecting choice was presented as final before meaningful agreement.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_03_1,SCN_03,Hidden,1,Mandate Was Ambiguous,"It was unclear who could decide, advise, consent, or veto.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_2,SCN_03,Hidden,2,Contributions Were Dismissed,Relevant input was ignored or treated as less legitimate.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_3,SCN_03,Hidden,3,One Voice Spoke for Others,A player claimed authority to represent people who had not agreed.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_03_4,SCN_03,Hidden,4,No Decision Rule,The group had no shared method for turning discussion into a legitimate choice.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_S,SCN_04,Surface,0,Private Information Spread,Information moved beyond the circle in which it was originally shared.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM_SURFACE
|
||||
PRB_04_1,SCN_04,Hidden,1,Confidentiality Was Assumed,The players never made the scope of confidentiality explicit.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_2,SCN_04,Hidden,2,Exposure Caused Harm,"The sharing changed another player's safety, reputation, or freedom to choose.",Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_3,SCN_04,Hidden,3,Consent Boundary Was Ignored,A clear or reasonably expected limit on sharing was crossed.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
PRB_04_4,SCN_04,Hidden,4,No Sharing Protocol,"The group lacked a repeatable rule for consent, need-to-know, and escalation.",Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,No card-specific effect; it simply remains unsolved.,BACK_PROBLEM
|
||||
|
|
|
|||
|
|
|
@ -5,10 +5,10 @@ PRB_01_2,SCN_01,Hidden,personal,2,Unspoken Overload,The work required more capac
|
|||
PRB_01_3,SCN_01,Hidden,bond,3,Bad News Was Delayed,A warning was withheld until the remaining options became worse.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=bond (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_01_4,SCN_01,Hidden,personal,4,No Checkpoint Process,The group had no reliable moment for testing progress and changing course.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_S,SCN_02,Surface,global,0,Shared Task Left Undone,"A recurring responsibility was not completed, and others absorbed the impact.",Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=global (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM_SURFACE
|
||||
PRB_02_1,SCN_02,Hidden,personal,1,Different Standards,"Players were using different definitions of complete, timely, or fair.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_2,SCN_02,Hidden,personal,2,Invisible Workload,Some contributions and constraints were not visible to the group.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_3,SCN_02,Hidden,bond,3,Resentment Never Raised,Frustration accumulated without a direct request or acknowledgement.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=bond (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_4,SCN_02,Hidden,personal,4,No Ownership Routine,The group relied on goodwill instead of a dependable allocation method.,Change,SYM_CHANGE,3,Resolve with Change. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_1,SCN_02,Hidden,personal,1,Different Standards,"Players were using different definitions of complete, timely, or fair.",Change,SYM_CHANGE,2,Resolve with Change. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_2,SCN_02,Hidden,personal,2,Invisible Workload,Some contributions and constraints were not visible to the group.,Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_3,SCN_02,Hidden,bond,3,Resentment Never Raised,Frustration accumulated without a direct request or acknowledgement.,Boundary,SYM_BOUNDARY,3,Resolve with Boundary. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=bond (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_02_4,SCN_02,Hidden,personal,4,No Ownership Routine,The group relied on goodwill instead of a dependable allocation method.,Repair,SYM_REPAIR,3,Resolve with Repair. Value: 3.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_03_S,SCN_03,Surface,global,0,Decision Announced as Settled,A group-affecting choice was presented as final before meaningful agreement.,Boundary,SYM_BOUNDARY,2,Resolve with Boundary. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=global (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM_SURFACE
|
||||
PRB_03_1,SCN_03,Hidden,personal,1,Mandate Was Ambiguous,"It was unclear who could decide, advise, consent, or veto.",Clarify,SYM_CLARIFY,2,Resolve with Clarify. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
PRB_03_2,SCN_03,Hidden,personal,2,Contributions Were Dismissed,Relevant input was ignored or treated as less legitimate.,Repair,SYM_REPAIR,2,Resolve with Repair. Value: 2.,None in the core set.,"H2: while unclaimed, +1 Stress at Round End to stress_scope=personal (personal=owner; bond=owner's Bond network; global=all).",BACK_PROBLEM
|
||||
|
|
|
|||
|
|
|
@ -25,7 +25,34 @@ a sample nobody chose (CB-REV-0002 #1).
|
|||
vary only face-down Problems and other seats' hands, and neither changes
|
||||
its move. The control is proven against a deliberate peeker first.
|
||||
|
||||
## 1 — SCN_01 and SCN_02 are the same board
|
||||
## 0 — what happened after this was reported
|
||||
|
||||
**ground-game ruled on all seven items the same day** (GROUND-RPT-0006
|
||||
§"disposition"). Two changed the engine or the edition, and the numbers
|
||||
below are therefore **superseded where noted**:
|
||||
|
||||
| item | ruling |
|
||||
|---|---|
|
||||
| SCN_01 ≡ SCN_02 | **not intended** — SCN_02 re-tuned upstream, §1 below is now history |
|
||||
| SCN_04 harder at 2p | acceptable variety; first lever would be priority-2's suit, **not** thresholds — which confirms our reading of the operative difference without our having measured it |
|
||||
| 6p formality | known (F17 line) |
|
||||
| modes change who wins | accepted as a design property, not a defect |
|
||||
| 2 relation slots | **intentional cap**; a third slot stays an extension, so our proposed sensitivity run would measure an extension and not the shipped game |
|
||||
| mastery: points or cards | **RULED: points.** Applied — see below |
|
||||
| package file manifest | accepted process ask, tracked as GROUND-WP-0008 |
|
||||
|
||||
**Mastery is now `total − blame − denied`.** `Modes.csv` was clarified
|
||||
upstream to say *"penalties apply to points, not card count"* and the
|
||||
engine follows. `gr-e02-shared-ground` went red on it — it pinned 0
|
||||
(2 claimed cards − 1 − 1) and now expects 2 (4 points − 1 − 1). The
|
||||
number moved because the rule was decided, not because the engine
|
||||
drifted, and the scenario records both rulings.
|
||||
|
||||
**SCN_02 re-measured after the re-tune:** 2p group success **73**, not 67
|
||||
— it is now its own board and matches SCN_03's difficulty rather than
|
||||
SCN_01's. §1 below describes the state that prompted the report.
|
||||
|
||||
## 1 — SCN_01 and SCN_02 were the same board (superseded)
|
||||
|
||||
Identical suit and value at **every** priority. Every cell matches
|
||||
exactly, in both policies, at all three seat bands.
|
||||
|
|
|
|||
|
|
@ -1056,16 +1056,20 @@ mod card_text_tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// **Two of the four scenarios are the same board** (CB-WP-0047).
|
||||
/// **The four scenarios are four boards** (F29).
|
||||
///
|
||||
/// SCN_01 and SCN_02 have identical suit-and-value profiles at every
|
||||
/// priority, so they play identically and differ only in prose. Not
|
||||
/// a defect — a designed reskin is a legitimate choice — but it is a
|
||||
/// fact about what "four scenarios" buys, and measuring them as four
|
||||
/// independent boards would be measuring two of them twice.
|
||||
/// They were not. SCN_01 and SCN_02 had identical suit-and-value
|
||||
/// profiles at every priority — they played identically and differed
|
||||
/// only in prose, so "four scenarios" bought three boards.
|
||||
///
|
||||
/// This is a **characterisation** test: it pins what is true today so
|
||||
/// that a change to either deck is a decision rather than a drift.
|
||||
/// Reported as F29; ground-game ruled it **unintended** and re-tuned
|
||||
/// SCN_02's suits the same day. **This test is how we found out**: it
|
||||
/// was a characterisation pinning the duplication, it went red on the
|
||||
/// re-tune, and that red was the notification, not a defect.
|
||||
///
|
||||
/// It now asserts the property that should hold from here — every
|
||||
/// pair distinct — which is the stronger statement the duplication
|
||||
/// had made unavailable.
|
||||
#[test]
|
||||
fn which_scenarios_are_mechanically_distinct() {
|
||||
let profile = |id: &str| -> Vec<(u8, String, u8)> {
|
||||
|
|
@ -1077,24 +1081,17 @@ mod card_text_tests {
|
|||
v.sort();
|
||||
v
|
||||
};
|
||||
assert_eq!(
|
||||
profile("SCN_01"),
|
||||
profile("SCN_02"),
|
||||
"SCN_01 and SCN_02 diverged — they were identical boards; \
|
||||
if this is intended, the panel now measures four real boards"
|
||||
);
|
||||
for pair in [
|
||||
("SCN_01", "SCN_03"),
|
||||
("SCN_01", "SCN_04"),
|
||||
("SCN_03", "SCN_04"),
|
||||
] {
|
||||
assert_ne!(
|
||||
profile(pair.0),
|
||||
profile(pair.1),
|
||||
"{} and {} became the same board",
|
||||
pair.0,
|
||||
pair.1
|
||||
);
|
||||
let ids = ["SCN_01", "SCN_02", "SCN_03", "SCN_04"];
|
||||
for (i, a) in ids.iter().enumerate() {
|
||||
for b in &ids[i + 1..] {
|
||||
assert_ne!(
|
||||
profile(a),
|
||||
profile(b),
|
||||
"{a} and {b} are the same board — four scenarios must be \
|
||||
four boards, or a panel treating them as independent \
|
||||
samples counts one of them twice"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1880,12 +1880,18 @@ impl GroundState {
|
|||
.map(|p| p.blame_from.len() as i32)
|
||||
.sum();
|
||||
let denied = self.problems.values().filter(|p| p.denied).count() as i32;
|
||||
let claimed = self
|
||||
.problems
|
||||
.values()
|
||||
.filter(|p| p.claimed_by.is_some())
|
||||
.count() as i32;
|
||||
let mastery = claimed - blame - denied;
|
||||
// **Points, not card count** — F28, ruled by ground-game
|
||||
// 2026-08-08 and clarified in `Modes.csv`: *"start from
|
||||
// that shared point total and subtract 1 point for each
|
||||
// Blame token still in play and 1 point for each Denied
|
||||
// Problem (penalties apply to points, not card count)."*
|
||||
//
|
||||
// This counted CLAIMED CARDS. Both readings fit the
|
||||
// sentence as it stood, and they differ on every game
|
||||
// where a 3-point Problem is claimed — which is most of
|
||||
// them. Reported rather than guessed; the card is the
|
||||
// authority (ADR-0015) and it now says so outright.
|
||||
let mastery = total as i32 - blame - denied;
|
||||
let winners = if group_success {
|
||||
self.players.keys().copied().collect()
|
||||
} else {
|
||||
|
|
@ -3552,7 +3558,7 @@ mod tests {
|
|||
/// does today and shows the size of the disagreement, so the ruling
|
||||
/// has a number in front of it.
|
||||
#[test]
|
||||
fn the_mastery_rating_and_the_shared_score_count_different_things() {
|
||||
fn the_mastery_rating_is_in_points_as_the_mode_card_now_says() {
|
||||
let mut s = setup_3p(11);
|
||||
s.mode = ScoringMode::SharedGround;
|
||||
// Two claimed Problems worth 2 and 3 — five points, two cards.
|
||||
|
|
@ -3587,16 +3593,40 @@ mod tests {
|
|||
assert_eq!(o.total, 5, "the shared score is claimed VALUE");
|
||||
assert_eq!(
|
||||
o.mastery,
|
||||
Some(2),
|
||||
"mastery is the claimed COUNT, with no penalties in play"
|
||||
Some(5),
|
||||
"mastery starts from the shared POINT total, not the card count"
|
||||
);
|
||||
// The disagreement, stated as a number rather than as a worry.
|
||||
assert_ne!(
|
||||
i32::try_from(o.total).unwrap(),
|
||||
o.mastery.unwrap(),
|
||||
"the two readings agree on this board, so F28 has no bite here \
|
||||
and the example needs replacing"
|
||||
// The board is chosen so the two readings disagree — two cards
|
||||
// worth five points. Without that the test would pass under the
|
||||
// reading it exists to exclude.
|
||||
assert_eq!(
|
||||
s.problems
|
||||
.values()
|
||||
.filter(|p| p.claimed_by.is_some())
|
||||
.count(),
|
||||
2,
|
||||
"the fixture must claim a number of CARDS different from the \
|
||||
POINT total, or it cannot tell the two readings apart"
|
||||
);
|
||||
|
||||
// **The edition's own sentence, not our memory of the ruling.**
|
||||
// `Modes.csv` was clarified upstream; if that clarification is
|
||||
// ever reverted this goes red rather than quietly diverging.
|
||||
let (card, _) = crate::edition::modes()
|
||||
.expect("Modes.csv")
|
||||
.into_iter()
|
||||
.find(|(c, _)| c.id == "MODE_COOP")
|
||||
.expect("MODE_COOP");
|
||||
assert!(
|
||||
card.rules_text.contains("not card count"),
|
||||
"the Mode card no longer rules out the card-count reading: {:?}",
|
||||
card.rules_text
|
||||
);
|
||||
|
||||
// And the penalties still bite, in points.
|
||||
let seat = seats[0];
|
||||
s.players.get_mut(&seat).unwrap().blame_from = vec![seats[1]];
|
||||
assert_eq!(s.score().mastery, Some(4), "a Blame token costs 1 POINT");
|
||||
}
|
||||
|
||||
/// **Every scenario is reachable through `setup`** (CB-WP-0047).
|
||||
|
|
@ -3634,14 +3664,13 @@ mod tests {
|
|||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
// SCN_01 and SCN_02 are the same board by design, so four
|
||||
// scenarios yield THREE distinct boards. Asserting 4 here would
|
||||
// be asserting a fact about the edition that is not true.
|
||||
// Four scenarios, four boards (F29). This asserted THREE until
|
||||
// 2026-08-08, because SCN_01 and SCN_02 were identical decks;
|
||||
// ground-game ruled that unintended and re-tuned SCN_02.
|
||||
assert_eq!(
|
||||
boards.len(),
|
||||
3,
|
||||
"the four scenarios yield {} distinct boards; SCN_01 and SCN_02 \
|
||||
were identical and the other two differ",
|
||||
4,
|
||||
"the four scenarios yield {} distinct boards at 4p",
|
||||
boards.len()
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ description: >
|
|||
shared total against the player-count threshold, with a Mastery
|
||||
rating reduced by each Blame token and each Denied Problem.
|
||||
covers: [GR-R09, GR-E01, GR-E02, GR-P03]
|
||||
ruled: 2026-08-03
|
||||
ruled: 2026-08-08
|
||||
ruled_by: ground-game
|
||||
ruled_note: >
|
||||
GROUND-WP-0002 T03, 2026-08-03 — confirm: encode Modes.csv MODE_COOP as printed. Encodes no U-item; it was provisional on the mode data, not on an undetermined rule.
|
||||
RE-RULED 2026-08-08 (F28 / GROUND-RPT-0006 §5(a)): mastery penalties apply to POINTS, not card count. Modes.csv MODE_COOP was clarified upstream and this scenario's expectation moved from 0 to 2. The schema has no field for a second ruling, so both are recorded here; the `ruled` date is the LATEST, because that is the one a reader must check the edition against.
|
||||
seed: 42
|
||||
setup:
|
||||
players: 3
|
||||
|
|
@ -44,8 +45,15 @@ expect:
|
|||
"outcome.total": 4
|
||||
"outcome.threshold": 7
|
||||
"outcome.group_success": false
|
||||
# 2 claimed Problems, −1 Blame, −1 Denied.
|
||||
"outcome.mastery": 0
|
||||
# POINTS, not card count (F28, ruled by ground-game 2026-08-08):
|
||||
# start from the shared point total (4), −1 point per Blame token,
|
||||
# −1 point per Denied Problem.
|
||||
#
|
||||
# **This scenario asserted 0** — 2 claimed CARDS − 1 − 1 — which is
|
||||
# the reading the clarified Modes.csv now rules out. The number moved
|
||||
# because the rule was decided, not because the engine drifted, and
|
||||
# the gate went red on exactly this line.
|
||||
"outcome.mastery": 2
|
||||
"outcome.winners": []
|
||||
# GR-R09: the game ended rather than advancing to Round 6.
|
||||
"round": 5
|
||||
|
|
|
|||
|
|
@ -196,3 +196,57 @@ their own.
|
|||
§3.1 would now forbid. They were reported on 2026-07-30, before the rule
|
||||
existed. They are grandfathered rather than rewritten, and the debt is a
|
||||
reported metric with a target of zero.
|
||||
|
||||
- **F28 — SHARED GROUND's mastery rating counts cards where the mode
|
||||
card counts points.** *"All claimed Problem cards form one shared score.
|
||||
… For a mastery rating, subtract 1 for each Blame token still in play
|
||||
and 1 for each Denied Problem."* The shared score is claimed **value**
|
||||
(`total`); `mastery` subtracts the same penalties from the claimed
|
||||
**count**. Both readings fit the sentence and they differ on every game
|
||||
where a 3-point Problem is claimed. Ours to report, theirs to rule.
|
||||
|
||||
**Sensitivity:** vary only the point value of the claimed Problems and
|
||||
the gap moves with `sum(value) - count`. The two readings agree exactly
|
||||
when every claimed Problem is worth 1 — no Problem in the edition is —
|
||||
or when nothing is claimed, which is a loss. Everything else is held
|
||||
fixed: same board, same penalties, same threshold.
|
||||
|
||||
**RULED and APPLIED 2026-08-08.** ground-game: *"points."* `Modes.csv`
|
||||
MODE_COOP clarified upstream to read *"start from that shared point
|
||||
total and subtract 1 point for each Blame token still in play and 1
|
||||
point for each Denied Problem (penalties apply to points, not card
|
||||
count)."* The engine now computes `total − blame − denied`.
|
||||
|
||||
**A recorded scenario went red on it**, which is the gate working:
|
||||
`gr-e02-shared-ground` pinned mastery 0 (2 claimed cards − 1 − 1) and
|
||||
now expects 2 (4 points − 1 − 1). The number moved because the rule was
|
||||
decided, not because the engine drifted, and the scenario says so.
|
||||
|
||||
- **F29 — SCN_01 and SCN_02 are the same board.** Identical suit and
|
||||
value at every priority; every measured cell matches exactly at every
|
||||
seat band under both policies. **Not called a defect** — a reskin is a
|
||||
legitimate design choice — but "four scenarios" is three boards, and a
|
||||
study treating them as four independent samples double-counts one.
|
||||
`inconsistent` because two artifacts that present as distinct are not;
|
||||
the register does not have a kind for "intended duplication", and
|
||||
inventing one before ground-game rules would be answering for them.
|
||||
|
||||
**Sensitivity:** none — this is an identity, not a measurement. It
|
||||
holds for every seed and every seat band by construction, and the test
|
||||
is a characterisation so a future divergence is a decision.
|
||||
|
||||
**RULED 2026-08-08:** *not* an intended reskin. ground-game will
|
||||
re-tune SCN_02's suits and/or values under a content workplan. The
|
||||
characterisation test stays as-is until they do — when the decks
|
||||
diverge it goes red, which is exactly the notification we want.
|
||||
|
||||
**APPLIED 2026-08-08, upstream.** SCN_02's suits were re-tuned the same
|
||||
day: priorities 1–4 are now Change / Clarify / Boundary / Repair
|
||||
against SCN_01's Clarify / Boundary / Repair / Change. Re-measured, it
|
||||
is its own board — 2p group success **73** where it read 67 as SCN_01's
|
||||
twin.
|
||||
|
||||
**The characterisation test is how we found out.** It pinned the
|
||||
duplication, went red on the re-tune, and that red was the
|
||||
notification. It now asserts every pair distinct — the stronger
|
||||
statement the duplication had made unavailable.
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ kinds, states and metrics: [`GameDesign.md`](GameDesign.md). Reported by
|
|||
| F21 | degenerate | note | — | — | 2026-08-06 | clay-borg |
|
||||
| F23 | inconsistent | applied | decisions/ADR-0017-chaos-window-2-verdict.md | counterexample | 2026-08-07 | clay-borg |
|
||||
| F22 | underdetermined | withdrawn | games_ground::edition::supply_tests::play_never_exceeds_the_components_the_box_holds | counterexample | 2026-08-07 | clay-borg |
|
||||
| F26 | inert | reported | `crates/cb-render-html/src/lib.rs::a_scoped_table_says_what_a_scope_does` | counterexample | 2026-08-08 | ground-game |
|
||||
| F26 | inert | ruled | `crates/cb-render-html/src/lib.rs::a_scoped_table_says_what_a_scope_does` | counterexample | 2026-08-08 | ground-game |
|
||||
| F27 | unplayed | reported | `games/ground/examples/scenario-panel.rs` | counterexample | 2026-08-08 | clay-borg |
|
||||
| F29 | inconsistent | reported | `games_ground::edition::card_text_tests::which_scenarios_are_mechanically_distinct` | counterexample | 2026-08-08 | ground-game |
|
||||
| F30 | degenerate | reported | `games/ground/examples/scenario-panel.rs` | counterexample | 2026-08-08 | ground-game |
|
||||
| F28 | underdetermined | reported | `games_ground::tests::the_mastery_rating_and_the_shared_score_count_different_things` | counterexample | 2026-08-08 | ground-game |
|
||||
| F29 | inconsistent | applied | `games_ground::edition::card_text_tests::which_scenarios_are_mechanically_distinct` | counterexample | 2026-08-08 | ground-game |
|
||||
| F30 | degenerate | ruled | `games/ground/examples/scenario-panel.rs` | counterexample | 2026-08-08 | ground-game |
|
||||
| F28 | underdetermined | applied | `games_ground::tests::the_mastery_rating_and_the_shared_score_count_different_things` | counterexample | 2026-08-08 | ground-game |
|
||||
|
||||
<!-- design-register:end -->
|
||||
|
||||
|
|
@ -66,19 +66,6 @@ Prose for **closed** findings (withdrawn or applied) lives in
|
|||
are the whole register and `make design` reads them from here.
|
||||
|
||||
|
||||
- **F29 — SCN_01 and SCN_02 are the same board.** Identical suit and
|
||||
value at every priority; every measured cell matches exactly at every
|
||||
seat band under both policies. **Not called a defect** — a reskin is a
|
||||
legitimate design choice — but "four scenarios" is three boards, and a
|
||||
study treating them as four independent samples double-counts one.
|
||||
`inconsistent` because two artifacts that present as distinct are not;
|
||||
the register does not have a kind for "intended duplication", and
|
||||
inventing one before ground-game rules would be answering for them.
|
||||
|
||||
**Sensitivity:** none — this is an identity, not a measurement. It
|
||||
holds for every seed and every seat band by construction, and the test
|
||||
is a characterisation so a future divergence is a decision.
|
||||
|
||||
- **F30 — SCN_04 is materially harder at 2 players.** 52/100 group
|
||||
success against 67 and 73, with **every other parameter held by the
|
||||
edition itself**: same deal shape, same 6 available points, same
|
||||
|
|
@ -95,6 +82,11 @@ are the whole register and `make design` reads them from here.
|
|||
effect is specific to the 2p deal, which is the band where the deck has
|
||||
fewest cards to route around a suit it cannot match.
|
||||
|
||||
**RULED 2026-08-08:** acceptable variety for now; SCN_04 stands as a
|
||||
harder board and is monitored. If table feel proves too swingy the
|
||||
first lever is priority-2's suit (dropping the double Repair), **not**
|
||||
the global thresholds — which also confirms our reading that the suit
|
||||
multiset is the operative difference, without our having measured it.
|
||||
- **F27 — the two competitive modes are scoring lenses over cooperative
|
||||
play.** `scenario-panel` finds group success *exactly* equal across
|
||||
SHARED GROUND, COMMON PROBLEM and BONDED COALITIONS in all 36 cells.
|
||||
|
|
@ -135,20 +127,12 @@ are the whole register and `make design` reads them from here.
|
|||
policy models a *rival* playing their objective, so a competitive mode
|
||||
in which nobody anticipates an opponent remains a weak test of that
|
||||
mode (CB-WP-0049 "Not done here").
|
||||
- **F28 — SHARED GROUND's mastery rating counts cards where the mode
|
||||
card counts points.** *"All claimed Problem cards form one shared score.
|
||||
… For a mastery rating, subtract 1 for each Blame token still in play
|
||||
and 1 for each Denied Problem."* The shared score is claimed **value**
|
||||
(`total`); `mastery` subtracts the same penalties from the claimed
|
||||
**count**. Both readings fit the sentence and they differ on every game
|
||||
where a 3-point Problem is claimed. Ours to report, theirs to rule.
|
||||
|
||||
**Sensitivity:** vary only the point value of the claimed Problems and
|
||||
the gap moves with `sum(value) - count`. The two readings agree exactly
|
||||
when every claimed Problem is worth 1 — no Problem in the edition is —
|
||||
or when nothing is claimed, which is a loss. Everything else is held
|
||||
fixed: same board, same penalties, same threshold.
|
||||
|
||||
**The seat-band explanation is answered, 2026-08-08.** ground-game:
|
||||
the two-relation-slot limit is an **intentional cap** on complexity and
|
||||
play time; a third slot stays an extension rather than core r0. So the
|
||||
6p flatness is designed, not a defect — and our sensitivity run is
|
||||
welcome but would be measuring an extension, not the shipped game.
|
||||
- **F26 — a package that adds a FILE is invisible, where a package that
|
||||
adds a column is not.** `h2-scoped-problem-stress` ships
|
||||
`Rules_Text.csv` — twenty-two passages of player-facing rules, including
|
||||
|
|
@ -169,6 +153,10 @@ are the whole register and `make design` reads them from here.
|
|||
it needed (CB-WP-0046); the other twenty-one remain unread and that is
|
||||
the standing evidence.
|
||||
|
||||
**RULED 2026-08-08:** accepted as a process ask. Catalog and modules
|
||||
will declare `consumed_files` / overlays so a consumer reading none of
|
||||
a package's files is a detectable state. Tracked on their side under
|
||||
GROUND-WP-0008.
|
||||
- **F17 — ATTACK cannot affect whether the table succeeds.** Reported
|
||||
from play as *"there is no incentive to play attacks as long as I have
|
||||
positive cards"*, and **the artifact now exists**:
|
||||
|
|
|
|||
|
|
@ -28,9 +28,13 @@ precisely the case a maintained list loses.
|
|||
files upstream does not have. `edition-check` reports both, and a sync
|
||||
tool that silently resolved them would remove the only signal that the
|
||||
mirror and upstream disagree about what exists.
|
||||
- It does not touch `editions/ground-darvo-r0/` except to write the
|
||||
digest block. That directory is the baseline package (ADR-0011) and its
|
||||
own provenance is a separate record.
|
||||
- It does not delete or add; see above. It **does** refresh the baseline
|
||||
package's CSVs, which the first version refused to do on the reasoning
|
||||
that `ground-darvo-r0/` is "a separate record". That was wrong within
|
||||
the hour: ground-game clarified `Modes.csv` and `make vendor` reported
|
||||
a clean sync while `make edition-check` went red on it. **A sync tool
|
||||
that covers less than the check it exists to satisfy is a tool that
|
||||
reports success into a red gate.**
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
|
|
@ -51,6 +55,20 @@ def digest(path):
|
|||
return hashlib.sha256(open(path, "rb").read()).hexdigest()
|
||||
|
||||
|
||||
def edition_csvs():
|
||||
"""The baseline package's own CSVs, as bare filenames.
|
||||
|
||||
Mirrors `edition-check`'s `vendored_files()`, including its limit:
|
||||
only `.csv`. A non-CSV added to that directory is invisible to both,
|
||||
which is recorded as a known hole rather than fixed here.
|
||||
"""
|
||||
return sorted(
|
||||
(n, os.path.join(EDITION_DIR, n))
|
||||
for n in os.listdir(EDITION_DIR)
|
||||
if n.endswith(".csv")
|
||||
)
|
||||
|
||||
|
||||
def siblings():
|
||||
"""Every file beside the edition directory, as `../`-relative paths.
|
||||
|
||||
|
|
@ -77,6 +95,16 @@ def refresh():
|
|||
return 1
|
||||
|
||||
copied, missing, extra = [], [], []
|
||||
# The baseline package first: it is the one `edition-check` checks
|
||||
# by a different code path, and the one this tool used to skip.
|
||||
for name, full in edition_csvs():
|
||||
up = os.path.join(UPSTREAM, "ground-darvo-r0", name)
|
||||
if not os.path.exists(up):
|
||||
extra.append(f"ground-darvo-r0/{name}")
|
||||
continue
|
||||
if digest(up) != digest(full):
|
||||
shutil.copy2(up, full)
|
||||
copied.append(f"ground-darvo-r0/{name}")
|
||||
for rel, full in siblings():
|
||||
up = os.path.normpath(os.path.join(UPSTREAM, rel.replace("../", "", 1)))
|
||||
if not os.path.exists(up):
|
||||
|
|
@ -102,16 +130,57 @@ def refresh():
|
|||
if not os.path.exists(here):
|
||||
missing.append(rel)
|
||||
|
||||
rows = [(digest(full), rel) for rel, full in siblings()]
|
||||
rows.sort(key=lambda r: r[1])
|
||||
block = "\n".join(f"sha256 {h} {r}" for h, r in rows)
|
||||
|
||||
# Two digest fences, and **which holds which is fixed by the prose
|
||||
# above them, not sniffed from their contents.**
|
||||
#
|
||||
# The first version detected the current arrangement and preserved
|
||||
# it — which faithfully preserved a swap an earlier buggy write had
|
||||
# introduced, leaving each fence under a heading describing the other
|
||||
# one. `edition-check` reads every `sha256` line and so passed
|
||||
# throughout: a document can be self-consistently wrong and green.
|
||||
#
|
||||
# Order is now asserted. `SIBLING_FENCE` is the fence whose prose is
|
||||
# about the packages beside the edition; it is the second in the file
|
||||
# and this refuses to write if that stops being true.
|
||||
text = open(PROVENANCE, encoding="utf-8").read()
|
||||
a = text.index("```\nsha256")
|
||||
b = text.index("```", a + 3) + 3
|
||||
open(PROVENANCE, "w", encoding="utf-8").write(
|
||||
text[:a] + "```\n" + block + "\n```" + text[b:]
|
||||
fences = []
|
||||
i = 0
|
||||
while True:
|
||||
j = text.find("```", i)
|
||||
if j < 0:
|
||||
break
|
||||
fences.append(j)
|
||||
i = j + 3
|
||||
if len(fences) < 4:
|
||||
raise SystemExit(
|
||||
f"{PROVENANCE}: expected two digest fences, found {len(fences) // 2}"
|
||||
)
|
||||
edition_fence, sibling_fence = fences[0], fences[2]
|
||||
# The heading immediately above the sibling fence must be about
|
||||
# siblings, or the file has been reorganised and this tool would be
|
||||
# writing digests under the wrong claim.
|
||||
lead = text[max(0, sibling_fence - 400) : sibling_fence]
|
||||
if "Digests" not in lead and "beside" not in lead and "outside" not in lead:
|
||||
raise SystemExit(
|
||||
f"{PROVENANCE}: the second fence is not the sibling digest block; "
|
||||
"the file was reorganised and this tool will not guess"
|
||||
)
|
||||
|
||||
rows_edition = sorted(
|
||||
((digest(full), name) for name, full in edition_csvs()), key=lambda r: r[1]
|
||||
)
|
||||
rows_sibling = sorted(
|
||||
((digest(full), rel) for rel, full in siblings()), key=lambda r: r[1]
|
||||
)
|
||||
rows = rows_edition + rows_sibling
|
||||
|
||||
out = text
|
||||
# Last fence first, so earlier offsets stay valid.
|
||||
for start, rowset in ((sibling_fence, rows_sibling), (edition_fence, rows_edition)):
|
||||
end = out.index("```", start + 3) + 3
|
||||
body = "\n".join(f"sha256 {h} {r}" for h, r in rowset)
|
||||
out = out[:start] + "```\n" + body + "\n```" + out[end:]
|
||||
open(PROVENANCE, "w", encoding="utf-8").write(out)
|
||||
|
||||
print("vendor-editions — the mirror, and what it now records")
|
||||
print(f" refreshed from upstream {len(copied)}")
|
||||
|
|
@ -152,6 +221,16 @@ def recorded_paths():
|
|||
return sorted(out)
|
||||
|
||||
|
||||
def recorded_all():
|
||||
"""Every path the digest blocks name, siblings and edition alike."""
|
||||
text = open(PROVENANCE, encoding="utf-8").read()
|
||||
return sorted(
|
||||
line.split()[2]
|
||||
for line in text.splitlines()
|
||||
if len(line.split()) == 3 and line.split()[0] == "sha256"
|
||||
)
|
||||
|
||||
|
||||
def self_test():
|
||||
"""A sync tool that cannot detect an unrecorded file is decoration.
|
||||
|
||||
|
|
@ -192,6 +271,31 @@ def self_test():
|
|||
disk = set(found)
|
||||
check("every vendored file has a recorded digest", not (disk - rec),
|
||||
f"unrecorded: {sorted(disk - rec)}" if disk - rec else "")
|
||||
check("the baseline package's CSVs are recorded too",
|
||||
set(n for n, _ in edition_csvs()) <= set(recorded_all()),
|
||||
"the first version skipped ground-darvo-r0/ and reported a clean "
|
||||
"sync while edition-check went red on Modes.csv")
|
||||
# **Each fence under its own heading** — the control that was
|
||||
# missing. An earlier write swapped the two blocks and everything
|
||||
# stayed green, because `edition-check` reads every `sha256` line and
|
||||
# does not care which fence it came from. A document can be
|
||||
# self-consistently wrong and pass every check that reads it flat.
|
||||
text = open(PROVENANCE, encoding="utf-8").read()
|
||||
fences = []
|
||||
i = 0
|
||||
while True:
|
||||
j = text.find("```", i)
|
||||
if j < 0:
|
||||
break
|
||||
fences.append(j)
|
||||
i = j + 3
|
||||
first_body = text[fences[0] : text.index("```", fences[0] + 3)]
|
||||
second_body = text[fences[2] : text.index("```", fences[2] + 3)]
|
||||
check("the first digest fence holds the edition's own CSVs",
|
||||
" ../" not in first_body and "sha256" in first_body)
|
||||
check("the second digest fence holds the siblings",
|
||||
all(" ../" in ln for ln in second_body.splitlines() if "sha256" in ln))
|
||||
|
||||
check("no digest is recorded for a file that is not here", not (rec - disk),
|
||||
f"recorded but absent: {sorted(rec - disk)}" if rec - disk else "")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue