uttrflow / uttrflow/uttrflow-swift

Deleting a dictation leaves its clipboard copy behind when a correction in it was undone first

Open
#652 0 comments 0 reactions 0 assignees View on GitHub
area:dictation bug P0 security
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

A finished dictation is saved twice: as a history record, and as a clipboard clip holding `outcome.text` (`Sources/Uttrflow/AppDelegate.swift:1164`, `recordAsClip(outcome.text)`).

Deleting the dictation is meant to remove both ("Both files, or the words are still one shortcut away in the panel", `AppDelegate.swift:1561-1570`). It looks up the record's *current* text, then deletes clips whose `origin == .uttrflow && text == spoken` (`forgetClips(saying:)`, `:1048-1058`).

Undoing a correction rewrites the record's text (`Sources/UttrflowHistory/CorrectionUndo.swift:16`, `undone.text = restoring(...)`), but not the clip. Once a correction has been undone, the record text and the clip text differ, the match fails, and the original transcript stays in `clipboard.v1.json` and in the panel until the clipboard's own retention removes it. The same happens if the clip text was edited in the panel (`ClipboardStore.setText`, `Sources/UttrflowClipboard/ClipboardStore.swift:154-160`), and forever if the clip was pinned.

## Why it matters

Deleting a dictation is how someone removes words they should not have kept. The words stay one ⇧⌘V away, and nothing says so.

## How to reproduce

1. Dictate a sentence where a dictionary correction fires.
2. On the Dictation page, undo that correction.
3. Delete the dictation.
4. Open the clipboard panel: the original sentence is still there.

## Acceptance criteria

- The clip made from a dictation carries the dictation's id (or the history record carries the clip's id), and deleting the dictation deletes by id rather than by text.
- A test covers delete-after-undo and delete-after-panel-edit.

Contributor guide

Open the contributing guide

Research direction

Start by tracing deletion in Sources/Uttrflow/AppDelegate.swift:1048-1058 and 1561-1570, then compare it with correction undo in Sources/UttrflowHistory/CorrectionUndo.swift:16 and edits in Sources/UttrflowClipboard/ClipboardStore.swift:154-160. Reproduce delete-after-undo and delete-after-panel-edit, then add tests showing that the associated clip is removed by identity even when its text differs or it is pinned.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.