Skip to content

Route speaker-pipeline decisions through DebugFileLog - #35

Merged
execsumo merged 4 commits into
mainfrom
speaker-pipeline-debug-logging
Aug 7, 2026
Merged

Route speaker-pipeline decisions through DebugFileLog#35
execsumo merged 4 commits into
mainfrom
speaker-pipeline-debug-logging

Conversation

@execsumo

@execsumo execsumo commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • NSLog wasn't reliably reaching Console/unified log for a user diagnosing a colleague who was diarized as Speaker_XXXXXX, spoke at length, but never appeared in the naming prompt or Speakers settings — Console showed nothing for the whole meeting.
  • DebugFileLog already exists for exactly this reliability gap (see its doc comment), but only dictation used it. This extends it to the speaker-naming pipeline.
  • Adds DebugFileLog.log() alongside the existing NSLog calls at every naming-pipeline decision point, gated behind Developer Mode (Settings → General):
    • matchSpeakers: matched-profile vs. no-confident-match, per detected speaker
    • Roster auto-naming: empty roster, 1:1 auto-assign, or suggestions-only fallback
    • 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.onNamingRequired receipt
    • NamingCandidateStore.load(): candidates silently dropped (or partially trimmed) on app restart because their clip files were gone — previously unlogged entirely

Why

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
  • On the affected machine: enable Developer Mode, reproduce a meeting with an unmatched speaker, confirm the full decision trail appears in ~/Library/Application Support/Heard/dict-debug.log

🤖 Generated with Claude Code

execsumo and others added 4 commits June 17, 2026 22:41
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>
@execsumo
execsumo merged commit fe3bbd9 into main Aug 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant