Skip to content

Commit a38b85f

Browse files
author
DavidQ
committed
Enforce object ID as runtime SSoT and remove duplicate object asset identity - PR_26133_027-object-id-ssot-manifest-schema-cleanup
1 parent 92b612d commit a38b85f

9 files changed

Lines changed: 183 additions & 83 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Object ID SSoT Cleanup Report
2+
3+
Task: PR_26133_027-object-id-ssot-manifest-schema-cleanup
4+
Date: 2026-05-13
5+
6+
## Runtime Identity Contract
7+
8+
Object IDs are the single source of truth for Object Vector runtime/gameplay identity. Object Vector Studio V2 assetLibrary entries now use the runtime object ID directly in `id`, and duplicate runtime alias fields are rejected.
9+
10+
Preferred Object Vector assetLibrary entry shape is now:
11+
12+
```json
13+
{
14+
"id": "object.asteroids.ship",
15+
"name": "Asteroids Ship",
16+
"tags": ["player", "ship"]
17+
}
18+
```
19+
20+
## Removed Or Replaced
21+
22+
- Removed `objectId` from `workspace.tools.object-vector-studio-v2.assetLibrary.assets[*]` in `games/Asteroids/game.manifest.json`.
23+
- Replaced redundant `asset.asteroids.*` Object Vector assetLibrary IDs with matching `object.asteroids.*` IDs.
24+
- Updated Object Vector Studio V2 editor logic so rename/delete/runtime preview/dependency graph behavior follows `asset.id` as the object ID.
25+
- Updated runtime asset validation and normalization so Object Vector assetLibrary entries cannot carry duplicate `objectId` aliases.
26+
27+
## What Remains And Why
28+
29+
- `object.asteroids.*` remains under `game.gameData.objectVectorRuntime.objectIds` and Object Vector Studio V2 object records because those are runtime object identities.
30+
- `vector.asteroids.*` remains only in vector-document/editor scoped data and is not used as runtime object identity.
31+
- `assets.*` asset-manager IDs remain for true media/file assets such as audio, image, and font records.
32+
- No `asset.asteroids.*` runtime Object Vector identity remains in active Asteroids runtime/editor payloads.
33+
34+
## Schema And Validation
35+
36+
- `tools/schemas/tools/object-vector-studio-v2.schema.json` no longer requires or permits `libraryAsset.objectId`.
37+
- Object Vector Studio V2 validation now requires each library entry `id` to reference an existing object.
38+
- Object Vector runtime validation now follows the same library ID/object ID contract.
39+
- Playwright coverage includes explicit rejection for:
40+
- `assetLibrary.assets[*].objectId`
41+
- `assetLibrary.assets[*].id` values that do not resolve to an existing object ID
42+
43+
## Editor Controls
44+
45+
- Triangle-labeled Object Vector polygon shapes hide Add Point and Delete Point controls.
46+
- Editable non-triangle polygons retain Add Point and Delete Point behavior.
47+
- Duplicate Frame renders between Frame Earlier and Frame Later.
48+
49+
## Validation
50+
51+
- PASS - Asteroids game manifest validates against the updated schema.
52+
- PASS - Asteroids small asteroid resolves by `objectId: object.asteroids.asteroid.small`.
53+
- PASS - Object Vector Studio V2 loads Asteroids objects through `object.*` IDs.
54+
- PASS - Object Vector Studio V2 rejects duplicate runtime alias fields in assetLibrary entries.
55+
- PASS - Active Asteroids runtime/editor payloads have no `asset.asteroids.*` Object Vector runtime identity.
56+
- PASS - Triangle/non-triangle polygon controls verified in Playwright.
57+
- PASS - Duplicate Frame ordering verified in Playwright.
58+
- PASS - `npm run test:workspace-v2` completed with 49 passed.

docs/dev/reports/playwright_v8_coverage_report.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# PR_26133_026 Playwright V8 Coverage Report
1+
# PR_26133_027 Playwright V8 Coverage Report
22

3-
Task: PR_26133_026-object-id-ssot-schema-and-editor-controls
3+
Task: PR_26133_027-object-id-ssot-manifest-schema-cleanup
44
Date: 2026-05-13
55

66
## Result
@@ -24,17 +24,18 @@ PASS - Coverage reporting was generated during `npm run test:workspace-v2`.
2424
## Changed Runtime JS Coverage
2525

2626
- `tools/object-vector-studio-v2/js/ToolStarterApp.js`: 94% function coverage, 4190/4190 reported lines executed, 452/483 reported functions executed.
27-
- `games/Asteroids/game/AsteroidsGameScene.js`: 52% function coverage, 846/846 reported lines executed, 25/48 reported functions executed.
28-
- `tools/shared/asteroidsPlatformDemo.js`: not collected by Playwright V8 coverage; covered by focused node test `AsteroidsPlatformDemo.test.mjs`.
27+
- `tools/object-vector-studio-v2/js/services/ObjectVectorStudioV2SchemaService.js`: 95% function coverage, 411/411 reported lines executed, 53/56 reported functions executed.
28+
- `src/engine/rendering/ObjectVectorRuntimeAssetService.js`: 98% function coverage, 916/916 reported lines executed, 106/108 reported functions executed.
2929

