Skip to content

A spoken Capture says what it said - #173

Merged
wschenk merged 1 commit into
mainfrom
claude/walking-thoughts-org-g0qlvt
Aug 8, 2026
Merged

A spoken Capture says what it said#173
wschenk merged 1 commit into
mainfrom
claude/walking-thoughts-org-g0qlvt

Conversation

@wschenk

@wschenk wschenk commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Why today's digest was worthless. Audio has been transcribed since ADR 0015, but the transcript lived only on the Enrichment row. Every surface that shows "the walker's own words" reads the Capture — and a Capture that was recorded rather than typed has empty text. So a spoken walk was blank to the day digest, search, the To-do list, the Day flow card, and the notebook alike. The digest was handed a corpus of empty lines and produced accordingly.

This was never a model problem. The model got nothing.

The fix

  • sync_captures.transcript, carried by both repositories and written through a new recordCaptureTranscripts seam as the enrichment transcribes. Best-effort: a failure there costs the other surfaces their words, never the walker's report.
  • Hydration adopts it onto Captures the device already holds, not just newly-imported ones. The Capture always syncs before it is transcribed, so without this the device that recorded the walk is precisely the one that never sees the words.
  • captureWords() is the single reader — typed text wins, the transcript speaks when there is none, and a transcript never overwrites typing. Applied at all six read sites, so a recording and a typed note are the same thing everywhere downstream.

Rescuing walks that already happened

scripts/backfill-capture-transcripts.mjs copies transcripts already recorded on past Enrichments onto their Captures. Deliberately a copy, not a re-enrichment: re-running the gateway would re-spend it and rewrite reports the walker may have already filed and routed.

fnox exec --profile prod -- node scripts/backfill-capture-transcripts.mjs --day 2026-08-08 --dry-run
fnox exec --profile prod -- node scripts/backfill-capture-transcripts.mjs --day 2026-08-08

--day rescues one walk; omit it for the whole archive. It refuses to run against a database that hasn't taken the migration yet, and keeps an existing transcript unless --force.

Test plan

  • tests/capture-transcript.spec.ts — 6 tests covering the seam end to end, including the exact failure: a day of recordings reaching the digest prompt as words rather than blanks. Also: typed text always wins, re-transcription is idempotent, an empty transcript never erases a good one, and hydration gives the words to a Capture the device already holds.
  • Neighbouring suites green (26 passed): todo-destination, journal-notebook, day-digest, sync-hydrate, globals-css
  • pnpm exec tsc --noEmit clean; eslint adds no new errors (the pre-existing set-state-in-effect ones are untouched)

No-ticket: true

🤖 Generated with Claude Code

https://claude.ai/code/session_01Mm4zPLAX77USAqyk12jgc1


Generated by Claude Code

Audio has been transcribed since ADR 0015, but the transcript lived only
on the Enrichment row. Every surface that shows the walker's own words
reads the Capture — the day digest, search, the To-do list, the Day flow
card, the notebook — and a Capture recorded rather than typed has empty
text. So a spoken walk was blank to all of them, and the day digest in
particular was handed a corpus of empty lines and produced nothing worth
reading.

The transcript now lands on the Capture as it is made:

- sync_captures grows a transcript column, carried by both repositories,
  written through a new recordCaptureTranscripts seam as the enrichment
  transcribes. Best-effort: a failure there costs the other surfaces
  their words, never the walker's report.
- Hydration adopts it onto Captures the device already holds, not just
  new ones — the Capture always syncs before it is transcribed, so
  without that the device that recorded the walk is the one that never
  sees the words.
- captureWords() is the one reader: typed text wins, transcript speaks
  when there is none. Applied at all six read sites, so a recording and
  a typed note are the same thing everywhere.

scripts/backfill-capture-transcripts.mjs copies transcripts already
recorded on past Enrichments onto their Captures, rescuing walks that
have already happened rather than re-enriching them (which would
re-spend the gateway and rewrite reports the walker may have filed).
--day rescues one walk; --dry-run shows what it would write.

Covered end to end in tests/capture-transcript.spec.ts, including the
exact failure: a day of recordings reaching the digest prompt as words
rather than blanks.

No-ticket: true

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mm4zPLAX77USAqyk12jgc1
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
walking-thoughts Ready Ready Preview Aug 8, 2026 2:00pm

Request Review

@wschenk
wschenk merged commit a52cf45 into main Aug 8, 2026
3 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.

2 participants