Record guarded shutdown and scoped UI acceptance
Some checks are pending
CI / Format, lint, test, build (push) Waiting to run

This commit is contained in:
Rbanh 2026-07-13 10:23:56 -04:00
parent 9e23ae731f
commit a048233fce
8 changed files with 154 additions and 5 deletions

View File

@ -413,6 +413,7 @@ crates/
- [x] Collider authoring health shared by the inspector, Collider viewport, Diagnostics panel, and physics placement, with scaled shape overlays, cooked mesh bounds, missing/stale/invalid/oversized findings, and undoable dimension-preserving shape switching ([collider guide](docs/editor/collider-authoring.md), [Gitea #26](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/26))
- [x] Non-blocking native file/folder/confirmation broker across scene, asset, prefab, composition, collaboration, and Project Browser workflows ([ADR 0038](docs/adr/0038-non-blocking-native-dialog-broker.md), [workflow guide](docs/editor/native-dialogs.md), [Gitea #52](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/52))
- [x] Guarded native/menu/programmatic editor shutdown with asynchronous multi-tab Save All / Discard / Cancel and canonical per-tab clean checkpoints for exact undo/redo dirtiness ([ADR 0042](docs/adr/0042-guarded-editor-shutdown-and-document-savepoints.md), [Gitea #55](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/55))
- [x] Scoped egui action safety for toolbar/navigation spawns, Inspector state, cross-panel selection/tab requests, diagnostics selection, and full-slice selection precedence ([evaluation](docs/editor/evaluations/scoped-ui-actions/), [Gitea #57](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/57))
- [x] Asset import, static mesh/prefab placement, texture assignment, and selection export
- [x] PIE player-only snapshot/restore (authored `LevelObject` edits persist on stop)
- [x] Unified viewport render-to-texture target + Play session bootstrap

View File

@ -95,6 +95,8 @@ Immutable-style log of significant decisions. Add a new numbered ADR when changi
| [editor/evaluations/navigation-authoring/](editor/evaluations/navigation-authoring/) | Live screenshots and acceptance results for navigation authoring and runtime parity |
| [editor/evaluations/operator-invariants/](editor/evaluations/operator-invariants/) | Source acceptance results for production operator lifecycle, rollback, cleanup, and undo/redo invariants |
| [editor/evaluations/sample-regression-pack/](editor/evaluations/sample-regression-pack/) | Exact-implementation source and native acceptance evidence for the editor sample regression pack |
| [editor/evaluations/guarded-shutdown-savepoints/](editor/evaluations/guarded-shutdown-savepoints/) | Source and native acceptance evidence for guarded editor exit and per-document clean checkpoints |
| [editor/evaluations/scoped-ui-actions/](editor/evaluations/scoped-ui-actions/) | Exact-implementation source and native acceptance evidence for actions invoked during scoped egui rendering |
| [editor/evaluations/production-readiness/](editor/evaluations/production-readiness/) | Current versioned production gate, evidence matrix, candidate commands, soak protocol, and independent sign-off requirements |
## Working plans (not canonical long-term)

View File

@ -42,6 +42,8 @@ Docs for the in-process egui editor (`crates/editor/`). Update this index when a
| [evaluations/navigation-authoring/](evaluations/navigation-authoring/) | Live screenshots and verification record for navigation authoring and runtime parity |
| [evaluations/operator-invariants/](evaluations/operator-invariants/) | Source acceptance record for production operator lifecycle, rollback, cleanup, and undo/redo invariants |
| [evaluations/sample-regression-pack/](evaluations/sample-regression-pack/) | Exact-implementation source and native acceptance evidence for the five-area editor regression pack |
| [evaluations/guarded-shutdown-savepoints/](evaluations/guarded-shutdown-savepoints/) | Source and native acceptance evidence for guarded editor exit and per-document clean checkpoints |
| [evaluations/scoped-ui-actions/](evaluations/scoped-ui-actions/) | Exact-implementation source and native acceptance evidence for actions invoked during scoped egui rendering |
| [evaluations/production-readiness/](evaluations/production-readiness/) | Current #50 release-candidate matrix and required clean-checkout, soak, performance, limitation, and independent-signoff evidence |
## Subsystems (code → doc)

View File

@ -12,6 +12,8 @@ Living checklist for the production editor program ([ADR 0012](../adr/0012-zero-
| Hydrated components in committed `.scn.ron` | CI | `scene::validate_scene_authoring_only` + `repo_editor_scene_has_no_hydrated_components` |
| Production mutation without commit/cancel/failure/undo invariants | Done | Shared operator harness plus typed history projections cover palette, asset, brush, terrain, physics, grouping, lighting, material-drop, and transform paths; see [evaluation](evaluations/operator-invariants/) |
| Representative editor coverage can silently disappear | Done | Versioned five-area manifest, typed scene gate, `validate-samples`, and native protocol; see [sample pack](sample-regression-pack.md) |
| Dirty editor exit can bypass an explicit decision, or transient entity IDs define document cleanliness | Done | Guarded shutdown and canonical authored-content checkpoints pass source validation and all seven native workflows at source implementation `4b33f32`, including dirty untitled Save All through Save As. See the [evaluation](evaluations/guarded-shutdown-savepoints/). |
| Scoped UI callbacks depend on temporarily unavailable host state or lose direct selection precedence | Done | Explicit selection/tab requests, panel-owned state, captured viewport data, and full-slice reconciliation pass six scoped regressions, independent re-review, and native toolbar/Inspector/diagnostics acceptance at `9e23ae7`; see the [evaluation](evaluations/scoped-ui-actions/). |
| Dual FBX thumbnail ad-hoc path (parallel to unified pipeline) | Partial | Phase 5 `assets/thumbnails/` refactor |
| `failed_keys` thumbnail cache without retry API | Partial | `asset_thumbnails.rs`; Phase 5 `ThumbnailState` |

View File

@ -0,0 +1,72 @@
# Guarded Shutdown And Clean Savepoints Evaluation
**Date:** 2026-07-13
**Issue:** [Gitea #55](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/55)
**Branch:** `codex/guarded-shutdown-savepoints`
**Implementation commit:** `4b33f3235761fd0dd3daf219e5bbbaee884eb626`
**Release-candidate commit:** Not nominated
**Implementation validation:** **Pass**
**Native acceptance:** **Pass**
This record covers editor-owned shutdown authorization and per-document authored-content clean
checkpoints. The permanent architecture contract lives in
[ADR 0042](../../../adr/0042-guarded-editor-shutdown-and-document-savepoints.md). The automated
results below apply to the exact implementation commit. Native rows exercise the same shutdown
implementation after the unrelated toolbar fix disclosed below. Neither replaces the clean-checkout,
soak, or independent-signoff requirements for a future release candidate.
## Automated Verification
| Command or suite | Result | Evidence |
|------------------|--------|----------|
| `cargo fmt --all -- --check` | Pass | Formatting check completed without changes. |
| `git diff --check` | Pass | No whitespace errors. |
| `cargo clippy --workspace --all-targets -- -D warnings` | Pass | Workspace and all targets completed with warnings denied. |
| `cargo test --workspace --all-targets --no-fail-fast` | Pass | All workspace targets passed; the editor crate reported 282 passing tests. |
| Guarded shutdown regressions | Pass | Native close, menu/programmatic exit, cancel/discard, broker contention, late-authoring mutation, and secondary-window behavior are covered by 13 focused tests. |
| Save All regressions | Pass | Named and untitled tab sequencing, cancellation, conflict retention, duplicate destination rejection, and active-tab restoration are covered by six focused tests. |
| Project-switch regressions | Pass | Three focused tests cover guarded handoff, cancellation, and browser-spawn failure. |
| Packaged acceptance | Deferred | Explicitly deferred by project-owner direction; no packaged result is claimed. |
## Native Acceptance
The guarded-shutdown implementation under test is the source commit named above. The native debug
editor was rebuilt at `9e23ae731f95dc351ecc744d6ca61f6bc4467317` after the independently scoped
[UI action-safety fix](../scoped-ui-actions/) ([Gitea #57](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/57))
made the untitled-scene toolbar workflow reachable, then launched as
`target/debug/editor --project .`. Each row records an observed workflow rather than inferring
behavior from the automated suite.
| Workflow | Result | Evidence |
|----------|--------|----------|
| Undo back to the clean checkpoint | Pass | A scene mutation added the dirty marker; undo restored the canonical authored projection and cleared the marker. |
| Native window close, then **Cancel** | Pass | The dirty-document decision appeared; Cancel retained the dirty document and kept the editor running. |
| **File > Quit**, then **Discard** | Pass | The same guarded decision path ran and the editor process exited with code 0 without saving the dirty draft. |
| **File > Switch Project...** guard | Pass | A dirty document was intercepted by the shared shutdown decision before project-browser handoff. |
| Dirty named document, **Save All** | Pass | The named scene write completed before authorization and the editor then exited with code 0. |
| Clean untitled document close | Pass | No dirty-work decision was needed and the editor exited with code 0. |
| Dirty untitled document, **Save All**, then Save As continuation | Pass | **File > New Scene** created an untitled tab; the toolbar Cube action spawned authored content and marked it dirty. Native close followed by **Save All** opened KDE Save As in `assets/levels`; saving as `issue55_shutdown_qa.scn.ron` wrote a 1,986-byte scene and the editor exited with code 0. The QA scene was verified and removed. |
## Evidence Status
![Native guarded-shutdown decision over the Blacksite editor](https://git.spacetrainclubhouse.com/attachments/b9538ef6-25e0-46b0-9997-9a4311584893)
- Native modal capture: `/tmp/blacksite-issue55-shutdown-modal-4b33f32.png` (temporary staging;
3426x1384 RGB PNG, 1,656,602 bytes).
- SHA-256: `2ddb2571325e0d99f5559efd1ba3164845ffba64767833d4e5ad8d2925aedfb5`.
- Gitea #55 native attachment: asset 36, uploaded through the issue attachment API.
The Gitea copy was uploaded as an ordinary issue attachment. No repository PNG or LFS raw URL is
claimed by this evaluation.
## Release Use
The #55 source and native feature-level acceptance record is complete. A future production candidate
must still rerun these workflows from the exact nominated commit; this record does not nominate a
candidate or establish production readiness.

View File

@ -1,6 +1,6 @@
# Production-Readiness Acceptance Matrix
**Matrix version:** 0.4
**Matrix version:** 0.5
**Last audit:** 2026-07-13
@ -30,20 +30,20 @@ another commit, a dirty worktree, or an older package do not transfer to the can
| ID | Requirement | State | Current evidence and gap |
|----|-------------|-------|--------------------------|
| G1 | Project create/open/resume, scene authoring, autosave/recovery, hierarchy, prefab, and asset integrity pass | Fail | Project/recovery/session/multi-scene/prefab implementations are documented in [project launcher](../../project-launcher.md), [session recovery](../../session-recovery.md), [multi-scene composition](../../multi-scene-composition.md), and [prefab authoring](../../prefab-authoring.md). Collaborative file safety `#49` and non-blocking native dialogs `#52` passed live acceptance, but `#55` records unguarded native dirty shutdown and a missing clean-history savepoint. Candidate-specific end-to-end reruns also remain. |
| G1 | Project create/open/resume, scene authoring, autosave/recovery, hierarchy, prefab, and asset integrity pass | Partial | Project/recovery/session/multi-scene/prefab implementations are documented in [project launcher](../../project-launcher.md), [session recovery](../../session-recovery.md), [multi-scene composition](../../multi-scene-composition.md), and [prefab authoring](../../prefab-authoring.md). Collaborative file safety `#49`, non-blocking native dialogs `#52`, guarded shutdown/savepoints `#55`, and scoped UI action safety `#57` have feature-level source/native acceptance. #55 passed all seven native paths at source implementation `4b33f32`; #57 passed toolbar, Inspector, diagnostics, selection, and guarded-exit paths at exact implementation `9e23ae7`. Candidate-specific end-to-end reruns remain. |
| G2 | Brush, material, terrain, physics placement, animation, audio, navigation, PIE, and build/package samples pass | Partial | The [five-area sample pack](../sample-regression-pack/) passed source and native acceptance on exact implementation commit `d52cc2e`, including Brush, Material, Terrain, Physics Placement, and Rendering. No release candidate is nominated, brush acceptance `#37` remains open, and combined animation/audio/navigation/PIE/build evidence is incomplete. Packaged testing is owner-deferred. |
| G3 | Undo/redo/cancel invariants and helper cleanup cover every production mutation path | Partial | Source implementation and focused evidence are complete in [operator regression testing](../../operator-regression-testing.md) and the [operator-invariants evaluation](../operator-invariants/); Gitea `#33` closed at `c55f347`. A clean, exact-candidate rerun is still required for `Pass`. |
| G4 | Representative project completes an eight-hour soak without unbounded memory/target growth or unrecoverable failure | Missing | No candidate soak log, resource timeline, failure ledger, or target-growth measurement exists. |
| G5 | Cold start, scene open/save, asset refresh, common manipulation, and package-build budgets are documented and measured | Missing | Gitea `#34` is open; no ratified budgets or candidate measurement record exists. |
| G6 | Headless content validation and CI are green from a clean checkout | Missing | [CI configuration](../../../../.github/workflows/ci.yml) hydrates LFS and includes both project and sample content gates. Local implementation checks have passed, but no clean-checkout candidate run is linked. The current Gitea server does not expose an Actions run endpoint for this repository. |
| G7 | First-hour UX and recovery QA are signed off by someone other than the implementer | External | No independent sign-off exists. Gitea `#36` remains open; historical H1-H6 implementation-pass notes do not count. |
| G8 | Known limitations have severity/workaround and no P0 blocker remains | Fail | Sample-pack gap `#32` has exact-implementation source/native evidence at `d52cc2e`, but guarded native shutdown and clean history savepoints remain the open P0 `#55`. A consolidated candidate limitations ledger is also missing. Deterministic imported-asset fingerprints `#56` and property-block application `#53` are P1; dynamic deformed Solari geometry `#54` is a documented P2 limitation with Forward/raster fallback. |
| G8 | Known limitations have severity/workaround and no P0 blocker remains | Partial | Sample-pack gap `#32`, guarded shutdown/savepoints `#55`, and the follow-on scoped UI action-safety defect `#57` have complete source/native feature acceptance at `d52cc2e`, source implementation `4b33f32`, and `9e23ae7` respectively; no known P0 implementation blocker remains. A consolidated candidate limitations ledger and exact-candidate rerun are still missing. Deterministic imported-asset fingerprints `#56` and property-block application `#53` are P1; dynamic deformed Solari geometry `#54` is a documented P2 limitation with Forward/raster fallback. |
## Deliverables
| ID | Deliverable | State | Evidence or next action |
|----|-------------|-------|-------------------------|
| D1 | Versioned acceptance matrix under `docs/editor/evaluations/` | Pass | This file, version 0.4. |
| D1 | Versioned acceptance matrix under `docs/editor/evaluations/` | Pass | This file, version 0.5. |
| D2 | Release-candidate representative project and reproducible validation commands | Partial | The committed [sample regression pack](../sample-regression-pack/), commands, and exact-implementation native evidence exist. Nominate a release candidate and rerun from a clean LFS-hydrated checkout. |
| D3 | Signed milestone comment linking evidence, limitations, and exact commit | Missing | Post only after G1-G8 pass; no candidate exists yet. |
@ -69,6 +69,8 @@ another commit, a dirty worktree, or an older package do not transfer to the can
| Build/package/runtime | Implemented foundation | Deferred by owner |
| Collaborative file safety | Implemented; `#49` closed with live external-change acceptance | Not rerun as one candidate |
| Native file/folder dialogs | Implemented; `#52` closed with live 12-second compositor-responsiveness hold | Not rerun as one candidate |
| Guarded shutdown and clean savepoints | Implemented; `#55` source validation and all seven native workflows passed at source implementation `4b33f32` | Feature-level acceptance complete; not rerun as one candidate |
| Scoped UI action safety | Implemented; `#57` source validation, six focused regressions, selection precedence, and native toolbar/Inspector/diagnostics workflows passed at `9e23ae7` | Feature-level acceptance complete; not rerun as one candidate |
## Candidate Validation Commands

View File

@ -0,0 +1,68 @@
# Scoped UI Action Safety Evaluation
**Date:** 2026-07-13
**Issue:** [Gitea #57](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/57)
**Implementation commit:** `9e23ae731f95dc351ecc744d6ca61f6bc4467317`
**Release-candidate commit:** Not nominated
**Source validation:** **Pass**
**Native acceptance:** **Pass**
This record covers synchronous editor actions invoked while the egui host scopes `UiState` out of
the Bevy `World`. The implementation keeps callback-owned state in independently registered
resources, passes viewport data into toolbar/navigation actions, routes cross-panel selection and
tab requests through explicit APIs, and reconciles the complete selection slice so a direct UI
selection takes precedence over a stale deferred request.
## Automated Verification
| Command or suite | Result | Evidence |
|------------------|--------|----------|
| `cargo fmt --all -- --check` | Pass | Formatting check completed without changes. |
| `git diff --check` | Pass | No whitespace errors. |
| `cargo clippy --workspace --all-targets -- -D warnings` | Pass | Workspace and all targets completed with warnings denied. |
| `cargo test --workspace --all-targets --no-fail-fast` | Pass | All workspace targets passed; the editor crate reported 290 of 290 tests passing. |
| Scoped-action regressions | Pass | Six focused regressions cover history multi-selection, diagnostics selection, Inspector collapse and asset reveal state, primitive spawn, and navigation spawn while `UiState` is scoped out. |
| Selection precedence | Pass | Full-slice reconciliation preserves a direct primary or secondary UI selection over stale single- or multi-selection requests. |
| Independent re-review | Pass | The post-fix review found no remaining blockers. |
| Packaged acceptance | Deferred | Explicitly deferred by project-owner direction; no packaged result is claimed. |
## Native Acceptance
The exact rebuilt debug binary from the implementation commit was launched as
`target/debug/editor --project .`.
| Workflow | Result | Evidence |
|----------|--------|----------|
| Toolbar authoring actions | Pass | After **File > New Scene**, Cube, Ramp, Sphere, Point Light, and Navigation Bounds all spawned. Selection, transform gizmo, viewport overlay, hierarchy, and Inspector stayed synchronized. |
| Inspector state | Pass | Collapsing the Transform component persisted across subsequent UI rendering and selection work. |
| Cross-panel diagnostics action | Pass | **Window > Brush Diagnostics > Select** kept the editor live and synchronized the selected actor across hierarchy, viewport, and Inspector. |
| Guarded shutdown | Pass | The dirty native-close decision accepted **Discard** and the editor exited with code 0. |
## Native Evidence
![Scoped toolbar actions with authored actors selected in the live editor](https://git.spacetrainclubhouse.com/attachments/d265651b-aa8e-4ea5-841c-1fa8eb622766)
- Gitea attachment asset 37: `blacksite-issue57-scoped-ui-actions.png`, 3426x1384 RGB PNG,
890,021 bytes.
- SHA-256: `4225aca19268e4817148507e95cdad56a5f18734fd69e2fe5702df1dc304142e`.
![Brush Diagnostics Select synchronized hierarchy, viewport, and Inspector](https://git.spacetrainclubhouse.com/attachments/ba176d82-fb2f-403b-a71c-108de9649f11)
- Gitea attachment asset 38: `blacksite-issue57-diagnostics-select.png`, 3426x1384 RGB PNG,
1,418,849 bytes.
- SHA-256: `40422be59766a3e61005973c315d0fd6f663dd2d227aa92055fa2aa2e91320c3`.
Both images were uploaded as ordinary Gitea issue attachments; this record does not use repository
raw or LFS pointer URLs.
## Release Use
The #57 source and native feature-level acceptance record is complete. A future production candidate
must still rerun representative toolbar, Inspector, diagnostics, selection, and guarded-exit paths
from the exact nominated commit. This record does not nominate a candidate or establish production
readiness.

View File

@ -151,7 +151,7 @@ with implementation sequencing in
| Milestone | Exit condition | Status |
|-----------|----------------|--------|
| M6 Reliability, recovery, and project workflow | Transactional save/recovery, stable sessions, project launcher, hardened hierarchy/prefabs, multi-scene composition | Implementation complete; all six scoped issues are closed after prefab #43 passed workspace, headless, packaged-runtime, and live editor acceptance |
| M7 Content production and shipping | Build/package profiles, content release gate, animation, audio, navigation, collaborative safety | Active; #44-#49 are complete after source, headless, and native acceptance. Final readiness gate #50 remains blocked by open P0 shutdown/savepoint work #55; deterministic imported-asset fingerprints #56 are P1 follow-up work. Packaged acceptance is deferred until requested by the project owner. |
| M7 Content production and shipping | Build/package profiles, content release gate, animation, audio, navigation, collaborative safety | Active; #44-#49 are complete after source, headless, and native acceptance. P0 #55 is complete at source implementation `4b33f32`, and follow-on P0 #57 scoped UI action safety is complete at `9e23ae7` after workspace, focused, independent-review, and native acceptance. No known P0 implementation blocker remains, but #50 is still the final candidate gate and production readiness is not established. Deterministic imported-asset fingerprints #56 are P1 follow-up work. Packaged acceptance is deferred until requested by the project owner. |
Production readiness is not inferred from feature count. Gitea
[`#50`](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/50)