CB-WP-0039: a seat that does not regulate — and it changes H1's verdict
Some checks failed
ci / check (push) Failing after 3s

CB-EV-0030 concluded H1's DARVO arm rate was still 0. That was true of the
panel, and the panel was greedy-family throughout. GreedyPolicy ranks
`Ground if gated => 100`, so it grounds the instant the stress gate bites,
Stress plateaus at 3, and the arm at 5 is unreachable by construction. "H1
does nothing" was really "H1 does nothing to a seat that already manages
its Stress" — and H1 was written for the seat that does not.

`reactive` is greedy with exactly one preference changed: GROUND demoted
below ATTACK. Under it, H1's criteria 1 and 2 are MET — DARVO arms 400
times per cell, ATTACK is chosen 3 times per seat per game. Criterion 3
fails harder: reactive wins nothing at any seat count.

The larger finding is about the baseline. Greedy and reactive play
IDENTICALLY under baseline, and peak Stress across 3,200 baseline games
was 1 — against a starting value of 2. The gate at 4, the DARVO arm at 5
and the Freedom token are all unreachable, and a policy built to be
reckless with Stress is indistinguishable from one built to husband it.
That is a deeper account of F17 than F17 has. Not raised as a finding yet:
it wants the plural panel first.

A constant was investigated rather than reported: darvo was exactly 400 in
every cell while atk scaled with seats. Six-player final Stress is
[5,5,4,4,4,4] every seed — H1-B holds the attacker at 4, below the arm,
and pushes its targets to 5. The self-soothe suppresses DARVO in the
aggressor and concentrates it in the attacked. The direction follows from
H1-B's arithmetic; the number 2 is partly an artifact of reactive's
first-legal targeting, and is labelled as such.

Still unreviewed: tier L review outstanding on CB-WP-0038, and nothing
here reaches ground-game until it runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-08 01:08:40 +02:00
parent 5a55af1a21
commit 0f64961d06
6 changed files with 681 additions and 1 deletions

View file

