5.4 KiB
5.4 KiB
Asset Package Contract Implementation Plan
Phase 0: Contract Lock-In
- Add a package-contract module that owns v1 schema constants, allowed roles and categories, URI containment validation, manifest construction and validation.
- Add focused unit fixtures for valid manifests and each invalid condition: missing schema/placement/bounds, malformed coordinates, invalid role/category, absolute or traversing URI, duplicate asset ID, missing primary scene, and referenced file outside the package.
- Document
package/as the sole downstream boundary in README and pipeline/config specs; retain a clear distinction between release assets and preview artifacts.
Gate: manifest v1 can be created and structurally validated without invoking Blender, Cesium or QGIS.
Phase 1: Package Paths and Static Export
- Extend
scripts/lib/area-config.jswith paths forpackageDir, package manifest, package model directory, primary GLB and semantic layer GLBs; keep all path derivation in this module. - Change
blender/export_cesium.pymetadata output to a static manifest seed: bounds, ENU placement and static scene/layer declarations only. Remove local source paths and inline Cesium source code from the published data. - Direct static GLB output to package staging paths and retain dynamic signal/countdown output as preview-only paths outside package staging.
- Update
build-area.js, semantic asset checks, stage manifests and diagnostics to consume the new path contract rather than constructing paths locally.
Gate: a Cesium export produces a valid static manifest seed and every declared static asset exists under package staging; no preview-only asset appears in it.
Phase 2: Compression and Atomic Publication
- Refactor the default compression stage to operate on staged package files, preserving the final manifest shape while replacing only the primary GLB bytes and integrity data.
- Add a
packagestage aftercompress; validate every asset and atomically promote staging tooutputs/<area-id>/package/. - Update canonical stage ordering,
all, interactive CLI labels and defaults. - Ensure a failed compression/package validation never replaces an existing published package; record diagnostics sufficient to identify the failed source/staging path.
Gate: a full build creates one publishable package with compressed primary GLB and no duplicate static GLBs at the area root.
Phase 3: Preview Adapter and Compatibility
- Change preview HTML generation to reference
package/manifest.jsonrelative to the area output root. - Move route/vehicle/dynamic-signal discovery into a preview-only descriptor beneath
_preview/, and makecesium-preview.jsmerge it after loading the package manifest. - Preserve existing preview controls and graceful behavior when preview-only data is absent; preview must still render the package static scene.
- Update
diagnose:area,check:areaand stage manifest freshness to distinguish package artifacts from preview-only files.
Gate: the local Cesium preview loads the published package and continues to show optional cruise/dynamic preview content without adding either to package manifest.
Phase 4: Downstream Consumption Proof
- Add Cesium example code that resolves the manifest URL, validates placement and loads the full scene or selected layers.
- Add Three.js example code with a manifest-relative resolver and an explicit ENU placement handoff to the host's georeferencing integration.
- Add automated resolver tests so neither example can regress to page-relative, desktop-absolute or repository-relative URLs.
- Publish consumer documentation including overlap rules for complete scene vs layers.
Gate: examples run from a copied package/ directory and require no files outside it.
Phase 5: Full Verification and Migration
- Run focused Node tests for package schema, stage resolution, compression metadata, preview behavior, diagnostics and asset budgets.
- Run the full default build for the primary area, then
check:areaand package integrity validation. - Inspect the packaged GLB structure and validate the Cesium example in browser; verify Three.js resolver output with the same manifest.
- Capture expected intentional output-contract changes in docs/changelog and update relevant Trellis pipeline/config/preview specs.
- Preserve legacy root-level artifacts during rollout; document that downstream
consumers must migrate to
package/manifest.jsonrather than treating legacy files as fallback.
High-Risk Boundaries
blender/export_cesium.pyto Node: static metadata fields and semantic asset file names are a cross-runtime contract.- Node packaging to preview runtime: preview-only dynamic data must never silently enter the package manifest.
- Compression to publication: paths must remain package-relative and a partial write must not replace the last valid package.
- Consumers: ENU axes and heading correction are load-bearing; examples must not create a second, incompatible georeferencing convention.
Validation Commands
npm run test:build-stages
npm run test:compress-glb
npm run test:preview-assets
npm run test:budgets
npm run test:preflight
npm run check:area -- --config config/areas/nantaizi-lake-innovation-valley.json
node scripts/glb-digest.js outputs/nantaizi-lake-innovation-valley/package/models/nantaizi-lake-innovation-valley.glb