Repository navigation
Integrate remaining Transcripted PRs with verified repairs and strict boundaries - #2173
Conversation
With AirPods, every muffled take waited 300 ms for a quiet moment before cutting, and then the music skipped back a hair at the cut. The copy-delay reading added the tap's reported latency, which on a Bluetooth output is the output's own 160 ms. The originals and the copy both go through that same device, so it's not lag between them. Every AirPods take looked 170.8 ms late (owner's Mac log, 51 takes), over the 15 ms quiet-wait line, so 36 of 45 cut only after the full 300 ms. The real lag is the IOProc's two 256-frame buffers, about 11 ms. DictationMuffleCopyDelay now counts only tap latency beyond the output's own. The gate now fades over the copy's lag (4-25 ms) at the cut and the hand back, so the few milliseconds the copy replays play quietly under what was just heard instead of as a full-level repeat. The engaged log line also records gate_fade_ms. Claude-Session: https://claude.ai/code/session_01DEL5vVKCBRYCvxaT5GS1nA
…iting The first fix was wrong. On AirPods the copy really does trail the originals by ~171 ms (the tap delivers the mix one output latency late). Taking away the quiet wait made every take repeat ~0.1-0.2 s of music, and the owner heard exactly that. This puts the lag reading back and fixes the seam instead. - DictationMuffleSplice: when the copy lags by more than 15 ms, the cut holds the copy's gate shut for the lag plus the ~4.5 ms the mute takes, then fades it in over 20 ms. The music drops out briefly and comes back where it left off, already gliding toward muffled, with nothing repeated. Short lags (wired, built-in, ~7 ms) keep the plain 4 ms fade, unchanged. - The IO thread counts the hold down per cycle. gateOpen is now stored releasing and loaded acquiring, so the hold and fade it reads are never stale. - The cut no longer waits for a quiet moment by default (quietWaitNanos 0). The hand back keeps its short quiet wait. - The engaged log line adds hold_ms. Claude-Session: https://claude.ai/code/session_01DEL5vVKCBRYCvxaT5GS1nA
- While the gate is held shut, the filter jumps straight to its muffle target (silent, so inaudible), so the AirPods copy comes back fully muffled: one "drop, then muffled" step instead of a drop and a sweep. - Add an 8 ms skip-side margin to the hold, so timing error (the mute latency was measured on built-in speakers) lands on a few skipped milliseconds in the gap, not a few repeated ones. - The IO thread's hold countdown goes through DictationMuffleSplice.remainingHold. A test renders 128-frame cycles and checks that the copy opens exactly when the hold runs out. - Fix stale comments. Claude-Session: https://claude.ai/code/session_01DEL5vVKCBRYCvxaT5GS1nA
Test variant. On AirPods the hold left ~0.12-0.18 s of silence before the muffled copy came back. Now the gate holds for half the catch-up and fades in over the other half, ending exactly where the originals stopped. The silence becomes a soft swell. The part it covers replays quietly and already muffled instead of at full level. Claude-Session: https://claude.ai/code/session_01DEL5vVKCBRYCvxaT5GS1nA
Rewrite all 27 AGENTS.md files against current code: fix stale paths, commands and behavior (single Right Option dictation key, 30-day dictation audio, 15-minute takes, removed call-matching setting), keep every rule and known trap, and cut narrative history and parent-doc duplication. Add AGENTS.md for Tests/, .agents/, .github/, scripts/release/, Tools/TranscriptedLive/ and Tools/TranscriptedCompanion/, and register them in .agents/agent-contract.json, the root guide and docs/repo-layout.md.
Transcripted runs for days as a menu bar app, so one session per launch left the per-session crash-free rate resting on a few very long sessions. The session now ends when the Mac sleeps, a new one starts on wake, and a session open for 24 hours is closed and restarted (checked every 15 min). Sessions still start only after onboarding and with crash reporting on.
…d passwords Save my writing kept a sudo password in plain text when the command that asked for it wasn't sudo itself. Now brew install/upgrade/uninstall, make install, install.sh-style scripts and curl | sh count as prompts, answered like sudo, except a line that just runs what was installed. A password starting with $ ($unsh1ne) is no longer skipped as if it were a shell variable or an amount. rulesVersion goes to 2, so day files already on disk are rescrubbed once. The prompt tables moved to WritingSecretScrubber+Prompts.swift to keep the scrubber under its size baseline. A password after a command recalled with the up arrow is still missed: the command never reaches the scrubber.
1.1.70 made dictation one key with a behavior picker, but the old paste-last shortcut and separate Hands-Free binding stayed in the tree. Remove the paste-last action, its event-tap routing, callback and stored binding, plus the unused Hands-Free binding writer and the DictationShortcutMode title/summary/writer. The legacy mode read stays, renamed legacyDictationShortcutMode, for the one-key migration. Kept on purpose: DictationShortcutMode.handsFree (models tap-kept and Tap to toggle takes; raw value is the shortcut_mode telemetry tag), .dictationHandsFree routing, and PasteLastDictationFeedback (the island's "Paste again" chip still uses it).
search_context gathered relevance-ranked meeting, dictation and writing lists, then sorted the union newest-first, so kind: all returned the newest matches instead of the best ones. Every per-kind list is ranked by relevance in every mode, so there's no case where the date sort was right. Merge the lists with reciprocal-rank fusion on each item's rank within its own list (BM25 and cosine scores aren't comparable); date is only a tiebreak between items at equal fused score.
Pure moves: SystemAudioCaptureTCC, SystemAudioPermissionRequester (+RequestAttempt, ProbeWorker), SystemAudioPermissionProbeClassifier into their own files.
…sonalHistoryStore.swift
docs/threat-model.md maps what Transcripted protects, its trust boundaries, known weak spots, and what a reviewer should flag as high severity. Set it as the threat-model path in Codex's code review settings. AGENTS.md gains a Review guidelines section that Codex's automatic review reads: privacy, audio real-time rules and the AirPods trap, main-thread work, hidden behavior changes in cleanup PRs, removed product surface, harness safety, weakened checks, and auto-merge widening.
Codex flagged a correct r3dbars commit on #2040 as authored by Codex, a false P1 that blocked the PR. Reviewers can't judge authorship from their checkout.
|
Final candidate: Independent full-diff reviews approved the staged audio gate, scrubber corrections, CI fail-closed rerouting, documentation/QA registration, and native overlay probe wiring. The native overlay runtime verdict remains pending protected hosted CI; local account isolation is respected. Fresh verification on this exact head is running: mapped union Current required hosted Swift CI run: https://github.com/r3dbars/transcripted/actions/runs/37821229014 . No required checks or conversation protection bypass. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d238b06ca
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This combines the 40 remaining Transcripted PR heads into one reviewed result while preserving their Git ancestry. It includes bug fixes, behavioral test replacements, file splits, documentation, CI runner repairs, and removal of the remaining module crossings without widening Core dependency tiers.
Repairs to the combined result cover coherent dictation muffle transitions, offline archived-audio queue retention, speaker naming and migration boundaries, mixed-time search ranking, secret scrubber command and old-token handling, automation worktree isolation, and actual overlay duration subscription coverage. The intentional dormant global shortcut cleanup preserves in-island Paste again and feedback.
Candidate:
4d238b06ca59052af40893737bbdc667fe461557. Reviewed against fetched mainb32f2346c4cdd49a570070ef39569dd5c9239ec8.Validation:
[0,1,2,5]. Premium performance budget PASS (1959.7 ms against the 3000 ms hosted ceiling). Evidence is from actual logs and checker enforcement; no directly downloaded report is claimed. Last duration review thread resolved after independent APPROVE.No required-check or conversation bypass. After protected merge, fetch main, recheck every live original head, and verify original PR closures before reporting zero open PRs. Local compilation, mocked plugin tests, and synthetic audio tests do not establish real microphone/Bluetooth behavior or a shipping release.