dictate v3 — from captured voice to executed action
One line: fix the three capture bugs this weekend, replace the Telegram transcript-flood with three-line action cards that agents actually execute, and close the loop with a daily triage that is deliberately not another to-do system.
Source: your five drive-time dictations tonight (2026-07-17, 04:00–04:55 UTC) — recovered from OB1 and the blob queue. Two of them were still sitting unconsumed in the queue when I looked, which is itself a finding: the consumer cron runs every 30 minutes, so "sent" can mean "invisible for up to 30 minutes." Noted in the roadmap.
The bugs — P0, in root-cause order
1. The lost message (the worst one). You dictated, the screen went off during the transcribe-then-route step, and the entire memo evaporated — you had to re-dictate from memory. Root cause: nothing persists until routing completes, and the foreground page dies when the screen does. The fix (sharpened by the critique — persisting after transcription returns would still lose the audio if the screen dies during the transcribe fetch): capture during recording. Audio chunks write to the existing dictate-offline IndexedDB as they're produced (ondataavailable), a wake lock holds the screen through recording, and transcription + routing become idempotent, retryable jobs on an already-saved record — never gates to saving. Screen dies mid-anything → reopen shows "1 unfinished memo," and the job resumes. A dictation becomes as unlosable as a photo, because it's saved before it's even finished being spoken.
2. No new memo after send-to-agent. The state machine dead-ends at sent — there's no path back to idle. Fix: after send, auto-reset to ready-to-record, and a New memo control visible in every state. One state-transition bug, one afternoon.
3. Android Auto missing. dictate-auto is a sideloaded personal APK (Car App Library, IOT category) — it does not install itself and does not survive some updates. Action: verify what's installed on the phone, re-sideload the current APK from dictate.arnao.ai/dictate-auto.apk, and add a version-check line to the nightly site audit so "Auto silently missing" becomes a detected condition instead of a discovery at 70mph. The v1.1 queue (steering-wheel MediaSession control, auto-chunk) is where the driver-friendly buttons land.
Telegram: the action card, not the flood
You asked for this before and it didn't take — the transcript still floods the chat. The v3 contract, enforced at the sender (the dictate pipeline), not by politeness:
- Per dictation, exactly one message, ≤3 lines: an emoji state, the one-line summary, and inline buttons — [▶ Execute] [⏸ Later] [🗒 Log only].
- Execute hands the action items to the routed agent; when it finishes, the same message edits in place to ✓ with a one-line result. No second message.
- The full transcript never appears in chat — the card deep-links to the memo's page in the portal for the rare time you want the whole text.
- This extends the existing Telegram noise contract (guards silent-on-success) to dictation traffic: the chat is a queue of decisions, not a log.
The action loop — explicitly not another to-do system
Your constraint, kept as a design rule: "I don't want to create another to-do system… I want these to end up in a place where I'm reminded about the more important, and somehow these are getting done." So nothing here creates a list you tend. The loop:
- On arrival, the model triages every dictation (your "go right directly to the model" instinct) — and the critique's ruling is adopted as the design: the safe class auto-executes without a tap. You dictate while driving; a card that needs a tap arrives exactly when you can't tap it — the tap-gate would defeat the product. Auto-execute: anything reversible and contained in your own systems (log to OB1, draft docs, research, code to a branch, calendar entries, podcast queue) — worst case, you delete an artifact. Never auto-execute: anything crossing the blast-radius boundary (messages to other humans, Signal sends, purchases, deploys, deletes) — worst case, you apologize to a person. Mechanics: per-destination allowlist + a confidence floor (below it, degrade to the tap-gated card); every auto-executed card edits to ✓ with result and [Undo] — Undo, not confidence scores, is what makes auto-execution trustworthy. Target: median taps per dictation = 0.
- One daily rollup, inside the Morning Brief you already read — not a new surface: yesterday's dictations, what got executed (with results), what's waiting, max three "important and stalled" items resurfaced. The same rollup feeds the podcast so the day's notes literally come back to you as audio.
- Mortality, again: anything untouched for 7 days auto-archives to OB1 with a one-line burial note in the brief. Nothing accumulates. The system's promise is the inverse of a to-do app's: it forgets safely so you don't have to hold it.
- The bet is instrumented, not assumed: the Morning Brief tracks executed-vs-buried ratio for
daily items and the lost-memo rate. If important things are quietly dying at day 7, that shows up in two weeks — not when you find yourself opening a notes app again.
The gap the critique caught that nothing above fixes: the system captures hands-free but confirms hands-required — every result is a visual card the driver can't read. So P2 closes the loop in voice: execution results come back as TTS through Android Auto ("Captured. Two actions running. One needs a decision when you stop"), and a spoken "yes" / "later" stands in for the tap on boundary-crossing actions. Same modality in as out.
Consumer lag fix rides along: the 30-minute blob-queue cron drops to 5 minutes, or better, the pipeline POSTs the consumer directly on upload (queue stays as the safety net).
Roadmap
- P0 (this weekend): the three bugs. Capture-first refactor, state-machine reset, Auto re-sideload + audit check. (Reminder that rides with any index.html deploy: bump the service-worker VERSION or installed PWAs keep the stale shell — that rule has burned this app before.)
- P1: action cards in Telegram (sender-enforced), triage-on-arrival with safe-class auto-execute + Undo.
- P2: daily rollup into Morning Brief + podcast; 7-day mortality with instrumentation; voice-out confirmations (TTS via Auto, spoken yes/later); Auto v1.1 big-button destinations (→ Gia, → Signal, → Podcast).
Self-critique — Fable adversarial pass
Full text: fable-critique-20260717.md. What it caught and what changed:
- My capture-first fix was wrong — persisting after transcription still loses the audio if the screen dies during the transcribe fetch. Fixed: chunked persistence during recording (
ondataavailable → IndexedDB), wake lock, transcription/routing as idempotent jobs on saved records.
- The tap-gated card defeats a driving product. Fixed: safe class auto-executes (reversible + contained; worst case you delete an artifact), boundary-crossing actions stay gated (worst case you apologize to a person); Undo everywhere; median-taps target = 0.
- "Not a to-do system" was an assertion, not a measurement. Fixed: executed-vs-buried ratio and lost-memo rate instrumented in the Morning Brief.
- Its bold catch: the modality asymmetry — hands-free in, hands-required out. Voice confirmations + spoken approvals are now P2.