# Content Workspace And Import Authoring Refactor

> **Active plan — desired scope and acceptance, not implementation truth.** Current shipped behavior is documented in the [Content Workspace guide](../../docs/editor/content-workspace.md).

Date: 2026-07-13

## Status

Active acceptance plan for Gitea milestone **M2 - Content workspace and asset pipeline**. Current
implementation state, user steering, invalidated evidence, and the exact next action live in the
ignored `.codex/session/STATE.md`; accepted scope and closure state live in Gitea #59 and #65. The
local candidate tree passed the complete candidate gate on 2026-07-17; its exact commit is assigned
at publication, so this plan must not be read as remote completion evidence yet. It remains the
desired acceptance target until M2 is accepted, then becomes a frozen historical record.

## Gitea Tracking

- Milestone: [M2 - Content workspace and asset pipeline](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/milestone/12)
- Epic: [#59 BS-JD-211 - Content workspace and import authoring refactor](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/59)
- Contract and catalog: [#60 BS-JD-212](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/60), [#62 BS-JD-214](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/62)
- File operations and import: [#20 BS-JD-205](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/20), [#61 BS-JD-213](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/61)
- Model materials: [#64 BS-JD-215](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/64), [#63 BS-JD-216](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/63)
- Final gate: [#65 BS-JD-217](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/65)
- Engine fallback: [#66 BS-JD-218](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/66)
- Responsive authored documents: [#67 BS-JD-219](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/67)
- Modular editor architecture: [#68 BS-JD-220](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/68)

## Goal

The active corrective slice also requires one overlay-first Material handle authority, conditional
ARM/ORM-only derived processing, registry-only Inspector dispatch, shared Material/asset-card UI,
and the ADR 0048 architecture ratchet. Both large UI files are now <=500-line shells; #68 remains
open until selective verification, critical native acceptance, and publication approval are
complete.

The current #68 refinement adopts the Penpot **Inspector Material Slot** as the first Blacksite
design-system reference. Penpot owns geometry, typography, and interaction-state references;
Blacksite's editor-owned semantic palette owns color and is published into Penpot Assets / Colors.
The current palette is the default, with preference selection deferred behind the same palette
seam. Shared semantic tokens, Source Sans Pro typography, action-returning
material panels, responsive property grids, and custom asset/color pickers must match the 620 px
and 420 px references. The Inspector has a hard 420 px floor and one actor-body scroll region.
Runtime material authority and explicit-save behavior remain
owned by #67 and ADR 0047; wider editor-panel migration is not part of this slice.

Make the Content Browser behave like a project file manager and make imported models behave like
editable engine assets:

- users organize source and authored assets in any folder beneath the project `assets/` content
  root;
- importing copies into the current or explicitly chosen project folder instead of sorting by file
  extension;
- static and skinned model assets expose stable material slots whose defaults can use source
  materials, existing project Materials/Material Instances, or extracted editable Materials;
- move, rename, reimport, validation, packaging, and headless processing preserve stable identity
  and never silently overwrite authored material work.

This matches the portable project-content model used by Unity and Unreal. Arbitrary absolute paths
outside the project are not part of this milestone: external linked assets require a separate
virtual-filesystem, packaging, and source-control decision.

## Existing Foundation To Reuse

- `AssetRegistry` owns UUIDs, source fingerprints, import settings, and generated-manifest paths.
- The Content Browser already scans nested folders below `assets/`, renders thumbnails and model
  subassets, stages import settings, reimports, and moves deleted files to `assets/.trash/`.
- Static and skinned renderers already share stable material-slot IDs, imported-source fallback,
  explicit scene-level project Material assignments, and orphan preservation.
- Project Materials and direct-base Material Instances are editable, schema-driven assets with a
  dedicated Material Library. Parameter edits update shared runtime handles every frame and mark an
  asset-keyed document dirty; pointer release performs no persistence or processing. Explicit Save
  publishes guarded source and queues affected-only derived processing in the background.
- Imported-source fingerprints are content-addressed, and FBX dependency bundles already use a
  sandboxed transactional copy.

The refactor must extend these contracts rather than add a second catalog, material type, or model
loader.

## Implementation Snapshot

- [Implemented] Destination-first Import Here/Import To, in-project adoption, exact-path review,
  dependency/source fingerprint guards, dependency-bundle preflight, and whole-batch rollback.
- [Implemented] Folder-independent registry-v3 classification and one `content_pipeline` engine for
  editor transactions, watcher refresh, validation, headless processing, and packaging catalogs.
- [Implemented] File-manager selection, folders, item/batch/visible-empty-space context menus,
  content-scoped keyboard operations, protected managed folders, safe navigation and subasset
  semantics, guarded undo, transaction review, collaboration state, trash, stable-reference
  rewrites, hidden-selection clearing when filters change, consistent right-click targeting, and
  restart-safe explicit identity selection for ambiguous out-of-editor moves.
- [Implemented] Stable per-slot model defaults, orphan reconciliation, six-layer material
  precedence, project fallback, immutable DefaultGrid, and reviewed exact-slot
  MaterialPropertyBlock promotion with transactional rollback.
- [Implemented] Transactional glTF/GLB/FBX material extraction with provenance, explicit
  diff/apply/create-new re-extraction, plus loose-texture PBR grouping.
- [Implemented 2026-07-15] Scene schema v6 and actor-only `MaterialSlot` ownership for
  primitives/static/skinned renderers; primitive-local `MaterialDesc` hydration and the synthetic
  Authoring Material card are removed. The unified slot widget supports valid/invalid drag state,
  inherited effective status, guarded shared parameter editing, direct-base instance creation,
  actor-exact source extraction, and property-block promotion.
- [Implemented 2026-07-14] Typed thumbnail keys separate textures, models, mesh subassets, and
  source materials. Models always queue geometry rendering and static draw previews request their
  exact mesh subasset; the Poly Haven metal office desk regression is unit-covered.
- [Implemented 2026-07-15] Thumbnail cache replacement, retry, and catalog invalidation release the
  last Egui image registration for each key. Repeated studio renders no longer retain hidden GPU
  render targets after the visible cache entry is gone.
- [Implemented 2026-07-14] Asset-keyed authored documents separate live Material/Instance and
  import-setting edits from explicit source publication. Context Save, Save All, recovery,
  conflict state, separate Git/processing badges, and revisioned background processing remove
  pointer-release writes and synchronous content work from material controls.
- [Implemented 2026-07-17] Penpot-led design-system foundations and the unified
  primitive/static/skinned material panel are in the local worktree. The revised handoff adds
  field-click texture pickers with Locate/Clear, Separate/ORM presentation, and shared UV
  Offset/Tiling controls. Blacksite's default semantic palette now replaces the panel-private
  prototype colors. Exact 640/420 px native acceptance and responsive resize/deep-scroll scenarios
  pass on the final geometry.
- [Implemented 2026-07-17] #67/#68 corrective sampler and Penpot v2.3 slice: project textures use
  catalog-authored Repeat/Clamp/Mirror sampling across Standard and Surface paths; the shared panel
  has one Shader selector, UV before Advanced, typed texture thumbnails, and a disabled Advanced
  preview with no authored/runtime state.
- [Implemented 2026-07-17] #68 Penpot v2.3.1 corrective pass: the design component and every state
  reference remove Shading Model and UV/Advanced overlap; the shared Material asset zone owns
  assignment and its current/recent/project picker; Surface, Packed Maps, inputs, UV, and Advanced
  use the locked reference heights; and the actor-salted Inspector body is clipped below its fixed
  identity header. Managed verification and Codex-owned native visual acceptance pass.
- [Implemented 2026-07-17] Direct exports of the default, expanded Advanced, Material picker, and
  color picker are now the numeric baseline. The exact pass removes the invented drop cue and Blend
  label, restores the fixed Inputs columns, boxed ORM guidance, `UV` label, Advanced summary, compact
  Material menu, paired color/HEX values, normal strength, and the seventh Emissive Intensity row.
- [Implemented 2026-07-17] The final #68 micro-geometry pass makes the exported 420 x 350 color
  overlay Inspector-centered and modal, locks its value/alpha/recents/footer coordinates, keeps the
  eyedropper as a disabled planned preview, replaces stock material sliders with the 130 px Penpot
  scalar control, and scroll-reveals the complete expanded Advanced body. Geometry and popup
  interaction tests plus native captures pass.
- [Implemented 2026-07-17] Native Inspector splitter endurance exposed a viewport-target ownership
  leak: every intermediate width allocated another full-resolution HDR Image and Egui retained each
  strong registration until Solari terminated on GPU OutOfMemory. The corrective path resizes one
  stable Image asset in place, unregisters exceptional replacements/absent targets, and requires a
  repeated wide/narrow drag endurance pass before #68 visual acceptance resumes.
- [Implemented 2026-07-17] Native top-level window resizing exposed a distinct NVIDIA Wayland
  swapchain-acquire timeout loop after the target-ownership leak was removed. The editor host now
  prefers an Immediate/Mailbox presentation path while packaged game windows retain VSync; repeated
  native-window resize remains the focused acceptance gate.
- [Implemented 2026-07-17] Native narrow/tall Inspector captures exposed a universal overflow
  boundary defect: solid scrollbar allocation changed responsive widths and nested component cards
  could replace the actor-body clip. The shared Inspector now keeps a stable floating scroll rail,
  intersects every touched child clip, and ready texture fields omit the redundant image glyph.
- [Implemented 2026-07-17] The final #68 Penpot boards supersede the earlier v2.2/v2.3 slot
  geometry. Inspectors render a 32 px **Materials** heading and ordered 82/52 px collapsible slots,
  a nested PARAMETERS spine, 616/396 px slot references, 592/372 px parameter bodies, and one
  420 px Inspector floor. Surface owns Separate/ORM; Inputs has six 30/56 px primary rows, with
  independently stored Emissive Intensity presented as the Emissive color companion.
- [Implemented 2026-07-17] The exact geometry correction replaces flow-derived Surface, input,
  texture-action, and UV placement with clipped owning-rectangle models for the exported 592/372 px
  sections. Texture names can no longer move row actions, UV labels no longer share coordinates,
  and transient sub-minimum widths use a bounded overflow fallback. Focused engineering verification
  and 640/420/short-height native captures pass.
- [Candidate gate passed 2026-07-17; pending publication] The complete all-feature test and strict
  lint gates, deterministic processing, level/sample validators, QA package, architecture audit,
  and documentation audit pass on the local candidate tree. Native runtime-injected property-block
  promotion, skeletal import, explicit scene-slot assignment, and broken project-fallback behavior
  also pass. Exact-commit clean-tree readback, evidence publication, and Gitea closure remain.
- [Corrective acceptance in progress 2026-07-17] The current Penpot README and active 01–30 boards
  supersede the earlier 640/420 material-only references and invalidate the prior candidate's UI
  acceptance. M2 now requires the shared 50 px Inspector Header, renderer Array Header/panels,
  foundation controls, overlays, and current 620/420 Material references across the complete
  Inspector. The new wide/narrow Material canvases are 596/396 px with 569/369 px parameter
  sections, 32/58 px rows, and 54/94 px UV sections. Candidate publication and issue closure remain
  blocked until refreshed engineering and Codex-owned native evidence pass on one exact tree.
- [Engineering-complete; acceptance in progress 2026-07-18] A lightweight `ui_gallery` now renders
  the same `editor_ui` production components without project/scene/renderer/gameplay startup. It
  provides exact Materials 620/420 and Renderer 760/480 presets, direct Penpot side-by-side,
  overlay, and Difference modes, all material ownership/health fixtures, runtime token/fixture
  reload, and a managed last-good rebuild/restart loop with bounded dependency progress. Focused
  tests, strict lint, and architecture audit pass; paired full-editor evidence remains required.

## Target Contracts

### Project content boundary

- User-managed content may live in any normal nested folder under `assets/`.
- Folder names are organizational only and never determine asset type.
- `assets/.index/`, `assets/.trash/`, thumbnail storage, and UUID-keyed derived artifacts remain
  editor-managed and protected from ordinary file operations.
- The storage ADR decides whether existing generated directories remain in place or migrate behind
  `.index`; either way, they stay hidden and are never presented as imported user content.

### Registry and type authority

- `AssetId` remains authoritative identity; the current project-relative path is mutable metadata.
- Extension plus parsed document schema/registry kind determines type. Moving a Material beside a
  model does not turn it into a level.
- All editor, hydration, validation, and packaging paths resolve current locations through stable
  identity before consulting cached path hints.
- Existing projects migrate without replacing UUIDs or rewriting semantically unchanged files.

### Filesystem operations

- Create Folder, Rename, Move, Duplicate, Cut/Copy/Paste, drag-to-folder, trash, and restore work on
  assets and folders.
- Ref-affecting operations show collisions, dependencies, collaboration state, and affected authored
  files before commit. They use guarded, staged filesystem transactions with rollback on failure.
- Reversible filesystem operations create guarded content-undo entries. Undo is refused after an
  external fingerprint change; trash/restore remains the recovery model for deletion.
- External filesystem changes reconcile by stable ID/fingerprint where unambiguous and otherwise
  produce an explicit repair flow.

### Destination-first import

- **Import Here** targets the selected Content Browser folder. **Import To...** chooses another
  folder beneath `assets/` without changing the browser location. The native picker opens only
  after the destination is pinned, then a second review previews every dependency and final path.
- External files are copied into the chosen project folder; files already inside project content
  are registered/processed in place instead of copied again.
- Import never silently creates visible `models/`, `textures/`, `audio/`, or `materials/` folders.
- Dependency-relative bundles, overwrite conflicts, collaboration guards, staging, and rollback
  are resolved before registry publication.
- Registry records retain optional source provenance and a deterministic reimport recipe without
  making an external absolute path a runtime dependency.

### Model asset material defaults

Material resolution uses the strongest valid authored layer in this order:

1. runtime `MaterialPropertyBlock`;
2. placed renderer/prefab slot assignment;
3. model-asset per-slot default;
4. imported source material;
5. project default Material/Instance;
6. immutable engine DefaultGrid.

Mappings are keyed by stable imported slot/subasset IDs, never display names. Changing a model-asset
default updates existing and future placements that do not carry a scene override; clearing a scene
override returns to the next intentional layer. A configured-but-broken explicit reference reports
a diagnostic and renders DefaultGrid instead of exposing a weaker assignment. Static and skinned
renderers use the same resolution rules without sharing geometry/hydration components.

Reimport reconciles by stable slot ID. Removed mappings become visible orphans and are never moved to
a similarly named slot automatically.

### Editable imported materials

- A model import can keep source fallback, map a slot to an existing project material, extract a
  supported source material into an editable project Material, or intentionally select Default.
- Extraction previews destination paths, naming collisions, external texture channels, render
  state, provenance, and supported PBR parameters before writing. Embedded texture payloads remain
  source-owned and are not misrepresented as extracted project textures.
- Extracted Materials are ordinary project assets and may live beside the model or anywhere else
  under `assets/`.
- Source provenance is recorded, but reimport never overwrites an edited Material silently. Updating
  an extracted material requires an explicit diff/apply decision.
- Unsupported source features produce diagnostics and preserve a predictable source/fallback path;
  partial conversion is never presented as lossless.

## Milestone Work Packages

### Epic — Content workspace and import authoring refactor

Tracks the milestone contract, dependencies, sequencing, and exit evidence. It is not an
implementation substitute for the focused issues below.

### Architecture — Project content and derived-artifact contract

- [Implemented] Add ADR 0045 covering the content root, registry/type authority, mutable paths,
  protected managed directories, import provenance, and the six-layer material resolution contract.
- [Implemented] Define explicit migrations for registry v1, project settings, legacy cached refs,
  whole-model material policy, and mesh material overrides.
- [Implemented] Replace fixed-folder consumers across editor, shared hydration, scene validation, project
  settings, and packaging.

### Existing BS-JD-205 — Content Browser file operations and reference-safe moves

Expand the existing rename/move repair ticket instead of duplicating it:

- [Implemented] create folder, rename, move, duplicate, cut/copy/paste, drag-to-folder, and
  transactional trash/restore with stable-ID manifests and collision guards;
- [Implemented] file-manager selection for assets and folders (single, Ctrl/Cmd toggle, Shift range, select all),
  batch operations, keyboard shortcuts, and scoped context menus on assets, folders, and unused
  content space;
- [Implemented] asset/folder collision, collaboration, external-fingerprint, and dependency-impact preview;
- [Implemented] atomic registry/reference repair and external-change reconciliation;
- [Implemented] selection, breadcrumb, thumbnail, and Material Library continuity after moves.

### Destination-first transactional import

- [Implemented] Replace extension-to-directory routing with current-folder/explicit-folder import.
- [Implemented] Register files already under project content in place.
- [Implemented] Preserve FBX/glTF relative dependencies safely and reject collisions before any
  selected source mutates the destination.
- [Implemented] Roll back the complete multi-source publication batch on failure; cancellation
  remains non-mutating.

### Path-agnostic catalog, loading, validation, and packaging

- [Implemented] Remove folder-name asset classification and fixed material/shader/model discovery paths.
- [Implemented] Resolve stable IDs to current paths in editor and runtime consumers.
- [Implemented] Make the live editor watcher, headless processing, validators, and build manifests
  share the same catalog rules. Live refresh debounces changes, ignores generated/managed noise,
  suppresses editor transactions, republishes registry/runtime catalog, and invalidates thumbnails.
- [Implemented] Migrate representative registry/model records while preserving UUIDs and
  semantically unchanged user-authored bytes.

### Built-in DefaultGrid and project fallback

- [Implemented] Provide one immutable, UV-independent engine material with forward/Solari parity and a shared
  emergency StandardMaterial handle.
- [Implemented] Let Project Settings select a registry-backed project Material/Instance fallback; Clear or an
  invalid reference returns to DefaultGrid with diagnostics.
- [Implemented] Apply the fallback to unresolved static/skinned slots, primitives without an active material,
  unassigned brush faces, and model/mesh previews. Terrain keeps its specialized layer fallback.

### Unified actor material slots and previews

- [Implemented] `MaterialSlot`/`MaterialSlotSet` are the primary contracts; schema-v4 renderer names
  remain compatibility aliases for one cycle. `Primitive.surface` always uses
  `slot:primitive:surface` and new placements begin unassigned.
- [Implemented] Hydration binds the exact primitive/static/skinned slot to one cached emergency
  handle, then resolves explicit/model source/project default/DefaultGrid without actor-local
  material creation. Component-form `MaterialDesc` remains only for the brush fallback path.
- [Implemented] One inspector widget exposes the effective Material sphere/name/status,
  Browse/Locate/Clear, a full-width Material/Instance target, red explanatory Texture rejection,
  expandable guarded shared parameters, exact-slot instance creation, imported-source extraction,
  and property-block information/promotion.
- [Implemented] Scene schema v6 stores actor-only slot assignments; the explicit upgrader converts primitive, mesh-wide, and per-slot legacy values
  into saved slots and deterministic deduplicated project Materials. Normal loading remains
  non-writing and validation diagnoses unmigrated actor components.
- [Implemented] Model cards always use the offscreen scene studio; texture loading is texture-only.
  Typed cache keys prevent cross-category collisions and static mesh inspector previews request
  exact mesh-subasset renders.

### Model-asset material slot mapping

- [Implemented] Persist model-default mappings by stable slot/subasset ID.
- [Implemented] Add Content Browser model-details controls to Browse, Assign, Locate, Clear, and inspect orphans.
- [Implemented] Apply the six-layer resolution contract to static and skinned hydration.
- [Implemented] Reimport without rewriting scene overrides or resetting skinned animation state.

### Editable source-material extraction and import-policy UX

- [Implemented] Convert supported glTF/GLB/FBX PBR source values and external textures into guarded
  `MaterialAsset` documents.
- [Implemented] Let each slot choose Source, Existing Project Material, Extract Editable, or Default.
- [Implemented] Integrate PBR texture-set detection from BS-JD-202 without conflating filename
  grouping with model source-material conversion. The folder action now previews confidence,
  supports manual roles and target merge/split, and publishes no-overwrite Material batches through
  the shared transaction engine.
- [Implemented] Preview converted values, destinations, collisions, provenance, and render state.
  Provenance-matched re-extraction requires an explicit diff-backed Apply or Create New choice;
  Apply is fingerprint-guarded and byte-restoring, while unrelated provenance is never overwritten.

### Migration and acceptance signoff

Use a representative project workflow:

1. Create `assets/Props/Office/` in the Content Browser.
2. Import a static model and a skeletal model directly into that folder.
3. Extract one valid source material, map another slot to an existing Material Instance, and keep a
   third slot on source fallback.
4. Place both models, add one scene-level material override, save, close, and reopen.
5. Move/rename the containing folder, reimport both models, and resolve a removed-slot orphan.
6. Verify unchanged UUIDs, model defaults, scene override precedence, editable Material contents,
   thumbnails, selection, PIE/runtime rendering, headless validation, and release packaging.
7. Verify a failed/cancelled import or move leaves the exact pre-operation filesystem and registry.

No M2 milestone issue of any priority may remain open at signoff.

## Sequencing

1. Epic and ADR/storage contract.
2. Path-agnostic registry/type resolution foundation.
3. BS-JD-205 file operations and destination-first import.
4. DefaultGrid/project fallback and model-asset material mapping.
5. Editable extraction plus BS-JD-202 PBR grouping integration.
6. [Implemented] BS-JD-204 live refresh and BS-JD-206 headless parity.
7. Migration/native/headless/package acceptance.

[Implemented] BS-JD-208 runtime MaterialPropertyBlocks applies after resolved bases with cached
per-owner/slot handles and exact-slot transactional promotion.
Solari dynamic-deformation work remains independent and is not a prerequisite for this refactor.

## Documentation On Implementation

- [Implemented] Create and index ADR 0045; update ADR 0035 and ADR 0044 where contracts changed.
- [Implemented] Add `docs/editor/content-workspace.md` as the canonical workflow/reference document and index it
  from `docs/README.md` and `docs/editor/README.md`.
- [Implemented] Update root README controls, troubleshooting, and implementation checklist.
- [Implemented] Add the M2 Content Workspace feature-level native evaluation record with capture
  checksums and headless/package evidence links.
- [Pending signoff] Upload the native PNGs to Gitea and rerun the record from the exact committed
  implementation revision.

## Verification Matrix

- Unit tests: path/type resolution, collision planning, slot mapping precedence, orphan
  reconciliation, conversion fidelity, provenance, and migration.
- Transaction fixtures: recursive move/rename, bundle import rollback, collaboration conflict,
  cancelled extraction, and external filesystem moves.
- Editor tests: file-manager actions, exact model-slot mapping, static/skinned parity, save/reopen,
  and no scene dirtiness from previews.
- [Passed 2026-07-13] Focused unit/transaction/editor suites; `cargo process-assets` write followed
  by read-only check over 42 assets; project validation over 97 dependencies with 0 blockers.
- [Passed 2026-07-13] Five sample projects validate with 0 blockers; repeated QA packaging reuses
  unchanged files, includes/fingerprints the runtime catalog, and the native executable remains
  healthy through a bounded launch smoke test.
- [Passed 2026-07-13] Development packaging publishes after accepting an equivalent legacy lock
  output with a trailing separator; the regression is unit-covered, the packaged runtime catalog
  is byte-identical to the headless catalog, and an eight-second native launch leaves no process
  behind.
- [Passed 2026-07-13] `cargo fmt --all -- --check`, strict workspace/all-target/all-feature Clippy,
  and the complete workspace/all-feature unit and documentation test suite.
- [Passed 2026-07-13] Native Content Browser selection, batch and empty-space menus, basic item
  actions, managed-folder hiding, background/item interaction priority, and Details resizing; see
  `docs/editor/evaluations/content-workspace-m2/`.
- [Passed 2026-07-14] All-feature workspace tests, strict all-target/all-feature Clippy, 48-asset
  write/check parity, 116/121-dependency validators with no blockers, byte-identical packaged
  catalog, and live mapped editor/package windows.
- [Passed locally 2026-07-14] Destination-first skeletal import and placement, broken project
  fallback to DefaultGrid, and exact-slot skinned scene override. The registry was restored to the
  built-in default before the final deterministic refresh.
- [Passed locally 2026-07-14] Focused Import To/review tests prove pinned destinations, no mutation
  before confirmation, collision refusal, source/dependency fingerprint conflicts, and complete
  textual-glTF dependency tracking. Focused promotion tests prove direct-base/exact-slot
  publication, one history edit, cancel/conflict/stale-input non-mutation, schema validation, and
  byte-exact file/catalog rollback after a failed scene edit.
- [Passed natively 2026-07-14] Import To selected `assets/Furniture/Office` while the browser stayed
  at `assets`, the second review showed the exact target for a temporary PNG, and Cancel published
  no file. Capture hashes are recorded in the M2 evaluation.
- [Passed 2026-07-14] The material-slot consistency follow-through migrated the active project to
  the then-current scene schema, processed 71 assets with write/check parity, passed 330 editor tests plus the
  complete all-feature workspace suite and strict Clippy, published the development package, and
  kept both the live editor and packaged runtime healthy through bounded Wayland launches. Native
  inspection confirmed the primitive-owned Surface Material slot and expandable shared parameters;
  typed thumbnail tests confirm the Poly Haven office desk queues geometry renders rather than its
  albedo texture.
- [Corrected 2026-07-14] Assigned Standard Materials now detach from the singleton emergency
  handle during resolution. The regression begins with a neutral-grey hydrated handle, verifies
  that fallback remains unchanged, and checks the resolved project asset's base color, metallic,
  and roughness on its reference-scoped cached handle.
- [Passed natively 2026-07-17] Editor-only BRP injected a two-parameter
  `MaterialPropertyBlock` into Ground's `slot:primitive:surface`; the Inspector promoted one sparse
  direct-base Material Instance, assigned the exact slot through one history edit, and removed the
  runtime block only after successful publication. Undo restored the prior slot, and the temporary
  instance, registry, catalog, scene, and Pebble fixture were restored byte-for-byte afterward.
- [Passed on candidate tree 2026-07-17; exact-commit readback pending] Refresh/validation of
  unchanged content writes no files (`process-assets --check`: 78 discovered, zero changes).
# Material authoring UI and Texture processing completion (2026-07-14)

- [x] Replace duplicated Standard fields with schema-v2 `MaterialInputSchema` and
  `MaterialInputSet` documents; keep Material Instance overrides sparse.
- [x] Use one compact primitive/static/skinned material-slot widget with an embedded sphere,
  assignment status/actions, responsive parameters, and diagnostics outside parameter rows.
- [x] Pair Standard Lit multipliers with textures and expose ARM/ORM, Separate Maps, and custom
  channel selection.
- [x] Add registry-v3 typed Texture properties and a shared deterministic UASTC/KTX2 processor.
- [x] Canonicalize AO/Roughness/Metallic selections to R/G/B ARM and publish runtime-catalog v2
  paths for Forward and Surface/Solari consumers.
- [x] Extend the explicit transactional upgrader for registry v2 and Material/Instance/Shader
  Schema v1 documents; current normal loading remains non-writing.
- [ ] Codex-owned critical native acceptance covers persistent live edits, scalar Save without
  processing, ARM background processing, final wide/narrow material cards, long Content Browser
  labels/status, clean-value recovery retirement, restart persistence, and Forward/Solari
  presentation. The user explicitly delegated this QA; low-quality UI is a failure, not
  acceptable evidence.
