Skip to content

Commit b23ab87

Browse files
author
DavidQ
committed
BUILD_PR_LEVEL_09_14_RUNTIME_ASSET_VALIDATION
1 parent ffb8e39 commit b23ab87

13 files changed

Lines changed: 212 additions & 44 deletions

docs/dev/CODEX_COMMANDS.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
12
MODEL: GPT-5.4
23
REASONING: high
34
COMMAND:
4-
- Consolidate runtime asset lookup into shared interface
5-
- Replace duplicate lookup logic where touched
6-
- Use manifest binding as source of truth
5+
- Add runtime asset validation layer
6+
- Validate manifest-resolved assets
7+
- Reject `/data/` paths at runtime
8+
- Integrate with lookup layer
79
- Update roadmap status only (no text changes)

docs/dev/COMMIT_COMMENT.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
BUILD_PR_LEVEL_09_13_ASSET_LOOKUP_CONSOLIDATION
1+
BUILD_PR_LEVEL_09_14_RUNTIME_ASSET_VALIDATION
22

3-
Consolidates runtime asset lookup into a shared manifest-backed interface, replaces duplicated runtime lookup logic in touched consumers, enforces manifest binding as the source of truth for bindable domains, and applies a status-only roadmap bracket update.
3+
Adds runtime asset validation for manifest-resolved assets, rejects `/data/` paths at runtime, integrates validation into shared runtime lookup resolution, and applies a status-only roadmap bracket update.

docs/dev/NEXT_COMMAND.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BUILD_PR_LEVEL_09_14_RUNTIME_ASSET_VALIDATION
1+
BUILD_PR_LEVEL_09_15_ASSET_ERROR_HANDLING
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
Summary
2-
- Consolidated runtime asset lookup behind one shared interface: `tools/shared/pipeline/runtimeAssetLookup.js`.
3-
- Replaced duplicated runtime lookup resolver logic in touched consumers with the shared manifest-backed lookup.
4-
- Kept manifest binding as the lookup source of truth for bindable runtime asset domains.
2+
- Added a runtime asset validation layer integrated into shared runtime lookup.
3+
- Manifest-resolved assets are now validated before runtime use.
4+
- Runtime `/data/` path resolution is rejected in validation.
55

66
Implementation
7-
- Added `createRuntimeManifestAssetLookup` and `getRuntimeBindingDomain`:
8-
- Builds/uses `coordinateGameAssetManifest` + `createRuntimeAssetBinding`
9-
- Exposes `resolvePackagedAsset` for runtime loaders
10-
- Supports strict (`missingBindingBehavior: "null"`) and fallback (`"static"`) missing-binding handling
11-
- Replaced local duplicate resolver logic in:
12-
- `tools/shared/asteroidsPlatformDemo.js`
13-
- `tools/shared/vectorNativeTemplate.js`
14-
- `tools/shared/vectorTemplateSampleGame.js`
15-
- `tools/shared/vectorAssetSystem.js`
16-
- Added focused consolidation test:
17-
- `tests/tools/RuntimeAssetLookupConsolidation.test.mjs`
18-
- Registered the test in `tests/run-tests.mjs`.
7+
- Added `tools/shared/pipeline/runtimeAssetValidation.js`:
8+
- validates manifest-resolved runtime assets by domain (`sprites`, `tilemaps`, `parallax`, `vectors`)
9+
- enforces required runtime path and domain-specific minimal field checks
10+
- rejects any `/data/` runtime path/source path usage
11+
- Updated `tools/shared/pipeline/runtimeAssetLookup.js`:
12+
- integrates `validateRuntimeResolvedAsset` into `resolvePackagedAsset`
13+
- returns `null` for invalid manifest-resolved assets so runtime loader blocks consumption
14+
- Added focused tests:
15+
- `tests/tools/RuntimeAssetValidation.test.mjs`
16+
- updated `tests/tools/RuntimeAssetLookupConsolidation.test.mjs` for validation integration behavior
17+
- registered `RuntimeAssetValidation` in `tests/run-tests.mjs`
1918

2019
Roadmap (status-only)
21-
- Updated one bracket status only in `docs/dev/roadmaps/MASTER_ROADMAP_HIGH_LEVEL.md`:
22-
- `Normalize tools/shared and tool boundaries` moved from `[.]` to `[x]`
23-
- No roadmap prose/order/wording edits.
20+
- `docs/dev/roadmaps/MASTER_ROADMAP_HIGH_LEVEL.md`
21+
- `Normalize assets/data ownership` moved from `[.]` to `[x]`
22+
- No roadmap wording/order/prose edits.

docs/dev/reports/validation_checklist.txt

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
1-
Validation Checklist - BUILD_PR_LEVEL_09_13_ASSET_LOOKUP_CONSOLIDATION
1+
Validation Checklist - BUILD_PR_LEVEL_09_14_RUNTIME_ASSET_VALIDATION
22

33
Scope
4-
[x] Runtime asset lookup consolidated via shared interface
5-
[x] Duplicate lookup logic replaced where touched
6-
[x] Manifest binding used as source of truth for bindable runtime domains
7-
[x] No engine-core changes
8-
[x] No tool UI changes
4+
[x] Runtime asset validation layer added
5+
[x] Manifest-resolved runtime assets validated before use
6+
[x] `/data/` runtime paths rejected
7+
[x] Validation integrated with shared lookup layer
8+
[x] No engine redesign
9+
[x] No tool UI work
10+
[x] No asset format expansion
911

1012
Code
11-
[x] Added `tools/shared/pipeline/runtimeAssetLookup.js`
12-
[x] Updated `tools/shared/asteroidsPlatformDemo.js`
13-
[x] Updated `tools/shared/vectorNativeTemplate.js`
14-
[x] Updated `tools/shared/vectorTemplateSampleGame.js`
15-
[x] Updated `tools/shared/vectorAssetSystem.js`
16-
[x] Added `tests/tools/RuntimeAssetLookupConsolidation.test.mjs`
13+
[x] Added `tools/shared/pipeline/runtimeAssetValidation.js`
14+
[x] Updated `tools/shared/pipeline/runtimeAssetLookup.js`
15+
[x] Added `tests/tools/RuntimeAssetValidation.test.mjs`
16+
[x] Updated `tests/tools/RuntimeAssetLookupConsolidation.test.mjs`
1717
[x] Updated `tests/run-tests.mjs`
1818

1919
Validation
20+
[x] `node --check tools/shared/pipeline/runtimeAssetValidation.js`
2021
[x] `node --check tools/shared/pipeline/runtimeAssetLookup.js`
21-
[x] `node --check tools/shared/asteroidsPlatformDemo.js`
22-
[x] `node --check tools/shared/vectorNativeTemplate.js`
23-
[x] `node --check tools/shared/vectorTemplateSampleGame.js`
24-
[x] `node --check tools/shared/vectorAssetSystem.js`
22+
[x] `node --check tests/tools/RuntimeAssetValidation.test.mjs`
2523
[x] `node --check tests/tools/RuntimeAssetLookupConsolidation.test.mjs`
26-
[x] Focused test passes: `RuntimeAssetLookupConsolidation`
24+
[x] `node --check tests/run-tests.mjs`
25+
[x] Focused tests pass: RuntimeAssetValidation, RuntimeAssetLookupConsolidation
2726
[x] Existing tests pass: RuntimeAssetBinding, GameAssetManifestCoordinator, AssetPipelineTooling, ProjectToolDataContracts
28-
[x] Existing touched-consumer non-regression tests pass: AsteroidsAssetReferenceAdoption, AsteroidsPlatformDemo, VectorNativeTemplate, VectorTemplateSampleGame, VectorAssetSystem
27+
[x] Existing consumer/lane tests pass: AsteroidsAssetReferenceAdoption, AsteroidsPlatformDemo, VectorNativeTemplate, VectorTemplateSampleGame, VectorAssetSystem
2928

3029
Roadmap
3130
[x] Status-only update applied

docs/dev/roadmaps/MASTER_ROADMAP_HIGH_LEVEL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@
594594
- [ ] Normalize samples phase structure
595595
- [ ] Establish games/_template and normalize games layer
596596
- [x] Normalize tools/shared and tool boundaries
597-
- [.] Normalize assets/data ownership
597+
- [x] Normalize assets/data ownership
598598
- [.] Expand testing/validation structure
599599

600600
### Later Capability Lanes
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
# BUILD_PR — LEVEL 09_14 — RUNTIME ASSET VALIDATION
3+
4+
## Objective
5+
Introduce a runtime-safe validation layer that verifies resolved assets (post-lookup) meet expected contracts and are safe for consumption.
6+
7+
## Scope
8+
- validate manifest-resolved assets before runtime use
9+
- ensure no `/data/` assets leak into runtime
10+
- validate required fields per domain (sprites, tilemaps, parallax, vectors)
11+
- integrate with existing lookup layer
12+
13+
## Out of Scope
14+
- no engine redesign
15+
- no tool UI work
16+
- no asset format expansion
17+
18+
## Roadmap Instruction
19+
Update roadmap status only. No text edits.
20+
21+
## Deliverables
22+
Standard docs/dev bundle.

