Skip to content

Commit b58f893

Browse files
author
DavidQ
committed
Add expected contract fields to tool-load diagnostics - PR 10.6H
1 parent be5872d commit b58f893

7 files changed

Lines changed: 624 additions & 16 deletions

docs/dev/codex_commands.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
# Codex Commands
1+
# Codex Commands - BUILD_PR_LEVEL_10_6H_TOOL_LOAD_EXPECTED_DIAGNOSTICS
22

3-
## Model
4-
GPT-5.4
3+
Model: GPT-5.4
4+
Reasoning: high
55

6-
## Reasoning
7-
high
8-
9-
## Command
106
```powershell
11-
codex --model gpt-5.4 --reasoning high "Execute BUILD_PR_LEVEL_10_6G_TOOL_INPUT_FETCH_LOAD_DIAGNOSTICS exactly. Add temporary structured diagnostics for tool request/fetch/load boundaries across active sample-loaded tools. Do not change contracts, do not add fallbacks, do not hardcode paths, and do not normalize palette data in this PR. Run npm run test:launch-smoke:games and npm run test:sample-standalone:data-flow. Create the report at docs/dev/reports/level_10_6G_tool_input_fetch_load_diagnostics_report.md. Update only roadmap status markers if execution-backed. Return a repo-structured ZIP at tmp/BUILD_PR_LEVEL_10_6G_TOOL_INPUT_FETCH_LOAD_DIAGNOSTICS.zip."
7+
codex --model gpt-5.4 --reasoning high "Run BUILD_PR_LEVEL_10_6H_TOOL_LOAD_EXPECTED_DIAGNOSTICS. Read docs/pr/BUILD_PR_LEVEL_10_6H_TOOL_LOAD_EXPECTED_DIAGNOSTICS.md. Extend the existing tool-load diagnostics to include explicit expected contract details at request, fetch, loaded, warning, and error boundaries. Keep the change diagnostic-only, no fallback data, no hardcoded paths, no schema rewrites. Run npm run test:launch-smoke:games and npm run test:sample-standalone:data-flow. Write docs/dev/reports/level_10_6H_tool_load_expected_diagnostics_report.md. Package the changed repo-relative files into tmp/BUILD_PR_LEVEL_10_6H_TOOL_LOAD_EXPECTED_DIAGNOSTICS.zip."
128
```

docs/dev/commit_comment.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add tool request/fetch/load diagnostics for sample data-flow debugging - PR 10.6G
1+
Add expected contract fields to tool-load diagnostics - PR 10.6H

docs/dev/reports/launch_smoke_report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Launch Smoke Report
22

3-
Generated: 2026-04-27T17:57:47.633Z
3+
Generated: 2026-04-27T18:15:42.698Z
44

55
Filters: games=true, samples=false, tools=false, sampleRange=all
66

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Level 10.6H Tool Load Expected Diagnostics Report
2+
3+
## Files changed
4+
5+
- `tools/shared/toolLoadDiagnostics.js`
6+
- `tools/Sprite Editor/modules/spriteEditorApp.js`
7+
- `docs/dev/reports/level_10_6H_tool_load_expected_diagnostics_report.md`
8+
- `docs/dev/reports/launch_smoke_report.md` (test-generated output update)
9+
10+
## Scope outcome
11+
12+
- Extended the shared diagnostics layer from 10.6G to auto-attach `expected` diagnostics across:
13+
- request
14+
- fetch (attempt + response)
15+
- loaded
16+
- warning
17+
- error (`[tool-load:error]`, emitted when warning payload includes `error`)
18+
- Kept change diagnostic-only:
19+
- no fallback data added
20+
- no hardcoded sample paths added
21+
- no schema rewrites
22+
- no sample contract normalization changes
23+
24+
## Sprite-editor 0219 log example (before -> after)
25+
26+
Before (10.6G style warning example):
27+
28+
```js
29+
{
30+
toolId: "sprite-editor",
31+
sampleId: "0219",
32+
samplePresetPath: "/samples/phase-02/0219/sample.0219.sprite-editor.json",
33+
error: "Preset payload did not include a sprite project."
34+
}
35+
```
36+
37+
After (10.6H warning boundary with expected contract):
38+
39+
```js
40+
{
41+
toolId: "sprite-editor",
42+
sampleId: "0219",
43+
samplePresetPath: "/samples/phase-02/0219/sample.0219.sprite-editor.json",
44+
error: "Preset payload did not include a sprite project.",
45+
receivedTopLevelKeys: ["$schema", "tool", "version", "config"],
46+
expected: {
47+
requiredPayloadShape: ["spriteProject"],
48+
receivedTopLevelKeys: ["$schema", "tool", "version", "config"],
49+
missingRequiredFields: ["spriteProject"],
50+
likelyCause: "wrong path or wrong wrapper"
51+
}
52+
}
53+
```
54+
55+
Loaded boundary for same launch now includes:
56+
57+
```js
58+
expected: {
59+
requiredPayloadShape: ["spriteProject"],
60+
detectedPayloadShape: ["$schema", "tool", "version", "config"],
61+
missingRequiredFields: ["spriteProject"],
62+
contractMatch: false
63+
}
64+
```
65+
66+
## Expected contract behavior for missing `spriteProject`
67+
68+
- Confirmed: `expected.contractMatch` is `false` for the current missing `spriteProject` case (sample `0219` sprite-editor launch).
69+
- Warning/error boundaries now include:
70+
- `requiredPayloadShape`
71+
- `receivedTopLevelKeys`
72+
- `missingRequiredFields`
73+
- `likelyCause`
74+
75+
## Palette expected diagnostics behavior
76+
77+
- Shared diagnostics now classify canonical palette expectations and wrapper mismatch indicators via `expected`:
78+
- canonical schema expected: `html-js-gaming.palette`
79+
- canonical required fields: `schema`, `version`, `name`, `swatches`
80+
- non-canonical wrapper indicators: `tool`, `config.palette`
81+
- Fetch/loaded boundaries include palette-oriented expected metadata so wrapper vs canonical mismatches are explicit in logs.
82+
83+
## Validation command results
84+
85+
1. `npm run test:launch-smoke:games`
86+
- Result: PASS
87+
- Summary: `PASS=12`, `FAIL=0`, `TOTAL=12`
88+
89+
2. `npm run test:sample-standalone:data-flow`
90+
- Result: PASS
91+
- Key checks:
92+
- `schemaFailures: []`
93+
- `contractFailures: []`
94+
- `roundtripPathFailures: []`
95+
- `genericFailures: []`
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# BUILD_PR_LEVEL_10_6H_TOOL_LOAD_EXPECTED_DIAGNOSTICS
2+
3+
## Purpose
4+
Add explicit `expected` contract diagnostics to the existing tool-load logging so each tool log shows what the launcher/tool expected to receive, fetch, and load.
5+
6+
## Scope
7+
- Extend the existing diagnostics added in Level 10.6G only.
8+
- Apply to every tool using the shared tool-load diagnostics helper.
9+
- Do not change sample contracts, palette schema, or runtime data normalization in this PR.
10+
- Do not add fallback data.
11+
- Do not hardcode sample asset paths.
12+
- Do not modify `start_of_day` folders.
13+
14+
## Problem
15+
Current logs show:
16+
- request
17+
- fetch attempt/response
18+
- loaded payload
19+
- warnings
20+
21+
But they do not show the expected shape/path/source, so failures still require guessing whether the launcher requested the wrong file, the tool fetched the wrong file, or the fetched payload lacked the tool-required contract.
22+
23+
Example current warning:
24+
25+
```text
26+
[tool-load:warning] Preset payload did not include a sprite project.
27+
```
28+
29+
The log needs to include the expected contract at the same boundary.
30+
31+
## Required Change
32+
Update the shared diagnostics utility and each calling tool so logs include an `expected` object where applicable.
33+
34+
### Required log shape
35+
36+
#### request
37+
```js
38+
{
39+
toolId,
40+
sampleId,
41+
samplePresetPath,
42+
requestedDataPaths,
43+
launchQuery,
44+
expected: {
45+
inputSource: "query.samplePresetPath | query.dataPath | manifest tool input | none",
46+
requiredPaths: [],
47+
requiredPayloadShape: [],
48+
optionalPayloadShape: []
49+
}
50+
}
51+
```
52+
53+
#### fetch attempt / response
54+
```js
55+
{
56+
toolId,
57+
phase,
58+
fetchUrl,
59+
requestedPath,
60+
pathSource,
61+
expected: {
62+
pathKind: "sample preset | palette | manifest | asset | unknown",
63+
mustExist: true,
64+
contentType: "json | text | image | unknown",
65+
payloadContract: []
66+
}
67+
}
68+
```
69+
70+
#### loaded
71+
```js
72+
{
73+
toolId,
74+
sampleId,
75+
samplePresetPath,
76+
fetchUrl,
77+
loaded,
78+
expected: {
79+
requiredPayloadShape: [],
80+
detectedPayloadShape: [],
81+
missingRequiredFields: [],
82+
contractMatch: true | false
83+
}
84+
}
85+
```
86+
87+
#### warning/error
88+
```js
89+
{
90+
toolId,
91+
sampleId,
92+
samplePresetPath,
93+
error,
94+
expected: {
95+
requiredPayloadShape: [],
96+
receivedTopLevelKeys: [],
97+
likelyCause: "wrong path | wrong wrapper | missing field | invalid json | unknown"
98+
}
99+
}
100+
```
101+
102+
## Sprite Editor Mandatory Expected Contract
103+
For sprite-editor preset loading, expected diagnostics must explicitly show:
104+
105+
```js
106+
expected: {
107+
pathKind: "sample preset",
108+
contentType: "json",
109+
requiredPayloadShape: ["spriteProject"],
110+
optionalPayloadShape: ["palette", "metadata", "sprites"],
111+
contractMatch: false when `spriteProject` is missing
112+
}
113+
```
114+
115+
If the loaded payload top-level keys do not include `spriteProject`, the warning must include:
116+
117+
```js
118+
receivedTopLevelKeys: Object.keys(payload)
119+
missingRequiredFields: ["spriteProject"]
120+
likelyCause: "wrong path or wrong wrapper"
121+
```
122+
123+
## Palette Expected Contract
124+
For palette-capable tools, expected diagnostics must distinguish:
125+
126+
- canonical palette file expected:
127+
- schema: `html-js-gaming.palette`
128+
- required fields: `schema`, `version`, `name`, `swatches`
129+
- tool wrapper not expected as canonical palette:
130+
- `tool`
131+
- `config.palette`
132+
133+
The diagnostic should make it obvious when a tool fetched a `*.palette-browser.json` wrapper instead of a `*.palette.json` canonical palette.
134+
135+
## Acceptance Criteria
136+
- Browser console logs include `expected` for request, fetch, loaded, warning, and error diagnostics where relevant.
137+
- Sprite editor warning includes expected required payload shape and received top-level keys.
138+
- Palette diagnostics identify canonical palette versus tool wrapper.
139+
- Existing launch smoke tests still pass.
140+
- Existing sample standalone data-flow test still runs.
141+
- No silent fallback data is added.
142+
- No hardcoded asset paths are added.
143+
144+
## Validation Commands
145+
```powershell
146+
npm run test:launch-smoke:games
147+
npm run test:sample-standalone:data-flow
148+
```
149+
150+
## Report Required
151+
Codex must write:
152+
153+
```text
154+
docs/dev/reports/level_10_6H_tool_load_expected_diagnostics_report.md
155+
```
156+
157+
Include:
158+
- files changed
159+
- before/after example log object for sprite-editor sample 0219
160+
- whether `expected.contractMatch` is false for the current missing `spriteProject` case
161+
- validation command results

