# SpeakTrue Work Log

## 2026-09-16 — Auto-unload previous Local TTS model; test CPU is Launch Services + iCloud

**Outcome.** Loading a second Local TTS model now unloads the resident one first on iOS and Android. iOS previously released MLX weights but left Pocket/MOSS/NeuTTS ONNX sessions in the engine registry. Android overwrote `loadedProfileId` without calling `unload()` on the previous family's engine. Preparing the next model now unloads every registered engine (and iOS MLX weights) before download/load of the replacement. Reloading the same model does not unload first.

**CPU during testing.** `lsd` here is macOS Launch Services (`/usr/libexec/lsd`), not a looping `ls`. At inspection it was idle (0%). The live cost during `xcodebuild`/Gradle was `SWBBuildService` (~256% CPU, the Swift build), `fileproviderd` (~110%), `mds_stores`/`mds` (Spotlight), `CoreSimulatorService`, and `fseventsd`. The SpeakTrue repo lives under iCloud-synced `~/Documents/Programming/SpeakTrue`, so compiler and test file writes wake File Provider and Spotlight. Simulator test installs also register the app with Launch Services, which is when `lsd` spikes.

**Verification:** iOS Simulator `LocalQwenPrototypeTests.testEngineRegistryUnloadAllReleasesEveryEngine` and `testMossReferenceClampKeepsTheMostRecentSpeech` **TEST SUCCEEDED**. Android `:app:testDebugUnitTest` for `LocalTtsViewModelTest` and `LocalTtsEngineRegistryTest` **BUILD SUCCESSFUL**, including `preparingSecondModel_unloadsTheFirstEngine` and `unloadAllReleasesEveryRegisteredEngine`. `git diff --check` passed. Full `scripts/verify_android_ci_local.sh` not run. No commit/push. No new device install.

**State:** uncommitted atop `4fb41740716faa25ff97fa32347bca934a5a05b1`. This slice also rides on the earlier uncommitted Qwen stream / MOSS memory work. No new untracked files from this slice.

## 2026-09-09 — Successful Qwen 6-bit sampling runs, user-confirmed quality


Latest device history confirms two runs with the same 223-character script and reference, temperature 0.9, top-k 50, repetition penalty 1.05452 and ceiling 4096. Top-p 1 produced 16 s audio in 14.7589 s (RTF 0.922, first internal audio 2.2071 s). Top-p 0.90248 produced 14 s audio in 12.6342 s (RTF 0.902, first internal audio 1.2889 s). Device tokenizer encodes this script to 47 tokens, giving a hidden SDK cap of 22.56 s; both outputs ended below that cap, consistent with natural EOS. Explicit token traces are still unavailable. User reports the unwanted tail is fixed and quality/speed are decent; no independent listening claim. Different script from the earlier failed 269-character run prevents isolating causality to sampling. Both top-p values worked; do not credit top-p reduction alone.

Sampling settings are now user-validated candidates; no app defaults or runtime code changed. Broader long-text/repeated-run validation remains pending. Device history retrieved read-only and token count checked locally. No audio/transcript content copied into documentation. Repository dirty state preserved atop 13dfb226, build remains 62, no new repository files, no commit/push/build. Map refreshed and checked at closeout.

## 2026-09-09 — Qwen stopping investigation; build remains 62

Read-only device tokenizer retrieval and local encoding verified 59 text tokens for the latest run. Pinned SDK hidden limit is min(user ceiling, max(75, text tokens times 6)): 354 codec frames / 12.5 Hz = 28.32 seconds, exactly matching the WAV. EOS is checked before appending audio frames, so evidence strongly indicates limit exhaustion without natural EOS; no token trace was retained. The reason EOS was not selected remains unresolved. Inspected suppression, sampling, ICL text-EOS prompt and stream finalization; no missing EOS check or duplicate final append found. Runtime currently ignores token events. Current sampling differs from upstream defaults (top-k 0 versus 50, repetition penalty 1.1 versus 1.05); causality unproven.

Natural stopping investigation is active. Next proposed slice: retain per-section EOS/limit diagnostics, then controlled repeated comparisons with the same script/reference and one sampling setting changed at a time. User excludes blunt duration trimming and transcription-based stopping. No runtime settings or generation behavior changed, and no new build/device generation was performed. Additional device config retrieval timed out in CoreDeviceService after tokenizer retrieval succeeded; device config was not reverified. No private transcript/audio included here.

Changed this slice: docs/guides/ios-local-qwen-prototype.md only; prior 12-file dirty state preserved atop 13dfb226. No new uncommitted files. Verified tokenizer count, WAV sample duration, pinned source and upstream source; git diff --check passed. No commit/push. External map regenerated and checked at closeout.

## 2026-09-09 — Qwen tail diagnosis and single temperature control, build 62

Retrieved latest Qwen 6-bit history/WAV from the phone. Total generation 23.2931 s; output 28.32 s; first internal chunk 1.8229 s. Settings: temperature 0.9, top-p 1, top-k 0, repetition penalty 1.1, ceiling 4096. Local cached Whisper-base places final requested words around 17.7 s; trailing approximately 10.6 s contains low-level nonzero sound, mostly -38 to -51 dBFS in one-second RMS windows. No external ASR received audio. ASR is supporting evidence, not proof of silence/non-speech. Inspected pinned Qwen streaming path emits each chunk once plus final remainder; no full-output duplication found. Late end-of-sequence behavior remains unresolved. File RTF 0.823 includes unwanted tail and is not a useful-speech speed claim.

Confirmed Variation and Temperature were duplicate bindings. Removed the redundant Variation control; one Temperature (variation) slider remains with clear help. Values/ranges and generation behavior unchanged. Prepared separate 18.30 s trimmed preview under /private/tmp/speaktrue-qwen6-trimmed-preview.wav; original phone clip unchanged. No automatic trimming introduced; avoid cutting quiet intended speech. No audio or transcript content stored in repo/vault.

Release 1.3 (62) built, installed over the existing iPhone app, launched and device version verified. Android/iOS parity passed 12 surfaces/24 gates; git diff --check passed. No new tests needed for the duplicate-control removal; prior build-61 suite had 52 passing focused tests. No physical tap-through or new generation result claimed.

This slice changes ios/SpeakTrue/LocalQwenPrototypeView.swift, ios/SpeakTrue.xcodeproj/project.pbxproj, android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt (iOS build assertion), docs/guides/ios-local-qwen-prototype.md, docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md and docs/product/LOCAL_QWEN_GENERATION_SETTINGS_PLAN.md. Prior changes preserved; 12 modified tracked files atop 13dfb226, no new uncommitted files. No commit/push, GitHub Actions or TestFlight upload. Full local Android gate remains required before commit/push. External map refreshed/checked at closeout.


## 2026-09-09 — Manual model unload, build 61

Added Unload from memory in the expanded Local TTS model controls. It names and unloads the model actually in memory, even when a different model is selected. Busy state prevents generation, load/delete, selection and repeated unload during the operation. Runtime unload releases weights, cached reference waveform/tokens and MLX cache; storage indicators refresh afterward. Downloaded model files, voice profiles, generated output and history remain. Generation requires reloading a model. Loading a replacement still unloads automatically; selection alone does not.

Verification: 52 focused LocalQwenPrototypeTests passed; signed Release 1.3 (61) built and installed over the existing app on Yoseif’s iPhone. Android/iOS parity passed 12 surfaces/24 gates; git diff --check passed. Runtime/button wiring reviewed, but no instrumented on-device RAM measurement or tap-through result claimed. OmniVoice accuracy remains unresolved from the earlier report; this task does not change generation math.

Changed this slice: ios/SpeakTrue/LocalQwenViewModel.swift, LocalQwenPrototypeView.swift, ios/SpeakTrue.xcodeproj/project.pbxproj; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt (iOS build assertion only); docs/guides/ios-local-qwen-prototype.md and docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md. Prior build-60 changes preserved. Total working tree: 11 modified tracked files atop 13dfb226; no new uncommitted files. No commit, push, GitHub Actions or TestFlight upload. Full local Android gate is required before committing/pushing the accumulated parity assertion. External map refreshed/checked at closeout.


## 2026-09-09 — Build 60 completes but speech fidelity fails

Build 60 completed the latest on-device OmniVoice run, but the user reports inaccurate speech; local cached Whisper-base ASR supports omissions/reordered words. Output 18.56 s, total 50.2075 s, RTF 2.705; diffusion 46.2285 s (92.1%), decoding 1.6797 s, reference encoding 2.2327 s (cache miss), preparation 0.0386 s and assembly 0.0257 s. Settings: 16 steps, guidance 2, speed 1. This is not the same text as the earlier baseline, so no controlled speedup is claimed.

