uttrflow / uttrflow/uttrflow-swift
No test covers starting a dictation with microphone access denied, and no code on that path checks the permission
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
Onboarding asks for microphone access and shows `PermissionError.microphoneDenied` when it is refused (`Sources/UttrflowUX/OnboardingPresenter.swift:270, 394`). After onboarding, nothing on the dictation path reads the permission: `DictationPipeline.startRecording` (`Sources/UttrflowPipeline/DictationPipeline.swift:181-211`) calls `capture.start()` and maps whatever it throws, and no code in `Sources/UttrflowAudio`, `Sources/UttrflowPipeline` or `AppDelegate` throws `microphoneDenied`. The pipeline tests start with `FakeAudioCaptureEngine(startOutcome: .failure(.noInputDevice))` (`Tests/UttrflowPipelineTests/DictationPipelineStateTests.swift:290`) but never with a permission failure.
What actually happens if the user revokes microphone access in System Settings after onboarding is unverified: `AVAudioEngine` may throw, or may start and deliver silence, which would look like a dictation that heard nothing.
## Why it matters
Revoking access by accident, or after a macOS update resets privacy settings, is common. The right outcome is a failure that says what is wrong and offers to open the Microphone pane (`PermissionError.microphoneDenied.recovery` already does), not a silent empty dictation.
## How to check
On a Mac: revoke microphone access for Uttrflow in System Settings → Privacy & Security → Microphone, then dictate. Note what the menu bar, the floating button and History show, and what `log stream --predicate 'subsystem == "com.uttrflow.Uttrflow"'` prints.
## Acceptance criteria
- The real behaviour with access revoked is recorded on this issue (macOS version included).
- If it is not already a clear failure, the capture engine or the pipeline checks the permission before opening the microphone and fails with `PermissionError.microphoneDenied`.
- A pipeline test starts a dictation with that failure and checks the resulting state and its recovery action.
`help wanted`: needs a Mac where microphone access can be revoked and restored.
Contributor guide
Research direction
Reproduce the revoked-microphone case on a Mac, recording the macOS version, menu bar, floating button, History, and relevant log output. Then read Sources/UttrflowPipeline/DictationPipeline.swift around startRecording and Tests/UttrflowPipelineTests/DictationPipelineStateTests.swift, comparing the existing no-input test with a permission failure. Done means the behavior is documented and, if needed, the pipeline reaches microphoneDenied with its recovery action covered by a test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, swift
- Domain
- desktop, security, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100