Blacksite/docs/adr/0028-authoritative-project-content-validation.md

3.6 KiB

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.

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.