3030
## PR-Specific Coverage/Validation Relevance
3131

3232
The workspace-v2 run exercises the Object Vector Studio V2 editor and Asteroids runtime paths changed in this PR:
3333

34-
- triangle geometry layout and controls,
35-
- frame control ordering,
36-
- objectId-based Asteroids Object Vector runtime rendering,
37-
- Workspace Manager game manifest schema loading and validation,
38-
- Object Vector Studio V2 loading of Asteroids workspace objects.
34+
- Object Vector Studio V2 schema rejection for duplicate runtime identity aliases.
35+
- Object Vector Studio V2 assetLibrary hydration through `object.*` IDs.
36+
- Asset library inheritance and runtime preview resolution through object IDs.
37+
- Asteroids runtime Object Vector rendering through `object.asteroids.*` IDs.
38+
- Triangle/non-triangle polygon point control behavior.
39+
- Duplicate Frame control ordering.
3940

4041
Generated source report: `docs/dev/reports/playwright_v8_coverage_report.txt`.
Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# PR_26133_026 Workspace V2 Validation
1+
# PR_26133_027 Workspace V2 Validation
22

3-
Task: PR_26133_026-object-id-ssot-schema-and-editor-controls
3+
Task: PR_26133_027-object-id-ssot-manifest-schema-cleanup
44
Date: 2026-05-13
55

66
## Result
@@ -9,32 +9,27 @@ PASS - `npm run test:workspace-v2`
99

1010
- 49 Playwright tests passed.
1111
- Focused Object Vector Studio V2 checks passed before the full run.
12-
- Asteroids runtime Object Vector rendering passed with objectId-based lookup.
12+
- Asteroids manifest schema validation passed after the assetLibrary cleanup.
1313
- No sample JSON files were changed.
1414

1515
## Targeted Verification
1616

17+
- PASS - Object Vector Studio V2 assetLibrary entries use `object.*` IDs and do not carry duplicate `objectId` fields.
18+
- PASS - Duplicate runtime identity aliases fail Object Vector Studio V2 schema validation.
19+
- PASS - Asteroids runtime resolves the small asteroid through `object.asteroids.asteroid.small`.
20+
- PASS - Object Vector Studio V2 loads Asteroids objects through `object.*` IDs.
21+
- PASS - Active Asteroids Object Vector runtime rendering uses object IDs for ship, asteroid, and UFO paths.
1722
- PASS - Triangle Geometry hides Add Point and Delete Point controls.
18-
- PASS - Non-triangle polygon geometry keeps Add Point and Delete Point controls.
23+
- PASS - Non-triangle polygon geometry keeps Add Point and Delete Point behavior.
1924
- PASS - Frame controls render as Frame Earlier, Duplicate Frame, Frame Later.
20-
- PASS - Asteroids runtime renders ship, asteroid, and UFO Object Vector objects using object.asteroids.* IDs.
21-
- PASS - Asteroids small asteroid resolves through objectId object.asteroids.asteroid.small.
22-
- PASS - Object Vector Studio V2 still loads Asteroids objects from workspace.tools.object-vector-studio-v2.
23-
- PASS - game.gameData.objectVectorRuntime.objectIds contains only object.* runtime references.
2425
- PASS - No runtime console/page errors were reported by the targeted Playwright coverage.
2526

2627
## Commands
2728

29+
- PASS - `node --check src/engine/rendering/ObjectVectorRuntimeAssetService.js`
2830
- PASS - `node --check tools/object-vector-studio-v2/js/ToolStarterApp.js`
29-
- PASS - `node --check games/Asteroids/game/AsteroidsGameScene.js`
30-
- PASS - `node --check tools/shared/asteroidsPlatformDemo.js`
31+
- PASS - `node --check tools/object-vector-studio-v2/js/services/ObjectVectorStudioV2SchemaService.js`
3132
- PASS - `node --check tests/playwright/tools/WorkspaceManagerV2.spec.mjs`
32-
- PASS - `node -e "JSON.parse(...)"` for schema and Asteroids manifest.
33-
- PASS - WorkspaceManagerV2ContextService game manifest validation script.
34-
- PASS - ObjectVectorRuntimeAssetService objectId lookup script for object.asteroids.asteroid.small.
35-
- PASS - `npx playwright test tests/playwright/tools/WorkspaceManagerV2.spec.mjs --project=playwright --workers=1 --reporter=list -g "compacts Object Vector Studio V2 geometry layouts|supports Object Vector Studio V2 animation states|loads Object Vector Studio V2 runtime assets"`
33+
- PASS - Asteroids manifest schema and runtime object ID probe with `WorkspaceManagerV2ContextService` and `ObjectVectorRuntimeAssetService`.
34+
- PASS - `npx playwright test tests/playwright/tools/WorkspaceManagerV2.spec.mjs --project=playwright --workers=1 --reporter=list --grep "schema-only palette gate|geometry layouts|animation states|asset library inheritance|runtime assets into Asteroids|header lifecycle"`
3635
- PASS - `npm run test:workspace-v2`
37-
38-
## Notes
39-
40-
Asset IDs remain in Object Vector Studio V2 assetLibrary as editor/library asset entries. Runtime game selection now uses object IDs directly.

