CB-REV-0002: round 2, and the corrections were not approvable either
Some checks failed
ci / check (push) Failing after 4s
Some checks failed
ci / check (push) Failing after 4s
Three FATAL, five SERIOUS. The substance of round 1's corrections held — Reactive is genuinely one arm different, the five replacement controls are non-inert, the inert metric is right, the numbers reproduce. What failed were the CLAIMS about them, and two defects the corrections introduced. FATAL 1: the fix for round 1's #11 did not fix it. The assertion was `games + setup_fails == 200`, and a refused setup increments setup_fails while skipping games — so the sum is invariant under exactly the failure it claimed to catch. Injecting setup failures gave exit 0 over 196-game columns. Now asserts games == GAMES, verified to exit 101. FATAL 2: the correction to the selective-column FATAL was itself selective. "81-1000 per cell, baseline AND H1" and "31-1000" twelve lines apart, both taken from the baseline row; under H1 rank-75 arms are 59/0/0/0. Every cell is now printed rather than summarised, and the corrected verdict is the opposite of the one it replaced: under rank-75, H1 REDUCES DARVO arms to zero at 3p and above. FATAL 3: "DARVO arms 2 per seat per game" is 1 per seat per game, exactly, at every band. SERIOUS: the tiebreak oracle asserted only that the winner set CHANGED, so reversing the tiebreak left it green; the #13 defect's impact was claimed and never measured (72,000 games: zero divergences — real in principle, witnessed only by a constructed board); a 29-of-363 citation pointed at a file that did not contain it (round 1's reviewer did report it, and it was never transcribed — the record was wrong, not the number); the harnesses were run by NO GATE, so every published figure came from a manual run of an ungated binary, including the assertion added for #1; and edition-check's sibling handling — added by the last correction — was self-certifying, crashed instead of failing, and counted Markdown lines as coverage. Now discovered on disk, and it found a real gap on its first run: Rules_Text.csv vendored with no digest. Also: "peak Stress held" was dead code kept quiet by `let _ = held;` — the numbers were right by coincidence. make panels is now a registered gate. Round 3 is owed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
84aa09264c
commit
da58e78e4a
10 changed files with 285 additions and 56 deletions
|
|
@ -20,9 +20,12 @@ use games_ground::{Action, GroundCommand, GroundState, ScoringMode, Variant};
|
|||
|
||||
/// Greedy, with GROUND demoted below ATTACK. Nothing else differs.
|
||||
///
|
||||
/// **The copy is deliberate.** `GreedyPolicy::rank` is private, and the
|
||||
/// point is to change one line of it while holding the rest identical —
|
||||
/// calling into it would make that impossible to demonstrate.
|
||||
/// **It delegates.** An earlier version re-typed an abridged copy of
|
||||
/// greedy's ranking and called changing one line of the copy "one
|
||||
/// preference"; it differed in five, and the seat burned its Freedom
|
||||
/// token in round one of every game. This comment used to argue for the
|
||||
/// copy, which gave a future maintainer written cover to restore it
|
||||
/// (CB-REV-0002 #11).
|
||||
struct Reactive;
|
||||
|
||||
impl Policy for Reactive {
|
||||
|
|
@ -72,6 +75,10 @@ impl Policy for Reactive {
|
|||
/// inlined so the peak metric cannot silently disagree with setup.
|
||||
const START_STRESS: u8 = 2;
|
||||
|
||||
/// Games per cell. Named once so the assertion and the banner cannot
|
||||
/// disagree — the banner said "200 games per cell" over 196-game columns.
|
||||
const GAMES: u32 = 200;
|
||||
|
||||
struct Cell {
|
||||
games: u32,
|
||||
won: u32,
|
||||
|
|
@ -99,7 +106,7 @@ fn sweep(mode: ScoringMode, variant: Variant, players: u8, reactive: bool) -> Ce
|
|||
setup_fails: 0,
|
||||
inert_arms: 0,
|
||||
};
|
||||
for seed in 0..200u64 {
|
||||
for seed in 0..GAMES as u64 {
|
||||
let Ok(mut st) = GroundState::setup(
|
||||
&Setup {
|
||||
players,
|
||||
|
|
@ -174,20 +181,31 @@ fn sweep(mode: ScoringMode, variant: Variant, players: u8, reactive: bool) -> Ce
|
|||
}
|
||||
if let games_ground::GroundEvent::StressSet { player, stress } = e {
|
||||
held.insert(*player, *stress);
|
||||
c.peak_stress = c.peak_stress.max(*stress);
|
||||
}
|
||||
// Read from `held`, which is the point. The first correction
|
||||
// BUILT `held`, then took the max over event payloads anyway
|
||||
// and silenced the unused binding with `let _ = held;` — so
|
||||
// the comment described code that did not exist (CB-REV-0002
|
||||
// #10). The published figures were right only because the
|
||||
// START_STRESS floor made the two agree.
|
||||
c.peak_stress = c
|
||||
.peak_stress
|
||||
.max(held.values().copied().max().unwrap_or(START_STRESS));
|
||||
}
|
||||
let _ = held;
|
||||
}
|
||||
// Reported as a REFUSAL, not left for a reader to notice a short
|
||||
// column. CB-REV-0001 #11: `games != 200` was printed, never asserted.
|
||||
// **`games`, not `games + setup_fails`** (CB-REV-0002 #1).
|
||||
//
|
||||
// The first version asserted the SUM — and a refused setup increments
|
||||
// `setup_fails` while skipping `games`, so the sum is invariant under
|
||||
// exactly the failure it claimed to catch. It could only ever fire on
|
||||
// a `play` error, the path that was already instrumented. Verified by
|
||||
// injecting setup failures: green, exit 0, and a full table printed
|
||||
// over 196-game columns under a banner reading "200 games per cell".
|
||||
assert_eq!(
|
||||
c.games + c.setup_fails,
|
||||
200,
|
||||
"{players}p {variant:?}: {} games ran and {} setups failed — the cell is short, \
|
||||
so every number in it is over a sample nobody chose",
|
||||
c.games,
|
||||
c.setup_fails
|
||||
c.games, GAMES,
|
||||
"{players}p {variant:?}: only {} of {GAMES} games ran ({} setups refused) — \
|
||||
the cell is short, so every number in it is over a sample nobody chose",
|
||||
c.games, c.setup_fails
|
||||
);
|
||||
if c.setup_fails > 0 {
|
||||
eprintln!(
|
||||
|
|
@ -202,7 +220,7 @@ fn main() {
|
|||
println!("CB-WP-0039 — does H1 reach a seat that does not regulate?\n");
|
||||
println!("`reactive` is greedy with ONE preference changed: GROUND is");
|
||||
println!("demoted below ATTACK, so the seat never grounds to shed Stress.");
|
||||
println!("SHARED GROUND; `won` is group success; 200 games per cell.\n");
|
||||
println!("SHARED GROUND; `won` is group success; {GAMES} games per cell.\n");
|
||||
|
||||
for (vlabel, variant) in [
|
||||
("BASELINE ground-darvo-r0", Variant::Baseline),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue