`insertNodeInTree` does not dedupe — it appends. So if the model emits a JSONL root whose id collides with a pre-existing live node, the doc ends up with two nodes sharing that id. `getNodeById(root.id)` returns the FIRST match (the pre-existing one), making the post-insert verify look successful even though the new node was appended elsewhere. A later rollback `removeNode(id)` then deletes the PRE-EXISTING node instead of the duplicate, corrupting the doc. Precheck: collect every id the JSONL tree introduces (roots and descendants). If ANY of them already exists in the live doc, refuse to insert and return `failed` immediately — doc state is preserved, no rollback needed, the orchestrator's retry path takes over. Once we know all ids are fresh, the existing post-insert verify and rollback paths are safe: every id we touch was provably absent before the dispatch, so `removeNode(id)` targets only what we just added. |
||
|---|---|---|
| .. | ||
| public | ||
| server | ||
| src | ||
| CLAUDE.md | ||
| components.json | ||
| dev.ts | ||
| package.json | ||
| tsconfig.json | ||
| vite.config.ts | ||