uttrflow / uttrflow/uttrflow-swift
Recordings are deleted after a day only while the main window is open, so the "kept for a day only" promise lapses for menu-bar-only use
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
Settings and onboarding promise: "Audio is deleted the moment it becomes text, and kept on this Mac for a day only if it couldn’t be, so you can retry" (`Sources/UttrflowUX/SettingsPresenter.swift:579-581`). `Docs/recordings.md:41` and `:67` say the same.
The 24-hour limit is enforced in only one place, `RecordingStore.waiting(now:)` (`Sources/UttrflowAudio/RecordingStore.swift:88-113`). That method discards files older than `retention` while it lists them (`:104-106`). Its only caller is `refreshMainWindow()` (`Sources/Uttrflow/AppDelegate.swift:1372`), which begins with `guard mainWindow != nil else { return }` (`:1361`). Nothing prunes at launch, on a timer, or after a dictation.
Transcript retention works the same way: expired records are dropped only when the history is read or appended to (`Sources/UttrflowHistory/DictationHistoryStore.swift:38-42`, `:56-62`). Someone who sets a short retention and then stops dictating keeps the old transcripts on disk indefinitely. (#613 covers retention measured against a wrong clock, which is a separate problem.)
## Why it matters
Uttrflow is a menu-bar app. Many people dictate for weeks without opening the main window, and a failed dictation's WAV (their voice, up to the recording cap) then stays on disk for as long as that lasts. That contradicts a promise written on the screen. The same applies to transcripts under the retention setting.
## How to reproduce
1. Close the main window. Make a dictation fail after recording so the audio is kept.
2. Set the file's creation date back two days (`SetFile -d` or `touch -t`), relaunch, and use only the menu bar and shortcut.
3. `ls ~/Library/Application\ Support/Uttrflow/recordings/`: the file is still there. Opening the main window deletes it.
## Acceptance criteria
- Recordings past retention are removed at launch and periodically, or after each dictation, whether or not a window exists. The same goes for transcripts past the retention setting.
- The sweep does not add a steady timer that breaks the energy budget (`Docs/performance.md`). Launch plus "after each dictation" is enough.
- An app-target or `Tests/UttrflowAudioTests` test shows that an old recording is removed without `waiting(now:)` being called from a window.
Contributor guide
Research direction
Start with Sources/UttrflowAudio/RecordingStore.swift, Sources/UttrflowHistory/DictationHistoryStore.swift, and the launch and dictation paths in Sources/Uttrflow/AppDelegate.swift; trace where waiting(now:) and transcript cleanup are currently triggered. Run the existing Tests/UttrflowAudioTests or app-target tests, then verify that old recordings and transcripts are removed without opening the main window and without a steady timer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100