CB-WP-0044: the page says which rules it plays
Some checks failed
ci / check (push) Failing after 4s
Some checks failed
ci / check (push) Failing after 4s
Reported as "I did a session and noted no changes" — correct, and the fault was ours twice. make ground passes no --variant, so the session was baseline, and CB-WP-0043 deliberately leaves the baseline layout untouched because a variant that redraws the baseline invalidates every prior look at it. But the deeper defect is that nothing said so. The page named the round, the step, the Lead, the scoring mode and the viewer, and never which rules it was playing — GroundView did not even carry the variant. There was no way from the screen to tell baseline from H1 from H2. A session that cannot say which rules it is playing cannot report a rules change; the player did the right thing and the instrument had nothing to tell them. Now: variant on GroundView, `rules <id>` in the page header beside the scoring mode, `rules <id>` in the inspector because a replay that cannot say which rules produced it is the same defect in the other tool, and make ground VARIANT=h2 so the capability is reachable. Both coverage probes caught the new field independently — the render crate's and cb-play's — the second time in two passes that they have turned an addition into a legibility requirement instead of letting it be silent state. Verified by fetching the served page rather than by reading the code: make ground VARIANT=h2 prints "rules: h2" and the page carries "rules h2-scoped-problem-stress" with the scope labels; the baseline says "rules ground-darvo-r0" and keeps its row. Still open: nothing explains what a scope DOES, and the trial log header does not record the variant either — the same defect one artifact along. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
471de44632
commit
25b18bddf7
9 changed files with 271 additions and 2 deletions
8
Makefile
8
Makefile
|
|
@ -31,6 +31,10 @@ TOOLS := $(REPO)/tools
|
|||
# reads the age from there (falling back to mtime).
|
||||
TRIAL_NAME := $(shell date +%Y-%m-%d-%H%M)$(if $(SLUG),-$(SLUG),)
|
||||
PLAYERS ?= 3
|
||||
# CB-WP-0044: which rules package to play. The page names it too --
|
||||
# a session that could not say which variant it was is what produced
|
||||
# the report "I did a session and noted no changes".
|
||||
VARIANT ?= ground-darvo-r0
|
||||
PORT ?= 0
|
||||
|
||||
# Every cargo recipe runs at the repo root; the shell does not persist cd.
|
||||
|
|
@ -68,11 +72,13 @@ help:
|
|||
## type in the notes panel is bound to the position you typed it at.
|
||||
## `make ground PLAYERS=2 SLUG=darvo-confusion`
|
||||
## Read the notes back afterwards with `make trials`.
|
||||
## play a session (VARIANT=ground-darvo-r0|h1|h2)
|
||||
ground:
|
||||
@echo " rules: $(VARIANT)"
|
||||
@mkdir -p $(REPO)/trials
|
||||
@echo " trial: trials/$(TRIAL_NAME).md (notes) + .yaml (the game)"
|
||||
$(IN_REPO) $(CARGO) run -q -p cb-play -- \
|
||||
--players $(PLAYERS) --serve $(PORT) \
|
||||
--players $(PLAYERS) --serve $(PORT) --variant $(VARIANT) \
|
||||
--record trials/$(TRIAL_NAME).yaml \
|
||||
--trial trials/$(TRIAL_NAME).md $(ARGS)
|
||||
|
||||
|
|
|
|||
|
|
@ -1044,11 +1044,17 @@ pub fn document_with_log(
|
|||
"<h1>GROUND \u{2014} round {round}, step {step:?}</h1>\
|
||||
<div><span class=\"k\">lead</span> {lead} \
|
||||
<span class=\"k\">scoring</span> {mode:?} \
|
||||
<span class=\"k\">rules</span> {variant} \
|
||||
<span class=\"k\">viewing as</span> {who}</div>",
|
||||
round = view.round,
|
||||
step = view.step,
|
||||
lead = seat_name(view.lead),
|
||||
mode = view.mode,
|
||||
// CB-WP-0044: the page must say which rules it is playing. It did
|
||||
// not, so a player who ran the default and was told the layout had
|
||||
// changed reported "no changes" — correctly, because the baseline
|
||||
// is deliberately unchanged and nothing on screen said so.
|
||||
variant = esc(view.variant.id()),
|
||||
who = match view.viewer {
|
||||
Some(p) => format!("{} (their hand only)", seat_name(p)),
|
||||
None => "a spectator (no hands)".to_string(),
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ mod coverage {
|
|||
// that could only be satisfied by geometry would have to be
|
||||
// OMITTED, and the page would be illegible to `text_of` and to a
|
||||
// screen reader alike.
|
||||
("variant", "ground-darvo-r0"),
|
||||
("problem_markers.*.owner", "P1\u{2019}s alone"),
|
||||
("problem_markers.*.scope", "P2\u{2019}s Bond network"),
|
||||
("outcome.total", "total 9"),
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ pub fn view(viewer: Option<PlayerId>) -> GroundView {
|
|||
(Pair::new(p2, p3), Relation::Bond),
|
||||
]),
|
||||
problems,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
focus: BTreeMap::from([(p1, p3)]),
|
||||
selections: BTreeMap::from([
|
||||
(
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ pub struct GroundView {
|
|||
pub lead: PlayerId,
|
||||
pub step: RoundStep,
|
||||
pub mode: ScoringMode,
|
||||
/// Which rules package is being played (CB-WP-0044).
|
||||
///
|
||||
/// **The page had no way to say this**, so a player could not tell
|
||||
/// baseline from H1 from H2 by looking — and reported a variant
|
||||
/// change as "no changes" after playing the default.
|
||||
#[serde(default)]
|
||||
pub variant: crate::Variant,
|
||||
pub players: BTreeMap<PlayerId, PlayerView>,
|
||||
pub relations: BTreeMap<Pair, Relation>,
|
||||
pub problems: BTreeMap<u32, ProblemView>,
|
||||
|
|
@ -170,6 +177,7 @@ impl Project for GroundState {
|
|||
lead: self.lead,
|
||||
step: self.step,
|
||||
mode: self.mode,
|
||||
variant: self.variant,
|
||||
players: self
|
||||
.players
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -140,11 +140,12 @@ fn render_player(id: PlayerId, p: &PlayerView, is_viewer: bool) -> String {
|
|||
pub fn render(view: &GroundView) -> String {
|
||||
let mut out = String::new();
|
||||
out.push_str(&format!(
|
||||
"\nround {} step {:?} lead {} mode {:?} deck {} discard [{}]\n",
|
||||
"\nround {} step {:?} lead {} mode {:?} rules {} deck {} discard [{}]\n",
|
||||
view.round,
|
||||
view.step,
|
||||
seat_name(view.lead),
|
||||
view.mode,
|
||||
view.variant.id(),
|
||||
view.solution_deck_len,
|
||||
cards(&view.solution_discard),
|
||||
));
|
||||
|
|
@ -493,6 +494,9 @@ mod tests {
|
|||
("step", "step Resolve"),
|
||||
("lead", "lead P2"),
|
||||
("mode", "mode BondedCoalitions"),
|
||||
// CB-WP-0044: the inspector must say which rules it is replaying,
|
||||
// for the same reason the page must.
|
||||
("variant", "rules ground-darvo-r0"),
|
||||
("viewer", "(you)"),
|
||||
("solution_deck_len", "deck 11"),
|
||||
("solution_discard.*.suit", "discard [Repair, Change]"),
|
||||
|
|
@ -617,6 +621,7 @@ mod tests {
|
|||
]),
|
||||
problems,
|
||||
problem_markers: Default::default(),
|
||||
variant: games_ground::Variant::Baseline,
|
||||
focus: BTreeMap::from([(p1, p3)]),
|
||||
selections: BTreeMap::from([
|
||||
(
|
||||
|
|
|
|||
18
trials/2026-08-08-1734.md
Normal file
18
trials/2026-08-08-1734.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Trial log
|
||||
|
||||
What the player said while playing, bound to the position they said it at
|
||||
(CB-WP-0027, ADR-0014). The recording beside this file is the position;
|
||||
`state_hash` is what reaches it.
|
||||
|
||||
**These are raw notes and they stay here.** Nothing in this file travels to
|
||||
`ground-game` (ADR-0014 D4) — a note reaches them only by being promoted to a
|
||||
register finding, by a human, with the wording chosen then.
|
||||
|
||||
<!-- trial-log:begin -->
|
||||
|
||||
| n | game | after | round | step | state_hash | comment |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | 1 | 0 | 1 | Select | 39c2ed586d57 | Ok, all problems are on the table, so they are all global? |
|
||||
| 2 | 1 | 32 | 5 | after the end | c852f3b15ee8 | Well, i did not notice any difference, maybe i did not start the H2 variation? |
|
||||
|
||||
<!-- trial-log:end -->
|
||||
149
trials/2026-08-08-1734.yaml
Normal file
149
trials/2026-08-08-1734.yaml
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
scenario: ground/cb-play-session
|
||||
description: recorded by cb-play (CB-WP-0008 T02)
|
||||
covers: []
|
||||
provisional: false
|
||||
provisional_owner: ''
|
||||
provisional_raised: ''
|
||||
ruled: ''
|
||||
ruled_by: ''
|
||||
ruled_note: ''
|
||||
encodes_u_item: ''
|
||||
seed: 1
|
||||
setup:
|
||||
players: 3
|
||||
preset: standard-3p
|
||||
patch: {}
|
||||
commands:
|
||||
- actor: P1
|
||||
cmd: select_action
|
||||
args:
|
||||
action: INVESTIGATE
|
||||
problem: 2
|
||||
- actor: P2
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 1
|
||||
- actor: P3
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 1
|
||||
- actor: SYSTEM
|
||||
cmd: reveal
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: resolve
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: end_round
|
||||
args: {}
|
||||
- actor: P1
|
||||
cmd: select_action
|
||||
args:
|
||||
action: INVESTIGATE
|
||||
problem: 3
|
||||
- actor: P2
|
||||
cmd: select_action
|
||||
args:
|
||||
action: INVESTIGATE
|
||||
problem: 3
|
||||
- actor: P3
|
||||
cmd: select_action
|
||||
args:
|
||||
action: INVESTIGATE
|
||||
problem: 3
|
||||
- actor: SYSTEM
|
||||
cmd: reveal
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: resolve
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: end_round
|
||||
args: {}
|
||||
- actor: P1
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 2
|
||||
- actor: P2
|
||||
cmd: select_action
|
||||
args:
|
||||
action: INVESTIGATE
|
||||
problem: 4
|
||||
- actor: P3
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 2
|
||||
- actor: SYSTEM
|
||||
cmd: reveal
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: resolve
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: end_round
|
||||
args: {}
|
||||
- actor: P1
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 3
|
||||
- actor: P2
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 3
|
||||
- actor: P3
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SOLVE
|
||||
problem: 4
|
||||
- actor: SYSTEM
|
||||
cmd: reveal
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: resolve
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: end_round
|
||||
args: {}
|
||||
- actor: P1
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SUPPORT
|
||||
target: P2
|
||||
- actor: P2
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SUPPORT
|
||||
target: P1
|
||||
- actor: P3
|
||||
cmd: select_action
|
||||
args:
|
||||
action: SUPPORT
|
||||
target: P1
|
||||
- actor: SYSTEM
|
||||
cmd: reveal
|
||||
args: {}
|
||||
- actor: P1
|
||||
cmd: respond_to_support
|
||||
args:
|
||||
response: accept_bond
|
||||
- actor: P2
|
||||
cmd: respond_to_support
|
||||
args:
|
||||
response: accept_bond
|
||||
- actor: SYSTEM
|
||||
cmd: resolve
|
||||
args: {}
|
||||
- actor: SYSTEM
|
||||
cmd: end_round
|
||||
args: {}
|
||||
expect:
|
||||
events: []
|
||||
state: {}
|
||||
rejects: []
|
||||
state_hash: c852f3b15ee8a8e68f0cecfa3c4a7dd7f1b3413a1b90df496e9418d121e6d9a4
|
||||
75
workplans/CB-WP-0044-the-page-says-which-rules-it-plays.md
Normal file
75
workplans/CB-WP-0044-the-page-says-which-rules-it-plays.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
id: CB-WP-0044
|
||||
kind: product
|
||||
title: "The page says which rules it plays"
|
||||
status: done
|
||||
---
|
||||
|
||||
# Purpose
|
||||
|
||||
```
|
||||
structural tier M (adds a field to the projection, a canonical
|
||||
interface, and a driver knob)
|
||||
declared tier M
|
||||
```
|
||||
|
||||
## The report
|
||||
|
||||
> *"I did a session and noted no changes."*
|
||||
|
||||
**Correct, and the fault was ours twice over.**
|
||||
|
||||
`make ground` passes no `--variant`, so the session was **baseline** — and
|
||||
CB-WP-0043 deliberately leaves the baseline layout untouched, because a
|
||||
variant that redraws the baseline invalidates every prior look at it.
|
||||
|
||||
**But the deeper defect is that nothing said so.** The page named the
|
||||
round, the step, the Lead, the scoring mode and the viewer — **and never
|
||||
which rules it was playing.** `GroundView` did not even carry the variant.
|
||||
There was no way, from the screen, to tell baseline from H1 from H2.
|
||||
|
||||
> **A session that cannot say which rules it is playing cannot report a
|
||||
> rules change.** The player did the right thing and the instrument had
|
||||
> nothing to tell them.
|
||||
|
||||
## Task: say it, and make it reachable
|
||||
|
||||
```task
|
||||
id: CB-WP-0044-T01
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Controls:**
|
||||
- **the page names the variant**, beside the scoring mode where a player
|
||||
already looks for what game this is;
|
||||
- **the inspector names it too** — a replay that cannot say which rules
|
||||
produced it is the same defect in the other tool;
|
||||
- **`make ground` can select it**, or the capability exists and nobody
|
||||
can reach it;
|
||||
- **verified end to end against a served page**, not by reading the code.
|
||||
|
||||
**Done 2026-08-08.**
|
||||
|
||||
`variant` on `GroundView`, `rules <id>` in the header, `rules <id>` in the
|
||||
inspector, and `make ground VARIANT=h2`.
|
||||
|
||||
**Both coverage probes caught the new field independently** — the render
|
||||
crate's and `cb-play`'s — which is the second time in two passes that the
|
||||
probes have turned an addition into a legibility requirement rather than
|
||||
letting it be silent state.
|
||||
|
||||
**Verified by fetching the served page**: `make ground VARIANT=h2` prints
|
||||
`rules: h2`, and the page carries `rules h2-scoped-problem-stress` plus
|
||||
the scope labels. The baseline page says `rules ground-darvo-r0` and keeps
|
||||
its row, which is the behaviour CB-WP-0043 intended and could not
|
||||
previously be told apart from a bug.
|
||||
|
||||
## What this does not fix
|
||||
|
||||
- **Nothing on the page explains what a scope does.** It says *whose* a
|
||||
Problem is; it does not say that an unclaimed personal card ticks only
|
||||
its owner at Round End. H2's `Rules_Text.csv` is vendored and unread.
|
||||
- **The variant is not in the trial log's header**, so a note written
|
||||
during an H2 session does not record which rules it was about. That is
|
||||
the same class of defect as this one, one artifact along.
|
||||
Loading…
Add table
Add a link
Reference in a new issue