The selected reference is 34.3846 s, with broadly matching transcript according to local ASR. Upstream OmniVoice recommends 3–10 s and warns that longer references can slow inference and degrade quality (https://github.com/k2-fsa/OmniVoice#voice-cloning). Our generic 10–30 s app guidance is unsuitable for this family and remains to be corrected. Long conditioning is a hypothesis, not confirmed causality; real-codec window equivalence also remains unverified. Quality status remains failing pending repeat comparison.

Prepared a separate 7.10 s first-sentence reference and matching transcript under /private/tmp/speaktrue-omnivoice-reference-test for user import as an alternative. Original phone profile/recording unchanged. Excerpt duration and local ASR checked. User should compare the same target text with unchanged 16-step/guidance/speed settings before further tuning. No external transcription service or external model received the audio; no audio/transcript content copied to the vault or repository.

This turn changed only docs/guides/ios-local-qwen-prototype.md and docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md; prior nine-file build-60 dirty state remains uncommitted atop 13dfb226. No new uncommitted repository files. No new app code, build, install, commit/push, CI run or TestFlight action. git diff --check passed; external map refreshed/checked at closeout.


## 2026-09-09 — OmniVoice memory termination and consent retry, build 60

Build 60 is implemented, signed Release-built, installed and launched on Yoseif’s iPhone; device app inventory confirms 1.3 (60). Device jetsam reports at 21:27:03 and 21:29:31 on 2026-09-09 explicitly identify SpeakTrue as killed for vm-pageshortage. The latest has 358358 resident pages at 16384 bytes/page, approximately 5.47 GiB. The exact generation stage is unproven. Initial CoreDevice 12040/12010 developer-image errors later cleared. Reports remain outside the repository/vault; no raw logs or user audio/text copied here.

Memory mitigations: evaluate conditional and unconditional diffusion passes separately, and decode 100-frame windows with 32 context frames on each side using the unchanged pinned codec. Trim shared context without additional fades, silence or crossfades; materialize CPU samples and release each decoder graph before the next window. Validate codec geometry, decoded length and finite samples; emit content-free Release phase/memory logs. The default sampling calculations and final normalization remain unchanged. Physical repeat-generation, listening continuity and measured memory/latency improvement remain pending.

Consent bug: failed remote lookups no longer mean missing consent. Preserve same-account verified acceptance on transient refresh failure, show a retry screen for unknown status, and reject stale responses after account reset/change. Only an actual negative result opens the notice. This fixes a code path that could explain the reported prompt, without claiming that the exact network failure was captured. The app-wide consent requirement remains; OmniVoice does not invoke ElevenLabs generation.

Verification: 52 focused Simulator tests passed (consent failures/account isolation, CPU-only decoder-window boundaries/length/errors and existing local TTS tests). Initial MLX-in-Simulator tests aborted in Metal initialization; the final tests exercise window orchestration without claiming real codec inference. Final Release build passed, Android/iOS parity passed 12 surfaces/24 gates, and git diff --check passed. No GitHub Actions triggered; no commit or push. Full Android local gate remains required before a future commit/push of the build assertion.

Working tree atop 13dfb226: nine modified tracked files: ios/SpeakTrue/AIDataSharingAgreementService.swift, AIDataSharingConsentGateView.swift, LocalOmniVoiceModel.swift, LocalQwenRuntime.swift; ios/SpeakTrueTests/LocalQwenPrototypeTests.swift; ios/SpeakTrue.xcodeproj/project.pbxproj; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt (iOS build assertion only); docs/guides/ios-local-qwen-prototype.md; docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md. No new uncommitted files. No archive/TestFlight upload.


## 2026-09-09 — Build 59 changes committed and pushed

2026-09-09: All 18 pending files committed and pushed to origin/main as 13dfb226ea6631619acb44f144c0818d67fbed41 (iOS 1.3 build 59). Includes Local TTS reliability, OmniVoice orchestration/configuration, TTS/STT integration, model controls, private history, tests and product documentation. Android source change is solely the release test assertion for iOS build 59. Commit includes [skip ci] as requested; no workflow configuration was changed. The full local Android CI-equivalent gate passed (unit suite, lint, release bundle, parity/readiness and backend contracts); external live checks remain unverified. Previously verified iOS Release build/install and focused tests remain the iOS evidence. Physical audio quality and latency testing remain pending. Working tree is clean; all three formerly untracked Swift files are now committed.

Earlier entries below are historical snapshots. The pending local commit gate is now satisfied; no archive or TestFlight upload was performed.

## 2026-09-08 — Release 59 delivered to Yoseif’s iPhone

2026-09-08: Optimized Release 1.3 (59) rebuilt successfully, installed over the existing app on Yoseif's iPhone 16 Pro Max, and launched successfully. Device app inventory confirms version 1.3 / build 59. No uninstall was performed. Physical generation, listening quality, latency and full UI smoke testing remain pending. No archive or TestFlight upload. Repository source unchanged by this delivery; existing changes remain uncommitted and unpushed atop d182a818.

Verification: xcodebuild Release build succeeded; devicectl install and launch succeeded; device app inventory verified; git diff --check passed. Existing 15 modified tracked files preserved. Existing new uncommitted files: ios/SpeakTrue/LocalOmniVoiceModel.swift, ios/SpeakTrue/LocalOmniVoiceModelConfig.swift, ios/SpeakTrue/LocalTTSHistoryStore.swift. No new repository files added this task. External map refreshed and checked at closeout.

## 2026-09-08 — Generation-first Local TTS workspace and history, build 59

Implemented all seven approved recommendations: compact expandable model setup; independent voice selection/preview and Manage voices; persistent Generate/Cancel with blocking reason; real stage and elapsed progress with estimates gated on three comparable saved-reference runs; immediate editor settings captured in each request with explicit default persistence; simple playback/regenerate/share/WAV export and expandable diagnostics; private rolling 20-clip history with replay, settings reuse and deletion. Preserved model-button colours, editable section colours and STT copying to both TTS drafts; STS remains unchanged. Reference previews stop before generation/recording. Current unsaved references can regenerate while available; history does not preserve reference audio. The history actor protects files, excludes the folder/audio from backup, caps retained entries, and refuses to replace unreadable metadata. Clips and text/settings remain after sign-out; user deletion and Files export are explicit actions.

Changed this slice: ios/SpeakTrue/LocalQwenPrototypeView.swift, LocalQwenViewModel.swift, LocalQwenContracts.swift, LocalQwenRuntime.swift, LocalOmniVoiceModel.swift and new LocalTTSHistoryStore.swift; ios/SpeakTrueTests/LocalQwenPrototypeTests.swift; ios/SpeakTrue.xcodeproj/project.pbxproj; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt (build assertion only); docs/guides/ios-local-qwen-prototype.md; docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md and LOCAL_QWEN_GENERATION_SETTINGS_PLAN.md. Earlier TTS/STT integration and cache fixes were preserved.

Verification: xcodebuild focused LocalQwenPrototypeTests suite passed 46 tests with zero failures, including history round-trip/cap/deletion, unreadable-index preservation, request snapshots and estimate gating. A final isolated rendering test passed after correcting large-text picker overlap; normal and accessibility render attachments were visually inspected under /private/tmp/speaktrue-ui59-screens-final. Generic-iOS optimized Release build passed for 1.3 (59). Android/iOS parity verifier passed 12 surfaces/24 gates; git diff --check passed. No physical-device generation, keyboard/navigation flow, export-picker interaction or estimate accuracy verification is claimed. No actual latency gain is claimed.

Working tree: 15 modified tracked files and 3 new uncommitted files: ios/SpeakTrue/LocalOmniVoiceModel.swift, ios/SpeakTrue/LocalOmniVoiceModelConfig.swift, ios/SpeakTrue/LocalTTSHistoryStore.swift. The first two predate this slice. State remains uncommitted atop d182a818; no push, install, archive or TestFlight upload. Full Android CI-equivalent gate remains required before committing/pushing the parity assertion. Generated maps index the three new files after they become tracked.

## 2026-09-08 — Coloured Local TTS model buttons, build 58

Replaced the dropdown and duplicate inventory list with five coloured adaptive buttons. Selection uses checkmark/border plus accessibility selected traits; each button shows name, approximate size and storage/preparation state. Loaded models show both Downloaded and Loaded in memory. Existing separate download/load/cancel/delete controls remain. Larger accessibility text uses a flexible single column to avoid horizontal overflow. Failed preparation refreshes inventory to avoid stale storage labels.

Changed this slice: ios/SpeakTrue/LocalQwenPrototypeView.swift, ios/SpeakTrue/LocalQwenViewModel.swift, ios/SpeakTrue.xcodeproj/project.pbxproj, android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt (build assertion), docs/guides/ios-local-qwen-prototype.md and docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md. Earlier TTS/STT integration and OmniVoice work preserved. Optimized generic-iOS Release 1.3 (58) built; Android/iOS parity passed 12 surfaces/24 gates; git diff --check passed. No new UI tests or device rendering/inference verification claimed; prior build-57 suite passed 41 tests. Physical UI/status and latency checks remain pending. Full Android gate is required before committing/pushing.

Uncommitted atop d182a818, no commit/push/install/archive/TestFlight upload. Working tree has 14 modified tracked files and two existing new uncommitted files: ios/SpeakTrue/LocalOmniVoiceModel.swift and ios/SpeakTrue/LocalOmniVoiceModelConfig.swift. This slice adds no files. The generated map indexes those adapter files after they become tracked.

## 2026-09-08 — Integrated Local TTS into the TTS tab, build 57

Implemented Standard / Local TTS modes and removed the Voice Cloning lab card. STT Copy to TTS now populates both drafts, including the hidden mode; STS remains unchanged per the user's correction. The local view model is owned by MainTabView, preserving its draft and loaded model across mode switches. Playback pauses and active reference recording is cancelled when leaving the local view; main-tab exit cleans temporary references and cancels operations.

This slice changed ios/SpeakTrue/MainTabView.swift, TextToSpeechView.swift, TTSViewModel.swift, SpeechToTextView.swift, VoiceCloneTabView.swift, LocalQwenPrototypeView.swift and LocalQwenViewModel.swift; ios/SpeakTrueTests/LocalQwenPrototypeTests.swift; ios/SpeakTrue.xcodeproj/project.pbxproj; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt (build assertion only); docs/guides/ios-local-qwen-prototype.md and docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md. Earlier LocalQwenContracts/Runtime and OmniVoice adapter work was preserved. No STS source change.

Verification: xcodebuild test -only-testing:SpeakTrueTests/LocalQwenPrototypeTests passed all 41 focused Simulator tests; optimized generic-iOS Release build passed for 1.3 (57). python3 scripts/verify_android_ios_parity_release.py passed 12 surfaces/24 gates; git diff --check passed. Device UI/generation and measured latency remain unverified. No commit, push, install, archive or TestFlight upload. Full Android CI-equivalent gate remains required before committing/pushing the parity assertion.

Working tree: 14 modified tracked files and 2 existing new uncommitted files, ios/SpeakTrue/LocalOmniVoiceModel.swift and ios/SpeakTrue/LocalOmniVoiceModelConfig.swift. This slice adds no new files. The map will index those two adapter files after they become tracked. State remains atop d182a818.

Status: active from 2026-07-25 onward.

This is the concise completion record for agent work in the SpeakTrue repository. It records outcomes and verification, not raw conversations or sensitive runtime data. Repository source, tests, tracked docs, and verified live state remain authoritative.

## 2026-09-08 — Implement OmniVoice reference-token reuse and phase timings

Delivery: optimized Release iOS 1.3 (56) build succeeded at /private/tmp/speaktrue-warning-fix/build/Build/Products/Release-iphoneos/SpeakTrue.app. No installation attempted, following the user's request to keep working on code while away from home. Device performance and listening validation remain pending.

2026-09-08, build 56: code-only OmniVoice latency work is implemented locally. A single in-memory reference-token cache encodes once before the section loop and reuses unchanged audio across later runs. Keys use reference-file SHA-256 plus sample rate, not temporary paths; model replacement/unload and profile deletion clear it, and failed/cancelled encoding is not cached. The app-owned LocalOmniVoiceModel/Config adapter reuses the SDK backbone, codec and parameter type while exposing prepared-token generation and phase timings. Default and custom settings now show diffusion-step progress. The timing panel reports reference preparation/encoding, diffusion, decoding and WAV assembly, cache reuse and build mode. Physical-device speed and quality remain unverified while the user is away.

- New uncommitted files: ios/SpeakTrue/LocalOmniVoiceModel.swift and ios/SpeakTrue/LocalOmniVoiceModelConfig.swift. Their MIT notices identify the pinned mlx-audio-swift source. No external package checkout modified. The local model loads the app-verified main checkpoint directly and retains the repaired default-cache handoff for the SDK audio codec.
- Existing files changed: LocalQwenRuntime.swift (cache and timed prepared-token path), LocalQwenContracts.swift (cache key/storage and metrics), LocalQwenPrototypeView.swift (phase/build labels and custom-step progress copy), LocalQwenViewModel.swift (clear cache after profile deletion), LocalQwenPrototypeTests.swift, project.pbxproj (build 56; Xcode ordering-only serialization changes preserved), AndroidReleaseReadinessContractTest.kt (build assertion), prototype guide and multi-model plan. Prior uncommitted fixes retained.
- Verification: 40 focused Simulator tests passed, including reference reuse, changed content/sample rate, explicit clearing, failed/cancelled encoding, pinned backbone defaults, and MLX discovery/replacement with explicit ModuleInfo storage. The explicit storage avoids Swift property-wrapper isolation warnings. Source comparison confirms unchanged diffusion loop and 11 core helper bodies. Android/iOS parity passed 12 surfaces/24 gates; git diff --check passed. Full Android gate not run; no commit or push.
- Limits: no phone generation, listening comparison, or speed gain measured. The original two-section/16-step baseline remains 141.93 s total for 37.48 s audio. Tokens are memory-only and bounded to one reference; no saved reference/audio/transcript material is placed in documentation. Map refreshed/checked at closeout; untracked files are listed here because the map will index them only after tracking.

## 2026-09-08 — Record user-provided OmniVoice latency baseline

Measured user baseline (2026-09-08): OmniVoice at 16 diffusion steps, two generation sections, first-audio metric 52.52 s, total generation 141.93 s, output 37.48 s, real-time factor 3.79. Local ffprobe independently confirms the attached WAV is mono float32 PCM at 24 kHz and 37.475 s. No listening-quality assessment is claimed from that metadata check. The first-audio metric marks an internally completed section; playback currently waits for the assembled output. Stage-specific timing and the benefit of reference-token reuse remain unmeasured. Optimized Release 1.3 (55) remains ready but uninstalled; the paired iPhone is still unavailable. No reference audio or transcript contents copied into these notes.

Read-only attachment metadata and device availability checks; no repository changes this turn, no new uncommitted files, no install, commit or push. Existing dirty working tree preserved. External map refreshed and checked at closeout.

## 2026-09-08 — Establish an optimized OmniVoice latency baseline

Outcome: Release iOS 1.3 (55) build succeeded; compiler output verifies -O for the app, MLX and MLXAudioTTS. Install attempt failed because the paired iPhone is unavailable; device listing confirmed the same unavailable iPhone 16 Pro Max. Artifact: /private/tmp/speaktrue-warning-fix/build/Build/Products/Release-iphoneos/SpeakTrue.app. Reconnection, installation and comparative latency readings remain outstanding. git diff --check passed; external map refreshed and checked. No installation, measured speed gain, commit or push is claimed.

2026-09-08 latency investigation: user still finds OmniVoice too slow at 16 steps. Prior device installs were Debug builds with Swift -Onone. Preparing an optimized Release build of the same iOS 1.3 (55) source as the next performance baseline. Source inspection confirms reference encoding repeats per section and the public OmniVoice API does not accept encoded reference tokens; waveform delivery waits for a whole section. No latency improvement or new reference cache is claimed until measured on the phone.

- This task changes the prototype guide and external project status only; prior uncommitted source fixes are preserved. No new uncommitted files. No app code or version change in this slice.
- The actual Release compiler invocations enable -O and whole-module optimization for MLX and supporting modules. Request sent for total-generation and output-duration readings using the same reference/text/settings. The previous 36-test Simulator result belongs to build-55 editor validation; no fresh test-suite result is claimed here.
- Runtime phase timing, encoded-reference reuse, lower-precision model evaluation and measured latency remain pending. No commit or push; full Android gate remains required before the accumulated parity assertion is committed.

## 2026-09-07 — Inline generation section colours (build 55)

Delivery: signed iOS 1.3 (55) built successfully and installed on Yoseif's iPhone over the network. External map refreshed and checked at closeout. Phone editing/visual validation remains pending.

Build 55 (2026-09-07): generation sections now use alternating text colours inside the editable generation box. The separate section-boundary preview is removed; the section count and character limit remain. Original whitespace and emoji are preserved, and the colours use the actual generation chunker. All 36 focused Simulator tests passed, including Unicode/whitespace range coverage; Android/iOS parity checks passed. User reports very good OmniVoice quality after build 54, with slow generation on iPhone 16 Pro Max. Profiling and encoded-reference reuse remain proposed, not implemented.

- Affected files: LocalQwenPrototypeView.swift (native attributed TextEditor and removal of boundary disclosure), LocalQwenContracts.swift (original-text section ranges), LocalQwenPrototypeTests.swift (range coverage), project.pbxproj (build 55), AndroidReleaseReadinessContractTest.kt (parity assertion), prototype guide and multi-model plan. Existing review and cache-repair edits preserved. No new uncommitted files.
- Verification: focused Simulator suite 36 passed, zero failed/skipped; parity check passed 12 surfaces/24 gates; git diff --check passed. Visual/cursor interaction on the phone remains a user check. No commit or push; full Android gate not run.

## 2026-09-07 — Repair OmniVoice's actual loader cache (build 54)

Delivery: signed iOS 1.3 (54) build succeeded and was installed on Yoseif's iPhone over the network. Reloading OmniVoice and listening to a new generation remain pending. Repository and external docs reflect the local uncommitted repair; git diff --check passed and the external map was refreshed and checked at closeout.

Build 54 OmniVoice repair (2026-09-07): device inspection confirmed a separate SDK-default model cache containing only 281,103,571 bytes versus the pinned 2,450,344,102-byte model present in the app-managed folder. Nested OmniVoice resolvers ignore the supplied cache; the old seed helper targeted its own source directory. The runtime now atomically publishes verified files into HubCache.default before loading, replaces existing entries and removes that cache on deletion. A regression test covers truncated and same-size corrupt cache files, repeated hard links and source preservation. All 35 focused Simulator tests passed. This confirms the cache repair, not audible speech quality; reload and generation/listening validation remain required.

- Latest generated device output inspected locally: valid float32 mono 24 kHz WAV, 6.4 seconds, finite samples, peak 0.5 and near-constant energy; consistent with the user's constant-noise report. No reference recordings, transcripts or raw audio were placed in documentation.
- Affected files this continuation: LocalQwenRuntime.swift, LocalQwenContracts.swift, LocalQwenPrototypeTests.swift, iOS project build 53 to 54, AndroidReleaseReadinessContractTest.kt, prototype guide and multi-model plan. Prior ViewModel/UI review edits remain preserved. No new uncommitted repository files.
- Verification: initial repeat-publication test exposed Foundation replacement failing for identical hard links; switched to atomic POSIX rename and reran the complete focused suite, 35 passed with zero failures/skips. Android/iOS parity verifier passed 12 surfaces / 24 gates. Full Android gate not run; no commit or push.

## 2026-09-07 — Review latest pushes and correct Local TTS behavior

Review 2026-09-07: origin/main remains d182a818a720dae19c5a311bdb78f216751ce63e. Local iOS 1.3 (53) corrections are implemented and uncommitted: cancellation reaches the owned transfer, an independent 25-second watchdog detects silent stalls, initial progress and known-size fallback remain visible, family switches reload saved editors, Chatterbox exposes only its supported temperature/top-p controls, and custom OmniVoice first-audio timing records the first section. All 34 focused Simulator tests and the signed generic iOS device build passed; the Android/iOS parity verifier passed. Physical tests were blocked by the locked iPhone; no new installation or listening validation is claimed. The full Android gate remains required before committing/pushing the updated build assertion. Chatterbox/OmniVoice listening, paragraph/speed work and presets remain pending; the prototype guide was refreshed.

- Reviewed main changes from 311cf548 through d182a818 against source, generation plans and pinned MLX Audio implementation. Independent native standards and spec reviews corroborated the cancellation, watchdog, family-editor and unsupported-control findings. Published Obsidian exports are intentionally dated snapshots and were preserved.
- Changed tracked files: ios/SpeakTrue/LocalQwenRuntime.swift, LocalQwenContracts.swift, LocalQwenPrototypeView.swift and LocalQwenViewModel.swift; ios/SpeakTrueTests/LocalQwenPrototypeTests.swift; ios/SpeakTrue.xcodeproj/project.pbxproj; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt; docs/guides/ios-local-qwen-prototype.md; docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md.
- Verification: focused LocalQwenPrototypeTests via xcodebuild on iPhone 17 Pro Simulator (34 passed, zero failed/skipped); signed generic iOS xcodebuild succeeded; python3 scripts/verify_android_ios_parity_release.py passed 12 surfaces / 24 gates; git diff --check passed. Regression cases cover cancellation before/after transfer start, timeout without byte callbacks, supported controls and family switching. These tests do not prove real-network throughput or model audio quality.
- Working tree: nine modified tracked files; no new uncommitted files. No commit, push, deployment or phone installation. External map refreshed and checked for the current HEAD at closeout.

## 2026-09-07 — Pull main and refresh local documentation

Local sync 2026-09-07: fast-forwarded main from 311cf548 to d182a818a720dae19c5a311bdb78f216751ce63e (20 commits, 25 changed paths). Source inspection confirms iOS 1.3 (52), Qwen/Chatterbox/OmniVoice catalog, owned download transfers, family-scoped saved settings and OmniVoice diffusion controls. Incoming work logs report 31/31 focused iPhone tests and build 52 installed/launched; these were not rerun or reverified on-device during this pull. Chatterbox/OmniVoice listening, remaining paragraph/speed work, presets, guide refresh and the later deferred Android gate remain outstanding.

Merged incoming project notes and preserved both local September 6 publication entries. Refreshed the external codebase map and checked its manifest against HEAD. Repository remained clean; no source edits, commits, pushes, build or test runs in this task. No new uncommitted files. Earlier notes about uncommitted build 40 or proposed settings are historical; source and this sync summary take precedence.

## 2026-09-07 — Phase 5b: OmniVoice diffusion knobs (build 52)

- Outcome: implemented OmniVoice diffusion controls with per-voice persistence. New `LocalOmniVoiceGenerationSettings` (numSteps 8-64, guidanceScale 1.0-4.0, speed 0.75-1.5; library defaults 32/2.0/1.0) stored per voice and revalidated through the clamping initializer by `LocalOmniVoiceParametersResolver` before reaching the model. The generation card shows Diffusion steps, Guidance, and Speed sliders with Save/Reset for the selected voice when OmniVoice is the family. Runtime behavior: at library defaults OmniVoice keeps the streaming protocol path (diffusion step fractions visible); with custom knobs the runtime downcasts to `OmniVoiceModel` and calls the ovParameters overload per section — section-level progress only, because the streaming wrappers hardcode library defaults (documented; upstream streaming-with-ovParameters is the eventual cleanup). Generation requests carry `omniVoiceSettings`; sampling-family settings are unaffected by OmniVoice overrides. iOS build 51 -> 52; Android parity assertion updated to 52.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 31/31, including three new tests (defaults and clamping including non-finite fallbacks, resolver mapping and isDefault detection, per-voice OmniVoice persistence with sampling-family independence). Signed device build 52 installed and launched on Yoseif's iPhone (network). Android gate still deferred per user instruction (iOS-only session); parity assertion rides in-tree.
- Pending: user listening evidence for Chatterbox and OmniVoice generation (phase 3/4 gates); A/B comparisons and presets closeout; prototype guide refresh; internal LocalQwen* renames; deferred Android gate.
- State: code commit 89f2d3e7 plus this documentation commit on main; pushed to origin/main. Map refreshed and checked.

## 2026-09-07 — Phase 5a: family-scoped generation settings (builds 50-51)

- Outcome: implemented family-scoped per-voice generation settings. Voice profiles now persist overrides per family (`generationSettingsByFamily` keyed by family raw value); legacy single-blob overrides migrate into the Qwen3-TTS slot on decode and re-encode in the new shape. The store resolves per (voice, family), the ViewModel editor reloads on model-family switches, and Save-for-this-voice / Reset operate on the selected family. The generation card shows the Variation and Sampling controls only for families that consume the sampling contract (Qwen3-TTS and Chatterbox); OmniVoice shows an explanatory note instead (diffusion defaults: 32 steps, guidance 2.0). Generation requests resolve settings for the selected model's family. iOS build 50 -> 51; Android parity assertion updated to 51.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 28/28, including new tests for legacy-blob migration into the Qwen slot (with round-trip) and per-family independence (save/clear one family leaves the others intact); existing per-voice persist/switch/reset, VM editor, and snapshot tests updated to the family-aware API and green. Signed device build 51 installed and launched on Yoseif's iPhone (network). Android gate still deferred per user instruction (iOS-only session); parity assertion rides in-tree and the full gate runs before any Android-facing release work.
- Pending: OmniVoice diffusion-knob controls (phase 5b) with their own settings type and family mapping; A/B listening comparisons and presets closeout (needs user listening evidence for Chatterbox/OmniVoice); prototype guide refresh; internal LocalQwen* renames; deferred Android gate.
- State: code commit e7011154 plus this documentation commit on main; pushed to origin/main. Map refreshed and checked.

## 2026-09-07 — Trace and rebuild model downloads as an owned transfer (builds 46-50)

- Outcome: root-caused the download freezes and rebuilt the transfer as an owned, fully-traced pipeline. Diagnostics (build 46) proved the device's URLSession reached the CDN (probe status 200 via us.aws.cdn.hf.co) while zero body bytes registered through the package's progress indirection. Root cause: URLSessionDownloadTask writes to its own temp file and reports bytes only through per-task delegate callbacks, which the async download(for:delegate:) path did not deliver on device; the staging file stays empty until the final move, so the fileProgress-based indicator, the interim disk-polling indicator, and the 25 s disk watchdog all misread healthy transfers as stalled. Rebuilt (builds 47-49) as an owned transfer: a runtime-private URLSessionDownloadTask with a session-level delegate (the pattern proven in builds 35-40), continuation-based completion, byte-level progress relayed to the UI, a 25 s stall watchdog on real delegate bytes, three fresh retries with backoff, and the SHA verification plus staging move preserved. Added the download speed readout (build 50): smoothed MB/s blended from 300 ms byte deltas, shown as "37% · 900 MB of 2.45 GB · 7.4 MB/s". User confirmed Qwen 4-bit and OmniVoice now download with a moving progress bar.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 26/26 across the slices. Endpoint audit documented: resolve chains return 302 to the Xet-bridge CDN with HTTP 200, full GETs stream ~7.7 MB/s from the Mac, URLSession repro pulled 17 MB in 1.1 s with the app's exact configuration, IPv4 and IPv6 both healthy. Signed device builds 46-50 installed and launched on Yoseif's iPhone (network). iOS build 47 -> 50; Android readiness parity assertion bumped to 50.
- Android gate note: the full verify_android_ci_local.sh run was intentionally deferred per user instruction (iOS-only focus this session); the parity assertion edit rides uncommitted-gate, and the complete gate must run before any Android-facing release work or Play-bound commit.
- Pending: user listening checks for Chatterbox and OmniVoice generation (phase 3/4 gates); OmniVoice load retest after the cache-seed fix; phase 5 open; internal LocalQwen* renames deferred.
- State: code commit 37c8abfb plus this documentation commit on main; pushed to origin/main. Map refreshed and checked.

## 2026-09-07 — Self-healing model downloads (stall watchdog + transport rotation)

- Outcome: the endpoint audit cleared the CDN — both pinned files stream from the Mac at ~7.7 MB/s on plain full GETs through the Xet-bridge signed URLs (154 MB in 20 s; ranged GETs 206), so the stall was device/transfer-path specific, not the endpoint. The download path is now self-healing: a watchdog polls the staged file on disk and cancels any attempt whose bytes stop arriving for 25 s, then retries fresh (up to three attempts) while rotating transports (.lfs then the automatic path twice) — rotating transports also rotates the CDN route and protocol, which is the likely fix for a device-specific stalled route. Hard errors (auth/404) break immediately without retry; user cancellation propagates through the attempt cancellation handler; after the final failed attempt the error surfaces as "The connection for <file> stalled after multiple attempts" instead of a silent freeze. iOS build 44 -> 45; Android parity assertion updated to 45.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 26/26. Signed device build 45 installed and launched on Yoseif's iPhone (network). Complete verify_android_ci_local.sh passed after the parity bump. `git diff --check` clean.
- Pending: on-device observation — whether the transfer now self-heals or surfaces the stalled error; Chatterbox/OmniVoice listening checks; phase 5 open.
- State: code commit 869c7a7b plus this documentation commit on main; pushed to origin/main. Map refreshed and checked.

## 2026-09-07 — Disk-polled download progress, honest load copy, fine-tuning future direction

- Outcome: fixed the model-download indicator freeze by polling the staged file's size on disk every 200 ms as ground truth (completed bytes now move whenever bytes are written, independent of the download client's Progress-object semantics; total comes from the pinned manifest). The load phase copy now states large models can take a few minutes, so the silent fp32 conversion window is not mistaken for a freeze. Recorded the per-user fine-tuning feasibility assessment as a future direction in the multi-model plan: zero-shot cloning stays the default; Mac-assisted per-user LoRA (mlx-tune lists Qwen3-TTS stable, mlx-audio-train RFC exports compatible adapters, chatterbox-finetuning PyTorch toolkit) is feasible today as a "studio voice" spike with strict on-device/no-server privacy design for the biometric-derived weights; on-device training assessed as not practical (memory math + no Swift training stack). iOS build 43 -> 44; Android parity assertion updated to 44.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 26/26. Signed device build 44 installed and launched on Yoseif's iPhone (network). Complete verify_android_ci_local.sh passed after the parity bump to 44. `git diff --check` clean.
- Pending: on-device re-download observation with the disk-polled indicator, OmniVoice load/generate retest, Chatterbox listening checks; phase 5 open.
- State: code commit 404db860 plus this documentation commit on main; pushed to origin/main. Map refreshed and checked.


