Previous "failed with non-empty insertedNodes" combination still bypassed retry. orchestrator-sub-agent.ts gates retry on `result.nodes.length === 0` — the partial inserts surfaced through DispatchResult.insertedNodes flowed through to the subtask's `nodes` field, made it look non-empty, and skipped the retry / minimal-skills / batch_design fallback chain. Hard-rollback partial inserts on JSONL fallback failure: call `store.removeNode(id)` for every root that did land, then return `failed` with `insertedNodes: []`. The dispatcher's surrounding history-batch wrapper absorbs both the addNode and removeNode calls so the user-visible undo entry is a net no-op, and the retry condition upstream now sees a genuinely empty result and re-runs the subtask cleanly. Three outcomes after this: - All roots land → `applied` with full insertedNodes. - Partial / total failure → `failed` with `insertedNodes: []` (any partial successes rolled back) so retry fires and the doc returns to its pre-dispatch state. |
||
|---|---|---|
| .. | ||
| cli | ||
| desktop | ||
| web | ||