56 lines
3.4 KiB
Markdown
56 lines
3.4 KiB
Markdown
# ADR 0023: Transactional Scene Persistence And Recovery
|
|
|
|
## Status
|
|
|
|
Accepted
|
|
|
|
## Context
|
|
|
|
Blacksite previously wrote scene RON directly to the authored path. An interruption during that
|
|
write could corrupt the last good scene. The save serializer also strips hydrated runtime state
|
|
before extraction and only rebuilt it after a successful write, so serialization or filesystem
|
|
failure could leave the live editor world partially stripped.
|
|
|
|
Daily production additionally needs a recovery path for dirty scenes that does not modify project
|
|
assets, mark a scene clean, enter source control, or silently replace authored work.
|
|
|
|
## Decision
|
|
|
|
- Manual scene, prefab, and selection writes use a temporary file in the destination directory,
|
|
flush and sync its bytes, atomically rename it over the destination, and sync the parent
|
|
directory where the platform permits.
|
|
- Authored document serialization is separate from persistence. Hydrated state is always rebuilt
|
|
after serialization attempts, including validation and serialization failures.
|
|
- Dirty saved scenes produce recovery snapshots every 120 seconds by default. The interval has a
|
|
15-second safety floor and the newest five generations are retained by default.
|
|
- Recovery data lives under `$XDG_STATE_HOME/blacksite-editor/recovery` or
|
|
`~/.local/state/blacksite-editor/recovery`. Stable hashes of project root and scene path keep
|
|
recovery files outside the project without leaking path names into directory names.
|
|
- A recovery snapshot never clears the dirty flag and uses the same authoring-only serialization
|
|
contract as manual save.
|
|
- On scene load, a newer recovery snapshot is surfaced in the status strip and File menu. The
|
|
editor never restores it automatically. Restore loads the snapshot into the original scene
|
|
context and leaves the scene dirty; the snapshot remains available until manual Save commits it
|
|
or Discard removes that scene's recovery generations. Save Recovery Copy As writes the snapshot
|
|
to a separate transactional scene file without changing the active scene or recovery lifecycle.
|
|
- A successful manual save retires recovery generations for that scene.
|
|
- A successful load or manual save establishes that tab's canonical authored-content checkpoint.
|
|
Undo and redo compare the current stable authored projection with this checkpoint to derive dirty
|
|
state. Failed writes, cancelled Save As, and recovery restores do not advance it.
|
|
- Native editor exit is authorized only after all dirty scene tabs save successfully or the user
|
|
explicitly discards them. See [ADR 0042](0042-guarded-editor-shutdown-and-document-savepoints.md).
|
|
|
|
## Consequences
|
|
|
|
- Interrupted manual writes retain the previous complete destination on filesystems with atomic
|
|
same-directory rename semantics.
|
|
- Recovery is machine-local and does not pollute builds or source control.
|
|
- Undoing exactly to the last loaded or saved authored state clears the dirty marker without
|
|
weakening recovery after direct edits or failed saves.
|
|
- Autosave still performs authored serialization and hydration rebuild work. Performance
|
|
instrumentation and background snapshotting remain follow-up work under the production roadmap.
|
|
- Unsaved new scenes do not yet have a stable recovery identity; they require a later session-ID
|
|
recovery extension.
|
|
- The initial controls use user preference fields and documented defaults; a dedicated Preferences
|
|
panel can expose them later without changing the storage contract.
|