@ -0,0 +1,107 @@
# CB-EV-0031 — a seat that does not regulate
CB-WP-0039. Tier M (adds a policy to the panel every future measurement is
reported against; chaos d8 = 2 → no override). **Declaration 11 of chaos
window 3.** Closed 2026-08-08.
> Like [CB-EV-0030](CB-EV-0030-h1-measured.md), **this has not had the
> tier-L adversarial review that pass owes, and none of it may reach
> `ground-game` until that review has run.**
**Delivered:** the `reactive` policy, and the measurement CB-EV-0030 §4
named as the one it had not run.
---
## 1. It changes CB-EV-0030's verdict
CB-EV-0030 concluded H1's DARVO arm rate was still 0. **That was true of
the panel, and the panel was greedy-family throughout.**
`GreedyPolicy` ranks `Action::Ground if gated => 100`: the instant the
stress gate bites it grounds. Stress plateaus at 3, and the arm at 5 is
unreachable **by construction**. So "H1 does nothing" was really "H1 does
nothing *to a seat that already manages its Stress*" — and H1 was written
for the seat that does not.
`reactive` is greedy with **one preference changed**: GROUND demoted below
ATTACK. SHARED GROUND, 200 games per cell, all 200 ran in every cell:
| | | greedy | | | | reactive | | |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| **seats** | won | atk | darvo | peak | won | atk | darvo | peak |
| 2p | 68 | 0 | 0 | 4 | **0** | 1200 | **400** | **5** |
| 3p | 0 | 0 | 0 | 4 | **0** | 1800 | **400** | **5** |
| 4p | 0 | 0 | 0 | 4 | **0** | 2400 | **400** | **5** |
| 6p | 0 | 0 | 0 | 4 | **0** | 3600 | **400** | **5** |
**H1's mechanism works.** Criterion 1 (DARVO arm rate non-trivial) and
criterion 2 (ATTACK selection rises for some subpopulation) are **met**
for the subpopulation H1 was aimed at. CB-EV-0030 reported both as
failures, and that report was about greedy.
**Criterion 3 still fails, and now worse.** Reactive wins **nothing**, at
any seat count, under H1.
## 2. The baseline finding, which is larger than H1
Look at the baseline half of the same run. Greedy and reactive are
**identical** — 132/165/190/200, zero attacks, zero DARVO, in all four
bands.
**Peak Stress across 3,200 baseline games was 1.** Starting Stress is 2,
so no seat's Stress was ever *set* above 1: it only ever went down.
> **The baseline's entire Stress economy is unreachable under this panel.**
> The gate at 4, the DARVO arm at 5, the Freedom token that buys past the
> gate — none of it can engage, and a policy built to be reckless with
> Stress plays identically to one built to husband it.
That is a deeper account of F17 than F17 has. ATTACK is not merely
unrewarding; **the pressure it is supposed to answer never exists.** H1 is
an attempt to fix exactly this, and it is aimed at the right thing.
## 3. What H1-B actually does, which is not what it was for
`darvo` is **exactly 400 in every cell** while `atk` scales cleanly with
seats (1200 / 1800 / 2400 / 3600 = 3 per seat per game). A constant across
seat counts is an artifact smell, so it was measured rather than reported.
Six-player final Stress, every seed: **`[5, 5, 4, 4, 4, 4]`**. Exactly two
seats arm, whatever the table size.
**The self-soothe is doing it.** An attacker at Stress ≥ 4 takes 1 for a
landed Attack, which holds it at 4 — *below the arm* — while its targets
take +1 or +2 and climb to 5. **H1-B suppresses DARVO in the seat that
attacks and concentrates it in the seat attacked.**
The hypothesis wanted ATTACK to be rational at high Stress. It is. The
side effect is that the aggressor is the one seat protected from arming.
**Stated as a limitation, not a finding about H1:** `reactive` picks its
Attack target by first-legal, not by any judgement, so the *concentration*
on two seats is partly an artifact of crude targeting. The direction —
attackers held at 4, targets pushed to 5 — follows from H1-B's arithmetic
and does not depend on the targeting. **The number 2 does.**
## 4. What this does not say
- **`reactive` is not a good player and is not meant to be.** It wins
nothing under H1 and exactly what greedy wins under baseline. It is an
instrument for reaching the Stress economy, not a claim about how people
play.
- **Two policies is still not a panel.** RetrospectiveAnalysis §4.1 asks
for greedy, random and first-legal at minimum; this pass added a fourth
axis to two of them, in one mode.
- **SHARED GROUND only.** CB-EV-0030 covered three modes; this covers one.
- **No felt-play**, and this is the kind of claim — about pressure, and
when a player feels cornered — that a human table answers and 3,200
simulated games do not.
## 5. Open
- **The baseline's Stress economy being unreachable (§2) deserves its own
finding**, and is not raised here because it wants the plural panel of
§4 first. It is the more consequential of the two results in this file.
- **Whether H1-B's suppression is intended** is ground-game's question,
and it is the sharpest thing this pass can hand them.

View file

