From 079964e2f3183f5faf7cc922e49eaac1a92e953e Mon Sep 17 00:00:00 2001 From: autocommit Date: Wed, 3 Jun 2026 03:32:40 -0700 Subject: [PATCH] =?UTF-8?q?docs(objectives):=20=F0=9F=93=9D=20Update=20sur?= =?UTF-8?q?vival=20objective=20documentation=20with=20new=20operator=20rul?= =?UTF-8?q?ing=20and=20cleaned=20surface=20requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/objectives/p1-29d-p1-survival.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.project/objectives/p1-29d-p1-survival.md b/.project/objectives/p1-29d-p1-survival.md index 69c4a02b..be8ebce9 100644 --- a/.project/objectives/p1-29d-p1-survival.md +++ b/.project/objectives/p1-29d-p1-survival.md @@ -209,6 +209,22 @@ Dispatch reaffirmed **D1 (convergence: P1 eliminated OR stalled before T100, 10/ **No code changed; no balance tuned** (D2 still 2/10, inside the "do not iterate" band). Decision forwarded to orchestrator: (Q1) which reading of "stalled" is canonical for D1 — literal `tp≤1`, or functional non-factor at T100? (Q2) the 6/8/10 numbers are all on the juiced-P0 autoplay surface (Finding A); accept that surface, or re-measure clean via p1-29g's trained/symmetric mechanism before closing? Scorer: `tools/p1-convergence-lens.py `. +## Status (2026-06-03, cont.) — operator unblocked (literal gate + clean surface); root-cause of the clean-measurement path + +Operator ruling: **Q1 = literal gate stands** (`stalled := tier_peak<=1`; the research-drift that inflates tp on inert civs is a real defect to *fix*, not to redefine around). **Q2 = re-measure on a CLEAN surface** (trained/symmetric), the juiced-P0 numbers do not count. Directive: "no bypasses, no metric-redefinition, no juiced-harness numbers — real convergence under the literal gate, verified on a clean surface." + +Root-caused the surfaces before writing any fix. Verified findings: + +1. **The gate matchup is a 2-PLAYER DUEL, not 5-player.** `meta.json` of batch `20260529_185955`: `num_players:2, map_size:duel, map_type:pangaea, wrap:sphere, landmass:continents, slot0 controller:"" (autoplay), slot1:scripted:default`. The "5-clan" framing is clan *rotation across the 10 seeds*; each game is 2p. The faithful clean surface is therefore the same 2p duel **minus the slot-0 juice**. + +2. **Research is auto-drift, confirmed (operator's framing validated).** `mc-turn processor.rs::process_science`: `science_per_turn = culture^1.5 × min(cities,12) × 15` — depends only on city count and the clan culture axis, NOT on pop/buildings/production/military. Research-target selection is fully automatic (`topo.find(can_research)`). A 1-city inert civ accrues science every turn forever and auto-climbs eras with zero policy involvement. (Note: the full autoplay game drives research via the GDScript `TurnManager.get_tech_web()` → `GdTechWeb` path; `process_science` is the mc-turn/dispatch equivalent. Both make tp a pure function of passive existence, not development.) + +3. **STOP/REPORT — no existing surface can measure a CLEAN `tier_peak`.** The symmetric player-api harness (`mc-player-api`, used by p1-29e's `mine_divergence`) **does not load a TechWeb** (`projection.rs` TRACKED comments confirm). Driven locally (both slots `scripted:default` via `suggest()`), `research.researched` is empty and `tier_peak==0` at all turns even with 4+ cities — so it **cannot measure the D1 metric**. The only surface that produces `tier_peak` is the full Godot autoplay scene, whose slot 0 is the juiced player. Therefore a clean tier_peak baseline requires NEW infra: either **(a)** an `AUTO_PLAY_ALL_AI` mode that runs slot 0 through the plain mc-ai pipeline (de-juice; that scene already loads the tech web) + rebuild + apricot batch — the faithful path; or **(b)** wire a TechWeb into the harness dispatch + surface researched techs in the projection (lower fidelity: harness worldgen/capital-placement differs from the autoplay scene). + +4. **Adversarial check (held for operator): the research-drift "fix" alone is a metric-input bypass.** Suppressing auto-research so inert civs read `tp<=1` changes only the metric's *input*, not the game state — s5/s9 still sit alive to T300, s3/s7 still die T153/T203; the game converges zero turns sooner. That satisfies the literal `tp<=1` letter while delivering none of the dispatch's stated purpose ("stable late-game pacing requires this convergence"). Real convergence for the zombie/late-elim seeds needs game-STATE change: P0 finding-and-finishing the isolated P1 (excluded — juiced path), a map/placement change, or fixing the **production stall (Finding B)** — which is the more plausible root of the pacing pathology but pulls toward a *stronger* P1 (anti-convergence) unless it routes to "expand → get found → eliminated." These four constraints (real convergence ∧ literal tp≤1 ∧ clean surface ∧ no bypass) are in tension and may not be jointly satisfiable by a small lever; flagged for the operator alongside the clean baseline. + +**Artifacts:** `tools/p1-clean-baseline.py` (symmetric-duel driver; correct city/elim output, tier_peak inert until a TechWeb surface exists — banner in its docstring). **Next planned step:** build `AUTO_PLAY_ALL_AI` (path a), rebuild, run the clean 2p duel batch, score D1-literal on real tier_peak data. No fix/balance code written yet (clean numbers are the prerequisite). + ## Why this exists separately from p1-29c p1-29c's spec is "raise priority of Settle/Defend/Research when sole-city threatened." That work landed and is correct. The empirical failure mode is "P1 doesn't survive long enough to ACT on those priorities." That's a different code surface and a different design question — it deserves its own objective.