games/Asteroids/game.manifest.json

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -225,39 +225,33 @@
225225
"assetLibrary": {
226226
"assets": [
227227
{
228-
"id": "asset.asteroids.ship",
228+
"id": "object.asteroids.ship",
229229
"name": "Asteroids Ship",
230-
"objectId": "object.asteroids.ship",
231230
"tags": ["player", "ship"]
232231
},
233232
{
234-
"id": "asset.asteroids.asteroid.large",
233+
"id": "object.asteroids.asteroid.large",
235234
"name": "Large Asteroid",
236-
"objectId": "object.asteroids.asteroid.large",
237235
"tags": ["asteroid", "large"]
238236
},
239237
{
240-
"id": "asset.asteroids.asteroid.medium",
238+
"id": "object.asteroids.asteroid.medium",
241239
"name": "Medium Asteroid",
242-
"objectId": "object.asteroids.asteroid.medium",
243240
"tags": ["asteroid", "medium"]
244241
},
245242
{
246-
"id": "asset.asteroids.asteroid.small",
243+
"id": "object.asteroids.asteroid.small",
247244
"name": "Small Asteroid",
248-
"objectId": "object.asteroids.asteroid.small",
249245
"tags": ["asteroid", "small"]
250246
},
251247
{
252-
"id": "asset.asteroids.ufo.large",
248+
"id": "object.asteroids.ufo.large",
253249
"name": "Large UFO",
254-
"objectId": "object.asteroids.ufo.large",
255250
"tags": ["ufo", "large"]
256251
},
257252
{
258-
"id": "asset.asteroids.ufo.small",
253+
"id": "object.asteroids.ufo.small",
259254
"name": "Small UFO",
260-
"objectId": "object.asteroids.ufo.small",
261255
"tags": ["ufo", "small"]
262256
}
263257
]

src/engine/rendering/ObjectVectorRuntimeAssetService.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ export class ObjectVectorRuntimeAssetService {
298298
});
299299
(payload.assetLibrary?.assets || []).forEach((asset) => {
300300
assetsById.set(asset.id, asset);
301-
const usage = assetUsageByObjectId.get(asset.objectId) || [];
301+
const usage = assetUsageByObjectId.get(asset.id) || [];
302302
usage.push(asset.id);
303-
assetUsageByObjectId.set(asset.objectId, usage);
303+
assetUsageByObjectId.set(asset.id, usage);
304304
});
305305
return {
306306
assetUsageByObjectId,
@@ -331,8 +331,8 @@ export class ObjectVectorRuntimeAssetService {
331331
this.log("FAIL", `Object Vector runtime asset resolution failed: assetId=${assetId} is missing from the asset library.`);
332332
return null;
333333
}
334-
resolvedObjectId = asset.objectId;
335-
this.logCacheOnce(`asset:${assetSet.sourceLabel}:${assetId}`, `Object Vector runtime asset ${assetId} resolved to ${resolvedObjectId}.`);
334+
resolvedObjectId = asset.id;
335+
this.logCacheOnce(`asset:${assetSet.sourceLabel}:${assetId}`, `Object Vector runtime library id ${assetId} resolved to object ${resolvedObjectId}.`);
336336
}
337337

338338
let object = resolvedObjectId ? assetSet.objectsById.get(resolvedObjectId) : null;
@@ -657,6 +657,9 @@ export class ObjectVectorRuntimeAssetService {
657657
if (Object.prototype.hasOwnProperty.call(schema.$defs?.object?.properties || {}, "type")) {
658658
errors.push("Object Vector Studio V2 object schema must not define object type.");
659659
}
660+
if (Object.prototype.hasOwnProperty.call(schema.$defs?.libraryAsset?.properties || {}, "objectId")) {
661+
errors.push("Object Vector Studio V2 library asset schema must not define objectId.");
662+
}
660663
}
661664

662665
validatePayload(payload) {
@@ -737,8 +740,8 @@ export class ObjectVectorRuntimeAssetService {
737740
errors.push(`root.assetLibrary.assets[${assetIndex}].id ${asset.id} duplicates an existing library asset id.`);
738741
}
739742
assetIds.add(asset.id);
740-
if (!objectsById.has(asset.objectId)) {
741-
errors.push(`root.assetLibrary.assets[${assetIndex}].objectId ${asset.objectId} must reference an existing object.`);
743+
if (!objectsById.has(asset.id)) {
744+
errors.push(`root.assetLibrary.assets[${assetIndex}].id ${asset.id} must reference an existing object.`);
742745
}
743746
});
744747
}
@@ -920,7 +923,6 @@ export class ObjectVectorRuntimeAssetService {
920923
assets: normalized.assetLibrary.assets.map((asset) => ({
921924
id: asset.id.trim(),
922925
name: asset.name.trim(),
923-
objectId: asset.objectId.trim(),
924926
tags: asset.tags.map((tag) => tag.trim()).filter(Boolean)
925927
}))
926928
};

0 commit comments

Comments
 (0)