tools/Sprite Editor/modules/spriteEditorApp.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,7 @@ async function tryLoadPresetFromQuery(state) {
15831583
samplePresetPath
15841584
});
15851585
renderHud(state);
1586+
let receivedTopLevelKeys = [];
15861587
try {
15871588
const presetUrl = new URL(samplePresetPath, window.location.href);
15881589
const presetHref = presetUrl.toString();
@@ -1607,6 +1608,9 @@ async function tryLoadPresetFromQuery(state) {
16071608
throw new Error(`Preset request failed (${response.status}).`);
16081609
}
16091610
const rawPreset = await response.json();
1611+
receivedTopLevelKeys = rawPreset && typeof rawPreset === "object" && !Array.isArray(rawPreset)
1612+
? Object.keys(rawPreset)
1613+
: [];
16101614
logToolLoadLoaded({
16111615
toolId: "sprite-editor",
16121616
sampleId,
@@ -1621,7 +1625,8 @@ async function tryLoadPresetFromQuery(state) {
16211625
toolId: "sprite-editor",
16221626
sampleId,
16231627
samplePresetPath,
1624-
error: error instanceof Error ? error.message : "unknown error"
1628+
error: error instanceof Error ? error.message : "unknown error",
1629+
receivedTopLevelKeys
16251630
});
16261631
setSampleSource(state, {
16271632
mode: "sample",

0 commit comments

Comments
 (0)