## 2026-09-07 — Fix OmniVoice local load and size-aware download progress

- Outcome: fixed the OmniVoice load failure ("unsupported type optional omnivoice from local directory") — root cause is the vendored `TTS.loadModel` dispatcher having no local-directory closure for the omnivoice family (and no `OmniVoiceModel.fromModelDirectory` upstream). The runtime now routes OmniVoice through `fromPretrained` with the shared cache after hard-linking the verified manifest files into the flat `<cache>/mlx-audio/<repo>` directory the package resolver checks first, so the load resolves from the app's verified bytes with no duplicate download; an upstream PR (dispatcher closure plus `fromModelDirectory`) is the eventual cleanup. Also made the download indicator size-aware: the runtime seeds each file's `Progress.totalUnitCount` from the pinned manifest, and the card now shows "percent · completed of total" with a determinate bar before the server reports a content length; friendly file labels cover the new families' paths (tokenizer, codec, chat template). iOS build 42 -> 43; Android parity assertion updated to 43.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 26/26. The generation card was refactored during this slice (settings and progress blocks extracted into @ViewBuilder properties) after a SwiftUI type-check timeout; all behavior unchanged. Signed device build 43 installed and launched on Yoseif's iPhone (network). Android gate running in background at closeout time (result recorded before push). `git diff --check` clean.
- Pending: on-device retest of the OmniVoice download/load/generate path with the seeded cache and the Chatterbox listening checks from the prior slice; phase 5 open.
- State: code commit 360e1cc6 plus this documentation commit on main; pushed to origin/main. Map refreshed and checked.


## 2026-09-07 — Implement Local TTS Lab multi-model phases 0-4

- Outcome: executed phases 0-4 of docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md. Phase 0 recorded the discovery results in the plan (pinned revisions, SHA-256 manifests, 24 kHz sample rates, streaming granularity, cloning constraints). Phase 1 renamed user-facing copy to "Local TTS Lab" (navigation title, delete dialog, share clip name, simulator message, model card label) with identifiers and type names unchanged. Phase 2 introduced `LocalTTSModelFamily`/`LocalTTSModelProfile`/`LocalTTSModelCatalog` — the runtime loads via `TTS.loadModel(modelType: profile.family.rawValue)` from the verified local directory, the model picker groups by family, language lists and memory thresholds are per-family, and language resets to English when a family lacks the current selection. Phases 3-4 added the Chatterbox multilingual fp16 profile (3-file manifest, 2.70 GB; S3TokenizerV2 ~495 MB auxiliary download is package-managed and disclosed in the summary) and the OmniVoice fp32 profile (9-file manifest, 3.27 GB; cloning requires the full checkpoint; sampling sliders do not apply — diffusion defaults). iOS build 41 -> 42; Android parity assertion updated to 42.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 26/26, including five new catalog tests (family order/type strings, Chatterbox and OmniVoice manifest integrity, per-profile languages/memory/manifest sizes) and the existing generation-settings, sampling-mapping, and snapshot tests regressed clean. Signed device build 42 installed and launched on Yoseif's iPhone (network). Android gate running in background at closeout time (result recorded before push). `git diff --check` clean.
- Pending: on-device download/load/generation and listening checks for Chatterbox and OmniVoice (8 GB classification experimental); phase 5 (family-scoped settings, A/B comparisons, presets) open; internal LocalQwen* renames deferred.
- State: code commit 57180319 plus this documentation commit on main; pushed to origin/main. No new uncommitted repository files after this closeout beyond the doc updates themselves.


## 2026-09-07 — Plan Local TTS Lab multi-model (Chatterbox + OmniVoice)

- Outcome: prepared docs/product/LOCAL_TTS_LAB_MULTI_MODEL_PLAN.md — a phased plan to rename the on-device Local Qwen Lab to "Local TTS Lab" and add Chatterbox and OmniVoice as model families with the same download-verify-load-generate flow, per-family languages and memory guidance, and family-scoped settings in a later phase. Internal LocalQwen* type/file renames are explicitly deferred to a mechanical follow-up commit.
- Grounding evidence: the vendored mlx-audio-swift (d9e6e7c) already exposes the runtime's model as the generic SpeechGenerationModel protocol loaded via TTS.loadModel with an explicit modelType from the verified local directory ("qwen3_tts" hardcoded today); ChatterboxModel and OmniVoiceModel conform to the same protocol; the loader accepts "chatterbox"/"chatterbox_tts"/"chatterbox_turbo" and "omnivoice" from local directories. Chatterbox streams .audio/.info events at 24 kHz with cloning via refAudio (Regular ~500M/23 languages, Turbo ~350M English with 8/4-bit variants). OmniVoice voice cloning requires the full fp32 checkpoint — the bf16 conversion strips the semantic encoder — with diffusion knobs (numStep 32, guidanceScale 2.0 defaults) in OmniVoiceGenerateParameters.
- Phases: 0 discovery/manifests (pin revisions, SHA-256 manifests, sample rates, streaming granularity) -> 1 user-facing rename -> 2 family-aware registry/loader/resolver refactor -> 3 Chatterbox end-to-end -> 4 OmniVoice end-to-end -> 5 family-scoped settings and A/B listening closeout. Each phase carries device gates; build bumps pair with Android parity updates and the full Android CI-equivalent gate.
- State: planning only; no code changed in this task. Vault planning status reclassified with a Proposed entry; map refreshed and checked. No new uncommitted repository files after this closeout beyond the plan and doc updates.


## 2026-09-07 — Close phase 0 and implement generation settings phase 2

