From b513209acf83fb650572994a9122bbcd7d1acb2e Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 3 Aug 2026 23:49:49 +0200 Subject: [PATCH] GD-0001: group success is unreachable below 5 seats, with its reproduction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maintainer played several 3-player games on 2026-08-03 and could not win any. This says why, from the engine's own constants rather than my arithmetic: claim every Problem the deal puts in play, concede nothing, and the total still falls short of GR-E01's threshold at 2, 3 and 4 seats. 2p: 2 problems worth 3 vs threshold 5 — UNREACHABLE 3p: 3 problems worth 6 vs threshold 7 — UNREACHABLE 4p: 3 problems worth 6 vs threshold 7 — UNREACHABLE 5p: 4 problems worth 10 vs threshold 9 — reachable 6p: 4 problems worth 10 vs threshold 9 — reachable The test reads problem_priorities (GR-S01's deal) and threshold (GR-E01) out of the engine, so it cannot drift from the rules it tests, and it holds for either dataset -- the stand-in gives 3/6/10 and Problems.csv gives 4/6/9 against the same 5/7/9. It ASSERTS THE DEFECT and is expected to keep passing until ground-game rules, then be inverted. This is CB-WP-0022's reproduction rule applied before the register exists, because delivering feedback should not block on building the tool that tracks it. Co-Authored-By: Claude Opus 5 --- games/ground/src/lib.rs | 63 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/games/ground/src/lib.rs b/games/ground/src/lib.rs index 20fba88..4359b81 100644 --- a/games/ground/src/lib.rs +++ b/games/ground/src/lib.rs @@ -2162,6 +2162,19 @@ mod replay_probe { use cb_kernel::EventSeq; use std::time::Instant; + /// A fresh game at `seats` players, for the seat-count sweep. + fn fresh_n(seats: u8) -> GroundState { + GroundState::setup( + &Setup { + players: seats, + preset: format!("standard-{seats}p"), + patch: BTreeMap::new(), + }, + 42, + ) + .expect("a standard deal") + } + fn fresh(seed: u64) -> GroundState { GroundState::setup( &Setup { @@ -2441,6 +2454,56 @@ mod replay_probe { } } + /// **GD-0001: group success is arithmetically unreachable below 5 + /// seats**, and this is the reproduction rather than an argument. + /// + /// The maintainer played several 3-player games on 2026-08-03 and + /// could not win any of them. This says why: claim *every* Problem + /// the deal puts in play, concede nothing, and the total still falls + /// short of GR-E01's threshold at 2, 3 and 4 seats. + /// + /// It reads both numbers out of the engine — `problem_priorities` + /// (GR-S01's deal) and `threshold` (GR-E01) — so it cannot drift from + /// the rules it is testing, and it holds for **either dataset**: the + /// stand-in gives 3/6/10 and `Problems.csv` gives 4/6/9, against the + /// same 5/7/9. + /// + /// **This test asserts the defect.** It is expected to keep passing + /// until ground-game rules, and to be inverted when it does — either + /// the deal count rises or the thresholds fall. + #[test] + fn gd0001_group_success_is_unreachable_below_five_seats() { + let mut verdicts = Vec::new(); + for seats in 2..=6u8 { + let state = fresh_n(seats); + let best: u32 = state.problems.values().map(|p| u32::from(p.value)).sum(); + let need = state.threshold(); + verdicts.push((seats, state.problems.len(), best, need, best >= need)); + println!( + " {seats}p: {} problem(s) worth {best} against a threshold of {need} \u{2014} {}", + state.problems.len(), + if best >= need { "reachable" } else { "UNREACHABLE" } + ); + } + let unreachable: Vec = verdicts + .iter() + .filter(|(_, _, _, _, ok)| !ok) + .map(|(s, _, _, _, _)| *s) + .collect(); + // Positive control: a run where everything is reachable would + // report a clean sheet and prove nothing. + assert!( + !verdicts.is_empty() && verdicts.iter().any(|(_, _, _, _, ok)| *ok), + "no seat count was reachable; the harness measured nothing useful" + ); + assert_eq!( + unreachable, + vec![2, 3, 4], + "GD-0001 has changed: ground-game may have ruled. Re-read the \ + finding before editing this test." + ); + } + /// AM-7 scaling floor from GameKernel §5: fold throughput at 100k /// events must be at least this fraction of throughput at 5k. ///