Skip to content

Four went in: terminal modes and the wipe that ends the session - #55

Merged
mmacy merged 8 commits into
mainfrom
phase-12-impl
Aug 6, 2026
Merged

Four went in: terminal modes and the wipe that ends the session#55
mmacy merged 8 commits into
mainfrom
phase-12-impl

Conversation

@mmacy

@mmacy mmacy commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Implements the phase 12 plan (#54): SessionMode.VICTORY with its command-legality contract, and every party wipe — battle or not — routed to game_over through one piece of terminal-state machinery. The milestone runs: the phase golden's trap wipe ends the session and replays and restores clean, a deprivation wipe ends it the same way, and the victory legality census holds at both the declaration and the executed seam.

What shipped

  • SessionMode.VICTORY and SessionMode.terminal — the second terminal mode and the one place "has this session ended?" is decided. Play commands are illegal in both terminal modes by construction; referee commands remain legal except the three that would resume play: PlaceParty (illegal in victory only — it stays legal in game_over as the documented salvage door to raise_dead) and SpawnMonsters/SpawnNpcParty (illegal in both; a concluded session opens no new play state). The spawn narrowing is a changelog Changed entry, and the spec's victory sentence gains the matching one-sentence carve-out.
  • The centralized wipe check in GameSession.execute, sharing one walk with _record_deaths: edge-triggered (fires only when the command's own events killed a member and nobody is left), so the salvage flow — PlaceParty(town) ferrying corpses to the temple — never re-triggers the ending. Terminal modes are sticky: a death after victory leaves victory alone, and nothing ends twice.
  • Battle's defeat transition folded in: _check_ends keeps ending the battle, the session check owns the mode flip and the GameOverEvent — one construction site, one reason string. The ResolveBattleRound TPK event stream is byte-identical to before the fold (verified against a main worktree, 4 seeds, full event dumps).
  • Wiped-party guards on every mid-command procedure that would otherwise start new activity for corpses: area treasure, keyed encounters, encounter and pursuit rounds, the turn-undead attacks branch, trapped-cache looting, and advance_turns' in-field cadences. The boundary is fact 5's: the wiping command's own bookkeeping (relocation, time, its report) stands; what never follows a wipe is a fresh procedure with fresh draws.
  • The phase golden (phase12_wipe.json): a scripted gas-trap wipe — seed chosen so the 2-in-6 spring fires, generator raises if it ever misses — plus two referee probes among the corpses, covering load-equals-replay over a session that ends, which no prior golden did.

No schema_version bump, no new events/codes/templates, no existing golden touched.

Review provenance

Implementation and review both ran as Opus subagents under coordination, per the phase loop. Round 1 came back NEEDS REVISION with one blocking finding the plan's guard census had missed — TurnUndead's attacks branch advances a round (where a delayed poison can wipe the party) and then opened a player-visible battle among corpses — reproduced by script, plus four non-blocking (unguarded trapped-cache draws on the treasure stream, a PlaceParty docstring contradiction, a vacuous stream assertion in the chute test, and a truncated-rest reporting nuance). Fixes landed as address rubber-duck review findings; the census gap and the truncated-rest boundary were folded back into the plan as amend phase 12 plan: extend the guard census to turn-undead and trapped-cache looting, so plan and code do not diverge. Round 2: SOLID — every fix re-verified by rerunning the original repros, both new guards proven load-bearing by reversion in a scratch worktree, TPK stream re-confirmed byte-identical, golden not regenerated by the fixes. Sign-off notes folded in.

Full gate green locally: ruff format --check, ruff check, pyright, pytest (1921 passed), mkdocs build --strict.

https://claude.ai/code/session_01CB29d5EbD7XWGrB1EC52dt

@mmacy
mmacy merged commit caef8ed into main Aug 6, 2026
5 checks passed
@mmacy
mmacy deleted the phase-12-impl branch August 6, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant