Skip to content

fix: refresh Home cache after WAV→M4A recompression and transcript rename#1139

Draft
r3dbars wants to merge 1 commit into
mainfrom
fix/home-cache-refresh-after-recompress-rename
Draft

fix: refresh Home cache after WAV→M4A recompression and transcript rename#1139
r3dbars wants to merge 1 commit into
mainfrom
fix/home-cache-refresh-after-recompress-rename

Conversation

@r3dbars

@r3dbars r3dbars commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Problem (P1 root cause)

Home caches each saved meeting's transcript + audio file URLs at scan time. After a capture is saved, background steps mutate those files:

  • MeetingAudioStorageManager recompresses retained WAV audio to M4A (deleting the WAV).
  • The post-save restyle (MeetingTranscriptStylerMeetingArtifactRenamer) can rename the transcript .md plus its audio/<stem>_audio/ directory.

Home's cached URLs then point at files that no longer exist → stale-reveal and rename races. #1134 patched the symptom (a reveal resolver with fallbacks). This PR fixes the cause: emit a refresh signal after recompression/rename so Home's cache can never outlive the real files.

Fix

SignalCaptureLibraryChangeBroadcaster (Sources/Support/) posts a debounced, coalesced .meetingCaptureArtifactsDidChange carrying the affected transcript id(s). Recompression fires many times (per file, plus launch/settings backfill), so the burst is coalesced into a single notification; an empty id list means a library-wide backfill. Idempotent.

Producers

  • MeetingSessionController.restyleSavedTranscriptInBackground: signals after the rename (new URL) and after recompressionprocessSavedTranscript now returns whether it actually changed audio, so we only signal on real change.
  • Launch backfill (TranscriptedAppState) and retention-change backfill (TranscriptedSettingsView) signal a library-wide change when processExistingRetainedAudio converts or prunes anything.

Consumer — Home's cache (HomeViewModel) subscribes via HomeCaptureRefreshObserver and silently re-resolves its visible captures from disk (no spinner flash), so cached transcript/audio URLs always reflect the current on-disk files.

Scope / non-overlap

Intentionally does not touch the meeting context-menu handlers or HomeArtifactRevealResolver — those are owned by the Home-hardening thread. This PR only adds the recompression/rename producer signal + Home's cache subscription.

Tests (fast harness, run-tests.sh)

  • CaptureLibraryChangeBroadcasterTests — burst coalescing into one debounced notification (de-duplicated union of ids), library-wide (empty) signal, idempotency with nothing pending.
  • HomeCaptureRefreshTests:
    • Home cache re-resolves transcript + audio URLs after a simulated WAV→M4A recompression + transcript rename (URLs updated, no stale .wav/old-stem path; every held URL exists on disk).
    • Home cache drops the stale path after a rename-during-scan race.

Full fast suite: 5435 passed, 0 failed.

Verification still needed

Full app build (build-deps.sh + build.sh) was not run here — this worktree has no prebuilt FluidAudio/MLX deps. The fast suite compiles + exercises the broadcaster, observer, and scanner re-resolution; the 4 app-only edits (HomeView, MeetingSessionController, TranscriptedAppState, TranscriptedSettingsView) need a deps-ready build / CI to confirm compilation.

🤖 Generated with Claude Code

…ename

Home caches each saved meeting's transcript + audio URLs at scan time. After a
capture is saved, background steps mutate those files: MeetingAudioStorageManager
recompresses retained WAV audio to M4A (deleting the WAV), and the post-save
restyle can rename the transcript .md plus its audio/<stem>_audio directory.
Home's cached URLs then point at files that no longer exist, causing
stale-reveal and rename races. PR #1134 patched the symptom with a reveal
resolver; this fixes the cause.

Producers now emit a debounced, coalesced "captures changed" signal carrying the
affected transcript id(s):
- CaptureLibraryChangeBroadcaster posts .meetingCaptureArtifactsDidChange,
  coalescing the burst of per-file recompression + backfill calls into one
  notification (idempotent; an empty id list means a library-wide backfill).
- MeetingSessionController signals after the restyle rename and after
  processSavedTranscript actually changes audio (now returns whether it did).
- Launch + retention-change backfill (processExistingRetainedAudio) signal a
  library-wide change when they convert or prune anything.

Home's cache subscribes via HomeCaptureRefreshObserver and silently re-resolves
its visible captures from disk, so cached transcript/audio URLs can never
outlive the real files.

Scope intentionally excludes the meeting context-menu handlers and
HomeArtifactRevealResolver (owned by the Home-hardening thread).

Tests (fast harness):
- CaptureLibraryChangeBroadcaster coalescing / library-wide / idempotency.
- Home cache re-resolves transcript + audio URLs after a simulated WAV->M4A
  recompression + transcript rename (URLs updated, no stale path).
- Home cache drops the stale path after a rename-during-scan race.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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