docs(mcp): add 10-agent research on scene-save workflow
10 parallel research agents (R1-R10) investigated whether MCP can save scenes as saveable entities that the user later opens in the editor — rather than injecting via a dev-only window.__pascalScene hook. Key findings: - Editor is already backend-agnostic via onLoad/onSave callbacks (R2,R7) - Current persistence is localStorage-only, single key (R1) - Zero dynamic routes and no backend code yet — env declared (R4,R5) - File import exists as "Load Build" but lacks Zod validation (R6) - MCP-written scenes load cleanly into the editor today (R6, Casa del Sol test already proved this) - Best path: filesystem-handoff this week, Supabase in weeks 2-4, Supabase Realtime for live mode in Q2. Skip Yjs for now. (R8) - 4-5 weeks to private beta, 10-14 to GA (R9) - 10 high-value ideas ranked; "photo -> scene" is the unblocker (R10) SYNTHESIS.md pulls all 10 reports together with the recommended implementation plan. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
bdb47a6e5d
commit
42bd05db9c
@@ -0,0 +1,55 @@
|
||||
# R6 — File I/O pathways
|
||||
|
||||
## TL;DR
|
||||
- Export: 2 JSON pathways + 3 binary (GLB/STL/OBJ) pathways.
|
||||
- Import: 1 JSON pathway ("Load Build"), **no Zod validation** at boundary.
|
||||
- No drag-drop, no clipboard-paste JSON import.
|
||||
- Round-trip export → re-import works; MCP-written JSON loads cleanly IF structure matches.
|
||||
|
||||
## Exports
|
||||
|
||||
| Trigger | Handler | File | Output |
|
||||
|---|---|---|---|
|
||||
| Settings → "Save Build" | `handleSaveBuild` | `settings-panel/index.tsx:205–216` | `layout_YYYY-MM-DD.json` |
|
||||
| Cmd palette → "Export Scene (JSON)" | `editor.export.json` | `command-palette/editor-commands.tsx:329–346` | `scene_YYYY-MM-DD.json` |
|
||||
| Settings/palette → "Export GLB/STL/OBJ" | `export-manager.tsx` | `editor/export-manager.tsx:71–78` | binary 3D geometry |
|
||||
|
||||
Both JSON paths serialise `{ nodes: useScene.getState().nodes, rootNodeIds: useScene.getState().rootNodeIds }`. No metadata (no name, no created_at, no projectId).
|
||||
|
||||
## Import
|
||||
|
||||
### "Load Build"
|
||||
- `settings-panel/index.tsx:218–239`
|
||||
- Accept: `application/json`
|
||||
- Handler: `JSON.parse` → check `data.nodes && data.rootNodeIds` → call `useScene.setScene(nodes, rootNodeIds)`
|
||||
- **No Zod validation.** Confirmed the security-audit flag from Phase 3.
|
||||
|
||||
### `setScene` behaviour (`core/store/use-scene.ts:242–271`)
|
||||
1. `migrateNodes()` — runs a few backward-compat patches. Stair nodes are zod-safeParsed and SILENTLY DROPPED on failure; other types are unvalidated.
|
||||
2. Orphan pruning — deletes any node whose `parentId` isn't present in the dict.
|
||||
3. `setState` with cleaned nodes + `dirtyNodes: new Set()`.
|
||||
4. Marks every node dirty to trigger re-render.
|
||||
|
||||
**Critical gap:** Invalid `type` strings silently load. Systems will later fail to find a renderer for them and the node will be invisible but consume state.
|
||||
|
||||
## Round-trip fidelity
|
||||
|
||||
| Scenario | Loads clean? |
|
||||
|---|---|
|
||||
| Export → re-import | ✅ |
|
||||
| MCP writes well-formed `{ nodes, rootNodeIds }` | ✅ (confirmed: Casa del Sol scene.json loads into the editor) |
|
||||
| MCP writes bad `node.type` | ⚠️ Silent load, invisible node |
|
||||
| MCP writes broken parentId chain | ⚠️ Orphans silently deleted |
|
||||
| MCP writes missing `children: []` on container | ⚠️ Core treats as `undefined` → system ignores |
|
||||
|
||||
## Missing / nice-to-have
|
||||
|
||||
- Drag-drop JSON onto viewport
|
||||
- URL-param load: `?load=<publicJsonUrl>`
|
||||
- Clipboard paste of JSON blob
|
||||
- `importFromFile` with Zod validation at the boundary
|
||||
- File-format version field (`formatVersion: "1"`) for forward-compat
|
||||
|
||||
## Recommendation
|
||||
|
||||
Every "save to cloud" implementation MUST Zod-validate at the boundary with `AnyNode.safeParse` per node + structural checks on `rootNodeIds`. The tool in MCP (`validate_scene`) already does this — run it before any save.
|
||||
Reference in New Issue
Block a user