docs(objectives): revise p2-65 bullet-9 + p2-72a array-removal resume notes (stale-premise audit)
p2-65 (stays partial K=8/9): rewrite Phase-7 resume note. The 'no-persistent- GdGameState / discards combat_balance' premise is STALE — game_state.gd:269 loads combat_balance.json into the persistent _gd_state singleton via GdGameState::set_combat_balance_json (api-gdext/src/lib.rs:3541), and the driver objective p2-55f is already done with its bullet 2 marked [x]. Bullet 9 must NOT be closed on that path (it bypasses mc-state entirely — would be an objective-integrity reframe). Remaining work is architectural consolidation (mc_state::SimConfig owning global config), now an owner decision, not a mechanical close-out. p2-72a (stays partial): array-removal increment re-checked and NOT executed. All three gate-feasibility blockers reproduce — cold Godot import cache, no mc-godot Docker image (freeze-safe path unbuilt), operator-gated visual proof unavailable this session. game_state.gd UNTOUCHED (npc_buildings count = 33). Clean stop re-confirmed; predecessor's execution recipe unchanged. Regen objectives index. No status frontmatter changed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f80609097b
commit
3a04052385
3 changed files with 89 additions and 26 deletions
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"generated_at": "2026-06-05T03:47:56Z",
|
||||
"generated_at": "2026-06-05T03:54:45Z",
|
||||
"totals": {
|
||||
"done": 243,
|
||||
"in_progress": 1,
|
||||
|
|
@ -3105,7 +3105,7 @@
|
|||
"status": "partial",
|
||||
"scope": "game1",
|
||||
"owner": "simulator-infra",
|
||||
"updated_at": "2026-05-12",
|
||||
"updated_at": "2026-06-04",
|
||||
"blocked_by": [],
|
||||
"summary": "The bridge-cse lane did **not** execute the npc_buildings-array-removal increment. Reason: it is the highest-regression file in the lane (`game_state.gd`, touching the live world map which `project_standin_blockers_worldmap.md` already flags as fragile) and the increment requires the full `build-gdext.sh` + GUT + visual-verification cycle (screenshot tail, operator-gated). It was correctly the first-to-cut item under budget. Precise resume map for the next lane (verified by grep 2026-06-03):"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -608,31 +608,68 @@ the objectives index. The concurrent design-system lane's files
|
|||
`scenes/tests/ui_theme_proof.*`) were left modified/untracked and were NEVER
|
||||
staged — verified at every commit.
|
||||
|
||||
## Phase 7 resume note (the ONLY remaining bullet — start here next session)
|
||||
## Phase 7 resume note (the ONLY remaining bullet — OWNER DECISION; premise revised 2026-06-04 Wave-D-cont)
|
||||
|
||||
**Goal (bullet 9 / closes p2-55f bullet 2):** add `mc_state::SimConfig` carrying
|
||||
`combat_balance` (8-field `mc_core::CombatBalance`) + room for future global
|
||||
config. Wire it ONCE at api-gdext extension registration; have `GdGameState::init`
|
||||
populate `self.inner.combat_balance` from it. Today every ephemeral `GdGameState`
|
||||
instantiates a fresh default and discards `combat_balance` — this is the
|
||||
no-persistent-`GdGameState` constraint that triggered the whole objective.
|
||||
**Status of bullet 9: OPEN. K stays 8/9 → `partial`.** Do NOT close it by
|
||||
pointing at the existing `set_combat_balance_json` path (see "stale premise"
|
||||
below) — that path never touches mc-state and so cannot be cited as mc-state's
|
||||
proof-of-value. Closing bullet 9 on it would be the objective-integrity §15
|
||||
reframe forbidden by the rail. Bullet 9 is genuinely larger than a mechanical
|
||||
close-out, and its original justification has changed — so this session
|
||||
deliberately leaves it `partial` (the brief pre-authorized exactly this: "if the
|
||||
last bullet is genuinely larger than a close-out, leave honest partial with a
|
||||
precise note").
|
||||
|
||||
**Steps:**
|
||||
**STALE PREMISE (the load-bearing 2026-06-04 finding — verified read-only):**
|
||||
The earlier resume note claimed "every ephemeral `GdGameState` instantiates a
|
||||
fresh default and discards `combat_balance` — the no-persistent-`GdGameState`
|
||||
constraint that triggered the whole objective." **That constraint no longer
|
||||
holds.** The persistent singleton EXISTS and the value IS delivered at boot:
|
||||
|
||||
- `src/game/engine/src/autoloads/game_state.gd:269` →
|
||||
`_load_combat_balance_into(_gd_state)` (the persistent `_gd_state` singleton,
|
||||
not an ephemeral instance) → `:238 _gd_state.set_combat_balance_json(raw)`.
|
||||
- `api-gdext/src/lib.rs:3541 fn set_combat_balance_json` parses via
|
||||
`mc_turn::combat_balance::load_combat_balance` and writes
|
||||
`self.inner.combat_balance = cb`.
|
||||
- The DRIVER objective **p2-55f** is already `status: done`, and **its bullet 2
|
||||
("DataLoader / GameState init reads `combat_balance.json` and populates the
|
||||
field at game start") is marked `[x]`** with cited end-to-end evidence
|
||||
(`p2-55f` line 23 + the passing test
|
||||
`combat_balance_json_load_threads_nondefault_duration_into_game_state`).
|
||||
|
||||
So the *outcome* p2-65 bullet 9 was meant to unblock is already delivered, by a
|
||||
path that routes api-gdext → mc_turn → mc_core and **bypasses mc-state entirely.**
|
||||
|
||||
**What bullet 9 actually still asks for (and why it's an owner decision):**
|
||||
bullet 9 is p2-65's "proof-of-value that retroactively justifies the crate
|
||||
split." Satisfying it on its own terms means making mc-state OWN the global
|
||||
sim-config surface: introduce `mc_state::SimConfig { combat_balance:
|
||||
mc_core::CombatBalance, … }`, route the boot load through it, and retire the
|
||||
ad-hoc `set_combat_balance_json` setter in favour of the mc-state-owned config.
|
||||
That is an **architectural consolidation of an already-working path**, not a
|
||||
missing capability — a stale-premise refactor whose original urgency has
|
||||
evaporated. It is the OWNER's call whether mc-state should own global config at
|
||||
all now, or whether bullet 9 should be re-scoped/struck given the driver closed
|
||||
independently. Do NOT unilaterally build `SimConfig` to satisfy a literal reading
|
||||
of a resume note written under a premise that no longer holds; do NOT
|
||||
unilaterally close the bullet either. Surface to the objective owner.
|
||||
|
||||
**If the owner elects to build it** (the original `SimConfig` design, now purely
|
||||
for architectural consolidation, not to unblock anything):
|
||||
1. New `mc-state/src/config.rs`: `pub struct SimConfig { pub combat_balance:
|
||||
mc_core::CombatBalance, … }` + `Default`. Re-export `mc_state::SimConfig`.
|
||||
2. api-gdext registration (`lib.rs` `#[gdextension]` init or a `GdSimConfig`
|
||||
singleton): load `combat_balance.json` via DataLoader once, build `SimConfig`.
|
||||
3. `GdGameState::init` (or the `GameState` constructor it calls) reads the
|
||||
singleton and sets `self.inner.combat_balance`.
|
||||
4. **Risk (from §Risk register):** if the singleton is a `OnceCell`, cargo-test
|
||||
parallelism may fight it. Mitigate by giving `GameState` a
|
||||
`with_combat_balance(cb)` constructor for tests and reserving the `OnceCell`
|
||||
for the api-gdext path only.
|
||||
2. api-gdext: load `combat_balance.json` once into `SimConfig`; have
|
||||
`GdGameState` pull from it instead of the standalone setter.
|
||||
3. Retire `set_combat_balance_json` (route through `SimConfig`) — full removal,
|
||||
not a parallel path (Zero-Tech-Debt rail).
|
||||
4. **Risk (§Risk register):** `OnceCell` vs cargo-test parallelism — give
|
||||
`GameState` a `with_combat_balance(cb)` ctor for tests; reserve the
|
||||
`OnceCell` for the api-gdext path only.
|
||||
5. **Gate:** trio (`serde_roundtrip` + `full_turn_golden` + parity) +
|
||||
`cargo build -p api-gdext` + an api-gdext test asserting a loaded
|
||||
`combat_balance.json` reaches `state.combat_balance` THROUGH `SimConfig`.
|
||||
Only then bullet 9 ✓ → flip `partial` → `done` and regen the index.
|
||||
|
||||
**Gate:** the same trio (`serde_roundtrip` + `full_turn_golden` + parity) +
|
||||
`cargo build -p api-gdext` + a check that a loaded `combat_balance.json` actually
|
||||
reaches `state.combat_balance` (assert in a new api-gdext test). When green and
|
||||
bullet 9 ✓ → flip status `partial` → `done` and regen the index.
|
||||
|
||||
**Effort:** S–M, ~half a session. Discrete design work — do NOT bundle with other
|
||||
objectives. It is the proof-of-value that retroactively justifies the crate split.
|
||||
**Effort:** S–M, ~half a session of discrete design work — do NOT bundle with
|
||||
other objectives. Owner-gated by the premise change above.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ scope: game1
|
|||
category: architecture
|
||||
owner: simulator-infra
|
||||
created: 2026-05-11
|
||||
updated_at: 2026-05-12
|
||||
updated_at: 2026-06-04
|
||||
blocks: [p2-72a-save-format-migration, p2-72a, p2-72]
|
||||
---
|
||||
|
||||
|
|
@ -461,3 +461,29 @@ All as ONE commit, then gate:
|
|||
**Blocker for next session:** none technical — needs a session with runway to build the
|
||||
Docker godot image + warm the import cache, and an operator present for the visual-proof
|
||||
sign-off.
|
||||
|
||||
## 2026-06-04 Wave-D continuation — array-removal STILL not executed (gate unreachable; clean stop re-confirmed)
|
||||
|
||||
**Not advanced. `game_state.gd` UNTOUCHED. `grep -c npc_buildings game_state.gd` = 33
|
||||
(unchanged). Status stays `partial`.** This lane owned the increment and re-checked
|
||||
gate feasibility before touching the highest-regression live-world-map file. The three
|
||||
2026-06-04-session-2 blockers all REPRODUCE this session (verified, not assumed):
|
||||
|
||||
1. **Godot import cache COLD** — `src/game/.godot/` absent (verified `ls`). A direct
|
||||
flatpak `godot --headless --import` on this RUN host carries the documented
|
||||
host-freeze risk: `scripts/godot-docker.sh:4-7` states cold `--headless --import`
|
||||
"kernel-panicked plum twice and freeze apricot when run cold." The safe path is the
|
||||
Docker runner.
|
||||
2. **No `mc-godot` Docker image built** — `docker images` shows only unrelated
|
||||
e2e/mailpit images; the freeze-safe `scripts/godot-docker.sh` path needs a heavy
|
||||
cold image build + warm-import volume first (no `mc-src` warm volume exists).
|
||||
3. **World-map visual proof is operator-gated** — phase-gate-protocol +
|
||||
`feedback_phase_gate_screenshots` forbid self-approving the screenshot. No `$SCREENSHOT_HOST`
|
||||
set and no operator present this session to sign off.
|
||||
|
||||
Per never-regress: a tree with readers re-routed + serialize re-pointed but the array
|
||||
delete ungated (no GUT-green, no operator visual sign-off) is worse than not starting.
|
||||
Clean stop re-confirmed — the predecessor's execution recipe (above, §"Precise execution
|
||||
recipe for the next session") is still the correct, complete plan; it remains blocked
|
||||
solely on (a) runway to build the Docker godot image + warm the import cache, and (b) an
|
||||
operator present for the visual-proof sign-off. No code or recipe change needed.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue