M1-09: VTT part writer — one-minute transcript chunks #23
No reviewers
Labels
No labels
area/agent
area/capture
area/editor
area/geo
area/security
area/sync
area/transcription
area/ui
area/vault
area/voice-memos
blocked
milestone/M1
milestone/M2
milestone/M3
milestone/M4
needs-decision
needs-hardware
p0
p1
p2
type/bug
type/enhancement
type/feature
type/idea
type/infrastructure
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Stash/stash-ios!23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "m1-09-vtt"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #9 — transcript parts written as a recording runs, validated on
wes-iphone.A 44-minute walk produced 40 parts, 320 cues, continuous numbering across 39 boundaries, with no
duplicated or dropped text at any seam. The issue asked for ten.
What is here
Parts land in a sibling
<base>.parts/folder so the vault agent can read a transcript before thememo is finished, and so a crash costs a minute rather than everything.
The boundary is a cue boundary, never the clock. A part closes when a cue arrives that starts
a minute or more after that part's first cue, and that cue opens the next part whole. Cutting at
exactly sixty seconds would cut through a sentence the recogniser has not finished with, leaving a
truncated cue in one part and a duplicated clause in the next.
Stash gets the hard half free: the transcriber only emits finalised cues, so there is no
in-progress cue to carry across a boundary. The one still being decided has not arrived yet and
lands in whichever part is open when it does.
Every part is complete on its own — its own header, timestamps absolute to the start of the
recording, cue numbers continuing across parts. Assembly is concatenation, not arithmetic. Writes
go through
.atomic, so a part is never visible half-written.The first test target
21 tests,
make test, and a CI step. This is the repository's first, and the design bent to allowit:
TranscriptPartsis a pure struct holding the boundary rule and nothing else, so the partmost easily got subtly wrong is exercised without a device, a microphone or a filesystem.
Fixtures are synthetic. This repository is public.
Reviewing it
One commit.
TranscriptPartsis the substance;VTTrenders;TranscriptPartWriteris an actorthat keeps the writes off the main actor.
CaptureNaminggained the parts naming.Still open
Cue times have not been checked by ear against a recording — carried from #8.
A recording killed before
stop()leaves parts that nothing assembles. Filed as #22, which alsocovers writing the assembled
<base>_transcription.vttbeside the audio, so a capture reaches thevault as the pair it expects.
🤖 Generated with Claude Code
Transcript chunks land in a sibling `<base>.parts/` folder as a recording runs, so the vault agent can read a transcript before the memo is finished and a crash costs a minute rather than everything. 2026-08-06-090139-tjgcaz.parts/ 2026-08-06-090139-tjgcaz_transcription.001.vtt 2026-08-06-090139-tjgcaz_transcription.002.vtt The boundary is a cue boundary, never the clock. A part closes when a cue arrives that starts a minute or more after the part's first cue, and that cue opens the next part whole. Cutting at exactly sixty seconds would cut through a sentence the recogniser has not finished with, leaving a truncated cue in one part and a duplicated or dropped clause in the next. Parts come out roughly a minute, which matters to nothing. Stash gets the hard half of that for free: the transcriber only ever emits finalised cues, so there is no in-progress cue to carry across a boundary. The one still being decided has not arrived yet and lands in whichever part is open when it does. Every part is complete on its own — its own WEBVTT header, timestamps absolute to the start of the recording, cue numbers continuing across parts. Assembly is concatenation, not arithmetic. Writes go through `.atomic` so a part is never visible half-written; a consumer reading a truncated .vtt has no way to tell. `TranscriptParts` is a pure struct holding nothing but the boundary rule, which is what makes the interesting part testable without a device. Adds the repository's first test target. 21 tests, `make test`, and a CI step that will run with the rest once a macOS agent exists. They cover the boundary rule against ten simulated minutes, cue numbering across parts, a cue spanning a boundary, a ten-minute silence, WebVTT rendering byte for byte, reassembly by concatenation, and the filesystem layout including a write that cannot happen. Fixtures are synthetic — this repository is public.