# ADR 0028: Authoritative project content validation

## Status

Accepted

## Context

Scene, prefab, and imported-asset checks were distributed across editor loading, hydration, and the
`validate-levels` task. A project could therefore pass headless scene validation while still
containing a missing model, texture, material, shader, generated mesh manifest, post effect, or
rendering profile reference. Editor-only validation would also risk disagreeing with CI and release
tooling.

## Decision

The Bevy-free `scene` crate owns `validate_project` and the structured
`ProjectValidationReport`. The report contains a deterministic dependency manifest and findings
with severity, stable code, source document, owning `ActorId` where available, referenced path,
message, and repair action.

Both the editor Diagnostics window and the `cargo validate-levels` headless command call this same
entry point. The command supports `--project <path>` and `--json`; the editor can select the live
owning actor for an attributed finding. Blocking errors produce a nonzero headless exit status.

The optional editor regression pack has one conventional manifest at
`assets/samples/editor_samples.ron`. Schema v1 contains exactly one Brush, Material, Terrain,
Physics Placement, and Rendering sample with stable metadata, project-relative scene paths, and
explicit manual checks. `cargo validate-samples` validates that catalog and combines its findings
with the authoritative project report. Projects without the manifest remain valid ordinary
projects; Blacksite CI invokes the sample command to make the complete pack mandatory for this
repository.

Project validation covers the project manifest and asset roots, registry IDs/sources/dependencies,
generated static mesh manifests, material and shader documents, post effects, scene and prefab
graphs, authored model/material/texture/brush/collider references, rendering profiles, and
unhydrated Git LFS pointer files. The validator owns the runtime-packageability predicate consumed by
the packager: editor/hidden trees, source-authoring formats, symlinks, and unreadable traversal are
blocking rather than being accepted and later omitted. The project default must be a regular
`.scn.ron` file under `assets/levels/`, which guarantees the full document dependency pass audits the
startup entrypoint. Unknown newer scene schemas are rejected rather than down-stamped. Platform
requirements are explicit findings; for example, Solari projects record the required forward-path
fallback QA when ray tracing is unavailable.

Imported model, texture, and audio registry records, animation manifests, and static-mesh manifests
share the content-addressed fingerprint contract in
[ADR 0043](0043-content-addressed-import-fingerprints.md). Validation hashes source bytes and catches
same-size changes without consulting mtimes. The validation entry point is read-only; CI asserts that
running both level and sample validation leaves the checkout unchanged.

Terrain descriptors participate in the same actor-owned dependency pass. Their authored dimensions,
height and weight grids, chunk settings, base material, and material layers are validated before
hydration so a sample or shipping scene cannot hide an invalid or unresolved terrain reference.

## Consequences

- Headless and editor validation share result semantics and finding ownership.
- Missing references are visible before Bevy hydration attempts to load them.
- Release packaging invokes this report before and after compilation and refuses blocking errors;
  Gitea #44 acceptance verifies the shared gate against real development output.
- Asset formats added later must register their dependencies with this validator and extend the
  valid, missing, cyclic, and incompatible project-fixture matrix.
- The sample manifest is discovery and regression metadata, not a second project-settings schema;
  editor UI and headless tooling consume the same scene ordering and validation result.
- CI must hydrate Git LFS before validation because a pointer file is intentionally treated as
  missing runtime content.
- Validators report stale or incomplete import fingerprints with repair guidance but never rewrite
  the registry or generated artifacts.
