CB-WP-0038: variant selection, H1 implemented, and H1 measured
Some checks failed
ci / check (push) Failing after 3s
Some checks failed
ci / check (push) Failing after 3s
ground-game packages hypotheses as selectable rules variants — a catalog, a rules_delta.yaml, and prose — and their note is explicit that CSV text alone is not executable here. So the kernel gains a Variant in game state: in the state, therefore in the hash, therefore in the recording, because a scenario replayed under a different variant would diverge silently. Baseline is bit-for-bit what it was, asserted across seat counts and seeds. A variant system that perturbs the baseline invalidates every measurement this repo has. H1-A and H1-B implemented from rules_delta.yaml and mutation-proven on their own defects: "unclaimed" misread as face-up-and-unsolved, and the attacker's Stress read after the attack's effects. Their `unchanged:` list is asserted rather than trusted — that list is their claim about their own experiment. Measured, and three of their four criteria fail. DARVO arm rate is still 0 under greedy; ATTACK selection does not rise and falls for the rank-75 policy; group success collapses from 165/190/200 to 0 at 3/4/6 seats. The mechanism is not the assumed one: greedy answers the pressure by regulating, Stress plateaus at 3, so it never reaches the gate at 4 or the arm at 5 — H1-A acts as a solve-rate tax and H1-B is unreachable under competent play. A harness defect was caught before the claim: sweep discarded refused games silently and never reported its count, so "nobody won" and "nothing played" printed identically. Reporting H1 as unwinnable on that basis would have been the ADR-0018 family aimed at another repo's design. All 200 games ran in every cell; the zeros are real. Chaos d8 = 8 — the window's first override, redrew L against a structural L, so it changed nothing. Window 3 recorded in ChaosRollHistory. NOT REVIEWED: tier L owes a separate-agent adversarial review, and no H1 result may reach ground-game until it has run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
627992bc85
commit
a928b5925c
15 changed files with 928 additions and 28 deletions
|
|
@ -1216,6 +1216,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: crate::table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
},
|
||||
std::io::Cursor::new(Vec::new()),
|
||||
out,
|
||||
|
|
@ -1406,6 +1407,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: crate::table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
},
|
||||
std::io::Cursor::new(Vec::new()),
|
||||
out,
|
||||
|
|
|
|||
|
|
@ -765,6 +765,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: crate::table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
};
|
||||
let mut sink: Vec<u8> = Vec::new();
|
||||
let summary =
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ play:
|
|||
--replay DIR write a .cbreplay bundle of the finished game to DIR
|
||||
--record FILE write the finished game as a scenario YAML
|
||||
--trial FILE write a trial log: what the player said, bound to where
|
||||
--variant V rules package: ground-darvo-r0 (default) or
|
||||
h1-problem-stress (experimental; ground-game H1)
|
||||
--pace P speed (default) or interactive: how much ornamentation
|
||||
is performed. Never changes the game -- the recording is
|
||||
byte-identical either way (specs/Ornamentation.md)
|
||||
|
|
@ -137,6 +139,13 @@ fn parse_args(argv: &[String]) -> Result<Mode, String> {
|
|||
// **The flag exists before anything reads it, deliberately.**
|
||||
// It is the seam `clay-animate` attaches to, and a seam is
|
||||
// cheap now where a retrofit would not be.
|
||||
// CB-WP-0038: ground-game names these in
|
||||
// `editions/catalog.yaml`; `--variant` takes that id.
|
||||
"--variant" => {
|
||||
play_flags.push(flag.into());
|
||||
config.variant = value(i, argv, flag)?.parse()?;
|
||||
i += 2;
|
||||
}
|
||||
"--pace" => {
|
||||
play_flags.push(flag.into());
|
||||
config.pace = value(i, argv, flag)?.parse()?;
|
||||
|
|
@ -306,6 +315,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
};
|
||||
let script = "0\n".repeat(400);
|
||||
let mut out: Vec<u8> = Vec::new();
|
||||
|
|
@ -352,6 +362,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
};
|
||||
let script = "0\n".repeat(400);
|
||||
let mut out: Vec<u8> = Vec::new();
|
||||
|
|
@ -420,6 +431,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
};
|
||||
let mut out: Vec<u8> = Vec::new();
|
||||
table::play(&config, "0\n".repeat(200).as_bytes(), &mut out).expect("game");
|
||||
|
|
@ -485,6 +497,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
};
|
||||
let mut out: Vec<u8> = Vec::new();
|
||||
let summary = table::play(&config, "".as_bytes(), &mut out).expect("bot game");
|
||||
|
|
@ -548,6 +561,7 @@ mod tests {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: table::Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
};
|
||||
let mut out: Vec<u8> = Vec::new();
|
||||
let summary = table::play(&config, "".as_bytes(), &mut out).expect("game");
|
||||
|
|
|
|||
|
|
@ -55,6 +55,11 @@ pub struct Config {
|
|||
/// rules cannot see gets shown. Calling both of them "mode" on one
|
||||
/// driver is a collision waiting to be mis-read.
|
||||
pub pace: Pace,
|
||||
/// Which selectable rules package to play (CB-WP-0038).
|
||||
///
|
||||
/// **Unlike `pace`, this changes the game** — outcome, state hash and
|
||||
/// recording all move, which is correct: a variant is mechanism.
|
||||
pub variant: games_ground::Variant,
|
||||
}
|
||||
|
||||
/// Speed or Interactive (Ornamentation §4).
|
||||
|
|
@ -99,6 +104,7 @@ impl Default for Config {
|
|||
trial: None,
|
||||
mode: games_ground::ScoringMode::SharedGround,
|
||||
pace: Pace::Speed,
|
||||
variant: games_ground::Variant::Baseline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -400,6 +406,9 @@ fn run_game<'a, R: BufRead + 'a, W: Write + 'a>(
|
|||
// GR-E02..E04. Set before the hash is taken, so a recorded session
|
||||
// replays in the mode it was played in.
|
||||
initial.mode = config.mode;
|
||||
// CB-WP-0038: set beside `mode` and before the hash, so a recorded
|
||||
// session replays under the variant it was played under.
|
||||
initial.variant = config.variant;
|
||||
let initial_json = serde_json::to_value(&initial).map_err(|e| e.to_string())?;
|
||||
let initial_hash = cb_events::state_hash_hex(&initial);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue