|
| 1 | +# BUILD_PR_LEVEL_11_179_WRITE_SVG_TILE_FROM_WORKSPACE_SHELL |
| 2 | + |
| 3 | +## Purpose |
| 4 | +Add the single correct writer for hosted SVG tile state. |
| 5 | + |
| 6 | +## Current State |
| 7 | +After PR 11.178: |
| 8 | +- legacy platformShell badge row is blocked/removed for hosted tools |
| 9 | +- assetUsageIntegration shared read/write path is disabled in hosted mode |
| 10 | +- shared handoff no longer owns SVG state |
| 11 | + |
| 12 | +That means the bad writers are gone. |
| 13 | + |
| 14 | +Now Workspace Manager must write the SVG tile label from `workspaceShell.js` state only. |
| 15 | + |
| 16 | +## Correct Data Flow |
| 17 | +```text |
| 18 | +SVG Asset Studio hosted iframe |
| 19 | + -> workspaceShell.js |
| 20 | + -> payloadJson.vectorAssetDocument |
| 21 | + -> normalized state |
| 22 | + -> postMessage tools:workspace-shell-state |
| 23 | + -> Workspace Manager |
| 24 | + -> SVG tile label/status |
| 25 | +``` |
| 26 | + |
| 27 | +## Scope |
| 28 | +One PR purpose only: |
| 29 | +- Create the correct hosted SVG workspace-shell write path. |
| 30 | + |
| 31 | +Do not modify schemas. |
| 32 | +Do not modify sample 1902 JSON. |
| 33 | +Do not restore shared handoff. |
| 34 | +Do not use assetUsageIntegration. |
| 35 | +Do not route hosted SVG through platformShell. |
| 36 | +Do not migrate all tools. |
| 37 | + |
| 38 | +## Implementation Requirements |
| 39 | + |
| 40 | +### 1. Ensure workspaceShell has a public init |
| 41 | +File: |
| 42 | +`tools/shared/workspaceShell.js` |
| 43 | + |
| 44 | +Export a clear initializer, for example: |
| 45 | +`initWorkspaceShell()` |
| 46 | + |
| 47 | +It must: |
| 48 | +- detect hosted mode from URL: |
| 49 | + - `hosted=1` |
| 50 | + - `hostToolId` |
| 51 | + - `hostContextId` |
| 52 | +- read hosted context using the existing host context utility |
| 53 | +- normalize state for `svg-asset-studio` |
| 54 | + |
| 55 | +SVG normalized state: |
| 56 | +- `toolId: "svg-asset-studio"` |
| 57 | +- `hostContextId` |
| 58 | +- `contractType: "vectorAssetDocument"` |
| 59 | +- `loaded: true` when `payloadJson.vectorAssetDocument.svgText` is non-empty |
| 60 | +- `assetLabel: vectorAssetDocument.sourceName || "Inline SVG"` |
| 61 | +- `statusLabel: "Loaded"` when loaded |
| 62 | +- `errors: []` |
| 63 | + |
| 64 | +If not loaded: |
| 65 | +- `loaded: false` |
| 66 | +- `assetLabel: ""` |
| 67 | +- `statusLabel` must be actionable |
| 68 | +- `errors` contains missing contract reason |
| 69 | + |
| 70 | +Required log: |
| 71 | +`[WORKSPACE_SHELL_STATE]` |
| 72 | + |
| 73 | +### 2. SVG hosted entry must call workspaceShell |
| 74 | +File: |
| 75 | +`tools/SVG Asset Studio/main.js` |
| 76 | + |
| 77 | +In hosted SVG mode: |
| 78 | +- log `[SVG_HOSTED_WORKSPACE_ENTRY]` |
| 79 | +- call `initWorkspaceShell()` |
| 80 | +- do not use platformShell or assetUsageIntegration for hosted SVG tile labels |
| 81 | + |
| 82 | +### 3. workspaceShell sends parent message |
| 83 | +When normalized state is created, post to parent: |
| 84 | + |
| 85 | +Message: |
| 86 | +```js |
| 87 | +{ |
| 88 | + type: "tools:workspace-shell-state", |
| 89 | + payload: state |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +Required log before send: |
| 94 | +`[SVG_POSTMESSAGE_SEND]` |
| 95 | + |
| 96 | +### 4. Workspace Manager receives and writes tile |
| 97 | +File: |
| 98 | +`tools/Workspace Manager/main.js` |
| 99 | + |
| 100 | +Listen for message type: |
| 101 | +`tools:workspace-shell-state` |
| 102 | + |
| 103 | +When payload is for: |
| 104 | +`toolId === "svg-asset-studio"` |
| 105 | + |
| 106 | +Match by `hostContextId` if the mounted tile tracks it. If no existing hostContextId mapping is available, Codex must add the smallest mapping when launching/mounting the tool. |
| 107 | + |
| 108 | +On loaded state: |
| 109 | +- set SVG tile asset label to `assetLabel` |
| 110 | +- set SVG tile status to `statusLabel` |
| 111 | +- mark tile loaded/active if existing model supports it |
| 112 | +- log `[SVG_POSTMESSAGE_RECEIVE]` |
| 113 | +- log `[SVG_TILE_WRITE]` |
| 114 | + |
| 115 | +On error state: |
| 116 | +- show actionable status from `statusLabel` |
| 117 | +- do not show `Asset: none` |
| 118 | + |
| 119 | +### 5. No legacy fallback |
| 120 | +Do not fallback to: |
| 121 | +- shared asset handoff |
| 122 | +- shared palette handoff |
| 123 | +- platformShell badge value |
| 124 | +- guessed sample names |
| 125 | +- palette-first ordering |
| 126 | + |
| 127 | +## Acceptance |
| 128 | +Manual UAT on sample 1902: |
| 129 | + |
| 130 | +Expected console: |
| 131 | +- `[SVG_HOSTED_WORKSPACE_ENTRY]` |
| 132 | +- `[WORKSPACE_SHELL_STATE]` |
| 133 | +- `[SVG_POSTMESSAGE_SEND]` |
| 134 | +- `[SVG_POSTMESSAGE_RECEIVE]` |
| 135 | +- `[SVG_TILE_WRITE]` |
| 136 | + |
| 137 | +Expected UI: |
| 138 | +- SVG tile shows `Asset: sample-0901-ship.svg` or actual `sourceName` |
| 139 | +- SVG does not show `Asset: none` |
| 140 | +- legacy platformShell badge row remains removed/blocked |
| 141 | +- Vector Map Editor still works |
| 142 | + |
| 143 | +Expected no logs: |
| 144 | +- no hosted SVG `renderToolAssetBadge -> none` |
| 145 | +- no hosted SVG shared asset handoff read/write |
| 146 | +- no hosted SVG palette-first dependency |
| 147 | + |
| 148 | +## Validation |
| 149 | +Run: |
| 150 | +- `node --check tools/shared/workspaceShell.js` |
| 151 | +- `node --check "tools/SVG Asset Studio/main.js"` |
| 152 | +- `node --check "tools/Workspace Manager/main.js"` |
| 153 | +- `node --check tools/shared/platformShell.js` |
| 154 | +- `node --check tools/shared/assetUsageIntegration.js` |
| 155 | + |
| 156 | +Full samples smoke: |
| 157 | +- Skip. |
| 158 | +- Reason: targeted hosted SVG tile write path; full samples smoke takes about 20 minutes and is not required. |
| 159 | + |
| 160 | +## Report |
| 161 | +Create: |
| 162 | +`docs/dev/reports/pr_11_179_validation.md` |
| 163 | + |
| 164 | +Include: |
| 165 | +- files changed |
| 166 | +- console evidence |
| 167 | +- tile label result |
| 168 | +- targeted validation result |
| 169 | +- full samples smoke skipped reason |
0 commit comments