@ -0,0 +1,186 @@
//! Does H1 do nothing, or does it do nothing **to a seat that already
//! manages its Stress**? (CB-WP-0039)
//!
//! [`CB-EV-0030`] measured ground-game's H1 with a panel that was
//! greedy-family throughout, and found DARVO never arms. But
//! `GreedyPolicy` ranks `Action::Ground if gated => 100`: the moment the
//! stress gate bites it grounds, Stress plateaus at 3, and the arm at 5
//! is unreachable **by construction**.
//!
//! H1 was written for the seat that does *not* do that. So this varies
//! **exactly one preference** — GROUND demoted below ATTACK — and holds
//! every other ranking identical to greedy's.
//!
//! [`CB-EV-0030`]: ../../../evidence/CB-EV-0030-h1-measured.md
use cb_game_runtime::{ScenarioGame, Setup};
use cb_kernel::PlayerId;
use games_ground::bot::{play, Choice, GreedyPolicy, Policy};
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.
struct Reactive;
impl Policy for Reactive {
fn name(&self) -> &'static str {
"reactive"
}
fn choose(
&mut self,
state: &GroundState,
seat: PlayerId,
legal: &[GroundCommand],
_may_pass: bool,
) -> Choice {
let gated = state
.players
.get(&seat)
.is_some_and(|p| p.stress >= 4 && !p.freedom_gate_lifted);
let rank = |c: &GroundCommand| -> i32 {
match c {
GroundCommand::SelectAction {
action, problem, ..
} => match action {
// THE ONE LINE. Greedy has `Ground if gated => 100`.
Action::Ground if gated => 5,
Action::Solve
if problem
.and_then(|p| state.problems.get(&p))
.is_some_and(|p| p.claimed_by.is_some()) =>
{
20
}
Action::Solve => 90,
Action::Investigate => 80,
Action::Support => 70,
Action::Ground => 5,
Action::Attack => 10,
},
GroundCommand::SpendFreedom => 95,
GroundCommand::ChooseGroundMode { .. } => 50,
GroundCommand::RespondToSupport { .. } => 90,
GroundCommand::ChooseDarvoTarget { .. } => 50,
GroundCommand::Reveal | GroundCommand::Resolve | GroundCommand::EndRound => -1,
}
};
let mut best = 0;
for (i, c) in legal.iter().enumerate() {
if rank(c) > rank(&legal[best]) {
best = i;
}
}
Choice::Command(best)
}
}
struct Cell {
games: u32,
won: u32,
atk: u32,
darvo: u32,
peak_stress: u8,
}
fn sweep(mode: ScoringMode, variant: Variant, players: u8, reactive: bool) -> Cell {
let mut c = Cell {
games: 0,
won: 0,
atk: 0,
darvo: 0,
peak_stress: 0,
};
for seed in 0..200u64 {
let Ok(mut st) = GroundState::setup(
&Setup {
players,
preset: format!("standard-{players}p"),
patch: Default::default(),
},
seed,
) else {
continue;
};
st.mode = mode;
st.variant = variant;
let mut ps: Vec<Box<dyn Policy>> = (0..players)
.map(|_| {
if reactive {
Box::new(Reactive) as Box<dyn Policy>
} else {
Box::new(GreedyPolicy) as Box<dyn Policy>
}
})
.collect();
// A refused game is not a lost game (CB-EV-0030 §3).
let g = match play(st, &mut ps) {
Ok(g) => g,
Err(e) => {
eprintln!(" !! {players}p seed {seed}: {e:?}");
continue;
}
};
c.games += 1;
if g.state.outcome.as_ref().is_some_and(|o| o.group_success) {
c.won += 1;
}
for (_, cmd) in &g.steps {
if let GroundCommand::SelectAction {
action: Action::Attack,
..
} = cmd
{
c.atk += 1;
}
}
for e in &g.events {
if matches!(e, games_ground::GroundEvent::DarvoTriggered { .. }) {
c.darvo += 1;
}
// How close does Stress actually get to the arm at 5? That is
// the number H1's whole mechanism turns on, and CB-EV-0030
// had to infer it from a single game.
if let games_ground::GroundEvent::StressSet { stress, .. } = e {
c.peak_stress = c.peak_stress.max(*stress);
}
}
}
c
}
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");
for (vlabel, variant) in [
("BASELINE ground-darvo-r0", Variant::Baseline),
("H1 h1-problem-stress", Variant::H1ProblemStress),
] {
println!("{vlabel}");
println!(" greedy (regulates) reactive (does not)");
println!("seats games won atk darvo peak games won atk darvo peak");
for players in [2u8, 3, 4, 6] {
let g = sweep(ScoringMode::SharedGround, variant, players, false);
let r = sweep(ScoringMode::SharedGround, variant, players, true);
println!(
" {players}p {:>4} {:>4} {:>4} {:>5} {:>4} {:>4} {:>4} {:>4} {:>5} {:>4}",
g.games,
g.won,
g.atk,
g.darvo,
g.peak_stress,
r.games,
r.won,
r.atk,
r.darvo,
r.peak_stress
);
}
println!();
}
}

View file

@ -64,6 +64,7 @@ it recurs; not evidence of anything on its own.
| 8 | CB-WP-0036 (re-declared L→M) | d8 = 7 | — |
| 9 | CB-WP-0037 | d8 = 1 | — |
| 10 | CB-WP-0038 | **d8 = 8** | **yes — redraw L, structural was L, so it changed nothing** |
| 11 | CB-WP-0039 | d8 = 2 | — |
**The window's first 8, at declaration 10.** Expectation over ten rolls at
d8 is 1.25; one is exactly on rate.
@ -71,7 +72,7 @@ d8 is 1.25; one is exactly on rate.
**The override changed nothing**, which is the observation ADR-0017 D2's
retirement condition is built from — it needs *a full window whose
overrides all change nothing*, in two consecutive windows. This window now
has one qualifying override and two declarations left to run.
has one qualifying override and **one declaration left to run**.
**Declaration 8 is a re-declaration of the same workplan**, counted
separately because it was a materially different pass: CB-WP-0036 was

View 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: 2
setup:
players: 3
preset: standard-3p
patch: {}
commands:
- actor: P1
cmd: select_action
args:
action: SUPPORT
target: P3
- 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: P3
cmd: respond_to_support
args:
response: accept_bond
- 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: INVESTIGATE
problem: 2
- actor: P3
cmd: select_action
args:
action: INVESTIGATE
problem: 2
- actor: SYSTEM
cmd: reveal
args: {}
- actor: P2
cmd: respond_to_support
args:
response: accept_bond
- 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: SOLVE
problem: 2
- 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: INVESTIGATE
problem: 4
- actor: P2
cmd: select_action
args:
action: INVESTIGATE
problem: 4
- actor: P3
cmd: select_action
args:
action: INVESTIGATE
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: SOLVE
problem: 4
- actor: P2
cmd: select_action
args:
action: SOLVE
problem: 4
- 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: {}
expect:
events: []
state: {}
rejects: []
state_hash: 18faddebb7568ff504b1f758a5906c54ed271c4705a192f458a20d8bb1a30650

149
trials/2026-08-08-0104.yaml Normal file
View 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: P3
- 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: P3
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: 0e9629eec89de6c479a617d2b8929819c502fc6d1020b30a871fe23ad8ea1a1b

View file

@ -0,0 +1,88 @@
---
id: CB-WP-0039
kind: product
title: "A seat that does not regulate"
status: done
---
# Purpose
```
structural tier M (adds a policy to the panel every future difficulty
and design measurement is reported against)
chaos d8 = 2 → no override
declared tier M
```
**Declaration 11 of chaos window 3.**
## Why
[CB-EV-0030](../evidence/CB-EV-0030-h1-measured.md) §4 named this as the
measurement it had not run, and it is the one that decides whether H1's
verdict is about **H1** or about **greedy**.
H1 assumes rising Stress pushes a table toward the DARVO arm. It does not,
**because greedy regulates**: `Action::Ground if gated => 100` makes
GROUND the top choice the moment the stress gate bites, so Stress
plateaus at 3 and neither the gate (4) nor the arm (5) is ever reached.
> **Every policy in that panel was greedy-family.** So "H1 does nothing"
> may be "H1 does nothing *to a seat that already manages its Stress*" —
> and H1 was written for the seat that does not.
## The one preference that varies
`Reactive` is `GreedyPolicy` with **GROUND demoted below ATTACK**, and
nothing else changed. It is the player who chases Problems and ignores
their own state — which is not a straw man: it is the commonest way a
person plays a co-operative game badly, and the behaviour GROUND's whole
Stress economy exists to punish.
**One preference, per ADR-0018 and the same discipline as
`attack-value.rs`'s `Attacker`.** A policy that differed in several places
would tell us a variant is different without saying which difference did
the work.
## Task: the policy, and the measurement
```task
id: CB-WP-0039-T01
status: done
priority: high
```
**Controls:**
- **exactly one preference differs from greedy**, and the artifact says
which;
- **both variants, same instrument, same run** — otherwise the comparison
is between harnesses;
- **the game count is reported**, because CB-EV-0030 §3's harness defect
was silently discarding games and printing zeros that read as losses;
- **the answer may be that H1 still fails**, and that is reported as
plainly as the other outcome.
**Done 2026-08-08.**
[CB-EV-0031](../evidence/CB-EV-0031-a-seat-that-does-not-regulate.md).
**It changed CB-EV-0030's verdict.** H1's criteria 1 and 2 are **met** for
the seat H1 was aimed at: DARVO arms 400 times per cell and ATTACK is
selected 3 times per seat per game. The earlier "H1 does nothing" was a
statement about greedy, which grounds the moment the gate bites.
**Criterion 3 fails harder**: reactive wins nothing, at any seat count.
**The larger finding is about the baseline, not H1.** Greedy and reactive
play *identically* under baseline — same wins, zero attacks, zero DARVO —
and **peak Stress across 3,200 baseline games was 1**, against a starting
value of 2. The gate at 4, the arm at 5 and the Freedom token are all
unreachable. That is a deeper account of F17 than F17 has, and it is
**not raised as a finding here** because it wants the plural panel first.
**A constant was investigated rather than reported.** `darvo` was exactly
400 in every cell while `atk` scaled properly with seats. Six-player final
Stress is `[5, 5, 4, 4, 4, 4]` every seed: **H1-B holds the attacker at 4,
below the arm, and pushes its targets to 5** — the self-soothe suppresses
DARVO in the aggressor and concentrates it in the attacked. The direction
follows from H1-B's arithmetic; **the number 2 is partly an artifact of
`reactive`'s first-legal targeting**, and is labelled as such.