- Outcome: phase 0 closed on user confirmation that on-device generation works at defaults; aggregate timing/memory metrics remain uncaptured. Phase 2 implemented and committed at 2a335f1c: the runtime resolves the request's settings snapshot through LocalQwenSamplingResolver (revalidates via the clamping initializer) and forwards temperature, top-p, top-k, repetition penalty, and the generated-audio-token ceiling to the Qwen adapter, replacing hardcoded literals; built-in defaults resolve to the prior fixed behavior. Prototype card adds a Variation slider mapped to temperature, always-visible sampling controls (user feedback: no hidden Advanced section) with help text and low-ceiling truncation warning, Save-settings-for-this-voice / Reset defaults, and a structured generation progress indicator — determinate bar from the SDK's progress events plus section count and tokens/s readouts. iOS build 40 -> 41; Android readiness parity assertion updated to 41.
- Verification: focused xcodebuild test of LocalQwenPrototypeTests on the connected physical iPhone passed 21/21, including three new mapping tests (built-in defaults parity, validated bounds forwarded, out-of-range edits re-clamped). Complete verify_android_ci_local.sh passed after the android/** parity edit: backend contract tests 22/22, clean unit suite, lint, signed release bundle build and verification (1.3/25), Android/iOS parity, Play local readiness, git diff --check. Build 41 installed and launched on Yoseif's iPhone (network).
- Pending: device listening checks at defaults and selected bounds (VoiceOver, Dynamic Type, narrow layout) remain with the user; phases 3-5 of the plan remain open.
- State: code commit 2a335f1c plus this documentation commit on main; pushed to origin/main. No new uncommitted repository files after this closeout beyond the doc updates themselves.


## 2026-09-07 — Document, commit, and push Local Qwen settings phase 1

- Outcome: committed and pushed the previously uncommitted phase 1 of the generation settings plan as cce80bf6 "feat(ios): add local qwen generation settings contract" (5 files, +424/-2): validated LocalQwenGenerationSettings value (sampling/segmentation/output) with fallback normalization, immutable per-request settings snapshot in LocalQwenGenerationRequest, per-voice overrides with explicit save/reset in LocalVoiceProfileStore and LocalQwenViewModel, legacy-profile default decoding, the nonisolated settings-normalizer warning fix, and seven phase 1 gate tests. Settings are not yet consumed by generation (runtime retains fixed 0.9/1.0/1.1 defaults) and no settings UI exists; phases 2-5 open.
- Verification: focused xcodebuild test of SpeakTrueTests/LocalQwenPrototypeTests on the connected physical iPhone (Yoseif's iPhone, network destination) — all 18 cases passed including the seven new phase 1 gate tests; TEST SUCCEEDED. Android parity assertion (CURRENT_PROJECT_VERSION 40) untouched because the iOS build number stays 40 for this non-user-visible slice; Android gate not applicable (no android/ changes). git diff --check clean.
- Vault updates: planning status reclassified from Proposed to In progress with phase 1 committed evidence; SpeakTrue.md active-work note updated; map regenerated and checked. Phase 0 baseline evidence remains unrecorded in docs and should be captured before wiring new sampling values into generation.
- State: code commit cce80bf6 plus this documentation commit on main; pushed to origin/main. No new uncommitted repository files after this closeout beyond the doc updates themselves.

## 2026-09-06 — Remove obsolete repo copy; iOS 18 asset purge needs Apple storage UI

- Outcome: deleted the obsolete repository copy at `~/Documents/SpeakTrue` per user confirmation that `~/Documents/Programming/SpeakTrue` is canonical. Verified first: HEAD `25f748b8` dated 2026-06-07 (months behind main), zero untracked and zero modified files — the only working-tree deltas were deletions of retired agent tooling already preserved in git history. Full 2026-06-07-era repo copy including node_modules and graphify-out; exact size not measured before deletion.
- Blocked: attempted root removal (via macOS admin dialog) of the three orphaned iOS 18.x simulator asset copies in `/System/Library/AssetsV2` (~25.4 GB). Failed with "Operation not permitted" even as root — the assets are owned by `_nsurlsessiond` and SIP-restricted. The asset registry xml no longer references them (0 matches), so they are orphaned pending purge. Sanctioned removal is via Apple's own UI: Xcode → Settings → Components, or System Settings → General → Storage → Developer (iOS Simulator Runtimes); system garbage collection may also reclaim unreferenced assets over time. Storage Settings pane was opened for the user.
- State: no repository source changes; documentation-only closeout. Map refreshed and checked. Total storage reclaimed today: ~39.8 GB simulator runtimes + ~7.8 GB stale DerivedData + obsolete repo copy (size unmeasured); ~25.4 GB remains pending the Apple storage UI.

## 2026-09-06 — Install build 40 on Yoseif's iPhone and finish DerivedData cleanup

- Outcome: installed and launched iOS 1.3 (40) on Yoseif's iPhone (iPhone 16 Pro Max, network) per user request. First install attempt used the wrong artifact: CLI builds map the current project path to DerivedData `SpeakTrue-ewzlgtrokzumvodnuvmhmumoszus`, while `SpeakTrue-alewgyfselbmjxfdhfgvazaznifr` is an orphan of the pre-restructure project path (repo `SpeakTrue/SpeakTrue.xcodeproj` era, March 2026) holding a 1.0 (1) relic that was briefly installed. Rebuilt via CLI (packages re-fetched; BUILD SUCCEEDED with only pre-existing MLX C++17-extension dependency warnings), confirmed CFBundleVersion 40 / 1.3 with team 3286WRK4FC signing, then installed and launched successfully.
- User Xcode recovery: deleting stale DerivedData while Xcode was open removed its `swift-nio-ssl` checkout, surfacing "The file x509_trs.cc couldn't be opened". The CLI rebuild regenerated SourcePackages on disk; the user should run File → Packages → Resolve Package Dependencies (or rebuild) in Xcode to clear the in-memory missing-file reference.
- Machine maintenance: stale DerivedData cleanup completed per user approval. Deleted `SpeakTrue-fdcerosaofjlfjaivctjtsbboyit` (~1.1 GB), `SpeakTrue-fzryfcidmzcsobaojdrznairqhuo` (~285 MB), and `SpeakTrue-alewgyfselbmjxfdhfgvazaznifr` (~1.6 GB); `SpeakTrue-ewzlgtrokzumvodnuvmhmumoszus` regenerated fresh at ~3.0 GB. A single DerivedData folder remains; ~7.8 GB net reclaimed this step, on top of the ~39.8 GB runtime deletion earlier today. The 25.4 GB `/System/Library/AssetsV2` sudo removal remains pending with the user.
- State: no repository source changes in this slice; documentation-only updates (this work log). Map refreshed and checked in closeout. The `~/Documents/SpeakTrue` duplicate-repo copy remains unexamined and untouched.

## 2026-09-06 — Fix Qwen settings isolation warnings; verify signed device build

- Outcome: marked `LocalQwenSettingsNormalizer` as a `private nonisolated enum` in `LocalQwenContracts.swift`, clearing 19 "main actor-isolated static method 'clamped'/'decoded'" warnings caused by the project's `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` default; the pure clamping/decoding helpers need no actor isolation. Removed the stale `SpeakTrue-primary.priors` file that produced the `SwiftDriver.ModuleDependencyGraph.ReadError` (error 14) cross-module incremental warning; a fresh priors file regenerated on rebuild. iOS version/build unchanged at 1.3 (40).
- Verification: generic physical iOS Debug build (signing disabled) succeeded with no Swift warnings and no priors warning. Signed device build for Yoseif's iPhone (iPhone 16 Pro Max, network destination id EB3F14EB-22DD-5EB0-BCF7-6914E83CC48E) succeeded; Debug-iphoneos app bundle has embedded.mobileprovision and valid codesign (identifier YH.SpeakTrue). Not installed to the device in this task (build only, per user request); simulators not used. Correction: the codesign-verified bundle in this check was later identified as a stale March 2026 relic from a pre-restructure project path; see the following entry for the corrected install.
- Machine maintenance (no repository effect): deleted five old simulator runtimes (iOS 18.3.1, 18.4, 18.5, 26.0.1, 26.3.1; ~39.8 GB) via `simctl runtime delete`, keeping the iOS 26.5 runtime and the existing iPhone device. About 25.4 GB of orphaned iOS 18.x system asset copies in `/System/Library/AssetsV2` require a user-run sudo removal and remain pending. Also identified ~9.2 GB of stale SpeakTrue DerivedData directories pending user approval; discovery only, nothing deleted.
- State: change uncommitted atop 77e76019. This task modified `ios/SpeakTrue/LocalQwenContracts.swift` and this work log; four other modified files (`LocalQwenRuntime.swift`, `LocalQwenViewModel.swift`, `LocalVoiceProfileStore.swift`, `LocalQwenPrototypeTests.swift`) are pre-existing user work preserved untouched. No new uncommitted repository files from this task. Map refreshed and checked in this closeout.

## 2026-09-06 — Publish vault into repository and commit Qwen build 31-40 stabilization

- Vault publication: SpeakTrue Obsidian project notes were published to the repository as commit c1abc18a (`docs/obsidian/*`, `docs/product/LOCAL_QWEN_GENERATION_SETTINGS_PLAN.md`, index links). Local main fast-forwarded to it; the external vault path is absent on this machine, so `docs/obsidian` inside the repository is now the synced vault location for `scripts/refresh_obsidian_docs.py` via `SPEAKTRUE_OBSIDIAN_PROJECT_DIR`.
- Commit 311cf548 "fix(ios): stabilize local Qwen downloads and generation" lands the previously uncommitted build 31-40 work: 10 files, +773/-119. Contents: pinned HF revisions with per-file expected sizes and SHA-256 in `LocalQwenContracts.swift` (6-bit model.safetensors 1,164,476,202 bytes; speech codec 682,293,092), staged `.download-` transfers with `verifyHashes: true` in `LocalQwenRuntime.swift`, progress/cancellation UX (builds 35-36 fixes), profile lifecycle hardening, `increased-memory-limit` entitlement (build 40), +96 lines of `LocalQwenPrototypeTests` regression coverage, Android readiness assertion update, prototype guide expansion, and build 40 / version 1.3 in the Xcode project.
- Verification: fast-forward pull succeeded; greps confirmed the expected-size/SHA-256 contract in `LocalQwenContracts.swift` and the `verifyHashes: true` staging path in `LocalQwenRuntime.swift`; entitlements contain the increased-memory key; `CURRENT_PROJECT_VERSION = 40` / `MARKETING_VERSION = 1.3`; working tree clean at 311cf548 except three untracked Apple signing artifacts at the repository root (`AuthKey_RM5837C69K.p8`, `SubscriptionKey_C3LWLUG8VJ.p8`, `SpeakTrue.mobileprovision`) that still need relocation out of the repository. No device inference evidence was produced in this session.
- State: local main == origin/main at 311cf548. Planning status updated: the build-31 "remains uncommitted" note is superseded, and the Local Qwen generation settings plan implementation is authorized to start with phase 0 baseline evidence on the physical device before phase 1 settings-contract code. Map refresh and check run in this entry's closeout; no new uncommitted repository files beyond this documentation update.

## 2026-09-05 — Confirm truncated six-bit checkpoint and enforce integrity

- User reported only about 1.69 GB downloaded and unusable six-bit output. Direct device file-size comparison with public Hugging Face metadata confirmed root model.safetensors was 995086264 bytes versus expected 1164476202; speech codec size matched 682293092. The old nonempty-file check wrongly accepted the truncated checkpoint.
- Build 37 pins all three model revisions and exact required-file sizes, verifies SHA-256 of model and speech-codec checkpoints with cancellable 1 MB reads, repairs invalid files through cache-disabled HTTP downloads into staging, and replaces only verified files. Existing valid files remain. UI has a distinct verifying state. No audio/profile data was fetched for this diagnosis.
- Verification: compiled Swift regression cases rejected missing, truncated, and equal-size corrupt data and accepted the valid checksum; signed physical iPhone build 37 passed and was installed/launched. Android/iOS parity and git diff --check passed. Full XCTest/Android CI gate not rerun. User instructed to run six-bit Download & load for repair; repaired download and speech remain pending, no success claim yet.
- State: iOS 1.3 (37); eight modified repository files atop 4cc7b69d, no new repository files or commit/push. Same affected file set as preceding entries, now including expected-file integrity manifests and tests. Prototype guide updated; vault map refreshed/checked.

## 2026-09-05 — Confirm cancellation and stabilize progress layout

- User confirmed Cancel works in build 35, but reported missing progress bar and changing model-card width during downloads. Build 36 keeps the card/content full width after the wide Download button disappears, uses short file-purpose labels with wrapping, always renders the linear progress track, and shows connecting/received-byte status until a server size permits percentage display. The working HTTP cancellation implementation is retained.
- Verification: signed physical iPhone build 36 passed and was installed/launched on Yoseif's connected device; Android/iOS parity script and git diff --check passed. Physical layout review and full six-bit download/generation remain pending; no broad quality claim. Four-bit speech and download cancellation were user-confirmed on prior builds. Full XCTest/Android gate not rerun for these uncommitted fixes.
- State: iOS 1.3 (36), eight modified repository files atop 4cc7b69d; no new files, commit, or push. Updated prototype guide and vault status; map refreshed/checked. Affected file set unchanged from prior generation/preparation entries.

## 2026-09-05 — Confirm 4-bit speech and replace stalled download transport

- User confirmed decent 4-bit speech generation in build 34 after codec repair, with subjective quality below target. This is physical iPhone generation evidence, not a broad quality/performance certification. User then deleted 4-bit, attempted 6-bit, and reported stalled progress at 4.5 MB plus stuck cancellation; supplied screenshot showed stopping state.
- Build 35 changes preparation to download required files sequentially using Hugging Face's explicit HTTP/LFS transport, bypassing automatic snapshot/Xet large-file transfer. Progress names the current file and reports bytes. Cancellation explicitly invalidates the URLSession; 30-second request inactivity timeout and six-hour resource limit apply. Completed files are preserved; interrupted file transfer may restart. Existing missing-codec validation, 2 MB MLX cache limit, duplicate-load prevention and previous-model release remain.
- Verification: signed iPhone build 35 passed, installed and launched on Yoseif's connected iPhone. Android/iOS parity script and git diff --check passed. User asked to test cancel while bytes move, then retry six-bit to completion; these results remain pending. Full Android CI-equivalent gate/XCTest not rerun; no commit/push. Repository has eight modified files atop 4cc7b69d and no new files; iOS 1.3 (35). Earlier tests and affected file list in previous entry.

## 2026-09-05 — Active iPhone Qwen generation and preparation fixes

- Device evidence: user successfully downloaded/loaded build 31 and saved a voice profile, then reproduced a signal-9 termination during reference conditioning. No matching jetsam report retrieved; memory pressure suspected, not confirmed. Build 32 capped unused MLX allocations at 2 MB and completed the same 34.4-second reference attempt, but user heard static. Local numerical WAV analysis found a 9.6-second mono 24 kHz float WAV, peak 0.0011 and RMS 0.000285; no audio transcription/provider request used.
- Root cause of invalid audio: direct device file listing showed speech_tokenizer configuration files but no model.safetensors. The SDK silently constructs an untrained codec when weights are absent and its cache readiness check only checks root weights/config. Build 33 repaired the missing 650.7 MiB codec file (verified on device) and rejects missing/empty required files.
- Additional evidence: build 33 completed a load, then a second load was killed with signal 9. Build 34 prevents duplicate loads, drops previous model ownership before switching, separates byte-based downloading from tensor loading, and immediately shows cancellation pending until active MLX work unwinds. Canceled loads are discarded. User also reported stuck percent/cancel controls before this change.
- Verification: signed physical iPhone builds 32, 33, 34 succeeded; each installed and launched on Yoseif's connected iPhone. Compiled Swift readiness regression checks passed for missing/empty codec and complete file sets; exact-ID regression retained. Android/iOS parity script and git diff --check passed. Full XCTest and Android CI-equivalent gate not rerun; no commit/push. Build 34 loaded complete model at about 1.63 GB active MLX memory and began same-reference generation; audio quality, cancellation, and responsiveness remain under device validation.
- Affected files: LocalQwenRuntime.swift, LocalQwenContracts.swift, LocalQwenViewModel.swift, LocalQwenPrototypeView.swift, LocalQwenPrototypeTests.swift, project.pbxproj, ios-local-qwen-prototype.md, AndroidReleaseReadinessContractTest.kt. Eight modified repository files including prior build-31 fixes; no new repository files. Debug memory diagnostics contain only stage, aggregate memory and reference duration; no audio/transcripts saved to vault. Working tree remains uncommitted atop 4cc7b69d; iOS 1.3 (34).

## 2026-09-05 — Fix Qwen download IDs and install iPhone build 31

- Outcome: corrected all three public Hugging Face repository IDs from display-name suffixes (4-bit/6-bit/8-bit) to published 4bit/6bit/8bit IDs. User reported immediate failures for all models. Live config requests reproduced HTTP 401 for the old 4-bit ID and HTTP 200 for each corrected ID. Generic localized HTTPClientError obscured the server response.
- Verification: Swift-compiled model-ID/display-label assertions passed; exact-ID XCTest regression updated; generic physical iOS build and signed connected-device build passed; Android/iOS parity script and git diff --check passed. Full XCTest and Android CI-equivalent gate were not rerun in this slice; no commit/push performed.
- Physical device: CoreDevice reported Yoseif's iPhone 16 Pro Max connected; signed SpeakTrue 1.3 (31) installed over the network and devicectl successfully launched YH.SpeakTrue. Full model download and inference remain unverified pending retry on the phone. Prior connectivity blocker is resolved for this session.
- Files: ios/SpeakTrue/LocalQwenContracts.swift, ios/SpeakTrueTests/LocalQwenPrototypeTests.swift, ios/SpeakTrue.xcodeproj/project.pbxproj, docs/guides/ios-local-qwen-prototype.md, android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt. Five modified files, uncommitted atop 4cc7b69d; no new repository files. Build artifacts and verification output remain outside repository.

## 2026-09-05 — Commit and push all repository changes

- Outcome: committed all 126 pending repository files and pushed `main` to `origin/main` at `4cc7b69df3dc5d619330cdbe0ac5388d5355c127`. Working tree clean. The first push timed out connecting to GitHub; the retry succeeded.
- Scope: experimental on-device Qwen lab and voice-profile persistence, iOS Keychain/privacy/warning fixes, hosted STT trials, database-authoritative web Soundboard migration and restore SQL fix, security/deployment safeguards, research notes, and audience demo assets. Previously untracked source, docs, and media are now tracked; no new uncommitted repository files remain. iOS version/build 1.3 (30); Android version/build 1.3 (25).
- Closeout adjustments: aligned AndroidReleaseReadinessContractTest with iOS build 30; ignored transient android/.kotlin compiler state created by verification. No credential files or ignored runtime media were added.
- Verification: full Python suite passed (1045 cases); four changed JavaScript runtime checks passed; complete verify_android_ci_local.sh passed including 564 unit tests, lint, backend contracts, parity checks and signed release bundle verification. Local readiness reports no source/local blockers; external Play/provider checks remain unverified. Fresh generic physical iOS Debug build passed earlier in this task with signing disabled. git diff --check and staged whitespace checks passed; common credential-pattern scan of pending files returned no matches.
- Deployment boundary: commit/push confirmed; no manual deployment, live provider smoke, iPhone installation, or physical-device Qwen generation performed. Map refreshed for the committed repository. Planning classifications unchanged.

## 2026-09-05 — iOS Xcode warning fixes

- Outcome: removed the uncalled filename debug helper from TTSViewModel and moved default Keychain store construction into the main-actor UserSettings initializer, preserving injected stores and credential migration. iOS version remains 1.3; app build increased from 29 to 30 in both configurations.
- Affected repository files: `ios/SpeakTrue/TTSViewModel.swift`, `ios/SpeakTrue/UserSettings.swift`, `ios/SpeakTrue.xcodeproj/project.pbxproj`. Changes remain uncommitted; pre-existing tracked and untracked changes preserved. No new repository files created by this task.
- Verification: Xcode 26.6 generic physical iOS Debug build with signing disabled succeeded using fresh DerivedData outside the repository. Neither reported Swift warning nor the module dependency priors warning appeared. Remaining warnings were four MLX C++17-extension diagnostics and App Intents metadata extraction without a framework dependency. `git diff --check` passed. No physical installation or execution was performed.
- Cache guidance: Product > Clean Build Folder and rebuild in the user's existing Xcode workspace; the original DerivedData cache was not removed. No architecture, deployment, or planning classification changed.

## 2026-09-04 — Read-only iPhone wireless Xcode diagnosis

- Outcome: confirmed a current device transport blocker, not a reproduced source/compiler failure. Xcode 26.6 lists the iPhone 16 Pro Max unavailable with deviceprep error -27 (browsing on LAN); CoreDevice tunnel unavailable and a read-only device request fails with error 1011. Stored device details report paired, Developer Mode enabled and iOS 26.5.2, but those fields may be cached because no active device session exists.
- Evidence: Bonjour resolves the iPhone development-service advertisement, but its advertised TCP port refuses both IPv4 and link-local IPv6 connections. The IPv4 route is directly through en0, not a VPN interface. No iPhone USB data path was observed in the USB registry check. Discovery working does not establish a functional development tunnel; this reproduces the earlier documented symptom. Device service state, stale pairing, and filtering remain possible underlying causes; no unique root cause beyond transport failure is proven.
- Next step: user unlocks the iPhone and connects directly with a known-good USB data cable, accepts Trust if prompted, then verifies availability in Xcode Device Hub before retrying wireless. No unpair/reset, network/firewall/VPN change, reboot, app installation, build, repository edit or deployment was performed. Initial sandbox-only discovery/service errors were excluded from the diagnosis and checks repeated with approved native access. No raw logs, addresses or device identifiers stored in the vault.
- State: existing dirty repository preserved at base `d8834620`; no new repository files. Diagnosis recorded in current status/planning; map refreshed/checked at closeout. Physical installation and launch remain unverified.

## 2026-09-04 — Approved DB-authoritative Soundboard migration continuation

- Outcome: the user approved continuing the full per-user migration using existing Supabase categories/clips as the authoritative index in every storage-adapter mode. Category lifecycle, individual/combined listing, copy, move, reorder, soft-delete/restore, conversion, and regeneration now use owned DB state. UUID category/output namespaces avoid path collisions; moves preserve stored references; conversion publishes/retires atomically and regeneration uses version CAS. Partial uploads and DB failures clean only invocation-owned outputs; signer failures after publication retain saved media. No shared-index/storage-scan fallback or reassignment/deletion of historical shared media.
- Surfaces/files: web routes/categories/helpers/soundboard; strict/category DB services; Soundboard/combined/regeneration services and legacy wrapper/dependency wiring; `static/js/index_soundboard.js`; focused API/unit/JS fixtures including authoritative-cache and TTS model-filter contracts; web README, speech contract, remediation report; additive backend restore SQL correction. The forward migration fixes an existing PostgreSQL ambiguous `sort_order` reference without changing auth, retention or grants. iOS is unchanged in this continuation (prior security build remains 1.3/29).
- Verification: primary final complete web suite `pytest -q -o addopts='' web/python-web-app/tests` passed 1045 tests. Four primary Node runtime checks passed (category management/surface, TTS-to-Soundboard, regeneration panel). `pip check`, JavaScript syntax and `git diff --check` passed. Independent synthetic PostgreSQL integration using actual table definitions and selected migrations passed cross-user rejection, stable-path moves, normal/combined trash/restore, duplicate filename/path-owner rejection, atomic conversion and stale regeneration CAS denial. This was not full Supabase/RLS or deployed storage testing. Actual template/scripts in synthetic headless Chrome at 1440x1000 and 390x844 showed owned categories and only the other category as a move destination, with no JS page errors; no move confirmation, real account, audio or provider call occurred. Temporary Flask and PostgreSQL servers were stopped; evidence stays outside the repository/vault.
- State: uncommitted on `main`, base `d88346208a855294f85050b7105896b89b2f9a18`; no push, deployment or hosted migration. Existing user changes preserved. New files from this continuation: `backend/supabase/migrations/20260904120000_fix_restore_clip_sort_order.sql`; `web/python-web-app/tests/unit/test_restore_clip_migration.py`. Earlier task-created files still untracked: `docs/ops/WEB_IOS_SECURITY_REMEDIATION.md`; `web/python-web-app/src/services/soundboard_namespace_service.py`; `web/python-web-app/tests/test_security_remediation_contracts.py`; `web/python-web-app/tests/unit/test_soundboard_namespace_service.py`. Earlier edited user-untracked iOS files remain those listed in the prior entry; other pre-existing untracked research/demo/prototype items were not created by this task.
- Remaining: apply/verify the SQL forward migration in an approved rollout; DB connectivity/schema are now required for legacy Soundboard management, without changing Supabase-only startup. Run complete Android CI-equivalent gate before future commit/push of this shared backend contract. Historical shared-data migration needs established ownership. Retention/version garbage collection, nonce CSP/browser token hardening, recording provenance, and deployed/physical-device proof remain open. No fresh magic link needed for synthetic local tests. Main/planning notes and generated map are refreshed at closeout; untracked files are listed because the map only indexes tracked files.

## 2026-09-04 — Daybreak web and iOS security remediation (prior checkpoint; superseded above)

- Final scope caveat: the user authorized full legacy migration; clip operations are now owner-scoped, but non-strict category lifecycle is incomplete. A safe completion needs a choice between existing per-user Supabase tables as the authoritative index (including legacy clips) and a separate storage-only per-user index. The attempted route-only approach was inspected and reverted before handoff because DB-only category changes do not track legacy object-only clips. Keep default strict mode for private multi-user use. No deployment or historical data migration was performed. Task-created baseline archive copies were removed after validation; original recordings and the text evidence log remain.

- Outcome: native Daybreak contributors implemented bounded web/iOS audit fixes; primary Codex independently reviewed boundaries and reran verification. The controlled-delegation workflow kept integration and deployment authority with Codex. No external-model disclosure, commit, push, deployment, or original recording removal.
- Affected surfaces: web generated-media/read/copy/regeneration identity, direct static/legacy downloads, consent, DOM rendering, browser headers, temporary-file allocation, dependency pins, deployment packaging; iOS Keychain migration/failure states, logs, protected local profiles and temporary-reference cleanup, soundboard extension normalization, embedded privacy, and build 29. Repository report and web-only speech-workflow contract examples updated.
- Verification: primary final full web suite 1024 passed/one failed; the remaining language-dropdown source assertion is also present in the exact base reconstruction. Focused regression tests prove owner-scoped GCS/Supabase operations, foreign persisted-path rejection before signing, job isolation, traversal rejection, copy-failure rollback and preexisting-sidecar preservation. Daybreak full iOS unit target 163 passed/zero failed; primary isolated security rerun 15 passed. `pip check`, JavaScript syntax checks, and `git diff --check` passed. Synthetic localhost desktop Chrome exercised real template/scripts and provider-consent checkbox/model switching without any account/audio/provider request; its CSP logo regression was fixed with a bundled asset. Logs/screenshots are temporary outside repository/vault.
- Working-tree state: uncommitted on `main`, base `d88346208a855294f85050b7105896b89b2f9a18`. All pre-existing user prototype/provider, package, guide, research, and demo changes preserved. Task-created untracked files: `docs/ops/WEB_IOS_SECURITY_REMEDIATION.md`; `web/python-web-app/tests/test_security_remediation_contracts.py`; `web/python-web-app/src/services/soundboard_namespace_service.py`; `web/python-web-app/tests/unit/test_soundboard_namespace_service.py`. Existing user-untracked files edited for security: `ios/SpeakTrue/LocalVoiceProfileStore.swift`, `ios/SpeakTrue/LocalQwenViewModel.swift`, `ios/SpeakTrue/LocalQwenPrototypeView.swift`, `ios/SpeakTrueTests/LocalQwenPrototypeTests.swift`. Other pre-existing untracked items were not created by this task.
- Compatibility/residuals: old ownerless generated files must be regenerated; ownerless shared cache and combined-download routes fail closed; shipped canned Soundboard assets stay public. Server-generated audio TTL cleanup, inline-script CSP/localStorage risks, recording provenance, approved staging verification, and physical-device protection remain open. iOS local profiles remain installation-wide after sign-out; failed Keychain migration preserves legacy storage with an observable error. No new magic link was needed for the synthetic local verification.
- Documentation: main/planning state updated; generated map refreshed and checked against the final repository state. New untracked files are listed here because the generated map indexes tracked paths only.

## 2026-09-02 — Muse Voice Transcribe fit assessment

- Outcome: assessed Meta Muse Voice Transcribe against SpeakTrue's current batch and realtime STT architecture. The recommendation is a non-production, non-PHI provider bakeoff beginning with batch transcription; retain ElevenLabs for rollback and current timestamp, audio-event, and wire-protocol coverage.
- Commit or working-tree state: uncommitted on `main` at `d8834620`; application code was not changed. New uncommitted research file: `docs/research/muse-voice-transcribe-speaktrue-fit.md`. All pre-existing tracked and untracked user changes were preserved.
- Affected surfaces/files: research documentation only. The assessment maps potential future integration across Supabase `stt-transcribe`, realtime provider sessions, iOS/Android/web clients, and provider-specific consent/privacy disclosures.
- Verification: primary-source review of Meta's announcement, official model/API documentation, official cookbook, pricing, and terms; inspected current SpeakTrue STT contracts; `git diff --check` passed and targeted status confirmed only the new Muse research note for this task.
- Documentation/status changes: work-log evidence and repository research note only. Current product behavior, deployment, architecture, and planning classifications remain unchanged.
- Residual risk or pending external proof: Meta quality and latency are vendor claims until tested on identical consented SpeakTrue recordings; API retention/ZDR, commercial terms, geographic coverage, and realtime credential handling require account-level confirmation before any private or regulated audio is sent.

## 2026-09-02 — Yoseif's iPhone signed build and blocked installation

- Outcome: produced a signed arm64 Debug build of SpeakTrue 1.3 (28) for
  physical iOS, including the experimental Local Qwen Lab. The app bundle is
  ready for installation at the temporary derived-data output, but it was not
  installed because CoreDevice reports `Yoseif's iPhone` as unavailable.
- Device evidence: CoreDevice resolves the target as an iPhone 16 Pro Max
  (`iPhone17,2`) on iOS 26.5.2. Developer Mode is enabled and the device is
  paired, but DDI services and the device tunnel are unavailable; the last
  recorded connection was 2026-07-25.
- Signing evidence: Xcode's physical-iOS build succeeded using the Apple
  Development identity for Yoseif Luay Faraj Haddad and the `YH.SpeakTrue`
  team provisioning profile. The embedded profile is valid through
  2027-06-28 and contains the target phone's UDID. Bundle ID is `YH.SpeakTrue`,
  architecture is arm64, and the built app is approximately 187 MB before any
  Qwen model download.
- Installation attempt: `xcrun devicectl device install app` failed with
  CoreDevice error 1011 because no reachable device matched the paired target.
  The phone must be awake, unlocked, trusted, and connected by USB or reachable
  over its paired development network before installation can complete.
- Commit or working-tree state: no repository file was changed by this build;
  the existing uncommitted iOS prototype and unrelated working-tree changes
  were preserved. Build output is under `/private/tmp` only.
- Documentation/status changes: work-log evidence only. Product and planning
  classifications remain unchanged because physical-device installation and
  runtime validation are still pending.

## 2026-08-31 — Installable iOS Local Qwen voice prototype

- Outcome: added an experimental physical-device Local Qwen Lab to the iOS
  Voice Cloning surface. The universal iPhone/iPad prototype can download and
  load pinned 4-bit, 6-bit, or 8-bit MLX Qwen3-TTS 0.6B Base models, record or
  import a reference, preserve named reference-audio/transcript profiles,
  generate chunked long-form WAV audio locally, play/share results, and report
  time-to-first-audio, total time, output duration, and real-time factor.
- Commit or working-tree state: uncommitted on `main` at `d8834620`; build
  number advanced from 27 to 28 and marketing version remains 1.3. Existing
  OpenRouter/homelab changes and untracked research/demo artifacts were
  preserved and not modified for this task.
- Affected surfaces/files: iOS project/package configuration,
  `VoiceCloneTabView.swift`, `SettingsTabView.swift`, tracked privacy/docs
  indexes, and the new installation guide. New uncommitted files are
  `ios/SpeakTrue/LocalQwenContracts.swift`,
  `ios/SpeakTrue/LocalQwenPrototypeView.swift`,
  `ios/SpeakTrue/LocalQwenRuntime.swift`,
  `ios/SpeakTrue/LocalQwenViewModel.swift`,
  `ios/SpeakTrue/LocalVoiceProfileStore.swift`,
  `ios/SpeakTrueTests/LocalQwenPrototypeTests.swift`, and
  `docs/guides/ios-local-qwen-prototype.md`.
- Verification: Swift package resolution passed; focused Qwen tests passed
  6/6; generic physical-iOS, iPhone 17 Pro Max simulator, and iPad Pro
  simulator compilation passed with package plugin validation explicitly
  skipped for CLI builds. The full iOS unit suite passed except the unchanged
  `SoundboardCacheManagerTests.testLocalFileURLIsScopedByUserId` assertion at
  line 31, which independently reproduces because its existing expected
  filename omits the extension that the existing call passes in the stable
  key. `git diff --check` passed.
- Documentation/status changes: tracked install/privacy guidance now separates
  local reference/profile storage from hosted ElevenLabs processing. This
  status note and the planning note classify the prototype as locally
  implemented but awaiting physical iPhone 16 Pro Max and iPad Pro M4 runtime,
  latency, memory, thermal, and quality validation.
- Residual risk or pending external proof: no model was downloaded or executed
  on either target mobile device, no signed archive was produced, and no app
  was installed. Simulator inference is intentionally disabled. The prototype
  preserves source audio/transcript across launches but does not yet serialize
  a precomputed speaker embedding.

## 2026-08-31 — SpeakTrue web ElevenLabs same-reference clone comparison

- Outcome: authenticated the documented staging admin account with a one-time
  Supabase magic link, used the live SpeakTrue web workflow to create an
  ElevenLabs Instant Voice Clone from the same 6.5-second WAV used by the local
  pilots, and generated the identical appointment sentence with Eleven Flash
  v2.5 and Eleven Multilingual v2.
- Authentication handling: the admin-generated action link was consumed only
  in an isolated browser session. Temporary token-response and browser-output
  files were removed, the session was explicitly signed out, and the browser
  was closed. No token, credential, or session state was written to the
  repository, vault, or pilot report.
- Live clone state: SpeakTrue created `Pilot Voice - Same Reference -
  2026-08-30` for the staging owner. Clone preflight scored 70 with three
  warnings and no failures; the warnings reflected one short sample, likely
  insufficient total duration for high fidelity, and a single source type.
  The persistent ownership row was read back with provider `elevenlabs`, one
  sample, consent accepted, and provider verification not required. The clone
  remains available for follow-up tests.
- Functional proof: after a catalog refresh, the new clone appeared in the TTS
  custom-voice selector. Both ElevenLabs models generated playable MP3 artifacts
  through `/api/text-to-speech`; local downloads validated as 5.57 seconds for
  Multilingual v2 and 5.90 seconds for Flash v2.5.
- Latency finding: sanitized browser resource timing measured 3.065 seconds for
  the Multilingual API request plus 0.084 seconds for the MP3 resource, and
  1.665 seconds plus 0.064 seconds for Flash. The current web route exposes a
  complete artifact rather than provider streaming first audio, so these are
  full-readiness measurements.
- Quality finding: local Whisper Base recovered the requested text at 0%
  normalized WER for both hosted outputs. Directional Chatterbox VoiceEncoder
  similarity to the reference was 0.876 for Multilingual v2 and 0.832 for
  Flash v2.5, compared with 0.916 for the selected local MLX full-waveform
  output, 0.860 for local MLX streaming, and 0.872 for Chatterbox Nano. These
  are one-sample directional measurements, not naturalness certification.
- Affected surfaces/files: provider and Supabase staging data changed through
  the normal product workflow. Generated audio, hashes, evaluation JSON, and
  the rerun harness were preserved outside the repository at
  `/Volumes/Haddadios/AI Models/SpeakTrue Voice Clone Pilots/`. The Codex
  browser-readable listening comparison was extended with both hosted samples.
  No application, backend, schema, deployment, or repository documentation
  files changed.
- Verification: completed live preflight, clone creation, catalog refresh,
  two-model TTS generation, MP3 duration/format/hash validation, local ASR,
  speaker-similarity evaluation, provider ownership-row readback, explicit
  logout, `git diff --check`, and final repository status inventory.
- Commit or working-tree state: no commit was created. All pre-existing modified
  OpenRouter/homelab files and untracked research/demo artifacts were preserved,
  with no new repository artifact from this task.
- Documentation/status changes: work-log entry and generated codebase-map
  refresh only; `SpeakTrue.md` and `SpeakTrue Planning Status.md` were unchanged
  because product behavior, architecture, deployment, active work, and plan
  classification did not change.

## 2026-08-30 — Local cloned-voice concurrency and capacity benchmark

- Outcome: measured synchronized 1-, 2-, 4-, and 8-worker MLX Qwen3-TTS
  generation on the 128 GB M1 Ultra Mac Studio. Two workers are the recommended
  baseline for 5–10 ordinary users; four workers are the practical ceiling when
  four simultaneous requests must begin playback in roughly 500 ms.
- Affected surfaces/files: preserved the benchmark harness and JSON results
  under `/Volumes/Haddadios/AI Models/SpeakTrue Voice Clone Pilots/` and added
  the capacity table to the Codex browser-readable pilot visualization. No
  application, backend, schema, deployment, or repository documentation files
  changed.
- Capacity finding: median first-audio latency was 0.211, 0.302, 0.435, and
  0.822 seconds for 1, 2, 4, and 8 workers respectively. Median completion was
  1.523, 2.049, 3.193, and 5.877 seconds. Aggregate audio throughput increased
  from 2.68 audio-seconds per wall-second with one worker to 5.51 with four,
  then plateaued at 5.62 with eight.
- Memory finding: each warm process reported approximately 1.9 GiB ready RSS
  and 5.1–5.8 GiB Metal peak allocation. Eight workers fit physically, at
  15.37 GiB aggregate RSS and 41.10 GiB summed reported Metal peak, but became
  compute-bound and usually generated slower than playback. Because macOS uses
  unified memory, RSS and Metal figures are not summed as exact physical use;
  7–8 GiB per warm worker is the conservative operating allowance.
- Profile finding: the MLX cache derived from the 6.5-second reference contains
  5,356 bytes of audio codes and text IDs; the source WAV is 312,078 bytes.
  Model workers therefore serve many user voices, rather than allocating one
  model process per user.
- ElevenLabs comparison status: the configured account exposed 21 premade
  voices and no existing matching clone. Creating an apples-to-apples clone was
  not performed because uploading the specific reference and retaining a new
  external provider-side voice requires explicit authorization. No audio was
  uploaded and no ElevenLabs voice was created or deleted.
- Verification: ran synchronized process barriers with offline model loading,
  measured per-worker load, warmup, first audio, completion, RTF, process RSS,
  Metal peak allocation, and aggregate throughput; inspected the in-memory ICL
  cache shapes and bytes; validated all four JSON result files and visualization
  values; and ran `git diff --check` successfully.
- Commit or working-tree state: no commit was created. All pre-existing modified
  OpenRouter/homelab files and untracked research/demo artifacts were preserved,
  with no new repository artifact from this task.
- Documentation/status changes: work-log entry and generated codebase-map
  refresh only; `SpeakTrue.md` and `SpeakTrue Planning Status.md` were unchanged
  because current product behavior, architecture, deployment, active work, and
  plan classification did not change.

## 2026-08-30 — Mac Studio cloned-voice latency optimization benchmark

- Outcome: established a substantially faster local serving path for the existing
  cloned-voice pilot. A warm MLX Qwen3-TTS 0.6B Base 6-bit worker yielded its
  first playable audio chunk in 0.226 seconds median across five runs and
  completed the streamed 3.84–5.12-second outputs in 1.787 seconds median.
- Affected surfaces/files: added isolated MLX-Audio and Chatterbox Nano
  environments, model caches, benchmark harnesses, generated audio, and JSON
  results under `/Volumes/Haddadios/AI Models/SpeakTrue Voice Clone Pilots/`.
  The browser-readable Codex visualization was extended with latency samples.
  No application, backend, schema, deployment, or repository documentation
  files changed.
- Runtime finding: MLX Qwen's median streaming real-time factor was 0.385 and
  its median full-waveform generation was 1.794 seconds, roughly 6.5 times
  faster than the earlier 11.64-second PyTorch/MPS Qwen short run. Cached model
  load was 1.099 seconds and peak MLX memory was 6.46 GB. The practical target
  is therefore 250–400 ms perceived start with HTTP overhead when the worker and
  active voice conditioning remain warm.
- Alternative finding: Chatterbox Nano saved a reusable 111,291-byte
  conditionals artifact and its fastest stable warmed run generated 4.06
  seconds of audio in 2.319 seconds (RTF 0.571). Its timings varied with output
  length and Metal compilation, and the tested API returned a full waveform,
  so MLX Qwen remains the stronger interactive serving candidate.
- Quality verification: local Whisper Base recovered the full target text from
  the selected MLX streamed, MLX full-waveform, and Chatterbox Nano outputs at
  0% normalized word error. Directional Chatterbox VoiceEncoder similarity to
  the reference was 0.916 for the selected MLX full-waveform output, 0.860 for
  the selected MLX stream, and 0.872 for Nano; these are directional checks,
  not independent naturalness certification.
- Verification: repeated cached warm benchmarks, measured time to first audio,
  completion time, RTF, memory, hashes, duration, normalized ASR error, and
  speaker similarity; validated the browser audio assets; and ran
  `git diff --check` successfully.
- Commit or working-tree state: no commit was created. All pre-existing modified
  OpenRouter/homelab files and untracked research/demo artifacts were preserved,
  with no new repository artifact from this task.
- Documentation/status changes: work-log entry and generated codebase-map
  refresh only; `SpeakTrue.md` and `SpeakTrue Planning Status.md` were unchanged
  because current product behavior, architecture, deployment, active work, and
  plan classification did not change.

## 2026-08-30 — Durable local voice profiles and long-form generation pilot

- Outcome: created and exercised compact reusable cloned-voice profiles for
  Chatterbox Multilingual V3 and Qwen3-TTS 0.6B. Both profiles generated speech
  after reload without access to the temporary 30-second reference excerpt.
- Affected surfaces/files: derived profile artifacts, manifests, reusable
  harnesses, long-form audio, hashes, and evaluation metadata were kept outside
  the repository at `/Volumes/Haddadios/AI Models/SpeakTrue Voice Clone Pilots/`.
  The browser-readable comparison under the Codex visualization directory was
  extended with long-form samples. No application, backend, schema, deployment,
  or repository documentation files changed.
- Profile finding: Chatterbox's saved conditional state is 167,867 bytes and
  Qwen's saved voice prompt is 54,605 bytes. The manifest binds each artifact to
  its provider, exact model revision, reference fingerprint, normalization,
  artifact hash, and serving strategy. The profile does not retain another raw
  reference-audio copy; the temporary 30-second excerpt was removed after
  profile creation and evaluation.
- Long-form finding: Qwen generated the full 77-word passage in one call and,
  after a new-process profile reload, produced 24.56 seconds of audio in 42.77
  seconds with 0% normalized Whisper word error. Chatterbox's initial 86-word
  single-call attempt terminated near 593 of 1,000 sampling tokens on MPS;
  sentence chunking completed the 77-word passage as 27.47 seconds of audio in
  64.94 seconds with 1.30% normalized word error.
- Voice-consistency finding: against the temporary 30-second reference,
  full-output directional cosine similarity was 0.931 for Chatterbox and 0.921
  for Qwen. Start, middle, and end segment similarity remained at or above 0.890
  for Chatterbox and 0.884 for Qwen. These are Chatterbox VoiceEncoder metrics,
  not independent naturalness certification.
- Verification: loaded both stored artifacts with weights-only deserialization;
  generated in processes that did not require the source recording; transcribed
  the long outputs locally; measured full and segmented speaker similarity;
  verified output/profile SHA-256 hashes and browser-audio assets; and ran
  `git diff --check` successfully.
- Commit or working-tree state: no commit was created. All pre-existing modified
  OpenRouter/homelab files and untracked research/demo artifacts were preserved,
  with no new repository artifact from this task.
- Documentation/status changes: work-log entry and generated codebase-map
  refresh only; `SpeakTrue.md` and `SpeakTrue Planning Status.md` were unchanged
  because current product behavior, architecture, deployment, active work, and
  plan classification did not change.

## 2026-08-30 — Mac Studio local voice-cloning functionality pilots

- Outcome: downloaded and ran two zero-shot local voice-cloning pilots on the
  M1 Ultra Mac Studio: Chatterbox Multilingual V3 and Qwen3-TTS 0.6B Base.
  Both models generated the short and clinical test prompts successfully from
  the same 6.5-second reference excerpt using direct PyTorch/MPS inference.
- Affected surfaces/files: model environments, caches, reusable harnesses,
  generated audio, hashes, and result metadata were kept outside the
  repository at `/Volumes/Haddadios/AI Models/SpeakTrue Voice Clone Pilots/`.
  A browser-readable listening comparison was generated under the Codex
  visualization directory. No application, backend, schema, deployment, or
  repository documentation files changed.
- Functional results: local Whisper Base reproduced the requested text with
  0% normalized word error for all four outputs. Directional speaker-encoder
  cosine similarity ranged from 0.880 to 0.918; same-speaker and different-
  voice controls measured 0.877 and 0.627 respectively. Chatterbox's warm
  clinical generation ran at 2.32 real-time factor; Qwen's clinical generation
  ran at 1.49 real-time factor.
- Runtime finding: Qwen3-TTS float16 inference on MPS failed with invalid
  sampling probabilities; float32 completed reliably. Chatterbox V3 completed
  on MPS and retained its built-in watermark behavior. Ollama, LM Studio,
  Docker Model Runner, and Unsloth were inspected but were not used for these
  audio pilots because their generic local-model paths do not currently supply
  the complete TTS codec and waveform-generation runtime needed by these
  models.
- Verification: validated output duration and SHA-256 hashes; transcribed all
  four outputs locally; measured reference, holdout, and control speaker
  embeddings; preserved per-run JSON metadata and rerun scripts; and ran
  `git diff --check` successfully.
- Commit or working-tree state: no commit was created. All pre-existing
  modified OpenRouter/homelab files and untracked research/demo artifacts were
  preserved. A transient untracked session sidecar produced during the pilot
  was removed, leaving no new repository artifact from this task.
- Documentation/status changes: work-log entry and generated codebase-map
  refresh only; `SpeakTrue.md` and `SpeakTrue Planning Status.md` were unchanged
  because current product behavior, architecture, deployment, active work, and
  plan classification did not change.

## 2026-08-29 — Local voice-cloning and per-user adaptation options review

- Outcome: completed a current technical review of locally hosted voice cloning,
  single-speaker fine-tuning, and per-user LoRA options for SpeakTrue. The
  recommended sequence is a zero-shot bakeoff first, followed by adapter
  training only for consented voices that fail an explicit quality gate.
- Affected surfaces/files: added the uncommitted research note
  `docs/research/local-voice-cloning-options.md`. No application, backend,
  deployment, schema, or planning state changed.
- Key finding: Qwen3-TTS 0.6B Base and Chatterbox are the leading zero-shot
  pilot candidates; VoxCPM2 has the clearest first-party LoRA lifecycle.
  XTTS-v2 and the official F5-TTS pretrained weights remain excluded from a
  default commercial path because of non-commercial model licenses.
- Verification: reviewed the note against primary model repositories, model
  cards, licenses, and first-party training/deployment documentation;
  independently inspected SpeakTrue's current ElevenLabs-specific clone,
  ownership, deletion, and TTS boundaries; `git diff --check` passed.
- Commit or working-tree state: no commit was created. The new research note is
  untracked. Pre-existing modified OpenRouter/homelab files and the untracked
  `artifacts/product-demo-60s/audience-variants/` directory were not modified.
- Documentation/status changes: work-log entry and generated codebase-map
  refresh only; `SpeakTrue.md` and `SpeakTrue Planning Status.md` were unchanged
  because this review did not change current behavior, architecture,
  deployment, active work, or plan classification.

## 2026-07-31 — Lecture3 clips synced from bogendds to staging

- Outcome: non-destructively synchronized the `Lecture3` Soundboard folder from
  `bogendds@gmail.com` into the staging account. One missing active clip and
  its `.mp3`, `.txt`, and `.metadata.json` storage objects were copied into
  staging's existing `Lecture3` category; staging-only data was not deleted or
  overwritten.
- Affected surfaces/files: live Supabase `soundboard_clips` metadata and
  `soundboard` Storage objects only. No repository files changed.
- Verification: live account IDs were revalidated before the copy. Final
  readback showed 72/72 active clips and 304/304 category-scoped storage
  objects matched by remapped destination path, with zero missing clip rows or
  objects. SHA-256 comparisons for all three newly copied objects were
  byte-identical between source and staging. Clip filename, transcript,
  transcript path, MIME type, file size, duration, sort order, and offline
  availability matched across all 72 rows; pre-existing per-account metadata
  differences were intentionally left unchanged. `git diff --check` passed.
- Commit or working-tree state: no commit was created. Pre-existing modified
  OpenRouter staging-prototype files and the untracked
  `artifacts/product-demo-60s/audience-variants/` directory were not modified.
- Documentation/status changes: work-log entry only; product behavior,
  architecture, deployment, and planning classifications were unchanged.

## 2026-07-30 — Current-speaker multi-sample transcription benchmark

- Outcome: compared seven approved current-voice samples, approximately
  5.5 minutes total, across ElevenLabs Scribe V2, OpenRouter MAI-Transcribe
  1.5, local VibeVoice ASR, and local Canary-Qwen 2.5B. Three clips had known
  reference text for objective normalized word-error scoring; the remaining
  four were reviewed qualitatively.
- Accuracy finding: Scribe V2 with a narrowly tailored per-speaker vocabulary
  was the clear best configuration, reaching 4.4%, 1.6%, and 0% word error on
  the three referenced clips. MAI-Transcribe 1.5 was the strongest unprompted
  alternative at 11.8%, 14.1%, and 21.4%. Scribe also produced the most useful
  technical dental transcript after clinical vocabulary prompting, although
  it still needs human review for medical terminology.
- Local-model finding: Canary produced 33.8%, 45.3%, and 71.4% word error on
  the referenced clips. VibeVoice's best tested passes remained between 64.7%
  and 100% and failed on the long technical sample. These original local
  architectures are not practical for this speaker without further model work.
- Product direction: use Scribe V2 with a consented per-user glossary as the
  primary accessibility path and MAI-Transcribe 1.5 as a comparison or
  fallback. Do not fine-tune from seven samples; first collect more consented,
  corrected reference transcripts and retain an explicit human-confirmation
  path for clinical content.
- Privacy and runtime verification: audio, raw transcripts, provider payloads,
  and temporary result files remained outside the repository and vault. The
  short-lived dev session was logged out. No VibeVoice or Canary process
  remained; LM Studio reported its server off, Ollama's local port was closed,
  and Docker Model Runner's server was unreachable.
- Commit or working-tree state: this benchmark changed no repository files.
  The existing uncommitted staging endpoint integration remains in the working
  tree, and the unrelated untracked
  `artifacts/product-demo-60s/audience-variants/` directory was not modified.
- Verification: all seven Scribe V2 and MAI-Transcribe 1.5 requests completed
  successfully; local model output was saved and reviewed; five result files
  passed JSON validation; objective scoring was repeated after the refined
  vocabulary pass; `git diff --check` passed. No dev or production deployment
  changed.

## 2026-07-30 — Local Apple-silicon ASR feasibility test

- Outcome: downloaded and ran the full Microsoft VibeVoice ASR HF model and
  NVIDIA Canary-Qwen 2.5B locally on the M1 Ultra Mac Studio against the
  approved 11-second accessibility-speech sample. All weights, isolated
  runtimes, and result JSON remain outside the repository under
  `/Volumes/Haddadios/AI Models/SpeakTrue ASR Tests/`.
- Accuracy finding: VibeVoice classified the complete clip as unintelligible in
  both blind and vocabulary-assisted passes on Metal float16 and CPU float32.
  Canary produced a partial transcription with 71.4% normalized word error
  rate: it retained the year and closing speech phrase but missed most of the
  medical context.
- Runtime finding: VibeVoice Metal generation took 6.0 seconds cold and
  2.3 seconds warm at about 19 GB peak memory; CPU float32 took about 42 seconds
  per pass at about 34 GB. Canary Metal generation took 1.4 seconds at about
  11 GB, after a 67-second NeMo construction step.
- Compatibility finding: neither original model is a native LM Studio, Ollama,
  or Docker Model Runner model. Their complete audio encoders require
  Transformers or NeMo. Docker Model Runner's Apple-silicon path is
  llama.cpp/GGUF text generation; its safetensors/vLLM path is CUDA-only on
  supported Linux/Windows systems.
- Commit or working-tree state: the local benchmark changed no repository
  files. The existing uncommitted staging endpoint integration remains in the
  working tree, and the unrelated untracked
  `artifacts/product-demo-60s/audience-variants/` directory was not modified.
- Verification: both models loaded their complete checkpoints locally;
  VibeVoice was repeated across Metal and full-precision CPU; Canary's tied
  output weights were validated and the corrected Metal pass completed; saved
  result files and model directory sizes were read back.
- Documentation/status changes: recorded the local feasibility result. No live
  dev or production deployment changed.

## 2026-07-30 — Accessibility-speech STT benchmark and staging model refresh

- Outcome: benchmarked the user-provided 11-second accessibility-speech sample
  against every transcription model currently listed by OpenRouter plus
  ElevenLabs Scribe V2, then replaced the three staging trial choices with the
  strongest OpenRouter candidates: MAI-Transcribe 1.5, Whisper Large v3, and
  Voxtral Mini Transcribe.
- Accuracy finding: raw MAI-Transcribe 1.5 was the strongest OpenRouter result
  at 3 word edits out of 14. Safe resampling, loudness normalization, denoising,
  and speed variants did not improve overall recognition. Scribe V2 reached an
  exact normalized match when supplied only the separate vocabulary terms
  `head`, `neck`, and `cancer`, supporting a future transient per-user glossary
  experiment rather than model retraining from one sample.
- Cost/availability finding: the complete raw OpenRouter sweep cost about
  `$0.0084`. Fish Audio Transcribe 1 was newly listed but returned provider
  HTTP 502 on the raw and two 16 kHz variants. No audio, transcript, provider
  payload, or credential was written to the repository or vault.
- Commit/deployment state: committed and pushed as
  `d88346208a855294f85050b7105896b89b2f9a18`
  (`feat(web): tune staging OpenRouter STT models`). GitHub Actions run
  `30594730527` deployed the exact commit to `dev.speaktrue.cc`; public health
  is OK and the live release marker is `dev-d88346208a85`. Production was not
  changed.
- Affected files:
  `web/python-web-app/src/services/openrouter_stt_prototype_service.py` and
  `web/python-web-app/tests/api/test_stt.py`.
- Verification: 17 focused Flask API/service tests passed; `git diff --check`
  passed; the deployment workflow completed successfully; public dev health
  and release endpoints returned the expected exact release. The unrelated
  untracked `artifacts/product-demo-60s/audience-variants/` directory was not
  modified.
- Documentation/status changes: the OpenRouter staging trial remains
  implemented and staging-account-only; only its three experimental model
  choices changed.

## 2026-07-30 — Staging account enabled for dev with full admin state

- Outcome: made the known staging account eligible to sign in to
  `dev.speaktrue.cc` while preserving all existing approved dev accounts.
  The account already had complete live Supabase admin privileges; the missing
  state was only its email in the dev-specific login allowlist.
- Durable configuration: appended the account to encrypted repository secret
  `SPEAKTRUE_DEV_ALLOWED_EMAILS` without exposing or replacing the existing
  allowlist, then redeployed exact commit `8e243c10` through successful workflow
  run `30558094938`.
- Live dev proof: `/api/auth/login/allowed` changed from HTTP 403/denied to HTTP
  200/allowed. A short-lived authenticated staging session received HTTP 200
  from `/api/pro-subscription-status` with `is_pro=true` and
  `source=supabase_entitlements`.
- Admin readback: entitlement remains active `admin` from
  `manual_staging_admin_access` with no period end; profile `is_pro=true`; all
  five enabled private voices are granted; all admin daily/monthly TTS/STT
  limits are null/unlimited; and the admin Soundboard category-cap bypass is
  present.
- Repository/deployment state: no tracked repository files changed. `main` and
  `origin/main` remain at `8e243c10`, public dev remains healthy on
  `dev-8e243c10fddc`, and no identity or credential values were written to the
  vault.

## 2026-07-30 — OpenRouter dev deployment prerequisite audit

- Outcome: rechecked the pushed OpenRouter prototype prerequisites and attempted
  a fail-closed deployment of exact commit `8e243c10` to the isolated dev host.
  No production deployment or configuration was changed.
- Provider state: the supplied OpenRouter key remains valid and unused on the
  free tier, but audio transcription remains unavailable without the
  provider-required balance. The repository still has no OpenRouter deployment
  secrets configured.
- Deployment evidence: GitHub Actions run `30521856709` targeted exact commit
  `8e243c10` but remained queued because registered runner
  `speaktrue-dev-la` was offline. Proxmox confirmed isolated dev VM `2201` is
  running with its expected address and guest agent.
- Root cause: the runner service was inactive because GitHub had automatically
  deleted its stale registration. Re-registering it would reactivate remote
  repository code execution on the dev VM and therefore requires explicit user
  authorization. No workaround or runner mutation was performed.
- Safe closeout: cancelled the queued deployment. The existing dev site remains
  healthy and unchanged on release `dev-7de4fa4e2794`.
- Final blocker audit: a third consecutive goal turn rechecked the external
  state and found it unchanged: the key is valid but unused on the free tier,
  both OpenRouter deployment secrets are absent, and the registered dev runner
  remains offline. The focused Python suite still passes 48 tests and the
  OpenRouter browser runtime guard passes. The goal is therefore classified as
  blocked pending explicit secret-storage and runner-registration authorization
  plus provider funding or a funded replacement key.
- Resumed rollout: the user subsequently authorized encrypted secret storage
  and runner re-registration. Both OpenRouter repository secrets are now
  configured, `speaktrue-dev-la` was successfully re-registered with its
  expected labels and is online, and workflow run `30555551199` deployed exact
  commit `8e243c10`. The public dev health check passes and the release marker is
  `dev-8e243c10fddc`.
- Live prototype proof: unauthenticated catalog access returns `401`; a
  short-lived session for the exact staging account returns the three-model
  catalog. Each model reaches the OpenRouter boundary through both direct web
  STT and Standard batch STS, but the currently deployed original key returns
  the normalized payment-required response on all six calls.
- Replacement-key proof: the newly supplied key reports `$10` total credits and
  completed a real synthetic Whisper transcription with usage/cost metadata.
  Rotating the encrypted deployment secret to that exact replacement remains
  pending explicit user approval for the credential transfer.
- Three-model funded-key benchmark: all three models returned HTTP 200 for the
  same 8.81-second synthetic dental sample. Whisper Large v3 Turbo was fastest
  at about 569 ms and cheapest at about `$0.000111`, but misspelled
  `pulpitis`; Parakeet completed in about 871 ms at about `$0.000220` and made
  multiple terminology errors; Qwen3 ASR Flash completed in about 2.18 seconds
  at about `$0.000280` and produced the most accurate dental transcript. This
  is a single-sample prototype baseline, not a general quality ranking.
- Full batch-STS proof: an isolated `/private/tmp` copy of the Flask runtime
  used the funded key, the exact staging identity, the existing ElevenLabs TTS
  boundary, and local-only artifact persistence. All three OpenRouter choices
  returned HTTP 200 end to end, generated audio artifacts, and preserved the
  selected model ID under `clip_metadata.stt_settings.model`. Total STS request
  times were about 5.76 seconds for Whisper, 4.30 seconds for Parakeet, and
  5.72 seconds for Qwen. The temporary runtime and generated artifacts were
  deleted after verification; repository status remained unchanged.
- Final replacement-secret audit: after three consecutive continuations without
  explicit approval for transferring the exact funded replacement credential,
  the encrypted key secret still had its original `2026-07-30T15:10:41Z`
  update timestamp, the latest dev deployment remained successful run
  `30555551199`, and the public release remained `dev-8e243c10fddc`. The goal
  is formally blocked only on that explicit credential-transfer authorization;
  implementation, runner recovery, deployment, staging gating, direct
  three-model STT, full local batch STS, and documentation evidence are
  complete.
- Final live completion: after explicit approval, rotated the encrypted
  `SPEAKTRUE_DEV_OPENROUTER_API_KEY` secret to the funded key at
  `2026-07-30T15:27:36Z` and deployed exact commit `8e243c10` through successful
  workflow run `30556797279`. Public health and release
  `dev-8e243c10fddc` passed. The deployed runtime reports the feature enabled,
  a configured server-only key, and exactly one allowlisted user.
- Live six-call proof: a short-lived exact staging-account session received the
  three-model catalog. Whisper, Parakeet, and Qwen each returned HTTP 200
  through direct STT and Standard batch STS; every STS response generated audio
  and preserved its selected model under
  `clip_metadata.stt_settings.model`. Unauthenticated catalog access remained
  HTTP 401.
- Final verification: 48 focused Python tests, the OpenRouter runtime guard,
  both existing STT/STS realtime transcript guards, `git diff --check`, tracked
  secret scanning, ignored-local-env verification, and `HEAD == origin/main`
  all passed. No API key is tracked in Git.
- Free-model assessment: the dedicated OpenRouter transcription catalog
  currently has no zero-cost models. The only free general audio-input model
  returned HTTP 200 but ignored the supplied audio (`audio_tokens=0`) and asked
  for an audio file, so it was not added as a misleading STT option.
- Repository state: tracked `main` and `origin/main` remain at `8e243c10`; the
  unrelated untracked `artifacts/product-demo-60s/audience-variants/`
  directory was not modified.

## 2026-07-29 — Staging-only OpenRouter web transcription trials

- Outcome: implemented and pushed three server-side OpenRouter transcription
  trials for the legacy web STT surface and Standard batch STS:
  `openai/whisper-large-v3-turbo`, `nvidia/parakeet-tdt-0.6b-v3`, and
  `qwen/qwen3-asr-flash-2026-02-10`. Realtime STS and native clients were not
  changed.
- Access boundary: the controls and routes fail closed behind an explicit
  feature flag, exact Supabase user-ID allowlist, and authenticated user
  resolution. Browser verification showed the selector for the staging account
  and kept it hidden for an ordinary authenticated account; direct non-allowed
  access returns `403`.
- Secret handling: the supplied test key remains server-side in an ignored
  local environment file and is absent from the commit. The dev deployment
  workflow accepts encrypted GitHub Actions secrets when configured and
  otherwise leaves the trials disabled.
- Affected surfaces/files: web STT and Standard batch STS routes, provider
  service, authenticated prototype controls, development/deployment
  configuration docs, and focused Python/JavaScript regression coverage.
- Verification: 48 focused Python tests passed; all three relevant JavaScript
  runtime checks passed; Python compile verification and `git diff --check`
  passed. Browser QA verified staging-visible and ordinary-user-hidden states.
  The full web suite retained one unrelated settings-default assertion failure
  in `test_web_defaults_race.py`.
- Commit or working-tree state: committed and pushed to `origin/main` as
  `8e243c10`. The unrelated untracked
  `artifacts/product-demo-60s/audience-variants/` directory was not modified.
- Live status: source implementation is complete, but the trials are not
  enabled on the dev host. Direct provider validation returned a payment-required
  response because audio requests require at least `$0.50` balance, and
  persisting the key in the repository's encrypted GitHub Actions secret store
  still requires explicit user authorization.

## 2026-07-28 — SpeakTrue LA/Canada automatic failover

- Outcome: activated Cloudflare Basic Load Balancing for
  `web.speaktrue.cc` with LA primary and Canada second and fallback. Both
  site-specific tunnel pools are healthy under the shared HTTPS `/health`
  monitor. Session affinity, adaptive routing, and active-active steering remain
  off.
- Billing/capacity: the approved subscription is `$5/month` and its two
  included endpoints are allocated to SpeakTrue. EndoNote was not added; its
  additional two endpoints would require separate approval for another
  `$10/month`.
- Live cleanup and topology: deleted the unused wrong-zone DNS record; verified
  LA tunnel `HL-Cloudflared LA3`
  (`f0380c66-e9b2-4d95-92f8-571c9adab4e7`) and Canada tunnel
  `speaktrue-web-ca`
  (`465696ec-f132-4f6f-ae4d-c72b4b55e352`) both publish
  `web.speaktrue.cc` to the local Flask origin.
- Failure drill: disabled the LA endpoint after both pools were healthy.
  Cloudflare reported 1 of 2 pools with Canada as the only enabled path;
  public `/health` and `/` remained HTTP 200 and reported release `15ca9d55`.
  Restoring LA returned the dashboard to healthy with 2 of 2 pools and 2 of 2
  endpoints, and final public checks remained HTTP 200.
- Affected files: `docs/ops/SPEAKTRUE_LA_CA_LOAD_BALANCER_PLAN.md` and
  `docs/index.md`; the homelab README, handoff, and focused SpeakTrue failover
  runbook were updated in parallel.
- Commit or working-tree state: SpeakTrue documentation committed and pushed as
  `1cdfd031`; homelab documentation committed and pushed as `de4fdce`. The
  unrelated untracked `artifacts/product-demo-60s/audience-variants/` directory
  was not modified.
- Verification: Cloudflare monitor and both pools healthy; baseline, Canada-only
  failover, and restored `/health` and `/` requests all returned HTTP 200;
  release marker remained `15ca9d55`; `git diff --check` and homelab shell
  syntax checks passed.
- Residual follow-up: build a secure dual-site deployment workflow that promotes
  and verifies the same immutable release in LA and Canada automatically.

## 2026-07-28 — Canada legacy-web warm standby

- Outcome: provisioned an isolated SpeakTrue legacy-web warm standby on Canada
  Proxmox node 2. VM `2201` runs Docker commit `15ca9d55` behind dedicated
  tunnel `speaktrue-web-ca`, starts automatically, and has a verified recurring
  PBS backup. Canonical production traffic was not changed.
- Commit or working-tree state: SpeakTrue planning/docs committed as
  `3341b94835893d58f3fbba237dd584ddbeb3cd18` and pushed to `origin/main`;
  homelab inventory/runbook committed as `fda1999` and pushed. No new
  task-owned uncommitted files remain. The unrelated untracked
  `artifacts/product-demo-60s/audience-variants/` directory was not modified.
- Affected surfaces/files: live Canada VM/tunnel/backup state;
  `docs/ops/SPEAKTRUE_LA_CA_LOAD_BALANCER_PLAN.md`; `docs/index.md`; homelab
  inventory, handoff, and `docs/runbooks/speaktrue-canada-failover.md`.
- Verification: VM and Docker services active; container healthy; local
  `/health` HTTP 200; checkout `15ca9d55`; tunnel connector healthy on
  Cloudflared `2026.7.3`; PBS job and archive
  `vm/2201/2026-07-29T04:43:27Z` verified; Canada 4/4 quorate with Ceph
  `HEALTH_OK`, 16/16 OSDs up/in, and 129 active+clean PGs; public production
  `/health` and release marker remained healthy on `15ca9d55`; documentation
  syntax and `git diff --check` passed.
- Documentation/status changes: LA/Canada failover moved from future/
  decision-gated to active, partially implemented. The tracked plan now uses
  one pool per tunnel UUID with the canonical Host header.
- Residual risk or pending external proof: automatic failover is not active.
  It awaits explicit approval for the exact recurring Cloudflare charge,
  authenticated deletion of the unused wrong-zone record, verification of the
  real LA origin, secure dual-site deployment, and failover/failback drills.
  No database migration or `supabase db push` was performed.

## 2026-07-25 — Scroll-contained combined-clip source list

- Outcome: constrained the web Combined clip properties source list to a compact, independently scrollable region. The fixed modal and summary remain stationary; wheel or trackpad input over the source list scrolls only that list, with scroll chaining contained and a dedicated right-side scrollbar gutter.
- Commit or working-tree state: committed as `15ca9d5503dcb1df8a4940bb39164f2a7fe37670` (`fix(web): contain combined clip source list`) and pushed to `origin/main`. The pre-existing untracked `artifacts/product-demo-60s/audience-variants/` directory was not modified.
- Affected surfaces/files: legacy Flask web Soundboard combined-clip properties UI in `web/python-web-app/static/js/index_soundboard.js` and `web/python-web-app/static/css/index_slow.css`, with regression coverage in the Soundboard JavaScript runtime check and Python surface contract test.
- Verification: JavaScript syntax and Soundboard runtime checks passed; 13 focused Python surface tests passed; browser QA with 52 source rows proved a 208px list viewport over 1,331px of content, list scroll movement from 0 to 650px, unchanged page scroll position, and unchanged fixed-panel position. `git diff --check` passed.
- Deployment: GitHub Actions run `30187579716` completed successfully and deployed exact commit `15ca9d5503dcb1df8a4940bb39164f2a7fe37670` to `web.speaktrue.cc`.
- Live verification: production `/health` returned `{"status":"ok"}`; `/deploy-version.json` and the HTML deploy marker returned `15ca9d55`; served JavaScript and CSS contain the labelled source region, responsive height cap, scrollbar gutter, and scroll-containment rules.
- Documentation/status changes: `SpeakTrue.md` now records the scroll-contained source list as current web behavior; planning classifications were unchanged.

## 2026-07-25 — Lecture3 historical combined-clip provenance backfill

- Outcome: backfilled component provenance for the four historical Lecture3 combined clips in both the staging account and `bogendds` account. Eight live `soundboard_clips` rows now connect the existing combined audio/text objects to ordered `metadata.combined_from.clips` arrays containing 53, 53, 53, and 52 source filenames per account.
- Scope: only user IDs `3d802446-751b-4fbd-b814-b6840923c8a0` and `37c4937d-bc07-451b-b4b0-c19c680cc391`, their two active Lecture3 category IDs, and their exact `users/<id>/soundboard/Lecture3/combined/` storage prefixes.
- Evidence: account/output-scoped Loki searches found no attributable filename, user-ID, or email lines. The authoritative recovery path was the legacy GCS Lecture3 order snapshot immediately preceding each combine, cross-checked against the stored combined transcript. The four outputs produced 45/53, 47/53, 53/53, and 52/52 surviving source transcripts in exact snapshot order; the two newest sequences were fully reconstructed independently and matched their snapshots exactly.
- Verification: live readback returned eight distinct `(user_id, storage_path)` rows, all eight with `combined_from`, and component array lengths equal to their declared clip counts. First/last filenames, snapshot evidence paths, transcript hashes/match counts, output object metadata, and account-specific source-row details were verified after the transaction committed.
- Data-quality boundary: historical source records that no longer exist are retained as exact filenames with `source_record_missing=true`; no newer clip ID or nested metadata was substituted. Historical gap settings and default break duration were not reconstructed and are explicitly listed as unavailable in the backfill metadata.
- Repository state: no tracked repository files changed; commit remains `42618dee2157953e8d89877c0d38c3b336110be7`. The unrelated untracked `artifacts/product-demo-60s/audience-variants/` directory was not modified.

## 2026-07-25 — Exact web combined-clip source metadata and components legend

- Outcome: extended strict-mode web Soundboard combining so every combined clip row snapshots each selected source clip's stored JSON metadata together with its stable ID, filename, storage/transcript paths, source order, duration, MIME type, file size, and source timestamps. Added a real `Combined components` button to the existing legend; it expands an ordered category-level source list, while the matching layer button on each combined row retains the full properties view.
- Commit or working-tree state: committed as `42618dee2157953e8d89877c0d38c3b336110be7` (`feat(web): expose combined clip provenance`) and pushed to `origin/main`. The pre-existing untracked `artifacts/product-demo-60s/audience-variants/` directory was not modified.
- Affected surface: legacy Flask web Soundboard combine flow, the Supabase `soundboard_clips.metadata.combined_from.clips` provenance contract, and the in-category web legend/combined-clip rows.
- Verification: 140 focused and related Python tests passed; JavaScript syntax and Soundboard runtime contracts passed; desktop and 390x844 browser inspection verified expand/collapse, ordered components, accessible labels, responsive wrapping, and the historical-clip fallback; Python compile check and `git diff --check` passed.
- Deployment: GitHub Actions run `30185682667` completed successfully and deployed exact commit `42618dee2157953e8d89877c0d38c3b336110be7` to `web.speaktrue.cc`.
- Live verification: production `/health` returned `{"status":"ok"}`; `/deploy-version.json` and the HTML deploy marker returned `42618dee`; the served `index_soundboard.js` contains the new combined-components legend implementation.
- Documentation/status changes: `SpeakTrue.md` now records the combined-clip provenance contract and deployed legend as current product behavior; planning classifications were unchanged.
- Residual risk or pending external proof: deployment verification did not create a new production combined clip, so a live database-row/UI provenance comparison remains pending to avoid mutating user content. Historical combined clips without saved provenance correctly display `Components were not recorded for this clip.`

## 2026-07-25 — Obsidian documentation refresh and permanent sync gate

- Outcome: refreshed the SpeakTrue vault from the 2026-07-14 snapshot to current `main`, added this work log, and established a mandatory repo-level closeout gate for all future agents.
- Current base: `72657c29f885ab6fb8ea44eeba9da6302bef5fe5` (committed and pushed to `origin/main`).
- Repo changes:
  - `AGENTS.md` — mandatory Obsidian sync gate;
  - `README.md` and `docs/index.md` — route contributors to the sync runbook;
  - `docs/ops/OBSIDIAN_DOCUMENTATION_SYNC.md` — durable workflow and content boundaries;
  - `scripts/refresh_obsidian_docs.py` — reproducible map generation and manifest check.
- Vault changes: refreshed `SpeakTrue.md`, `SpeakTrue Planning Status.md`, all platform codebase-map notes, and `manifest.json`; added `SpeakTrue Work Log.md`.
- Verification: Python compile check, staged map generation, manifest count against `git ls-files`, vault link/reference checks, `python3 scripts/refresh_obsidian_docs.py --check`, `git diff --check`, and final repository status review.
- Workspace note: the pre-existing untracked `artifacts/product-demo-60s/audience-variants/` directory was not modified.

## 2026-07-24 — Native speech reliability and playback controls

- Outcome: simplified native playback controls, preserved current workflow state/retry behavior, restored Android realtime-session compatibility, retained structured speech failures through Android state boundaries, and normalized realtime finalization metadata.
- Commits: `f187542d`, `176b062b`, `6e1ef78b`, `a534d524`, `e77fecd0`.
- Affected surfaces: iOS, Android, Supabase STS handlers, native parity/release guards, runtime documentation.
- Documentation effect: current product state and STS contract summaries now reflect these behaviors.

## 2026-07-23 — Pronunciation dictionaries across mobile speech

- Outcome: applied pronunciation dictionaries across supported mobile TTS and live STS paths and cleaned obsolete pronunciation defaults.
- Commit: `0f6145ff`.
- Affected surfaces: iOS, Android, `tts-generate`, live STS Edge Functions, migration/schema defaults, contract tests.
- Documentation effect: current generation and STS architecture summaries now include pronunciation processing.

## 2026-07-20 — Artifact metadata, provider settings, and long-form retirement

- Outcome: persisted canonical generation artifact metadata across backend/clients, corrected provider voice-setting mapping, and retired the web long-form/Studio pilot in favor of standard direct TTS.
- Commits: `2e62f814`, `30178e4e`, `c6961fb7`, `caa9c6bf`, `e6be60f8`.
- Current contract: direct TTS caps input at 10,000 characters; 5,001–10,000 characters requires `eleven_multilingual_v2`; `tts-longform` is a provider-free `410 Gone` tombstone.
- Documentation effect: the main status note and planning note now classify long-form as retired and artifact metadata as implemented.

## 2026-07-19 — Soundboard category ZIP export

- Outcome: added legacy-web category ZIP export with visible progress and retained existing Soundboard clip workflows.
- Commits: `428551f1`, `5e6ac73f`.
- Affected surfaces: Flask Soundboard routes/services, browser UI/runtime, templates/styles, API/unit/browser-contract tests.
- Documentation effect: the current product-state note now includes category export.

## Entry Template

### YYYY-MM-DD — Short outcome

- Outcome:
- Commit or working-tree state:
- Affected surfaces/files:
- Verification:
- Documentation/status changes:
- Residual risk or pending external proof:

## 2026-09-05 — Local Qwen usability and selectable references, build 39

Implemented model inventory for all variants, a persistent default local voice, section boundary previews with the 420-character bound and separate generated-audio-token cap, removal of the inserted 140 ms section gap, and a 5 ms crossfade. Added selectable recordings with separate transcripts under each profile, remembering the chosen recording. Existing metadata remains readable; profile deletion removes all recordings. Generation still uses one selected reference. No enforced reference-duration maximum was introduced.

Affected files (all existing, uncommitted atop 4cc7b69d): ios/SpeakTrue/LocalQwenContracts.swift, LocalQwenRuntime.swift, LocalQwenViewModel.swift, LocalQwenPrototypeView.swift, LocalVoiceProfileStore.swift; ios/SpeakTrueTests/LocalQwenPrototypeTests.swift; ios/SpeakTrue.xcodeproj/project.pbxproj; docs/guides/ios-local-qwen-prototype.md; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt. No new uncommitted files. Build is 1.3 (39); Android assertion only aligns the iOS build.

Verification: focused xcodebuild test on Yoseif’s iPhone passed all 11 tests, including legacy metadata, additional recordings, transcript selection, persistent preference, file cleanup, integrity, chunking and crossfade. Test installation completed and CoreDevice normal app launch succeeded. Android/iOS parity check passed 12 surfaces/24 gates; git diff --check passed. Earlier progress test counts were imprecise; the final result is 11. Full Android CI was not run because no commit/push is being performed; that gate remains required before committing this parity assertion. No speech-quality conclusion follows from the synthetic tests: actual section-boundary listening and repaired six-bit output remain pending. No commit or push in this slice.

## 2026-09-05 — Build 40: confirmed generation memory-limit termination

Retrieved the crash-time jetsam report from the iPhone. SpeakTrue was frontmost and killed for `per-process-limit`, with 216125 resident 16 KiB pages (approximately 3.30 GiB), at 11:16:16. No inference code exception was reported. The app entitlement file lacked Apple's increased-memory-limit capability. Added it and verified it in the signed app. Build 1.3 (40) succeeded, installed, and launched with console capture; actual generation retry is pending. This is a targeted mitigation for the confirmed limit, not a claim that every reference/model now fits.

This slice changed ios/SpeakTrue/SpeakTrue.entitlements, ios/SpeakTrue.xcodeproj/project.pbxproj, android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt, and docs/guides/ios-local-qwen-prototype.md. Ten existing files are now uncommitted atop 4cc7b69d including preceding Qwen changes; no new uncommitted files. Android/iOS parity passed 12 surfaces/24 gates and git diff --check passed. No new inference tests claimed; the prior 11 tests cover contracts only. Full Android gate remains required before commit/push. Raw diagnostic reports remain outside the repo/vault.

## 2026-09-05 — Local Qwen settings implementation plan

Prepared a proposed, phased plan covering all discussed controls, explicit per-voice persistence/reset behavior, immutable generation requests, provisional bounds, structured paragraph boundaries, pitch-preserving final-file speed, and real-device/listening verification. Inspected the checked-out Qwen adapter: shared seed/cache parameters are not forwarded, so the plan excludes unsupported knobs. Added docs/product/LOCAL_QWEN_GENERATION_SETTINGS_PLAN.md (new uncommitted file) and linked it in docs/index.md. Created a temporary browser-readable review artifact with Markdown copy/export outside the repo. No app code, build, install, commit or push in this planning task. Existing ten-file dirty implementation preserved; twelve repo paths now differ including the new plan. git diff --check passed. Proposed status recorded; code implementation awaits the next step. The generated map will index the new plan once tracked.

## 2026-09-06 — Committed and pushed iOS Local Qwen build 40

Committed and pushed `311cf548` (fix(ios): stabilize local Qwen downloads and generation) to origin/main at the user's request. Ten files included: ios/SpeakTrue.xcodeproj/project.pbxproj; ios/SpeakTrue/LocalQwenContracts.swift, LocalQwenPrototypeView.swift, LocalQwenRuntime.swift, LocalQwenViewModel.swift, LocalVoiceProfileStore.swift, SpeakTrue.entitlements; ios/SpeakTrueTests/LocalQwenPrototypeTests.swift; docs/guides/ios-local-qwen-prototype.md; android/app/src/test/java/com/speaktrue/contracts/AndroidReleaseReadinessContractTest.kt. No new app edits or build-number increment were made during this publication; version remains 1.3 (40).

Fresh generic physical-iOS build passed. Required bash scripts/verify_android_ci_local.sh passed: 564 Android unit tests with zero failures/errors, 22 backend contract tests, lint, release AAB verification and local Play readiness. External Play/provider proof remains unverified and is explicitly ignored by the local-only gate. Reviewed the prior final 11-test physical-iPhone pass for unchanged inference/profile source; no new listening or inference success claimed. Staged diff whitespace check passed; no unrelated paths included. No new uncommitted files. Working tree clean after commit. External overview/planning state updated and map refreshed/checked after the final repository commit.


## 2026-09-06 — Published Obsidian project notes to GitHub main

Committed and pushed documentation-only commit `c1abc18a` to origin/main. Published 16 Markdown files and one manifest under docs/obsidian, including the overview, planning status, work log and generated codebase maps. Converted 27 wikilinks to relative Markdown links; all 33 relative links resolve. Added an export README explaining historical entries, local-uncommitted build descriptions and static map provenance. Also committed the referenced docs/product/LOCAL_QWEN_GENERATION_SETTINGS_PLAN.md and its docs/index.md links. No application source was staged or committed. Ten existing implementation files remain dirty. No new uncommitted files from this task. Credential-pattern scan, manifest checks and staged git diff --check passed. Android CI was not required for this docs-only commit. The external map is refreshed after publication; the published snapshot remains fixed at its recorded source state.

Status: active from 2026-07-25 onward.

This is the concise completion record for agent work in the SpeakTrue repository. It records outcomes and verification, not raw conversations or sensitive runtime data. Repository source, tests, tracked docs, and verified live state remain authoritative.
