Write the file format spec v0 #2

Open
opened 2026-08-06 10:53:43 -04:00 by agent · 0 comments
Member

The on-disk contract that every Stash client must agree on.

Why this is its own document, in its own repo

It is the one artifact iOS, the relay and Android all have to implement identically. In v2 the
equivalent shared thing was two byte-identical Swift files held together by copy-paste with
nothing enforcing it
— and that class of drift ends in a silent decrypt failure, which is
the worst bug this system can produce. One versioned spec, consumed by everyone.

It also has a consumer outside the codebase: the vault's CLAUDE.md documents this naming and
the inbox processing depends on it. A change here is a change to Wes's daily workflow.

Must specify

Completed capture — exactly two files (three from M2, with the optional GPS track):

YYYY-MM-DD-HHMMSS-<hash>_audio.m4a
YYYY-MM-DD-HHMMSS-<hash>_transcription.vtt

Timestamp is the original capture time, not the completion time. Define the hash: length,
alphabet, and what it is derived from.

In-flight transcript parts:

YYYY-MM-DD-HHMMSS-<hash>.parts/
  YYYY-MM-DD-HHMMSS-<hash>_transcription.001.vtt
  • Sibling folder named for the capture, so only finished artifacts appear at the top level.
  • Absolute timestamps — cues are offset from the start of the recording, so every part is
    valid WebVTT standalone and assembly is pure concatenation.
  • Continuous cue numbering across parts.
  • Atomic write — temp name, then rename. A part is invisible until complete.
  • Parts are deleted once the final transcript is assembled.

Audio: AAC, mono, ~48 kbps, in a fragmented MP4 container so a killed process still leaves
a playable file.

WebVTT conformance: check the output against the actual spec. Wes: "We should make sure
that the VTT output is actually matching. I don't know if there is a standard for VTT, but
let's match it."
There is one — verify against it rather than against what v2 happened to emit.

Version the document from day one, and state what a consumer should do when it encounters
a version it does not know.

Open, and deliberately not answered here

The GPS JSON track lands at M2 and can be added then. Encryption envelope and wrap formats land
at M3 — with the note that whatever they are called, no two format identifiers may differ by
a transposition
, since v2 shipped STASHWK2 and STASHKW1 alongside each other.

Milestone 1 of the Stash v3 rebuild, scoped 2026-08-06. M1 is a functioning iOS app on Wes's
phone with no sync at all — the entire goal is recording voice memos reliably and getting
them off the device by hand. Sync arrives in M3.

Working agreement for every issue in this repo: feature branch, tested before the PR opens
(on-device where the label says so), then Wes reviews the PR and we walk the code together.
Docs update in the same commit. A PR that takes more than 20 minutes to review is too big —
say so and split it.

The on-disk contract that every Stash client must agree on. ## Why this is its own document, in its own repo It is the one artifact iOS, the relay and Android all have to implement identically. In v2 the equivalent shared thing was **two byte-identical Swift files held together by copy-paste with nothing enforcing it** — and that class of drift ends in a silent decrypt failure, which is the worst bug this system can produce. One versioned spec, consumed by everyone. It also has a consumer outside the codebase: the vault's `CLAUDE.md` documents this naming and the inbox processing depends on it. A change here is a change to Wes's daily workflow. ## Must specify **Completed capture — exactly two files** (three from M2, with the optional GPS track): ``` YYYY-MM-DD-HHMMSS-<hash>_audio.m4a YYYY-MM-DD-HHMMSS-<hash>_transcription.vtt ``` Timestamp is the **original capture time**, not the completion time. Define the hash: length, alphabet, and what it is derived from. **In-flight transcript parts:** ``` YYYY-MM-DD-HHMMSS-<hash>.parts/ YYYY-MM-DD-HHMMSS-<hash>_transcription.001.vtt ``` - Sibling folder named for the capture, so only finished artifacts appear at the top level. - **Absolute timestamps** — cues are offset from the start of the recording, so every part is valid WebVTT standalone and assembly is pure concatenation. - **Continuous cue numbering** across parts. - **Atomic write** — temp name, then rename. A part is invisible until complete. - Parts are deleted once the final transcript is assembled. **Audio:** AAC, mono, ~48 kbps, in a fragmented MP4 container so a killed process still leaves a playable file. **WebVTT conformance:** check the output against the actual spec. Wes: *"We should make sure that the VTT output is actually matching. I don't know if there is a standard for VTT, but let's match it."* There is one — verify against it rather than against what v2 happened to emit. **Version the document from day one**, and state what a consumer should do when it encounters a version it does not know. ## Open, and deliberately not answered here The GPS JSON track lands at M2 and can be added then. Encryption envelope and wrap formats land at M3 — with the note that whatever they are called, **no two format identifiers may differ by a transposition**, since v2 shipped `STASHWK2` and `STASHKW1` alongside each other. --- *Milestone 1 of the Stash v3 rebuild, scoped 2026-08-06. M1 is a functioning iOS app on Wes's phone with **no sync at all** — the entire goal is recording voice memos reliably and getting them off the device by hand. Sync arrives in M3.* *Working agreement for every issue in this repo: feature branch, tested before the PR opens (on-device where the label says so), then Wes reviews the PR and we walk the code together. Docs update in the same commit. A PR that takes more than 20 minutes to review is too big — say so and split it.*
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Stash/stash-docs#2
No description provided.