tests/run-tests.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import { run as runAssetPipelineTooling } from './tools/AssetPipelineTooling.tes
9494
import { run as runGameAssetManifestCoordinator } from './tools/GameAssetManifestCoordinator.test.mjs';
9595
import { run as runRuntimeAssetBinding } from './tools/RuntimeAssetBinding.test.mjs';
9696
import { run as runRuntimeAssetLookupConsolidation } from './tools/RuntimeAssetLookupConsolidation.test.mjs';
97+
import { run as runRuntimeAssetValidation } from './tools/RuntimeAssetValidation.test.mjs';
9798
import { run as runToolEntryLaunchContract } from './tools/ToolEntryLaunchContract.test.mjs';
9899
import { run as runProjectPackagingSystem } from './tools/ProjectPackagingSystem.test.mjs';
99100
import { run as runRuntimeAssetLoader } from './tools/RuntimeAssetLoader.test.mjs';
@@ -213,6 +214,7 @@ const tests = [
213214
['GameAssetManifestCoordinator', runGameAssetManifestCoordinator],
214215
['RuntimeAssetBinding', runRuntimeAssetBinding],
215216
['RuntimeAssetLookupConsolidation', runRuntimeAssetLookupConsolidation],
217+
['RuntimeAssetValidation', runRuntimeAssetValidation],
216218
['ToolEntryLaunchContract', runToolEntryLaunchContract],
217219
['ProjectPackagingSystem', runProjectPackagingSystem],
218220
['RuntimeAssetLoader', runRuntimeAssetLoader],

tests/tools/RuntimeAssetLookupConsolidation.test.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export async function run() {
1313
"vector.ship": { file: "games/asteroids/assets/vectors/ship.vector.json", kind: "vector" },
1414
"tilemap.main": { file: "games/asteroids/assets/tilemaps/main.tilemap.json", kind: "tilemap" },
1515
"parallax.bg": { file: "games/asteroids/assets/parallax/background.parallax.json", kind: "parallaxLayer" },
16+
"vector.bad": { file: "games/asteroids/assets/vectors/bad.vector.json" },
1617
"vector.tool-only": { file: "games/asteroids/assets/vectors/data/tool-only.vector.json", kind: "vector" },
1718
"palette.hud": { kind: "palette", colors: ["#ffffffff"] }
1819
},
@@ -21,7 +22,7 @@ export async function run() {
2122

2223
assert.equal(strictLookup.binding.status, "ready");
2324
assert.equal(strictLookup.binding.issues.length, 0);
24-
assert.equal(strictLookup.binding.domains.vectors.length, 1);
25+
assert.equal(strictLookup.binding.domains.vectors.length, 2);
2526
assert.equal(strictLookup.binding.domains.tilemaps.length, 1);
2627
assert.equal(strictLookup.binding.domains.parallax.length, 1);
2728
assert.equal(
@@ -30,6 +31,7 @@ export async function run() {
3031
);
3132

3233
assert.equal(strictLookup.resolvePackagedAsset({ id: "vector.ship", type: "vector" }).file, "games/asteroids/assets/vectors/ship.vector.json");
34+
assert.equal(strictLookup.resolvePackagedAsset({ id: "vector.bad", type: "vector" }), null);
3335
assert.equal(strictLookup.resolvePackagedAsset({ id: "vector.tool-only", type: "vector" }), null);
3436
assert.equal(strictLookup.resolvePackagedAsset({ id: "palette.hud", type: "palette" }).kind, "palette");
3537

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import assert from "node:assert/strict";
2+
import { validateRuntimeResolvedAsset } from "../../tools/shared/pipeline/runtimeAssetValidation.js";
3+
4+
export async function run() {
5+
const validVector = validateRuntimeResolvedAsset({
6+
domain: "vectors",
7+
assetId: "vector.ship",
8+
runtimePath: "games/asteroids/assets/vectors/ship.vector.json",
9+
source: {
10+
kind: "vector",
11+
file: "games/asteroids/assets/vectors/ship.vector.json",
12+
runtimeKind: "vector-geometry"
13+
}
14+
});
15+
assert.equal(validVector.valid, true);
16+
17+
const dataPathBlocked = validateRuntimeResolvedAsset({
18+
domain: "vectors",
19+
assetId: "vector.tool-only",
20+
runtimePath: "games/asteroids/assets/vectors/data/tool-only.vector.json",
21+
source: {
22+
kind: "vector",
23+
file: "games/asteroids/assets/vectors/data/tool-only.vector.json"
24+
}
25+
});
26+
assert.equal(dataPathBlocked.valid, false);
27+
assert.equal(dataPathBlocked.issues.some((issue) => issue.includes("/data/")), true);
28+
29+
const invalidTilemap = validateRuntimeResolvedAsset({
30+
domain: "tilemaps",
31+
assetId: "tilemap.main",
32+
runtimePath: "games/asteroids/assets/tilemaps/main.tilemap.json",
33+
source: {
34+
file: "games/asteroids/assets/tilemaps/main.tilemap.json"
35+
}
36+
});
37+
assert.equal(invalidTilemap.valid, false);
38+
assert.equal(invalidTilemap.issues.some((issue) => issue.includes("Tilemaps")), true);
39+
}

0 commit comments

Comments
 (0)