feat(1001): recover_half_written_items MCP tool

Adds db::recover, a discovery + recovery layer for pipeline items that
got half-written before the Stage 1 fix landed (content in content
store + SQLite shadow, no live CRDT entry). For each orphan, the
content body is re-anchored to a fresh non-tombstoned id and the old
id's content row is cleared.

Exposed as the recover_half_written_items MCP tool. dry_run defaults
to true so the caller can review what would change before mutating.

YAML front-matter parsing is hand-rolled and scoped to the three
fields the create_*_file path emits (name, type, depends_on). It
tolerates missing or malformed lines by falling back to safe
defaults; the orphan is recovered with the best metadata we can pull
from the body and the rest is left to the operator to fix up.

The discovery step is read-only and idempotent. Recovery is also
idempotent in the sense that once an orphan is lifted, the next
discovery pass won't see it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Timmy
2026-05-13 19:16:05 +01:00
parent c61f715878
commit cd411ba443
6 changed files with 452 additions and 1 deletions
+2
View File
@@ -93,6 +93,8 @@ pub async fn dispatch_tool_call(
"purge_story" => story_tools::tool_purge_story(&args, ctx),
// Debug CRDT dump (story 515)
"dump_crdt" => diagnostics::tool_dump_crdt(&args),
// Recover half-written pipeline items (bug 1001)
"recover_half_written_items" => diagnostics::tool_recover_half_written_items(&args),
// Read-only peer mesh diagnostics (story 720)
"mesh_status" => diagnostics::tool_mesh_status(&args),
// Arbitrary pipeline movement