From 8dcab6df6e144208b60981e4f5e863453e33f7a6 Mon Sep 17 00:00:00 2001 From: Natalie Date: Mon, 8 Jun 2026 03:08:16 -0700 Subject: [PATCH] =?UTF-8?q?feat(@projects):=20=E2=9C=A8=20clarify=20inline?= =?UTF-8?q?=20movement=20separation=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/designs/p2-80-bullet2-port-sizing.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.project/designs/p2-80-bullet2-port-sizing.md b/.project/designs/p2-80-bullet2-port-sizing.md index db761df9..e54392c2 100644 --- a/.project/designs/p2-80-bullet2-port-sizing.md +++ b/.project/designs/p2-80-bullet2-port-sizing.md @@ -186,3 +186,40 @@ produce live-grade games (**2531 kills**, conquest, 47-city winner over 250 turns). Use those as the convergence harness for the cutover; leave `dominion_bench` as the fast inline-AI economic/expansion bench it was designed to be. The real-AI viability question (step 1) is **already answered** there. + +--- + +## Task #2 finding (2026-06-08) — inline movement runs in the AUTHORITATIVE path, not bench-only + +Corrects an earlier framing. The inline bench movement (Phase-5: nearest enemy +unit → enemy city → lair, `processor.rs:2009-2031`) is **bundled into** +`process_fauna_encounters_inner(state, result, move_units)` — the `move_units` +flag (`processor.rs:1994`) gates the Phase-5 loop: +- `TurnProcessor::step()` → `move_units=true` → inline movement runs. +- `TurnProcessor::step_encounters_only()` → `move_units=false` → movement + skipped, **but it also skips production/growth** (it is encounters-only; see + `bridge_contract_tests.rs:256,279`). + +**Caller map (`grep '\.step('`):** +- **Authoritative/harness path:** `mc_player_api::dispatch::apply_end_turn` + (`dispatch.rs:415`) calls `processor.step(state)` — `move_units=true`. So the + authoritative turn runs the inline heuristic movement **on top of** + `run_ai_turn`/`drive_ai_slot` (which already moved units). The dumb heuristic + re-moves what the real AI positioned. (`full_game_transcript` still produces + 2531 kills — the combination works, but the inline pass is redundant and can + undermine the real AI's tactical placement.) +- **Benches:** `dominion_bench`, `solo_dominion`, `tournament_bench`, + `fauna_pressure_bench`, `mc-sim/lib.rs`, `processor_invariants` — all + `step()` (`move_units=true`), relying on the inline AI as their only mover. + +**Precise cutover fix (next increment — pure-Rust, benched on +`full_game_transcript`):** give the authoritative path a way to run the FULL +turn (production/growth/combat/victory) with `move_units=false`, so movement +comes ONLY from `run_ai_turn`. Options: (a) add `move_units: bool` param to a +`step_full(move_units)` and have `apply_end_turn` pass `false`; (b) a dedicated +`step_no_inline_move()`. Then `run_ai_turn` owns all movement and the inline +heuristic is genuinely bench-only (only the `mc-sim` benches keep `move_units=true`). +Verify: `full_game_transcript` / `long_game_transcript` still produce combat + +sane shape with movement driven solely by `run_ai_turn`. Acceptance for task #2 +(documented separation: authoritative=run_ai_turn, inline=bench-only) is met +once `apply_end_turn` no longer triggers the inline movement.