Route speaker-pipeline decisions through DebugFileLog - #35
Merged
Conversation
Introduce the persisted archive that the planned Library window will read, decoupled from the ephemeral PipelineQueueStore so dismissing a job never loses its history record. - TranscriptRecord: Phase-1 metadata schema (id == PipelineJob.id, title, start/end, stored duration, transcriptPath, rosterNames, notesCount, hasUnnamedSpeakers, fileMissing). Defensive decodeIfPresent on additive fields so the Phase-2 speaker-ID join won't break old records. - TranscriptRecord(completedJob:hasUnnamedSpeakers:): the intended write path, mapping a finished job to a record (nil for unfinished jobs). - TranscriptStore: upsert (idempotent by id), rename, record-only remove, and reconcile(fileExists:) with an injectable existence check. Reuses the existing JSONStore corrupt-quarantine convention. - TranscriptLibrary.meetings(from:search:): pure newest-first sort + case- insensitive title/roster filter, independent of store and view. - AppPaths.transcriptsFile -> transcripts.json. Pure logic only; no pipeline/UI wiring yet. 11 new tests (192 total, green). Also gitignore .codegraph/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
NSLog wasn't reliably reaching the unified log for a user diagnosing a speaker who never appeared in the naming prompt — Console.app showed nothing for the whole meeting. DebugFileLog already exists for exactly this reason (see its doc comment) but only dictation used it. Adds DebugFileLog.log() alongside the existing NSLog calls at every naming-pipeline decision point, so turning on Developer Mode makes the full trail available in dict-debug.log: - matchSpeakers: matched vs. no-confident-match per detected speaker - roster auto-naming: empty roster, 1:1 auto-assign, or suggestions-only - clip extraction: skipped candidates now log speaking time/word count so a "no playable clip" drop can be checked against actual talk time - naming prompt trigger and AppModel receipt - NamingCandidateStore.load(): candidates silently dropped (or partially trimmed) on restart because their clip files were gone Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Speaker_XXXXXX, spoke at length, but never appeared in the naming prompt or Speakers settings — Console showed nothing for the whole meeting.DebugFileLogalready exists for exactly this reliability gap (see its doc comment), but only dictation used it. This extends it to the speaker-naming pipeline.DebugFileLog.log()alongside the existingNSLogcalls at every naming-pipeline decision point, gated behind Developer Mode (Settings → General):matchSpeakers: matched-profile vs. no-confident-match, per detected speakerAppModel.onNamingRequiredreceiptNamingCandidateStore.load(): candidates silently dropped (or partially trimmed) on app restart because their clip files were gone — previously unlogged entirelyWhy
Metadata only (speaker IDs, counts, durations, distances) — no transcript or note content is logged, consistent with
DebugFileLog's existing rule.Test plan
swift build— clean~/Library/Application Support/Heard/dict-debug.log🤖 Generated with Claude Code