Fort Kit · Sovereign Seed Archive · SSA v2.0.0 / UCLS v1.2
BETA READER
— Selfware Seed
A listening room for manuscripts. Readers listen, tap once, and talk — every note pins itself to the exact passage and files itself into a repo.
A seed is a specification with a germination gate. You give it to your AI. Your AI grows it into a working build on your stack — and iterates against the gate until every check passes. You own the fruit. The code your AI writes is yours.
A seed without a gate is a prompt pack. This one has a gate — eight checks, every one of them able to fail.
github.com/TheFortThatHolds/beta. Fork it and you have that build. This seed is for growing yours — your host, your questions, your notes store, your voice provider — with your AI iterating against the gate. The repo is one fruit; the seed grows orchards.Beta Reader
Hand a reader a link. They listen to your book, and when something lands — good or bad — they tap once and say it. Written feedback is slow and vague, so people don't give it; talking is fast, so they do.
Two Organs, One Optional
- THE ROOM — one static HTML file. The whole app, both sides: the reader's listening session and the author's collation view. Zero build, zero dependencies, zero framework.
- THE COURIER — an optional one-file worker. Voice out (TTS), voice in (transcription), notes into a repo you own. The only organ that ever holds a key.
The Room works with no Courier at all — browser voice, typed notes. Quieter, never dead.
The Hangar
Any static host for the Room (a file:// open works). Any serverless runtime for the Courier. Any GitHub repo for the notes. Any OpenAI-compatible speech API for the voice.
The Collation Is the Point
The deliverable is the passage-by-passage view — every reader's voice, grouped where they clustered — handed straight to your agent. Where two readers land on one passage, that's the signal.
Linguistic Attractors
Passage — the atomic unit; notes pin to passages, never pages. Debrief — the twenty questions at the end, fully replaceable. Branch-per-reader — isolation by construction. Collation — the clustering made visible. The Room — never "app," never "platform."
The Prime Directive
"I AM THE LISTENING ROOM. One file plays the book. One courier keeps the keys. Every note lands on the passage that caused it. With no courier I am quieter, never dead. The room forgets; the repo remembers."
The Author — and Their Invited Readers
Readers never see each other's notes and never conflict. The author sees everyone, grouped by passage.
How It Behaves
- Passage splitting — Markdown or plain text split into passages, headings announced aloud, playback resumes where the reader left off.
- Tap-to-note — typed or spoken; spoken notes transcribe through the Courier or the browser's own dictation.
- The debrief — twenty questions at the end, fully replaceable in config.
- Branch per reader — notes commit to
reviews/<book-id>.REVIEW.mdon the reader's own branch. Repeat sessions append, never overwrite. - Collation flags the cluster — passages hit by more than one reader are flagged; consolidated Markdown exports for your agent.
- The honest probe —
GET /healthreports{ok, tts, stt, notes}truthfully, each flag reflecting whether its secret is actually set. An organ that cannot report its own state fails silently by default — this one reports.
Spoken Beats Written
Passage beats page. Degraded beats dead. The signal is where readers cluster, and the room's job is to make clustering visible.
Gear
fetch— the Room's only network verb, all of it aimed at the CourierMediaRecorder— voice notes, feature-detectedspeechSynthesis— the free fallback narrator, no key requiredlocalStorage— manuscripts stay on the reader's device- GitHub Contents API — spoken only by the Courier, never the Room
The Courier's Contract, Verbatim
GET /health → { ok, tts, stt, notes } capability probe
POST /tts → audio/mpeg { text, voice?, speed?, model? }
POST /transcribe → { text } multipart form, field "file"
POST /notes → { ok, path, branch } { reader, bookId, bookTitle, markdown }
GET /notes?bookId=<id> → [{ reader, branch, markdown }] every reader's notes for one book
GET /readers → [{ reader, branch, books: […] }] who has submitted anything
Secrets (Courier only, never client-side): TTS_API_KEY · GITHUB_TOKEN (fine-grained, Contents R/W) · ACCESS_CODE (optional; callers send X-Access-Code)
Vars: TTS_API_BASE · TTS_MODEL · TTS_VOICE · STT_MODEL · NOTES_REPO · NOTES_BRANCH_BASE · NOTES_DIR · ALLOWED_ORIGINS · MAX_TTS_CHARS
The Room's config surface (config.json, served to every browser — a key here is a gate failure): title · tagline · accent · workerUrl · ttsProvider · remoteVoice · accessCode · library[] · questions
Soil · Water · Fruit · Gate
SOIL: any code-capable AI + a static host + (optionally) a serverless runtime and a GitHub repo for notes.
WATER: GERMINATE BETA READER: [YOUR PRESS / BOOK] — hand your AI this seed and that phrase.
FRUIT: the Room (index.html + config.json) live on a static host; the Courier (worker.js) deployed with its secrets, pointed at a notes repo.
THE GATE — iterate until all eight pass. Each check can fail; that is the point.
| # | Check | Pass condition |
|---|---|---|
| G1 | One-file room | The entire app is one static HTML file, zero dependencies, zero build; opens from a plain static host or file:// |
| G2 | Degraded, never dead | With NO Courier deployed, the Room still reads a manuscript aloud (browser voice) and takes typed notes |
| G3 | Passage pinning | A note taken mid-listen lands attached to the exact passage that was playing |
| G4 | Honest probe | /health flags match reality: each of tts/stt/notes is true only when its secret/var is actually set |
| G5 | Key audit | config.json and the Room's source contain no key; keys live only in the Courier's secret store |
| G6 | Reader isolation | Two readers on one book produce two branches; neither can reach the other's notes through the Room |
| G7 | Append, never clobber | A repeat session by the same reader appends to their REVIEW.md; prior notes survive verbatim |
| G8 | Collation clusters | The author view groups all readers' notes by passage and flags every passage hit by two or more readers |
THE BURN: manuscripts live in the reader's local storage and nowhere else. The Room forgets; the repo remembers.