feat: tell users when a mutation's undo could not be recorded#77
Conversation
When an undoable mutation (archive/trash/spam/...) committed but writing its undo entry failed, the response's `mutation_id` came back `None` — indistinguishable from a mutation that simply isn't undoable. The undo affordance vanished silently. Add an `undo_unavailable` flag to `MutationResultData` (serialized only when true, so existing consumers are unaffected). The handler sets it on the undo-write failure path; the CLI prints a note that undo is unavailable, and the JSON contract carries the flag so agents can tell "undo failed" apart from "not undoable by design".
|
Warning Review limit reached
More reviews will be available in 9 minutes and 8 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
1 issue found across 8 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="crates/daemon/src/handler/mutations.rs">
<violation number="1" location="crates/daemon/src/handler/mutations.rs:549">
P1: `merge_mutation_result` does not propagate `undo_unavailable` from chunk to aggregate, so the flag is silently lost in the background job (`run_mutation_job`) path. A chunk that returns `undo_unavailable: true` will have that bit dropped, and the final `job.result` will always show `false` — defeating the feature for any multi-chunk or even single-chunk job.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| failed: 0, | ||
| accounts, | ||
| mutation_id: None, | ||
| undo_unavailable: false, |
There was a problem hiding this comment.
P1: merge_mutation_result does not propagate undo_unavailable from chunk to aggregate, so the flag is silently lost in the background job (run_mutation_job) path. A chunk that returns undo_unavailable: true will have that bit dropped, and the final job.result will always show false — defeating the feature for any multi-chunk or even single-chunk job.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/daemon/src/handler/mutations.rs, line 549:
<comment>`merge_mutation_result` does not propagate `undo_unavailable` from chunk to aggregate, so the flag is silently lost in the background job (`run_mutation_job`) path. A chunk that returns `undo_unavailable: true` will have that bit dropped, and the final `job.result` will always show `false` — defeating the feature for any multi-chunk or even single-chunk job.</comment>
<file context>
@@ -546,6 +546,7 @@ pub(super) async fn mutation(
failed: 0,
accounts,
mutation_id: None,
+ undo_unavailable: false,
},
});
</file context>
What
Surfaces "undo unavailable" when an undoable mutation succeeds but its undo entry can't be persisted. Audit backlog item P2 #19. Off
main.Why
On the undo-write failure path the handler returned
mutation_id: Noneand logged a warning — butNoneis also what non-undoable mutations (star, label, move) return. So a lost undo affordance looked identical to "no undo by design," and the user was never told.How
undo_unavailable: boolonMutationResultData,#[serde(default, skip_serializing_if = "std::ops::Not::not")]so it's omitted from the wire unless true — existing consumers are unaffected.trueonly when an undoable mutation succeeded butwrite_undo_entryfailed.Verification
false.mxr-protocol(33+1),mxrmutation/chimes (100),mxr-tui(3),mxr-web(54) tests pass; clippy + fmt clean across all four crates.guides/automation-contract.mddocuments how agents should read the flag.Note
openapi.json/ web TS types are generated artifacts and regenerate on the web build; the field is additive/optional, and the web UI doesn't consume it yet, so no generated files are committed here.Generated with Claude Code
Summary by cubic
Tell users when an undoable mutation succeeded but its undo entry couldn't be saved, so a lost undo is not mistaken for a non-undoable action. Addresses P2 #19.
undo_unavailable: booltoMutationResultData(omitted unless true).mutation_idremainsNone.undo_unavailableis true; JSON includes the flag for agents.Written for commit be880f5. Summary will update on new commits.