BS-PR-709 - Guarded editor shutdown and clean history savepoints #55

Closed
opened 2026-07-13 01:00:16 -04:00 by Rbanh · 1 comment
Owner

Summary

Prevent silent loss of authored scene work when closing the editor, and make the dirty marker follow the actual saved history position.

Why

Native operator QA on 2026-07-13 exposed two production blockers:

  • After a clean scene committed Group Selection and then undid back to the exact loaded hierarchy, the title remained dirty. apply_command_undo unconditionally marks the scene dirty and history has no saved-state checkpoint.
  • Alt+F4 closed the dirty editor immediately. Dirty confirmation currently protects scene-tab close and project switch, but not native window/application exit. Recovery snapshots reduce impact but are not a substitute for an explicit Save / Discard / Cancel decision.

Implementation notes

  • Intercept native close/window-exit requests before Bevy terminates.
  • Use the existing non-blocking NativeDialogBroker; never block the render loop.
  • Present one clear Save All / Discard / Cancel workflow for every dirty scene tab.
  • Exit only after successful save or explicit discard; Cancel must keep the exact session alive.
  • Track a clean checkpoint per document/history timeline. Undoing to it clears the dirty marker; redo away from it restores dirty.
  • Saving at nonzero undo depth establishes a new checkpoint. Branching history after undo invalidates an unreachable checkpoint.
  • Tab switching/history clearing must preserve each tab's actual dirty state.

Acceptance criteria

  • Alt+F4, window close, menu quit, and programmatic editor exit share the guarded path.
  • Save, discard, and cancel are non-blocking and deterministic across one or multiple dirty tabs.
  • Undo to the last saved state clears the title/tab dirty indicator; redo away marks it dirty.
  • Savepoints survive normal undo/redo and are invalidated correctly by branched history.
  • Failed saves do not exit or clear recovery data.
  • Headless tests cover clean/dirty/savepoint branches and exit decisions.
  • Native Linux QA proves the modal, cancel path, save/discard path, and clean logs.

Docs/tests

Update scene persistence/recovery docs and ADR 0023 if the shutdown contract changes. Packaged-runtime tests remain deferred until re-enabled.

## Summary Prevent silent loss of authored scene work when closing the editor, and make the dirty marker follow the actual saved history position. ## Why Native operator QA on 2026-07-13 exposed two production blockers: - After a clean scene committed Group Selection and then undid back to the exact loaded hierarchy, the title remained dirty. `apply_command_undo` unconditionally marks the scene dirty and history has no saved-state checkpoint. - `Alt+F4` closed the dirty editor immediately. Dirty confirmation currently protects scene-tab close and project switch, but not native window/application exit. Recovery snapshots reduce impact but are not a substitute for an explicit Save / Discard / Cancel decision. ## Implementation notes - Intercept native close/window-exit requests before Bevy terminates. - Use the existing non-blocking `NativeDialogBroker`; never block the render loop. - Present one clear Save All / Discard / Cancel workflow for every dirty scene tab. - Exit only after successful save or explicit discard; Cancel must keep the exact session alive. - Track a clean checkpoint per document/history timeline. Undoing to it clears the dirty marker; redo away from it restores dirty. - Saving at nonzero undo depth establishes a new checkpoint. Branching history after undo invalidates an unreachable checkpoint. - Tab switching/history clearing must preserve each tab's actual dirty state. ## Acceptance criteria - [ ] `Alt+F4`, window close, menu quit, and programmatic editor exit share the guarded path. - [ ] Save, discard, and cancel are non-blocking and deterministic across one or multiple dirty tabs. - [ ] Undo to the last saved state clears the title/tab dirty indicator; redo away marks it dirty. - [ ] Savepoints survive normal undo/redo and are invalidated correctly by branched history. - [ ] Failed saves do not exit or clear recovery data. - [ ] Headless tests cover clean/dirty/savepoint branches and exit decisions. - [ ] Native Linux QA proves the modal, cancel path, save/discard path, and clean logs. ## Docs/tests Update scene persistence/recovery docs and ADR 0023 if the shutdown contract changes. Packaged-runtime tests remain deferred until re-enabled.
Rbanh added this to the M7 - Content production and shipping milestone 2026-07-13 01:00:16 -04:00
Author
Owner

Completed and published on main.

Implementation

Source gates at the #55 implementation

  • cargo fmt --all -- --check: pass
  • git diff --check: pass
  • cargo clippy --workspace --all-targets -- -D warnings: pass
  • cargo test --workspace --all-targets --no-fail-fast: pass; editor 282 tests
  • Focused shutdown, Save All, savepoint, and project-switch regressions: pass

Native Linux acceptance

  • Undo back to the canonical saved projection cleared the dirty marker.
  • Native close then Cancel retained the exact dirty session.
  • File > Quit then Discard exited cleanly.
  • Switch Project... used the same guarded decision.
  • Dirty named Save All wrote before exit.
  • Clean untitled close exited without a decision.
  • Dirty untitled Save All continued asynchronously through KDE Save As, wrote the scene, and exited with code 0.

Guarded shutdown decision

The temporary QA scene was removed. Packaged-runtime acceptance remains explicitly owner-deferred; no packaged result or production-candidate signoff is claimed.

Completed and published on `main`. **Implementation** - Guarded shutdown/savepoints: [`4b33f3235761fd0dd3daf219e5bbbaee884eb626`](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/commit/4b33f3235761fd0dd3daf219e5bbbaee884eb626) - Acceptance record: [`a048233fceab86649f8c1004137a59f0cd62ac12`](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/commit/a048233fceab86649f8c1004137a59f0cd62ac12) - Follow-on scoped UI fix discovered during native acceptance: [`9e23ae731f95dc351ecc744d6ca61f6bc4467317`](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/commit/9e23ae731f95dc351ecc744d6ca61f6bc4467317) (#57) **Source gates at the #55 implementation** - `cargo fmt --all -- --check`: pass - `git diff --check`: pass - `cargo clippy --workspace --all-targets -- -D warnings`: pass - `cargo test --workspace --all-targets --no-fail-fast`: pass; editor 282 tests - Focused shutdown, Save All, savepoint, and project-switch regressions: pass **Native Linux acceptance** - Undo back to the canonical saved projection cleared the dirty marker. - Native close then **Cancel** retained the exact dirty session. - **File > Quit** then **Discard** exited cleanly. - **Switch Project...** used the same guarded decision. - Dirty named **Save All** wrote before exit. - Clean untitled close exited without a decision. - Dirty untitled **Save All** continued asynchronously through KDE Save As, wrote the scene, and exited with code 0. ![Guarded shutdown decision](https://git.spacetrainclubhouse.com/attachments/b9538ef6-25e0-46b0-9997-9a4311584893) The temporary QA scene was removed. Packaged-runtime acceptance remains explicitly owner-deferred; no packaged result or production-candidate signoff is claimed.
Rbanh closed this issue 2026-07-13 10:25:37 -04:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Falling-Metal-Interactive/Blacksite#55
No description provided.