--- title: "BDPD v0.9 — Release Notebook" subtitle: "Governance: cheap talk, pacts, sanctioning — Paper 1 MVP closed" author: "Roberto Brunelli" date: "2026-05-28" release_tag: "v0.9" release_type: "scientific" format: html: toc: true code-fold: true embed-resources: true --- # Overview {#sec-overview} v0.9 is the **Governance** release. It closes the three "*Not directly implemented*" rows of the Ostrom table from Paper 0 (§4): pact tracking, cheap-talk surface, sanctioning perturbation. Opened 2026-05-22 on branch `v0.9-dev` from `d63436d`. The Paper 1 MVP critical path is complete: A1 + A3 + B1 + B3 + C1 + D1, plus D2 + D3 ladder sweeps that anchor the headline finding. This is a **scientific** release: it introduces a new agent channel (cheap talk), a new violation tracker (pacts), a new sanction mechanism (`sanction` perturbation), new metrics (`cooperation_index`, `lie_score`, `silent_defection`, `announce_frequency`, `sanction_rate`), and a new sanctioning-meta-agent class (`SanctionerAgent`, `VoluntarySanctionerAgent`). Paper 1 is the citable artefact; v0.9 is the platform underneath it. # Headline empirical finding (D1) {#sec-d1} *Pure cheap talk does not solve the cliff.* In a 6-agent canonical cliff setup (5 conservative + 1 aggressive, K=150, regen=0.12, threshold=10, 30-turn max), enabling cheap talk for all six LLM agents (`broadcast`, `send_private`, `announce_intended_harvest`, `pact_propose`, `pact_accept`) results in **earlier collapse** at N=5 (mean preservation 0/5 in A, 2/5 in B). The aggressor wins in wealth (105 vs mean 64) even with cheap talk on, announcements are honoured (`lie_score ≈ 0`) but communication decays from 8 → 1 messages/turn after T7. This is the Farrell–Rabin negative result that motivates the Phase B → C transition in Paper 1: sanctioning is required. The N=5 sweep also reveals that **`silent_defection`** is the robust diagnostic for the aggressive archetype: `lie_score` is dead at honour=100%, but `silent_defection = 0.38 ± 0.07` in cheap-talk condition vs `0.72` in the mechanically-pinned baseline. # What changed {#sec-what-changed} ## A — State foundations - **A1 — PactRegistry** (`platform/pacts.js`). Per-arena pact lifecycle: propose / accept / decline / cancel. Term types: `harvest_cap`, `commons_floor`, `reciprocity`. Automatic violation tracking via `checkViolations()` called by `arena.tick`. - **A2 — ReputationRegistry** (P1, included). EMA per-player cooperation score, exposed via `query_reputation` tool. Mirrored in middle-man for prompt observation. - **A3 — Governance metrics in METRIC_REGISTRY** (`engine/metrics.js`). Five entries: `cooperation_index`, `lie_score`, `sanction_rate`, `announce_frequency`, `silent_defection`. All populated per-turn in `turnRecord.governance` by `governanceSnapshot`. ## B — Communication (cheap talk) - **B1a — MessageBus** (`platform/messages.js`). Append-only, recipient-filtered cheap-talk channel with broadcast / private / announcement scopes. - **B1b — Arena action protocol + SDK cheap-talk tools.** Agents return `actions[]` alongside `harvest`. SDK exposes `broadcast`, `send_private`; inbox surfaced in `buildObservation` with one-turn lag. - **B1c — Pact actions** on both sides. Arena consumes `pact_propose` / `pact_accept` / `pact_decline` / `pact_cancel`; SDK exposes the same tool surface. - **B1d — `announce_intended_harvest`** as both a tool and a JSON field on the structured response. Empirical finding: agents prefer the JSON field over the tool when both exist. - **B3 — Lie score + announce_frequency + silent_defection bundle.** `lie_score` is dead at honour=100%; `silent_defection` is the diagnostic for D1. ## C — Mechanisms (sanctioning) - **C1 — `sanction` perturbation + `pact_violation` trigger** (`platform/perturbation.js`). New perturbation type (`amount + factor` penalty model) and trigger kind that fires on each violation recorded by `PactRegistry`. - **C3.a — Arena-level governance meta-agent class.** New `role: 'meta'` channel on `Arena.addAgent`. `SanctionerAgent` (reflexive) and `VoluntarySanctionerAgent` (discretion: `triggerStockRatio` + `repeatThreshold`) shipped. ## D — Science - **D1 — Cliff under active cheap talk** (`scripts/pilot_d1.mjs`). Side-by-side 2-cell mini-pilot at the canonical cliff. Output: `data/pilot/d1/{cell_A_off,cell_B_on,comparison}.json` + headline figure rendered in all three themes. - **D2 — Graduated ladder** (`scripts/pilot_d2.mjs`). 5-agent Mule scenario, ladder `[1, 3, 10]` vs constant `3`. Ladder dominates (28 vs 21 turns survival, −50% violations, mule wealth −40%). Mechanism: wealth ablation in built-in, not pure deterrence. - **D3 — Voluntary sanctioner ladder sweep** (`scripts/pilot_d3.mjs`). N=5 × 3 ladders (soft `[1,2,4]`, canonical `[1,3,10]`, hard `[1,5,25]`). Graduated ladders preserve ≥ 4/5 vs flat-5 1/5. Soft preserves 4/5 with mule wealth 77.8; hard preserves 5/5 with mule wealth 21.6 (−72% deterrence). Pareto trade-off identified. # Storage and reproducibility {#sec-storage} - **§5 #8 storage path world-prefix** (commit `36c914c`). Arena files now write to `data/worlds/default/arenas//` instead of `data/arenas//`, honouring nested-safety decision #8. `default` is the implicit `world_id`; v1.0 nested-arena dispatch populates other worlds without code changes. Idempotent migration script ships in `scripts/migrate_storage_world_prefix.mjs`. - **`max_history` 6/8 → 32** (commit `61d7d62`). DeepSeek prompt-cache hit ~89% T1-T9 dropped to ~27% from T10 onwards because `deque(maxlen=max_history*2)` evicted earlier turns and changed the cache-stable prefix. Default `32` covers 30-turn BDPD games without eviction; ~3-4× cheaper input tokens for full-game runs. # Smoke coverage {#sec-smoke} 15 smokes green pre-pilot: 11 Node (`smoke_governance_arena`, `smoke_messages`, `smoke_pact_actions`, `smoke_pacts`, `smoke_reputation`, `smoke_action_protocol`, `smoke_b1d1`, `smoke_b3`, `smoke_c1`, `smoke_world_prefix`, `smoke_b1b2`) + 4 Python. Plus 3 optional DeepSeek pilots (`pilot_c1`, `pilot_d1`, `smoke_b1d_pilot`). # References {#sec-refs} - [Paper 1 — Governance MVP](../publications/paper_01/_site/index.html) - [Governance meta-agents](../platform/governance.md) - [Perturbations — `sanction`](../platform/perturbations.md) - [V0.9_PLAN.md](../dev/V0.9_PLAN.md) - [Changelog v0.9](../dev/changelog.md)