# Multi-Scene Tabs And Composition

Blacksite keeps scene-document controls at the right end of the existing main toolbar. Each tab has
its own path and dirty marker; **+** creates an untitled tab and **x** closes a tab with a
save/discard/cancel prompt when needed. **File > Open Scene...** opens another tab instead of
discarding the active document. Save and Save As affect the active tab, while project switching
offers to save every modified tab.

## Composition workflow

The **Composition** menu beside the tabs edits the active scene's persisted `SceneComposition`:

- **Add Subscene...** accepts a validated `.scn.ron` under the active project root.
- **Loaded** loads or unloads that reference from the active world.
- **Locked** routes every loaded actor through the hierarchy's read-only selection, gizmo, drag,
  and mutation guards.
- **Focus** selects a loaded actor owned by the reference and frames it in the editor camera.
- Remove deletes only the reference; it never deletes the referenced scene file.

Composition edits mark only the owner tab dirty and participate in undo/redo. Loaded child actors
carry runtime-only ownership metadata and are excluded when the owner saves, so editing the
composition cannot flatten child content into the parent file. To edit a child scene, open it as
its own tab.

## Validation and PIE

References use stable scene/reference IDs and project-relative paths. Editor load and
`cargo validate-levels` recursively reject missing files, path escapes, duplicate IDs, and cycles
before replacing the active world. Hidden references remain validated even though they are not
loaded. Nested loaded scenes inherit a locked ancestor's read-only boundary.

The active world is the authoritative composition for PIE and viewport rendering. Switching tabs
is disabled during Play. The safe materialization boundary clears entity-edit undo history on tab
activation because current history commands contain runtime entity IDs; composition changes
themselves are stable-resource commands and remain undoable until the next tab activation.

## Recovery and migration

Every dirty saved tab receives its own bounded transactional recovery generations, including tabs
that are currently inactive. Untitled tabs must be saved once before automatic recovery can assign
them a durable scene path.

Legacy scenes need no manual migration. They receive a deterministic `legacy:<project path>` scene
identity in memory and write the current `SceneComposition` resource on the next normal save.
Project startup still opens the manifest's `default_level`; clean session recovery resumes only the
last active authored scene, not the full transient tab set.

See [ADR 0026](../adr/0026-stable-scene-composition-and-active-document.md) for the ownership and
materialization decision.
