Mic callbacks returned early when the system-audio tap was live, so your
own voice was never transcribed or recorded. Always run the mic writer;
it feeds the STT buffer in both modes and writes the WAV only when the
system tap is unavailable (mic-only).
- Accept [batch, hidden, time] ('encoder_outputs' = [-1, 1024, -1]) instead
of requiring hidden to be the last axis; derive the hidden axis/size from
decoder session metadata.
- normalize_enc_layout: materialize a true C-contiguous [batch, time, hidden]
copy after permuting, since permuted_axes keeps the original memory order
and to_owned()'s fast path preserves those strides (timestep slices were
non-contiguous, breaking decode_step's as_slice() -> 'ndarray shape error').
- decode_step: build target_length as Int32 to match the model's declared
input type (was i64, an ORT type mismatch).
- Include the ndarray source message in the Shape error display.
- Add unit tests for hidden-axis detection.
Adds title rename using the external editor, inspired by the bulk_mv
script (dump names -> edit -> validate -> apply):
- Meetings list: `e` renames the selected meeting, `E` bulk-renames all
titles (one per line) in $EDITOR/$VISUAL, defaulting to nvim
- Transcript/Summary views: `e` renames the currently open meeting
- Terminal is suspended (raw mode + alternate screen) for the editor
session via a RearmGuard, then restored on return/error/panic
- Bulk rename is all-or-nothing: rejects line-count changes, empty
titles, duplicates within the batch, and collisions with existing
titles; reports per-line errors before applying anything
- db: rename_meetings() applies a batch of title updates in one
transaction
- tests: plan_bulk_renames validation + db batch rename roundtrip
Security (summary/CLI):
- Delimit untrusted transcript as data in all prompts; add data-hardening
- agy: --sandbox + --disable-slash-commands; isolate cwd for all CLIs
- claude: prompt via stdin (no argv leak); agy argv capped below E2BIG
- non-zero CLI exit is now an error; process groups killed on timeout/quit
- executable check in which(); stop stripping json code fences
- 0600 temp prompt file; atomic prefs writes; truncate stderr in errors
Data loss (recording/system-audio):
- stop_recording now real-joins the STT worker and re-drains the queue,
so the final ~3-10s of speech is persisted
- non-destructive STT queue drain on DB error
- periodic WAV flush for crash safety
- RAII kill+wait for the Swift helper on all error paths
- non-blocking READY wait (no frozen TUI); mic callback moved off the
audio thread and skipped when system audio is up
- f32 carryover, tap-death diagnostics, actual stream-rate reporting,
capped STT feed, wall-clock timestamps, transactional import
STT/model:
- poisoned-mutex locks can no longer kill the STT worker
- decoder tensors are metadata-driven with loud shape/dtype validation
- non-overlapping STT windows; tail flushed on stop
- intra_threads=1, scratch reuse, FIR anti-alias resampler,
vocab-size mismatch check, tightened model discovery
TUI/terminal:
- RAII terminal guard + panic hook (no more bricked terminal)
- handler errors surface in status instead of killing the TUI
- Ctrl-C / q / Esc cancel an in-flight summary
- wrapped-line scroll reaches the bottom; dead code removed
- markdown checkboxes render; db cleanup on TUI exit
DB/paths:
- index on transcripts(meeting_id); ALTER errors no longer swallowed
- atomic summary store + segment append; transactional import helper
- safe sqlite filename connect; lowercase statuses; absolute fallbacks
Hardens the unbounded live WAV path: install the writer after system-audio READY
and before the PCM reader starts, open mic-only WAVs before the stream, drain
metering samples instead of cloning, and add a regression test beyond 3 minutes.