|
| 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 |
0 commit comments