Fix dead record button after mic permission denial

The watch app's permission-denied state was a computed property reading
AVAudioApplication.shared.recordPermission — external state Observation
cannot track — so after a denied prompt the UI never flipped to the
'Microphone access is off' screen and the record button silently did
nothing. Store the denied flag as a tracked property instead, updated
on every permission request.

Also: log (instead of swallow) recorder start failures, drop phantom
recordings when no file was written (the watch simulator has no audio
input device), sweep orphaned metadata sidecars on reconcile, and add a
DEBUG-only 'autorecord' launch argument for CLI-driven testing.

Claude-Session: https://claude.ai/code/session_01GKfAiKiQKLDTmbiGva4FGE
This commit is contained in:
2026-07-15 14:58:57 -04:00
parent 86d74806c9
commit 3a9c36d843
4 changed files with 47 additions and 8 deletions
@@ -70,6 +70,16 @@ final class WatchTransferService: NSObject {
duration: meta?.duration ?? 0,
timeZoneID: meta?.timeZoneID)
}
// Sweep sidecars whose audio file is gone (e.g. a simulator "recording"
// that never produced a file) so they don't linger forever.
let audioBases = Set(entries.filter { $0.pathExtension == "m4a" }
.map { $0.deletingPathExtension().lastPathComponent })
for sidecar in entries where sidecar.lastPathComponent.hasSuffix(".meta.plist") {
let base = sidecar.lastPathComponent.replacingOccurrences(of: ".meta.plist", with: "")
if !audioBases.contains(base) {
try? fm.removeItem(at: sidecar)
}
}
refreshPendingCount()
}