Specialist agents had ZERO shared instruction layer — each inlined its own knowledge, none
referenced the rails/layering/verification rules, so the same mistakes recurred. Restructured
into a DRY shape grounded in the bugs this session surfaced:
NEW specialist-preamble.md — the shared core every specialist loads first. Six commandments,
each earned by a real violation: (1) verify-don't-infer incl. docs/memory drift (the rust-source
false claims), (2) code-layering (formula vs orchestration vs presentation vs content vs type),
(3) prove-it by output type (cargo test / headless loop / golden-repin / render-proof), (4) stay
in scope (Game 1, no gold-plating disabled systems), (5) objective state = pointer+protocol not
embedded, (6) safety/workflow (build-output, atomic commits, worktree-fork→file-extraction).
agents-task-map.md rewritten as the orchestration PLAYBOOK (not just a lookup): dispatch-vs-inline,
parallel-by-default, the mandatory verify gate per output type, the worktree-fork integration rule,
"specialists return data not prose". Fixed the phantom mc-magic row (Game 2/3, no crate).
All 13 agents converted to thin shared-core pointer + domain delta (fault line + domain docs +
how-to-verify), each fault line drawn from a real drift risk for that specialist. Router + README +
CLAUDE.md agents section updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Better-guide-agents pass, grounded in this session's architecture review (GDScript turn-logic
divergence, rules leaked into mc-core). Two-pronged:
NEW `code-layering.md` — the decision PROCEDURE that was missing (the Rails state the rule; agents
still drifted because there was no "where does this code go?" procedure). Classifies every change as
formula/orchestration/presentation/content/shared-type, gives each one home, mandates grep-before-
reimplement, uses biomes as the template, records the real anti-patterns hit. Wired into the
always-loaded router + README index.
FIX `rust-source-of-truth.md` drift (it was actively misleading agents):
- "AI exception (one of one)" CONTRADICTED Rail-1 → recast as tech-debt; GdAiController DOES exist
(api-gdext/src/ai.rs:333), dispatch via mc_player_api::controllers.
- crate table listed phantom `mc-magic` + claimed BiomeRegistry in mc-core (false) → accurate
pure-logic-vs-orchestrator table; mc-core = shared TYPES, no rules.
game-systems + godot-engine agents point at code-layering at the fault lines they own.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
project_resources hardcoded happiness_pool: 0 (a stub from before the happiness phase
existed). Now that process_happiness_phase computes player.happiness each turn, surface it
in the PlayerView so the headless view exposes it end-to-end (compute → projection → view).
mc-player-api 135/0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three geological natural-event categories (parallel agent port, extracted file-only onto
current main — the agent worktree forked from a stale base, so a branch merge was unsafe;
events.rs is a clean superset verified to compile + test against current HEAD):
- seismic — shifts tile elevation over a radius (with falloff).
- impact (asteroid) — T1-4 crater (biome/elevation/moisture/quality + local heat + aerosol);
T5 extinction (global aerosol injection). Magic/anchor/resource-spawn deferred (Game-3).
- tsunami — floods coastal land (moisture/quality/reef_health), skips open water.
Each: apply_X + dispatch_X + match arm in process_events + tests. Configs already present
(seismic/impact/tsunami.json) + auto-loaded via the headless harness, so they dispatch in
process_climate_phase with no extra wiring. mc-climate 61/0; mc-turn builds.
6/12 categories live (wildfire/drought/volcanic/seismic/impact/tsunami).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Exposed by a new hotseat full-game driver (drives both player seats over the
multi-slot wire, no AI dependency) — a 31-turn 2-player game surfaced these.
- mc-player-api: the AI→PlayerAction converter (apply_ai_action + the suggest
sibling) emitted the bare tactical city index ("0") for QueueProduction, but
find_city_indices needs the projector wire id "{player}_{c_idx}" — so every
AI/suggested queue_production failed UnknownCity. This silently broke the
in-box AI's production-steering, not just the wire. Emit the wire id at all
three sites; thread slot into the suggest converter; add a regression test.
Result in the playthrough: roundtrip failures 58→1, city_building_completed 0→18.
- api-gdext: advance_round_phase/end_player_round_phase did not compile at HEAD —
godot-rust 0.2.4 Array::push needs &Dictionary (AsArg); Pcg64 builds via ::seed
not ::seed_from_u64; dropped a dead rng binding. The gdext crate could not be
rebuilt from source until this.
- mc-worldsim: pub use GamePhase/RoundPhase (api-gdext references them through
mc_worldsim; they were a private re-export → E0603).
- tooling: add hotseat_playthrough.py — applies each seat's suggested actions
and flags any offered action that fails to apply, with severity triage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stale May 31–Jun 8 agent worktrees, all behind main with no unique work
(every change landed or superseded). Removed checkouts, branches, and the
accidentally-committed gitlink entries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first in-session magic_civ_screenshot timed out: windowed Godot spawned by
the MCP (a throttled background GUI process under Claude Code) inits far slower
than a terminal launch, exceeding the 45s connect timeout — though the driver
DID bind the port (verified 8787 open). Fixes:
- connect-first: if a rendered driver is already listening (e.g. a foreground
`MC_MCP_RENDER=1 ./run play`), connect to it directly and skip the slow,
throttled background spawn entirely.
- start timeout 45s -> 150s for the spawn fallback.
- a failed start now clears its cached promise + reaps the child so the next
tool call respawns instead of replaying the rejection until an MCP restart.
Re-verified end-to-end through the built RenderClient (spawn path): ping {ok},
screenshot -> a real 3420x1923 PNG of the live world map.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- render_client.ts: TCP client that spawns the rendered game via
render-driver-server.sh, then sends screenshot / open_screen / ping correlated
by id (distinct from the headless stdin HarnessClient).
- scripts/render-driver-server.sh: boots the REAL game (MC_AUTO_START +
MC_MCP_RENDER, gl_compatibility, not --headless) so the driver captures real
frames; client connects on MC_MCP_PORT.
- index.ts: magic_civ_screenshot + magic_civ_open_screen tools, render-client
holder + cleanup.
Verified end-to-end through the BUILT TypeScript (no Claude restart needed):
RenderClient -> game -> TCP ping {ok}, screenshot -> a real 3420x1923 PNG of the
live world map. dist/ is gitignored (built locally per .mcp.json); the tools
surface in a Claude session after the next restart.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Full integration of worktree-bridge-cse_01Nnt (54 commits) into main.
Conflicts (17) resolved: adopt branch's p2-65 GameState->mc-state crate move
across mc-ai/mc-core/mc-player-api/mc-turn; keep main's design-token theme
system (build-ui-theme.py, tile_info_panel.gd) and main's newer p0-26b evidence.
Workspace: 2624 tests pass; 5 pre-existing/environmental failures inherited from
main (constructor_smoke capping test, five_players_overflow, 3x gpu_rollout_parity)
— zero regressions introduced by the merge. api-gdext (GDExtension) compiles.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>