Stop-path latency, transcript survival, and a dead-bridge crash - #73
Merged
Conversation
… settings) lane_truth_keychain_only_secret_sets_probe_core_readiness hard-coded LLM_ASSISTIVE_API_KEY while operator Settings select Anthropic, so key_env_key became LLM_ANTHROPIC_API_KEY and the test failed outside a clean env. Inject Keychain-only secret for the active assistive provider's api_key_env_key instead. Authored-By: grok <agents@vetcoders.io>
Enable Anthropic adaptive thinking in request payloads when policy allows it, so reasoning deltas can stream instead of showing only a placeholder. Rework Agent Chat sidebar behavior from hide/show to expanded/compact rail modes with mode-owned split widths, preventing unrecoverable collapse and empty column gaps. Also update focus policy to treat NSScrollView-backed text views as text input targets (fixing TextEditor click focus loss), and add tests for both the focus fix and sidebar mode geometry/toggle behavior. model: claude opus 6 time: 2026-08-05 15:10:48
… example - keygen: fresh Ed25519 pair, prints the ready gh-variable line and fingerprint, seed shown once on stderr and zeroed after - sign: mints CSK1 tokens from CODESCRIBE_LICENSE_SIGNER_SEED_HEX at runtime; email/sku/updates-months/seat-limit as arguments - refuses the RFC 8032 dev seed — production issuance can never reuse the publicly known test vector - closes the gap where the repo shipped a verifier and a dev signer but no production issuance path at all Authored-By: claude <agents@vetcoders.io>
…source pointers
- adaptive_thinking: cover the true path — thinking:{type:"adaptive"} reaches
the wire, never a manual budget_tokens; false leaves the body untouched
- DEFAULT_MAX_TOKENS 8192 -> 128_000 (model-family output ceiling; we always
stream). Doctrine: the agent's output is never capped — with adaptive
thinking counting against max_tokens the old cap throttled doubly
- new tools/output_guard: single tool chunks above ~25K chars are truncated
WITH a pointer instead of silently — generated output (process/git/search)
spills in full to Config::config_dir()/agent/spill and the chunk names the
file; on-disk sources (read_file) point back at their own path
- read_file previously cut at 40K chars with no marker at all — silent
knowledge loss; now every cut is visible and recoverable
- unit tests: pass-through, spill integrity (full original preserved),
pointer presence for both guard variants
Authored-By: claude <agents@vetcoders.io>
…art final pass - Add pure `tail_gap_start_index(total_samples, sample_rate, from_secs)`: clamped sample-index math for the uncommitted tail boundary; non-positive or non-finite `from_secs` means whole file, past-the-end yields `len`, zero sample rate cannot produce a bogus offset. - Add `whisper_tail_gap_transcribe_file(path, from_secs, language)`: loads the WAV, slices off everything before the last committed utterance end and runs the existing VAD-gated `whisper_tail_patch_transcribe` on that tail only. Boundary past the recording returns an empty transcript without touching Whisper. Never a full-file re-pass when a positive boundary exists — full-file re-pass stays FINAL_PASS_MODE=Always territory. - Cover both with inline tests: clamp math, a synthesized 2s silence WAV whose tail short-circuits on the VAD gate, and an out-of-range boundary. Authored-By: claude <agents@vetcoders.io>
- Add `FinalPassAction` (SkipStreamingFinal | FullFileRepass | TailGapFill): the lossy bool could not distinguish "re-transcribe the whole file" from "transcribe the uncommitted tail and append it" — both collapsed to false, which is how Smart drifted into full-file re-passes over committed text. - Add `final_pass_action(mode, completeness)` with the operator hard mapping (2026-08-05): Always -> FullFileRepass regardless of completeness; Smart+Complete -> SkipStreamingFinal; Smart+Incomplete -> TailGapFill; Off -> SkipStreamingFinal regardless. FullFileRepass is reachable from Always and from nowhere else. - Keep `should_skip_full_final_repass` as a documented transitional shim delegating to the typed action with byte-for-byte unchanged runtime semantics; it must die once the stop path consumes actions directly. - State the Smart hard rule in the module doc header: per-utterance / tail-only gap fill, appended to immutable committed text, never full-file. - Tests: full (mode x completeness) matrix, the shim-agreement property, and `test_only_always_mode_may_full_file_repass` iterating every combination to assert FullFileRepass is produced by Always alone. Authored-By: claude <agents@vetcoders.io>
…n session telemetry - Add `committed_through_secs: Option<f32>` to SessionTelemetrySnapshot — the audio boundary of committed streaming text. - SessionTelemetrySink folds EngineEvent::UtteranceFinal `end_ts` as a monotonic max, so an out-of-order final never rewinds the boundary. - Default/reset leave the boundary as None (no committed audio yet). - Test-first: test_session_telemetry_tracks_committed_through_secs_monotonic_max covers default None, 3.2 -> 7.9 advance, out-of-order 5.0 held at 7.9, reset. - Adapt the one exhaustive SessionTelemetrySnapshot literal in controller tests so the new field keeps the crate compiling. - Enables Smart-mode stop to transcribe only the uncommitted tail instead of a full-file re-pass (append-only doctrine — committed text is immutable). Authored-By: claude <agents@vetcoders.io>
…ss actions - add append_tail_gap in final_pass.rs: append-only join of a Whisper tail gap-fill onto committed streaming text (trimmed streaming is always an untouched prefix of the result; single-space seam; empty operands handled) - switch the stop path from should_skip_full_final_repass to a match on final_pass_action: SkipStreamingFinal and FullFileRepass keep byte-identical behavior, Off stays hard off - add the Smart TailGapFill arm: boundary from session telemetry committed_through_secs, spawn_blocking whisper_tail_gap_transcribe_file, append via append_tail_gap, LocalFinalPass verdict with reason=smart_tail_gap and disposition Changed/Unchanged, FinalPassStages timing + info! receipt `final_pass_tail_gap mode=smart from_secs=.. appended_chars=..` - retire the transitional shim should_skip_full_final_repass and port every bool-based scenario to the typed action API (Smart+Incomplete now asserts TailGapFill, never FullFileRepass — the old expectation was the violation) - pin lexicon as ungated on the tail-gap path: dictionary rewrites both the committed prefix and the appended tail of a composed transcript Authored-By: claude <agents@vetcoders.io>
…ail duplication holes - Add codescribe_core::stt::resolve_tail_gap_boundary + TailGapBoundary: Some(t>0) -> From(t); missing/zero/non-finite boundary -> WholeSessionBootstrap only when the streaming canvas is EMPTY, otherwise Skip. Kills the committed_through_secs.unwrap_or(0.0) path that turned Smart+Incomplete (no_commit_source / no_coverage / empty) into a whole-file Whisper pass appended onto existing streaming text. - Wire the controller TailGapFill arm to the policy: From(t) keeps reason "smart_tail_gap", WholeSessionBootstrap runs from 0.0 with reason "smart_bootstrap_gap_fill", Skip emits an honest Skipped verdict with reason "tail_gap_no_boundary" and never invokes Whisper. FinalPassStages bookkeeping unchanged. - Dedup overlapping preview words in append_tail_gap: drop the longest leading tail word-run that repeats the trailing streaming words (case- and edge-punctuation-insensitive comparison, original tail words appended). Tail fully contained in the committed suffix appends nothing. The streaming side is never mutated - it stays an exact prefix of the result. - Tests: resolve_tail_gap_boundary_matrix (core) and test_append_tail_gap_dedups_overlapping_preview_words (app), both RED first. Authored-By: claude <agents@vetcoders.io>
- Commit 50ecc83 added the offline license signer example reading CODESCRIBE_LICENSE_SIGNER_SEED_HEX without a registry entry, so the shared e2e_env_registry gate failed for every agent on the tree. - Register it in the build category next to CODESCRIBE_LOCAL_INSTALL: empty default, string, restart reload, described as an example-only signing seed that the app runtime never reads and that must never reach .env or CI. Authored-By: claude <agents@vetcoders.io>
…L_PASS_MODE - Move FinalPassRoutingMode + env resolution (FINAL_PASS_MODE / CODESCRIBE_FINAL_PASS_MODE / legacy CODESCRIBE_LOCAL_STT_FINAL_PASS, default Smart) into codescribe_core::config::final_pass so every stop lane consults one parser; app/controller/final_pass.rs re-exports it at the historic path, controller call sites untouched - Move the env/parse tests with the type (serial-guarded, matching the neighbouring env-test discipline in core) - ComposerTranscript now folds UtteranceFinal::end_ts into a monotonic-max committed_through_secs, mirroring SessionTelemetrySink; empty finals still seal their audio so it is never gap-filled twice - Add composer_final_pass_plan: Always -> FullFile, Off -> SkipStreaming, Smart -> resolve_tail_gap_boundary (From/WholeSessionBootstrap/Skip) - stop_recording/run_final_pass obey the plan: tail gap-fill via whisper_tail_gap_transcribe_file under Smart, no Whisper at all under Off (streaming splice stays the fallback), full WAV only under Always; plan + mode logged at info on target "composer-dictation" - Closes the verifier hole: the composer voice-note lane ran an unconditional full-WAV re-pass with zero mode consultation Authored-By: claude <agents@vetcoders.io>
… merge
- Composer voice-note lane lost gap-fill words under FINAL_PASS_MODE=smart:
the Smart tail was routed through `merge_live_whisper`, whose
`coalesce_substitutes` folds the boundary DeleteA+InsertB pair into a
Substitute that keeps live and DISCARDS the whisper token. Measured at HEAD:
("raz dwa" live + "trzy cztery" tail) -> "raz dwa cztery".
- Promote the audited append-only composer to core as
`codescribe_core::stt::append_tail_gap` (with `overlap_key` /
`leading_overlap_words`), beside `resolve_tail_gap_boundary`, so both Smart
stop lanes share ONE implementation instead of a twin. `final_pass.rs` keeps a
`pub(crate)` re-export at the historic path; controller call sites and tests
are untouched.
- Bridge: new plan-aware `compose_composer_transcript` — `TailGap` appends the
bare tail via the shared core primitive, `FullFile` keeps the whole-WAV merge,
`SkipStreaming` returns the streaming splice. New internal
`ComposerTranscriptSource::TailGapAppend` label (enum is bridge-private, never
crosses the UniFFI surface) and the stop receipt now carries `plan`.
- Make `run_final_pass`'s plan dispatch exhaustive: `FullFile` is named
explicitly so a future `ComposerFinalPassPlan` variant is a compile error
instead of silently falling into the forbidden full-file re-pass.
- Controller: replace the `f32::NAN` Skip sentinel with `Option<(f32, &str)>`, so
the Skip arm never produces a `from_secs` and correctness no longer depends on
branch ordering. Verdict reasons unchanged (`tail_gap_no_boundary`,
`smart_tail_gap`, `smart_bootstrap_gap_fill`).
- Tests: bridge TailGap append/merge/empty-tail cases (RED first) plus core
`append_tail_gap` prefix-immutability, dedup and empty-operand tests. Drop a
rotting `mod.rs:NNNN` reference from a controller test doc comment.
Authored-By: claude <agents@vetcoders.io>
Standardizes repository guidance by rewriting AGENTS.md with the canonical swarm/doctrine directive, simplifying CLAUDE.md to defer to AGENTS.md, updating the commit message template, and removing the legacy .aiassistant markdown rule while ignoring the .aiassistant directory. It also appends a new UI divergence audit signal to AGENT_BUS.md. On the code side, it cleans the Teacher HTML report heading to a neutral title and updates Swift UniFFI bridge stop-recording documentation to reflect FINAL_PASS_MODE behavior (Always/Smart/Off), with the regenerated stop_recording checksum updated accordingly.
…s tail-silence contract on CI - tail_silence_contract went red on CI after deprivatize (6ffcf44) removed the in-repo operator-speech fixture: without ~/.codescribe/data_assets the test fell back to a synthetic 440 Hz sine, which real Silero rightly refuses to classify as speech, so BOTH whisper segments were dropped (dropped_count 2 != 1). - Add tests/assets/synthetic_speech_tts.wav: 10.8 s of macOS TTS speech (pl_PL voice, 16 kHz mono, 343 KB) — synthetic by construction, zero operator voice, safe under the deprivatize fence (which stays untouched: tests/assets/data_assets/* remains ignored). - canonical_wav_path now falls back to the committed TTS fixture before the sine synthesis; private fixtures still win when present. - Verified RED->GREEN in a CI-like env (HOME hidden): FAILED 2!=1 before, ok after; normal env stays green on the private fixture. Authored-By: claude <agents@vetcoders.io>
…che rail formatters Sample 2026-08-07 10:43 (0.13.3) caught the main thread pinned 93/93 samples inside _NSPopoverCloseAndAnimate -> becomeKeyWindow -> AgentChatStore refreshThreadsFromExternalChange -> RealThreadsEngine.listThreads, with 42/93 under fresh NSDateFormatter/ICU construction per rail row. Distinct from the 2026-08-01 (0.13.2) freeze (SwiftUI render storm, fixed by 937189f). - AgentChatStore: external-change triggers now coalesce onto the next main-queue tick (single pending flag, no timers) — a window-ordering storm collapses to one disk re-read and runs outside the notification callout - AgentChatStore.replaceThreads: identical rail rows no longer publish — an unchanged `threads =` still rebuilt the whole window body (937189f lesson); matched rows reuse instances, so equality also fixes selection - ThreadRailMeta.relativeTime: cached DateFormatters (full ICU init was paid once per row per refresh); calendar reassigned only when a caller differs - ThreadsRefreshTests: C5 storm-coalescing (10 posts -> 1 list call) and C6 unchanged-refresh-does-not-publish, observed RED before the fix; existing contracts drain the coalescing tick before asserting Authored-By: claude <agents@vetcoders.io>
…finite end_ts; mark signer seed as secret PR #69 review findings (Copilot): - helpers.rs telemetry fold: non-finite end_ts (NaN/±inf) no longer touches committed_through_secs — NaN fell through the `current >= end_ts` arm and overwrote a valid boundary, silently degrading Smart tail gap-fill to Skip; now at parity with ComposerTranscript::note_committed_through (RED observed before the guard: NaN replaced Some(3.2)) - ENV_REGISTRY: CODESCRIBE_LICENSE_SIGNER_SEED_HEX typed as "secret" (was "string") matching LLM_API_KEY convention so tooling never renders it as plain config The two rustfmt comments are stale: cargo fmt --check exits 0 on the current branch and the CI Format Check is green. Authored-By: claude <agents@vetcoders.io>
…ugh the documented order - add scripts/lib/data-assets.sh — the one shell-side implementation of the fixture resolution contract (CODESCRIBE_DATA_ASSETS → ~/.codescribe/data_assets → gitignored in-repo drop dir) that the README, the Rust e2e helpers and bench-stt.sh already shared but the harness and the Makefile did not - scripts/e2e-blackhole-dictation.sh: resolve the fixture argument through it; a missing corpus exits 2 listing every path checked, before any audio device is touched - Makefile: derive DATA_ASSETS_DIR, ENGINE_CLIP, the parity clip and the 01–04 ENGINE_ALL_CLIPS glob from the resolver — all four hardcoded the single tier gitignore keeps empty by design, so every ENGINE_* target was dead on a host whose home corpus held the audio - retain the parity test log under target/e2e-blackhole (gitignored) and surface the `parity similarity` line — the measurement evaporated with $WORK, leaving the grinding loop a verdict with no number - tests/data_assets_resolution.rs: 10 hermetic contract tests (fake HOME, fake repo root, stub WAVs — no private audio, no audio hardware) - tests/assets/data_assets/README.md: name the shared resolver, add the cold-worker one-liner No private audio enters git; the .gitignore fence is untouched. Baseline on this host (macOS 27.0 arm64, branch fix/whisper-final-pass-move-out-if-not-needed): `make test-engine-parity` exit 0 — parity similarity 161/173 = 0.931 (bar 0.90). Authored-By: claude <agents@vetcoders.io>
…d fails - scripts/e2e-blackhole-dictation.sh: `cd "$(dirname "$0")/.." || exit 2`. Everything after it is repo-root relative — now including the `.` source of the fixture resolver — and the script proceeds to mutate the operator's audio device mute/volume state, so a failed cd must abort rather than relocate the run (shellcheck SC2164, latent before the resolver, load-bearing after it) - scripts/lib/data-assets.sh: print the expanded home corpus path in the not-found hint instead of a literal `~`, which never expands inside quotes and is less useful than the real path (SC2088) shellcheck -S warning: clean on both files. semgrep: 0 findings. Authored-By: claude <agents@vetcoders.io>
…e stream state - Pin bridge swiftc to -target arm64-apple-macos26.0 (Makefile ENGINE_BRIDGE_TARGET + build-app.sh) so host triple no longer drifts to minos 28.0 - Isolate non-Sendable SFSpeech request / DispatchWorkItem / AV teardown behind serial-queue handles (SfSpeechRequestHandle, SfSpeechTimeoutCancel, SfSpeechBufferSession) - Close Sendable warnings at stream/buffer path without @preconcurrency suppression - Document the pin in apple_stt README and bridge build comment Authored-By: grok <agents@vetcoders.io>
…gressive path The Apple progressive path (daily driver) emitted raw SFSpeech text and relied on the stop-path postprocess to correct it — a post-commit rewrite, which the append-only doctrine forbids. Every seal now runs the shared lexicon + cleanup pass before the text becomes committed canvas. - route all three Apple seal sites (phrase final, summary fallback, open-partial-on-stop) through StreamPostProcessor::process_utterance (lexicon + cleanup, no semantic gate); no second postprocessor forked - keep Preview events RAW — previews are in-flight presentation, not canvas, so the rewrite lands exactly once at seal time - emit DropKind::FilteredEmpty with a counter and a log line when postprocess reduces an utterance to nothing, instead of sealing "" - restore raw_text contract parity with the VAD path: text is corrected, raw_text preserves the engine output for the quality loop - group the six mutable seal counters into AppleSealState so the shared postprocessor instance survives the whole stream and emit_stream_events stays under the argument-count gate - report filtered_empty_drops alongside sealed count in the session log Tests: five apple_seal_lexicon_* cases cover the corrected seal, raw previews, the filtered-empty drop, the summary fallback seal, and idempotency under a second stop-path pass. Authored-By: claude <agents@vetcoders.io>
…or Apple path - add `LiveAudioBuffer`: bounded drop-oldest PCM ring addressed by session-time seconds, so a sealed `UtteranceFinal` resolves back to the audio behind it (Layer 1 tail-patch prerequisite, W2-A) - refuse rather than truncate: ranges evicted past the 120 s cap, starting past captured audio, or overshooting it beyond one chunk-quantisation step return `None` — a short window looks like success and would address wrong audio - reject non-finite / negative bounds instead of coercing them; `f32 as u64` maps NaN to 0 and saturates inf, same class as the non-finite `end_ts` guard - feed the buffer worker-side, off the same counter `audio_secs` is derived from, so buffer and seal clock cannot drift and the async select loop stays lock-free (2026-07-27 interleave contract) - resolve every seal to its window, prune committed audio, and count `unresolved_windows` — F3 falsification sensor visible in the live path before Whisper is wired onto the boundary clock Authored-By: claude <agents@vetcoders.io>
…pple progressive path
W2-A. `CODESCRIBE_LAYERED_TRANSCRIPTION=phase1+` now gap-fills the live canvas
on the daily-driver Apple path, not just on VAD/scheduler.
- Seal-time hand-off: every sealed `UtteranceFinal` resolves to its retained PCM
window (W1-B) and is handed to an async Layer 1 lane together with the exact
committed string `ReplaceRange` offsets are computed against.
- F1: the seal path runs on the PCM-forwarding worker thread, so it `try_send`s
into a bounded queue and counts drops instead of ever blocking capture; the
async side admits at most one job in flight and runs inference on
`spawn_blocking`, never on the event-drain loop.
- Ordering: the patch branch flushes every queued engine event before emitting,
so a `ReplaceRange` can never overtake the `UtteranceFinal` it patches.
- F3 carry-over: a boundary that cannot address retained audio stays counted as
unresolved and is never handed to Whisper.
- Stop path: the bounded backlog is settled after capture drains rather than
raced against `ev_rx` closing — a patch that lands only sometimes is worse
than one that always lands. Capture-sender safety still runs first.
- F2: `TailPatchConfig` thresholds untouched; the shared primitive keeps owning
the skip decision.
- Hoisted `tail_patch_enabled` / `compute_tail_patch_job` /
`emit_tail_patch_result` / `emit_session_finalised` to `pub(super)` so both
live paths read one gate and report one `LayerSummary` shape — no duplication.
- Deleted the `session.rs` honesty warning that said Apple progressive does not
run Layer 1; updated `tail_patcher` module docs and `docs/env.md`, which the
wiring turned into falsehoods.
- Tests (RED first): window/committed-text hand-off, unresolved window enqueues
nothing, layered-off wires nothing, backpressure drops without stalling,
induced gap emits one bounded `ReplaceRange{TailPatch}` and counts into
`SessionFinalised.layer_summary`, divergent re-transcription skipped, env gate
(serial). The Whisper leg itself is the shared VAD-path job, stubbed here
since no model is loadable under `CODESCRIBE_NO_EMBED=1`.
Authored-By: claude <agents@vetcoders.io>
… tail-patches - `assemble_live_from_events` dropped `ReplaceRange` on the floor, so every Layer 1 `TailPatch` was invisible to the live assembly — and the assembly is exactly what `capture_clip_via_device` measures. A layered-on parity run therefore scored identically to layered-off: the bar gated nothing. - Apply the patch to the sealed utterance it targets, keyed by `utterance_id` (parallel id vector; `LiveAssembly`'s public shape is unchanged). `rposition` mirrors the overlay's `lastIndex(where:)` so both sides patch the same slot. - Reuse `EngineEvent::apply_to_committed_text` — one source of truth for the char-offset contract, shared with the emitter's authoritative buffer. - Out-of-range and unbound windows are dropped whole, never half-applied; `InsertAnnotation` stays out (decoration, not transcript content). - Tests: patch lands on its own utterance, char-not-byte offsets, unbound / overrunning windows dropped, pre-seal patch does not retro-apply. - `parity_assembly_reads_layer1_tail_patches` guards the harness itself, always-on (no model, no loopback): layered-on must not read byte-identical to layered-off. - New `make test-engine-parity-layered` names the layered-on gate instead of leaving it an undocumented env incantation. Authored-By: claude <agents@vetcoders.io>
…ilPatch; composer consumes layer events
- `{selection_N}` markers anchor to absolute offsets in the live text captured
at selection time. A `ReplaceRange` that changes an earlier span's length
slid every marker behind it, walking the intent fence into the middle of an
unrelated word. `applyReplaceRange` now rebases them in the same transaction:
markers before the span hold, markers after ride the delta, markers whose
anchor text was rewritten collapse to the patch boundary (never dropped,
never left past the replacement).
- `renderedOffset(forTextOffset:)` translates Rust char offsets into rendered
offsets so annotation decoration cannot skew the rebase.
- `liveTextOffset(ofSegmentAt:)` mirrors `rawLiveText`'s own assembly (blank
segments dropped, single-space join) so the two cannot drift apart.
- `ComposerDictationListener.onReplaceRange` was an accidental no-op: the
composer builds its own preview from `onFinal`, so it kept showing text the
engine had already retracted — split-brain against the overlay. It now
applies bounded patches with the same drop-whole rule.
- `onContextMarker` / `onInsertAnnotation` stay inert on the composer path, now
documented as a deliberate destination-scoped contract rather than a gap.
- OverlayStateTests: mid-stream replace, own-utterance targeting, char-not-byte
offsets, unbound/out-of-range drop, and four marker-coexistence bars.
- ComposerMicTests: patch corrects the live preview, targets only its own
utterance, drops unbound/overrunning windows.
Authored-By: claude <agents@vetcoders.io>
…-0 bar stops scoring Layer 1
- `make test-engine-parity` did not control which lane it measured.
`CODESCRIBE_LAYERED_TRANSCRIPTION` is a power-user key, NOT promoted to
settings.json, so `Config::inject_file_env_for_runtime` copies it out of
`~/.codescribe/.env` into the process environment. The operator's dotenv
carries `phase1`, so Layer 1 armed itself inside a target whose whole
purpose is to score Layer 0 against an Apple-fidelity reference — and
Layer 1 is supposed to diverge from Apple. The bar went red for doing its
job, and the number was read as an engine regression.
- Receipt, one binary, consecutive runs of the same target: 05:32 census
`Other: 1` → similarity 0.931 PASS; 05:35 census `Other: 22` → 0.833 FAIL.
The 05:35 run is the one the supervisor refuted.
- The target now pins `CODESCRIBE_LAYERED_TRANSCRIPTION=off`. Explicit `off`
also blocks the injection at source: `inject_file_env_for_runtime` only
fills keys absent from the process env, and the settings.json seed in
`loader.rs` is guarded the same way.
- `e2e_apple_live_parity` snapshots the requested lane BEFORE capture (the
first `Config::load()` mutates the process env mid-run, so reading it
afterwards would report a leak as the request) and asserts it against the
lane the events actually show. `ReplaceRange { source: TailPatch }` has a
single producer, so the event stream is a witness no env read can
contradict.
- The mirror case is covered too: a layered target that produced zero
tail-patches scored Layer 0 while claiming to gate Layer 1 — the P1-01
shape, a gate asserting nothing about the thing it exists to gate.
- Seal-time lexicon (W1-A) also emits `ReplaceRange` and rides Layer 0 by
design; the guard counts `TailPatch` only, so it is not mistaken for a leak.
- Three always-on tests (no model, no loopback) cover leak, unarmed layer,
and the lexicon-on-Layer-0 case. RED observed on a stub before GREEN.
- The harness prints `layered lane: …` and the test prints `parity lane:
requested … · measured N tail-patch event(s)`, so every retained log under
`target/e2e-blackhole/` is self-describing.
- No bar was moved: `PARITY_SIMILARITY_BAR` stays 0.90.
Authored-By: claude <agents@vetcoders.io>
…t stop
- Add CODESCRIBE_QUBE_DONOR (off|on, default off) env + settings seed
- On stop, when on: copy WAV + delivered TXT to ~/.codescribe/qube_inbox/<date>/<session_ts>.{wav,txt}
- Donor writes files only — never Whisper; failures warn, never break delivery
- Register env; unit + controller donor_optin tests (layout, default-off, zero-Whisper Off, Smart)
Authored-By: grok <agents@vetcoders.io>
- Move ensureSpeechAuthorizedForSfSpeech into SF-only helpers (URL, buffer, stream) - Stop calling Speech auth before ST/SF backend selection on transcribe/stream/live - Rust init hard-fails / request_auth only when speech_recognition_tcc_required - Matrix tests: SF × speech_auth outcomes; ST ignores Speech TCC; mic orthogonal - Document backend-scoped TCC + responsible-process D1 (app vs bridge identity) Authored-By: grok <agents@vetcoders.io>
…parity bars - add a third Apple bridge lane, `dictation_transcriber` (SpeechAnalyzer family), gated OFF behind `CODESCRIBE_APPLE_DICTATION_TRANSCRIBER=1`; unarmed, probe/transcribe routing is byte-for-byte the shipped ST → SF order - probe/transcribe order becomes ST → DT (armed) → SF; the pure table now lives in `probe_backend_fallthrough` + `DictationLane` and replaces the narrower `probe_st_sf_fallthrough` seam - reserve the locale via `AssetInventory` before use: unreserved, DT reports `status == .supported` and the analyzer yields ZERO results with no error even though `installedLocales` lists the locale - compose the DT preset by hand (punctuation + volatileResults + audioTimeRange) because `.progressiveLongDictation` carries no time index and `BridgeSegment.startTs/endTs` is a hard bridge contract - scope Speech TCC honestly: DT ran the full 140.85 s pl-PL fixture with `SFSpeechRecognizer.authorizationStatus() == notDetermined`, so it joins ST on the not-required side of the W4-B matrix - fix `streamAudio`: the feeder fed `AVAudioConverter` one buffer per convert call and answered `.endOfStream` to every further pull, so a sample-rate conversion ended the stream after 1 buffer / 1486 frames of 2 253 600 — ST's file path was truncated to ~0.09 s (empty text, zero segments). Now pulls inside the input block and treats `framePosition >= length` as EOF; measured coverage 1.0000, last segment 140.82 s - add `examples/apple_backend_bars` — one lane per run, chosen by the same env the product reads, scored with the parity test's own aligner - measured (05_apple-live-parity, 140.85 s): DT 0.947 vs the system-dictation reference at ratio 0.99, head+tail sealed, byte-identical over 3 runs; the shipped SFSpeech streaming lane scores 0.898-0.931 and is not repeatable Authored-By: claude <agents@vetcoders.io>
… canaries - `scripts/smoke-macos27.sh`: durable per-beta host smoke. Headless rows only — raises no TCC dialog, posts no synthetic events, never reads pasteboard content unless asked; operator-only rows report SKIP instead of passing quietly. `--out` writes the filled checklist, `--with-inference` adds the Metal/candle cold-vs-warm row. - `scripts/smoke/macos27_probe.swift`: permissionless canaries — the 14 CoreGraphics constants `app/os/hotkeys/platform.rs` hardcodes as raw literals checked against the live SDK, CGEventTap create → force-disable → re-arm, TCC status matrix with the asking process named, and the S-5 `responsibility_spawnattrs_setdisclaim` dlsym canary. - `scripts/smoke/overlay_placement_probe.swift`: NSPanel placement proven by compiling `OverlayPlacement.swift` standalone — 65 assertions over six anchors × normal/fullscreen/secondary-display geometry plus stale-origin clamp. Skips the XCTest host, which boots AppModel and hangs beside the running app. - `scripts/smoke/appkit-observers.allow`: pinned census of AppKit-notification observers. The census is 4, not 1: three `NSScrollView` live-scroll observers in `MessageList.swift` are object-scoped with O(1) handlers, so the rule is "coalesced OR object-scoped", not "always coalesce". - `AGENTS.md`: the d79781b lesson as Operational Law 5, enforced by the census rather than left as prose. - `Makefile`: `make smoke-macos27` plus a help entry. Run on macOS 27.0 (26A5388g), Xcode 26.6, app 0.13.3 (447) live: PASS 8 · FAIL 1 · SKIP 5 · INFO 6. The single FAIL is real and is NOT a 27 regression — the Sparkle appcast at the shipped SUFeedURL returns HTTP 404 because `site/public/appcast.xml` never reached `main`, so Pages never published it. Left unfixed on purpose: publishing is an operator button. Authored-By: claude <agents@vetcoders.io>
…rected env keys W3-B. `validate-envs.sh` was green because it was not looking, not because the registry was complete: every pattern it scanned required the key as a literal at the call site, so `env_bool(ENV_DICTATION_TRANSCRIBER, false)` was invisible. - Scanner gains a fifth pass over `const NAME: &str = "KEY"` declarations, filtered by the repo's own ENV-token naming convention — which is why `LICENSE_PREFIX = "CSK1"` and the Keychain-account consts stay out. - RED first: with the pass added, 8 previously invisible keys were unregistered (checked variables 128 -> 140). - Registered all 8 with defaults read at the source, not guessed: CODESCRIBE_APPLE_DICTATION_TRANSCRIBER, CODESCRIBE_TAIL_PATCH_MAX_CHANGE_RATIO, CODESCRIBE_AGENT_MAX_TURN_ITERATIONS, CODESCRIBE_LICENSE_PUBLIC_KEY_HEX, and the four OpenAI/Anthropic OAuth client-id/issuer keys. - Corrected the CODESCRIBE_LAYERED_TRANSCRIPTION registry description, which still claimed Layer 1 runs on the VAD path only — false since a6b1233 — and recorded that it is a power-user key a stale dotenv can arm silently. - docs/env.md gains the DT gate and the Layer 1 safety threshold. `.env.example` needs no change: the mirror check is one-directional (example must be in the registry, not the reverse). Authored-By: claude <agents@vetcoders.io>
- runtime already defaults CODESCRIBE_LAYERED_TRANSCRIPTION unset → phase1; AGENTS.md, STT_CONTRACT, WHISPER_LIVE, the ADR 2026-08-08 table, and the tail_patcher module table still said opt-in/off — aligned to the code - THE_ENGINE_ROADMAP exec table no longer lists W13-2…6 as unstarted after settlement 13b1eed; §13 marks single-writer 75c89f5 done - lbrx file-mode stays a U-WER bench, never a canvas replacement; next field cut is take-614 fusion A/B, then operator flips - prettier on two W13 fixture docs so make check can see the aligned surfaces - ENV_REGISTRY / docs/env.md alignment landed in the same tree via 230443f (peer scooped those two files mid-gate) Authored-By: grok <agents@vetcoders.io>
…rmatting turns - 26d0982 dropped the instructions PARAM on chained Responses requests to stop the HTTP 400 — but instructions do NOT persist server-side across previous_response_id (OpenAI contract), so every chained formatting turn ran with no system prompt at all - live leak on build 661 (2026-08-14 12:06): gpt-5.4-nano answered the raw transcript as a chat assistant ("Jasne — oto to samo, przepisane czytelnie…" + a follow-up question) and that fiction shipped as the formatted lane; semantic guard flagged 0.746 and vetoed auto-paste only - chained turns now re-carry the prompt as a leading developer input item; first turns keep the instructions param only (no duplicate); all three call sites (plain, inline chunk, streaming) share build_responses_input - wire tests: chained request still has no instructions key AND carries the developer item; first turn carries neither duplicate Authored-By: claude <agents@vetcoders.io>
…agent turns - same promptless-chain class as 5d62aac, agent side: chained_instructions drops the instructions param (HTTP 400 pair) but the chain does NOT preserve instructions server-side, so every chained agent turn ran with no system prompt at all - new build_request_input prepends the prompt as a leading developer input item on chained turns only; first turns keep the param (no duplicate); no prompt configured => no developer item - corrected the lying doc comments (param contract vs server-side carry) - test chained_turn_recarries_prompt_as_developer_item covers all three shapes; existing 400-regression test stays green Authored-By: claude <agents@vetcoders.io>
…lero VAD probe - CODESCRIBE_SEAL_ATLAS_DUMP=<path>: after the session-end seal pass the Apple-live worker writes every SealedSpan (PCM range, per-word pins, whisper_words, typed evidence) as JSON — the session's own final state, not a reconstruction; no env, no-op - core/examples/vad_atlas_probe.rs: production Silero (embedded ONNX, default config) over a take WAV -> per-32ms speech probability + RMS/peak envelope on the same chunk grid, for overlaying seal-atlas word ranges - core/examples/format_chain_probe.rs: 1:1 exhibit for the promptless-chain formatting leak — two format_text turns in one process, second chained Verified on take 01 (60.1 s replay, live SFSpeech bridge): 11 sealed spans dumped; 20/20 word-grain pins sit >=75% on Silero speech chunks; span 2 exposes a 41-chars-in-100ms clock lie (known unresolved-window family). Authored-By: claude <agents@vetcoders.io>
…rsion after AUTO format - finalizeTranscript and late applyFinalTranscript now arm the one-step revert slot when the shown FINAL came from auto formatting and differs from the raw assembly; before, only manual Format armed it, so an auto-formatted transcript was a one-way door (operator agreement 2026-08-13, re-raised 2026-08-14) - guards: no arm when Auto Format is off, when a manual slot is already held, or when shown == raw (nothing to revert to) - tests: both arrival orders (authoritative-before-finalize and late) plus the Auto-Format-off negative; falsified against pre-fix code — same suite RED with 4 failures exactly in the new tests, GREEN 351/351 after Authored-By: claude <agents@vetcoders.io>
…tead of hard-failing - previous_response_not_found is key-scope poison, not retention: the id minted under a rotated-away Keychain key is invisible to the new key (measured 2026-08-12 22:31->23:02: three identical failures after the swap, transcript delivered raw; same-key chain proven alive hours later with full content recall on 2026-08-14) - one-shot recovery in the retry loop: drop the stored response_id for THIS mode only and re-run the same attempt unchained (first-turn shape carries the system prompt via instructions - no promptless leak) - retry loop converted to explicit counter so the recovery does not consume the (often zero) retry budget - unit test pins the classifier to the provider error code alone Authored-By: claude <agents@vetcoders.io>
…on path linearized - seven lines (Apple live, VAD/scheduler, Layer-1 tail-patch, stop path, formatting LLM, assistive agent, file/cloud) as station-by-station maps with file::symbol anchors verified on HEAD - seven named junctions (PCM clock, canvas, truth adjudication, postprocess, Responses chain, history, overlay delivery) with their contracts - dashed-lines table: all six built-but-OFF flags with evidence and the measurement each flip still needs - user-surface table: what each UI surface shows and which line feeds it Authored-By: claude <agents@vetcoders.io>
…reaming ground truth - new api_truth prompt section appended to BOTH composers (controller helpers + UniFFI bridge, both personas): /v1/responses wire shape, previous_response_id as durable server-side memory, the three measured sharp edges (pair-400, no prompt carry across chains, key/org-scoped ids), SSE event order, resp_stt cross-modal chaining, layered STT shape - ANSWER-FIRST RULE: extract intent from rough spoken requests and answer substantively; at most one clarifying question; never numbered option menus (operator incident 2026-08-14: engine question got a questionnaire) - anchor test pins the load-bearing facts through future edits Authored-By: claude <agents@vetcoders.io>
…nto a let-chain clippy collapsible_if (-D warnings) went RED on HEAD after 5f7755e and blocked everyone's gates; edition-2024 let-chain restores green with identical behavior. Authored-By: claude <agents@vetcoders.io>
…s and endpoints live together
- operator directive 2026-08-14: three tiers (vendors with PINNED official
endpoints + OAuth, custom compatible {endpoint,api-key} atomic rows,
STT lanes ws/ndjson/file); lanes consume provider references, never URLs
- names the measured drift classes it closes: chain poisoning on key swap,
dual auth identity per lane, slot asymmetry, contradictory settings surface
- invariants I1-I5 incl. chain state keyed by credential fingerprint with
reset-on-write (self-heal 65e578e demoted to backstop)
Authored-By: claude <agents@vetcoders.io>
…ed audio A first SFSpeech final that arrives after the 120 s retention horizon poisoned the whole session: last_sealed_end only advances on a successful resolve, so the [0..end_ts] window failed forever and Layer 1 received zero Whisper windows for the entire take. Measured live 2026-08-14: 247 s take, first final at 156 s, 11/11 unresolved_windows, tail-patch lane open but starved, WARN-only. - clamp from to retained_start_secs when it fell off retention (that audio is committed canvas by definition); WARN receipt on every clamp - genuine clock lies stay fail-closed: an end_ts that precedes the sealed canvas or overshoots the session still resolves to None (F3 contract) - test seal_window_clamps_start_after_retention_eviction: falsified — RED with the clamp disabled, GREEN with it; module suite 34/34 Authored-By: claude <agents@vetcoders.io>
…le engine lifecycle The product ships a "Hands-free silence" setting and the progressive lane logged a WARN that it ignores it — on every single take. One monolithic SFSpeech request ran for the whole session, so a take that is mostly silence starved the engine: measured 2026-08-14, a 247 s take whose first final arrived at 156 s went 11/11 unresolved windows and fed Layer 1 nothing. The threshold now drives the engine lifecycle: speech opens an SFSpeech epoch, silence past the threshold closes it (seal + finish), and the engine rests while the mic and Silero keep watching. The next speech edge wakes a fresh epoch with a 0.40 s pre-roll cut from retained audio. - EpochGate + SpeechEdgeSource (own SpeechSession, independent of the CODESCRIBE_SILERO_FUSION experiment flag); Silero unavailable = fail open to one continuous stream - shift_events: bridge timestamps are lifted onto the session PCM clock in ONE place, so seal windows, Layer 1 ranges and word pins keep speaking the same clock across epochs - retention and fusion ingest keep running while the engine rests - utterance_silence_sec unset = the pre-lifecycle worker, bit for bit - tests: shift identity at base 0, shift onto session clock, sleep after threshold silence + wake with pre-roll, disarmed never sleeps; falsified (2 RED against stubs, 4/4 green after wiring); module 38/38, chunker 15/15, clippy clean Authored-By: claude <agents@vetcoders.io>
…ire-truth change and defuse a two-clock flake - chunk_failure_is_fail_open_and_keeps_chain: the tail matcher pinned the OLD wire order (previous_response_id before instructions param); since 5d62aac the closing prompt rides as a leading developer input item INSIDE input, which serializes before previous_response_id - matcher updated to the current truth and strengthened (developer item required) - stop_seam settle waiter: 10s backstop raced the chunk request's own 10s budget under machine load (measured flake, chunk still Pending at the deadline); backstop moved out of reach to 30s and the three CODESCRIBE_INLINE_FORMAT_*_TIMEOUT_MS clocks pinned in the lane pin so the operator dotenv cannot recalibrate them under the tests - stability: 5 consecutive green family runs post-fix (was ~1-in-3 red) Authored-By: claude <agents@vetcoders.io>
…mary - Wire TOGGLE_SILENCE_SEC onto hold as well as toggle so EpochGate actually rests SFSpeech on the daily-driver Fn/Globe path and Layer 1 can be fed - Settings Layer 1 absent now matches core (unset → phase1); drop the "Experimental" lie that could persist off and starve the live tail-patch - Replay inherits settings silence when set; product copy/docs/registry describe epoch rest/wake, not wav-VAD auto-send - Name CODESCRIBE_VAD_* as dead folklore; register CODESCRIBE_SEAL_ATLAS_DUMP - lbrx stays a U-WER bench; fusion stays OFF; do not crown candle Authored-By: grok <agents@vetcoders.io>
… the canvas Three walls stood between a computed recovery and the user's text. All three were measured on the operator's own take (144425), 2026-08-14. 1. AUTHORITY GATE discarded richer truth. change_ratio>0.5 skipped the patch, and the under-commit escape needed 0.8 token coverage — which collapses exactly when Layer 0 mangles words, so the worse Apple heard the more certain the rejection. Live log: 295 change-ratio skips, 181 (61%) carrying MORE material, 5341 characters discarded. Now the two fused decisions are split: placing into the canvas still needs trusted anchors, but a starved canvas (Whisper carrying ~3x) escalates to the stop path instead of the receipt. Divergence on a healthy canvas still skips; low agreement still never touches the live canvas. 2. LATE COMPLETIONS WERE ORPHANED. tail_patch_outcomes was drained only inside the seal tick, so a window finishing after its span sealed sat in the map forever: the patcher logged 2 residual_required recoveries while the session counted under_commit_escalations=0 and the UI got zero warnings. deliver_sealed_tail_patch now delivers those, sharing one emit path with the seal tick. 3. FUSION CANCELLED LAYER 1. With the lane armed, a rewrite refused by the sealed fence returned Skipped — throwing away the bounded patches Layer 1 had already computed for the same audio. It now falls back to them: fusion loses the race, the append lane still lands. Measured effect on take 144425: escalations 0 -> 2, delivered text 171 -> 216 chars, "hard pruna" recovered correctly. KNOWN DEFECT, not fixed here: recoveries can duplicate a phrase the NEIGHBOURING utterance already carries (measured: 3 repeated 4-grams, WER 0.463 -> 0.610 on this take). canvas_already_carries only sees the patched utterance's own canvas; cross-utterance duplication needs the neighbour context this seam does not receive. Do not ship before that. Co-authored work: Silero edge unification, ledger->seal binding and the atlas receipt landed in the same tree from a dispatched agent. Authored-By: claude <agents@vetcoders.io>
…stop duplicate appends
Layer 1 sees one utterance at a time, so a phrase the canvas already holds
elsewhere reads as a gap and is appended a second time. Measured on the
operator's take the first run where recoveries reached the canvas at all:
three repeated 4-grams, WER 0.463 -> 0.610.
- TailPatchRequest carries neighbour_context (the sealed prefix); threaded
through the lane into compute_tail_patch_with_context. The VAD lane has no
sealed-prefix accumulator and passes empty, i.e. previous behaviour.
- canvas_already_carries matches a CONTIGUOUS run of DUPLICATE_RUN_TOKENS (4)
on alignment keys, in the utterance's own canvas or the neighbour's. Full-run
equality was defeated by the very defect it guards: one mangled edge word
('hard Pru' vs recovered 'hard pruna') and the duplicate lands anyway.
- classify_under_commit takes UnderCommitScan instead of growing an eighth
positional argument (no new clippy silencer).
- test reproduces the measured duplication and pins both halves: blind call
duplicates, context-aware call escalates and leaves the canvas byte-identical.
Gates: tail_patcher 31/31, streaming 162/162, clippy -D warnings clean.
STILL OPEN, measured this run: on take 144425 the duplicate comes from the
NEXT utterance, not a previous one — Whisper's window for a short utterance
carried speech Apple later assigned to the following final. A past-only
neighbour context cannot see it; the delivered text is unchanged (216 chars,
same three repeated 4-grams). Deduplication has to happen where the canvas is
complete (reducer/delivery) or the patch must wait for its neighbour. Not
shippable until that lands.
Authored-By: claude <agents@vetcoders.io>
…y delivered Layer 1 computes a patch against the canvas as it stood when the job was dispatched. SFSpeech can restate the SAME utterance at greater length in the meantime and deliver those words itself; the patch then lands on the restatement and duplicates the phrase. Measured on take 144425: an append computed for a 15-char canvas landed on the 47-char restatement — three repeated 4-grams, WER 0.463 -> 0.610, i.e. the recovery cost more than it gained. The reducer is the last place that sees the canvas as it actually stands, so the guard sits there: pure insertions (start == end) are dropped when the committed text already carries a 4-token run of them, via the new public seam. Substitutions are untouched — they replace the very span they would be compared against. Replay of the same take: duplicate 4-grams 3 -> 0, WER 0.610 -> 0.439, and a genuine gap fill still lands (pinned by the new reducer test). HONEST LIMIT: on this take Whisper now contributes almost nothing to the LIVE canvas (174 chars vs 171 without Layer 1) — most recoveries route to residual_required, i.e. the stop path, which this harness does not measure. The next measurement is delivered text after stop, not live_text. Authored-By: claude <agents@vetcoders.io>
…t the live canvas The harness printed live_text only, so every measurement this session judged the during-hold canvas and called it the result. Layer 1 recoveries that cannot be placed inline are escalated as residual_required — i.e. explicitly owed to the stop path — and that path was invisible here. First measurement with it visible, take 144425: DELIVERED == LIVE TEXT, 174 chars, byte-identical. The escalated recoveries add nothing. Authored-By: claude <agents@vetcoders.io>
…he coverage bar Hypothesis, after finding that escalation has no executor (stop path is routing_off on this lane and composes its residual from session partials, never from Layer 1): if the recovery cannot be escalated anywhere, place it even on weak anchors and let the last-mile duplicate guard sort it out. Measured across five takes, DELIVERED text vs the lbrx reference: take OFF ON delta 01_no-to-dobra 0.356 0.425 +0.068 02_kubernetes 0.713 0.713 0.000 03_algorytm 0.726 0.709 -0.017 05_apple-parity 0.784 0.773 -0.010 144425_loctree 0.439 0.439 0.000 mean 0.604 0.612 +0.008 Rejected. Words placed beside an anchor the canvas cannot vouch for land in the wrong part of the sentence more often than they fill a real gap, and the duplicate guard cannot catch that — it catches repeats, not misplacement. Reverted; the verdict is recorded where the bar is read so the next session does not re-run it. Two findings worth more than the experiment: - Delivered WER against lbrx is 0.44-0.78 across these takes REGARDLESS of the flag. The gap is not in this gate. - 05_apple-parity delivers 30 repeated 4-grams and 03_algorytm 6, with Layer 1 patches barely involved — that duplication comes from the Apple lane's own restated finals, not from recovery. Unexamined. Authored-By: claude <agents@vetcoders.io>
- clear a fully re-heard Apple final instead of presenting the committed canvas as a volatile tail - make SessionFinalised persist committed canvas and close the presentation emitter on the Apple path - pin both production seams with regressions proven red before the runtime fix and green after it Authored-By: Codex <agents@vetcoders.io>
- Merge the five-commit fusion authority series with cumulative-final duplication guards. - Keep W13 fusion default OFF and align the lane docs with the engine roadmap. - Remove process-env test races and capture restart-only idempotence per session. Authored-By: Codex <agents@vetcoders.io>
- make Silero fusion default ON with explicit falsey off-switch tokens - align the active lane map and env registry with the canonical transcript-lanes contract - preserve race-free pure flag parsing and verify the full hermetic gate Authored-By: Codex <agents@vetcoders.io>
- restore the original engine roadmap rule that default flips stay operator decisions - keep the fusion implementation available behind an explicit truthy env value - align the env registry and pin the unset-default behavior with a focused test Authored-By: Codex <agents@vetcoders.io>
- clamp Apple callback timestamps to the captured sample clock before advancing the seal floor - count tail patches only after the live worker accepts them and abandon orphaned stop-time work honestly - pace the WAV channel replay through the production buffered-session helper Authored-By: Codex <agents@vetcoders.io>
m-szymanska
approved these changes
Aug 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Carries the accumulated branch work plus today's stop-path and STT cuts.
What this fixes
The stop path cost 49.5s on a take that owed no work. Measured 2026-08-12,
stop_path_budget: total=49.492s phases={rec_stop=36.701s, final_pass=0.000s, postproc=0.122s, format=11.085s}.rec_stopwas a timeout on the wrong condition. Theend-of-session closure loop exited on
pending_spans().is_empty(), but a spancan be held by the Apple volatile window rather than by a missing Whisper
window, and no completion clears that gate. It now waits on outstanding
Layer 1 jobs. Verified live after install:
rec_stop36.7s → 6.9s.the PCM sample counter while span timestamps come from SFSpeech's segment
clock, which can sit milliseconds ahead — the span missed the volatile window
by one millisecond and froze there.
seal_remaining_at_session_endanchorson the spans' own timestamps.
formatwas a cold embedder loaded in series behind the LLM.The load now overlaps the model round-trip, scoped to lanes that will
actually reach the semantic guard.
The live-overlay repetition, root-caused and fixed. SFSpeech cumulative
finals REVISE the previous hypothesis (substitutions "szuty" → "skróty",
insertions, deletions). The segment-less rescue split the novel suffix with an
exact
canvas.contains(prefix)probe — anchored at the callback's first wordand all-or-nothing — so one revised word re-committed the whole restatement.
The 2026-08-12 18:44 take delivered 62% of its words inside a repeated 6-gram,
one phrase four times over.
revision_tolerant_known_prefixreplaces theprobe: longest callback prefix within
max(1, k/5)word edits (bandedword-level edit distance over the canvas tail; 1-2-word probes stay exact; the
matched prefix's last word must itself align, so trailing novel speech can
never be deleted into the match).
Verified by replaying the operator's actual take WAV through the production
Apple lane (
tests/replay_take.rs, ignored diagnostic harness, env recipe inits doc):
contains319 delivered words against ~318 spoken — parity with speech; the residual is
largely the take's genuinely repeated content.
A dead Apple STT bridge took the whole app down. Rust's SIGPIPE-ignore
setup never runs in a
cdylibinside a Swift host; the firstwrite_pcmafterthe bridge died killed the application with no ReportCrash entry. Same defect
the MCP client already carried a fix for (U14,
a35a64b); the per-fdF_SETNOSIGPIPEremedy now lives inutil::pipesand both callers share it.Engine warnings no longer discard the transcript.
EngineEvent::Warningisnon-fatal by FFI contract, but the overlay's phrase-matching filter let
recoverable warnings reach
presentTerminalError, which clears every committedutterance. A non-empty draft is never thrown away now.
A correction, stated plainly
f8519df2removed the lexicon pass from the cumulative-final prefix probe onthe strength of a comment claiming the canvas was pre-lexicon. The claim was
false and the change was a regression; it is reverted in
7dc7bf28with aguard that actually exercises a lexicon rewrite.
Still open
take against a dead engine and only admits it at stop time.
formatis the provider generating tokens over SSE.Gates
cargo test -p codescribe-core --lib— 1189 passed, 0 failed, 6 ignoredcargo clippy --workspace --all-targets -- -D warnings— cleanmake verify-swift-format— wired intomake lintthis branchAuthored-By: claude agents@vetcoders.io