Repository navigation
pm workspace snapshot restore silently discards divergent items and truncates history JSONL, with exit 0 and no removal report #812
Description
pm workspace snapshot restore (new in 2026.7.29) silently discards items created after the snapshot and truncates their history JSONL, exits 0, and reports only the files it wrote — never what it removed.
Reproduction (pm 2026.7.29)
git init -q probe && cd probe && pm init
pm create Task --title "First probe task" # -> pm-6hkz
pm workspace snapshot create baseline
# diverge: append history to the existing item, and add a second item
pm notes pm-6hkz --add "note added AFTER the baseline snapshot"
pm create Task --title "Task created AFTER baseline"
ls .agents/pm/tasks/ | wc -l # 2
wc -l < .agents/pm/history/pm-6hkz.jsonl # 2
pm workspace snapshot restore baseline --json; echo "exit=$?"Observed
ls .agents/pm/tasks/ # pm-6hkz.toon <- second item DELETED
wc -l < .agents/pm/history/pm-6hkz.jsonl # 1 <- history event DESTROYED
exit=0
The --json payload lists only the 7 files restored:
{
"schema": "https://schema.unbrained.dev/pm/workspace-snapshot/v1",
"fingerprint": "c8c67d14afb648c895177dc556409614aa357684ff307d80b437e5a17702b34c",
"files": ["history/pm-6hkz.jsonl", "schema/...", "settings.json", "tasks/pm-6hkz.toon"],
"bytes": 7682
}Nothing in the response distinguishes "restored, nothing lost" from "restored, discarded 1 item and 1 history event". pm workspace snapshot --help shows Options: -h, --help only — there is no --dry-run, no --force, no confirmation, and no summary of removals.
Why this matters for agents
Two properties of this command are load-bearing for the multi-agent workflows pm is designed around, and both are currently unmet:
-
The history JSONL is the audit trail. Snapshot create correctly captures
history/*.jsonl, so restore correctly rewinds it — but rewinding history is not the same as discarding it silently. After a restore, the record that a note was ever added is gone, with no marker and no report. For a workflow where several agents append to the same item across branches, an accidental restore is an undetectable audit-trail rollback. -
Exit 0 plus a write-only file list is unauditable. An agent that runs
restorecannot programmatically answer "did I just destroy work?" — the only way to know is to have snapshotted the pre-restore state first, which is exactly the thing the agent was usingrestoreto avoid needing. Every other destructive pm operation is gated (pm closeon a closed item needs--force; the merge surface reports conflicts); restore is not.
Suggested fix
Any one of these would close the gap; the first two are the valuable ones:
- Report removals in the payload — e.g.
"removed": ["tasks/pm-xxxx.toon"],"history_rewound": [{ "id": "pm-6hkz", "events_discarded": 1 }], and a"destructive": trueflag. This alone makes the operation auditable without changing behavior. - Require
--force(or an explicit--discard-divergent) when the working tracker has diverged from the snapshot, refusing with a non-zero exit and the divergence summary otherwise. That matches the existingpm close --forceprecedent. - Add
--dry-runso an agent can preview the removal set. - Optionally auto-create a pre-restore safety snapshot and name it in the output, so the rollback is recoverable.
Filed from a hands-on probe while adopting 2026.7.29 across an 18-package fleet; happy to test a patch.
Activity
coderabbitai commentedon Jul 29, 2026
🔗 Related PRs
#44 - feat(history): audited history-repair re-anchor command; clear legacy drift so pm health is ok [closed]
#549 - feat(sdk): ship history time travel, rich reads, and runtime integrity [merged]
#593 - SDK-first agent UX graph, ownership, and recovery contracts [merged]
#712 - SDK context integrity: atomic Plans, batch similarity, sparse settings, and tombstones [merged]
#783 - Harden SDK context integrity, merge safety, and agent-efficient output [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
unbraind commentedon Jul 29, 2026
Tracked and already delivered by pm-6l2mza. The guarded, audited, reversible restore shipped in PR #813 with dry-run preview, explicit force confirmation, exact impact reporting, recovery snapshots, and durable restore provenance. Closing as completed.