Skip to content

fix(capture): Undo, marks and Copied only claim what really happened - #1669

Merged
kitlangton merged 5 commits into
devfrom
annotate-audit-fixes
Nov 13, 2026
Merged

kitlangton merged 5 commits into
devfrom
annotate-audit-fixes

Conversation

@kitlangton

@kitlangton kitlangton commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

Captures no longer claim things that didn't happen: Undo can't outlive a rule's send, a shot's marks are never silently dropped, and "Copied" appears only once the clipboard has it.
Three small honesty fixes in the capture capsule and the screenshot editor. Routing, recording and transcription are unchanged.

❌ Before

  1. A capture matched a saved rule. The Undo ring counted 5 s, but the send went out after 3 s ❌, so the last 2 s of Undo did nothing.
  2. If a screenshot's marks couldn't be drawn, the editor copied, saved or sent the plain screenshot ❌ and said it had worked.
  3. Cards said "Copied" before the clipboard write ran ❌, and the capsule said "Copied" even when the write failed ❌. It also never said what was copied: the capsule copies a text summary, not the movie.

✅ After

  1. The Undo ring and the send share one 3 s window. Undo disappears as soon as the send starts.
  2. A failed mark render exports nothing. The editor shows "Couldn't draw your marks" in red with a Retry button until the next export.
  3. Cards say "Copied" (a shot) or "Movie copied" (a recording) after the write succeeds, or "Couldn't copy". The capsule says "Summary copied", or "Couldn't copy" with a warning. Paste still works from there, because it copies again.
- ring = undo_s() (5 s)             ; send after SEND_HOLD (3 s)
+ ring = SEND_HOLD, counted from when the rule's answer arrives; Undo hides on Sending
- png() -> marks failed? -> plain image
+ png() -> marks failed? -> MarksNotDrawn -> red note + Retry, nothing exported
- note("Copied"); copy(file)        ; capsule: copy() then "Copied" regardless
+ copy(file) -> Ok ? "Copied"/"Movie copied" : "Couldn't copy"; capsule: "Summary copied" | "Couldn't copy"

📊 Proof

Case Before After
Undo pressed 4 s after a rule matched ❌ send already gone ✅ Undo already hidden at 3 s
Rule's answer arrives late ❌ hold counted from the write ✅ hold counted from the answer
Marks can't be drawn ❌ plain image exported ✅ nothing exported, error + Retry
Clipboard write fails ❌ "Copied" ✅ "Couldn't copy"

Rule send, before and after (the ring now drains over 3 s):

rule before rule after

Editor when marks can't be drawn (new state):

editor failed

Capsule after a capture: before, after, and a failed copy:

saved before saved after copy failed

New tests: a late rule answer holds its send from the answer, a shot whose marks can't be drawn isn't exported, a failed export stays until retried, and a failed copy never reads as copied (flow and feed). They weren't run against the old code.

👀 Read: routing/preparation.rs, where the send's deadline is set when a rule's answer arrives. It used to be set at write time, so a slow answer ate into Undo. One known harmless race: an Undo pressed in the single frame between the post and the capsule seeing it becomes a withdraw. A guess's post-send withdraw keeps its own 5 s window on purpose. The rest is routine.

🔍 Found in a UX audit of captures · no user reports · goldens: capsule ones regenerated on a Mac, the new editor one from the Linux check

Checks run
  • scripts/check capture_capsule routing (bug 1): 314 passed

  • cargo nextest run capture_capsule screenshot_thumbnail capture_host i18n: 282 passed (plus one ignored routing benchmark that timed out, not part of this change)

  • cargo clippy --all-targets -D warnings: clean

  • Check Linux (full suite, goldens from its golden-actual): test job passed. Its nix job fails only on onboarding_kit::stories::motion_gate::the_first_run_moves_cleanly, which fails the same way on other branches (scrub-fixtures), so this change didn't cause it

Export::png() refused to fall back silently: when the marks couldn't be
drawn it now fails with MarksNotDrawn, and the editor keeps its error
note in danger ink beside a Retry button until the next export. Nothing
is copied, saved or sent.
Screenshot cards show their note after the clipboard write returns:
"Copied" for a shot, "Movie copied" for a recording, or "Couldn't
copy". The capsule's finished capture reads "Summary copied", since its
clipboard carries the summary, and "Couldn't copy" with a warning when
the write failed (SettledCapture.copy_error).
@kitlangton
kitlangton merged commit 8b15f56 into dev Nov 13, 2026
4 checks passed
@kitlangton
kitlangton deleted the annotate-audit-fixes branch November 13, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant