feat(history): undo a file an agent run created (BEA-35) (#82)

History could restore an edit or a deletion, but a file a run CREATED was
the one thing it couldn't reverse — the ADDED row said so in copy and
offered no button. The missing capability was a hub-written delete op:
restore.go only ever journaled puts.

POST /api/p/<id>/remove journals exactly one journal.KindDelete op under
the hub's own device identity, behind restore's gates (gateUpload,
PermWrite, cleanUploadPath, quota CheckWrite/RecordUsage) plus a volume-
snapshot existence check so the API 404s on what the tree doesn't show.
Commit's journal-append tail moves into RemoteSource.appendOp, which both
writes now share — one writer per journal, unchanged.

The ADDED-in-a-run row gets an "undo — remove file" control that confirms
first (it reaches every synced device), and the DELETED row it leaves
behind restores the file with its original bytes.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Snow Lee (Sungwon)
2026-07-31 07:11:20 +09:00
committed by GitHub
co-authored by Claude Opus 5
parent 31472c56e7
commit 4dfe6f44f0
20 changed files with 620 additions and 163 deletions
+5 -3
View File
@@ -89,9 +89,11 @@ versions in between stay in the history, the restore itself shows up in
teammate like any other edit — so you can restore away from a restore. The hub
has the same button on every history row.
**Known gap:** restore puts content back; it cannot yet remove a file, so a
file that a run *created* cannot be un-created. Delete it yourself and let the
next sync carry that.
**Restore puts content back; it does not delete.** To un-create a file an agent
run *created*, open that run in the hub's History view and use the row's
**undo — remove file** button (it asks first: the file leaves every synced
device, and the DELETED row it leaves behind restores it). From the CLI, delete
the file yourself and let the next sync carry that.
### `bdrive forget` and `bdrive sync --prune` — cleaning up the hub