State

August 18, 2026 · View on GitHub

Only progress ledger. Update when something verifiably passes or fails.
Target: INVENTORY.md — 2 ASR + 5 TTS (shipped) + 3 emb
Next work: operator runtime verification of the pending-operator rows below (needs container + GPU + HF token). All code-complete criteria for Tasks 5–8 pass.

Last updated: 2026-08-03

Legend: pass = verified with evidence. pending-operator = code is complete and unit/contract-tested, but the load+inference proof requires the operator's container/GPU/HF token and has not been run here. fail = known broken.


How to update this file

  1. Run verify commands from RULES.md
  2. Set status to pass or fail — not “done”, “mostly”, “assumed”
  3. Add evidence: test class/method, operator command, or PR link
  4. For per-model runtime, all four columns (manifest, download, load, infer) must be pass for overall pass

Executive summary

LayerStatusGap
Discovery / inventory docCompleteINVENTORY.md lists all models + config semantics
Emb manifestComplete3/3 GGUF entries
ASR manifestComplete2/2 entries
TTS manifestComplete5/5 shipped entries
Client model picker (API)CompleteTask 1
Download .NET validationCompleteTask 2 — catalog membership enforced
UI per-model configComplete (code)Task 5 — hardcoded LocalTtsVoiceNames/LocalTtsVoiceLanguageCodes removed; VoiceName is catalog-driven; voice-pack API end-to-end
TTS runtime all familiesComplete (code)Task 6 — Chatterbox funnel removed; server config + synth payload driven by catalog family/voiceInput. Per-model load+infer is pending-operator
CI drift guardCompleteTask 7 — verify-catalog-contract.ps1 green
NOTICE / bootstrapCompleteTask 8 — NOTICE matches Kokoro-synthetic manifest; bootstrap/compose voice = af_alloy
Full runtime matrix1/5 TTS pass, 4/5 pending-operatorDeferred families excluded until blockers close

Infrastructure baseline

CheckStatusEvidence
Torch removed from imagepasscuda13 ~13.5GB; import torch fails in container
cuda13 ASR+TTS+emb round-trippassOperator 2026-07-02
cpu ASR+TTS round-trippassOperator 2026-07-03 (backend env fix)
Contract golden replaypendingcapture-contract-goldens.ps1 not recorded
Final CodeQLpendingrun-final-codeql.ps1 not recorded

Manifest completeness

ServiceInventory countIn catalog/manifest.jsonStatus
ASR22pass
TTS5 shipped5pass
Embeddings33pass

Plumbing checklist

ItemStatusEvidence / blocker
I2 Client catalog fetchpassCatalogDownloadModelDialog, Task 1
I3 .NET catalog proxypassSettingsServiceLocalModelsEndpoints.cs
I3 Download validatorpassServiceLocalModelDownloadValidator.ValidateCatalogMembership + ServiceLocalModelCatalogSupport.GetCatalogIdsAsync (1 min cache); tests: ValidateCatalogMembership_RejectsUnknownModelId, ValidateCatalogMembership_AcceptsKnownModelId, GetCatalogIdsAsync_UsesCachedCatalogIds
I4 UI from voiceInputpassLocalTtsVoiceNames removed; VoiceName kind=text (catalog-driven); voice-pack panel from API. Tests: ServiceEditorMetadataProviderTests.GetProviderFields_LocalSpeechSynthesis_VoiceNameIsCatalogDrivenNotHardcodedEnum, TtsModelManager "catalog-driven voice-pack presets"
I5 No .NET lang mapspassLocalTtsVoiceLanguageCodes removed; wire is {text, voice?, speed?}. Tests: SpeechSynthesisServiceTests.SynthesizeToWavAsync_Local_ForwardsVoiceWithoutLangCode, ...UsesLocalTtsProvider_WhenModeSelectsLocal
I6 Family-aware runtimepass (code)tts_service.py server config + resolve_voice_fields driven by catalog family/voiceInput; asr_service.py family from catalog entry ({family}.weight_type). Per-model load+infer pending-operator
I7 Voice-pack APIpassGET /admin/voice-pack (tts_service.py) + .../local-models/voice-pack proxy + api.settings.localModels.voicePackOutcome
I7 Voice-pack baked + attributionpassCOPY in Dockerfile + check-voice-pack-attribution.py (54 voices, kokoro_synthetic/CC0-1.0)
I7 NOTICE alignedpassNOTICE rewritten for Kokoro-82M synthetic provenance; sourceDataset corrected common_voicekokoro_synthetic
Cloud-active local inventory reportingpass (code)Saved local selections no longer overwrite cloud routing or runtime inventory. Tests: ServiceLocalModelListEnricherTests.ProxyAndEnrichImageBundlesAsync_ExposesSavedSelectionWithoutRewritingRuntimeState, NotebookHeaderToolbarServiceTests.GetToolbarAsync_CloudProvidersDoNotPresentSavedLocalModelsAsActive, LocalAiStartupWarmupServiceTests.SyncDesiredAndApplyAsync_SkipsImageBundleProjectionWhenCloudIsActive
I10 CI drift scriptpassscripts/native-ai-migration/verify-catalog-contract.ps1 — ASR 2/2, TTS 5/5 shipped, Emb 3/3, no hardcoded lists

Per-model runtime matrix

Pass = manifest yes + download pass + load pass + at least one successful inference.

ASR

idmanifestdownloadloadtranscribeOverall
qwen3_asr_0_6byespasspasspasspass
citrinet_asryespending-operatorpending-operatorpending-operatorpending-operator (family=citrinet_asr wired; needs converter download + load)

TTS

Runtime columns below are pending-operator: the code path is family-aware (resolve_voice_fields + resolve_engine_task), but load+synthesize proof needs the operator's container. voiceInput shows the wired voice contract.

idvoiceInputmanifestdownloadloadsynthesizeOverall
chatterboxvoice_packyespasspasspasspass
qwen3_tts_0_6b_basevoice_packyespending-operatorpending-operatorpending-operatorpending-operator
qwen3_tts_1_7b_basevoice_packyespending-operatorpending-operatorpending-operatorpending-operator
qwen3_tts_1_7b_voice_designinstructyespending-operatorpending-operatorpending-operatorpending-operator
omnivoicevoice_packyespending-operatorpending-operatorpending-operatorpending-operator

Deferred (not in catalog): qwen3_tts_1_7b_custom_voice, pocket_tts, miotts_1_7b, voxcpm2, vibevoice_1_5b, vibevoice_7b, vevo2 — see INVENTORY.md.

Operator verification commands (per model id <ID>, service SpeechSynthesis/SpeechTranscription):

# 1. download (enforced against catalog): POST /settings/services/<svc>/local-models/downloads {"model_id":"<ID>"}
#    gated (pocket_tts): include {"hf_token":"hf_..."}
# 2. load:      POST /settings/services/<svc>/local-models/load   {"model_id":"<ID>"}
# 3. readiness: GET  /settings/services/<svc>/local-models/ready  (expect 200 ready:true)
# 4. synthesize (TTS): POST tts /tts/synthesize {"text":"hello","voice":"<per voiceInput>"}
#    voice_pack -> pack id (e.g. af_alloy); builtin -> engine speaker id; instruct -> design text; optional_ref -> pack id or omit
# 4. transcribe (ASR): POST /v1/audio/transcriptions {"audio":"/path.wav"}
# Record wav duration / transcript here and flip the row to pass.

Embeddings (reference)

idmanifestdownloadloadembedOverall
qwen3_embedding_0_6byespasspasspasspass
embedding_gemma_300myesnot recordednot recordednot recordedpartial
bge_m3yesnot recordednot recordednot recordedpartial

Task completion

TaskStatus
1 Catalog API + client picker✅ complete
2 Download validator✅ complete
3 ASR full manifest✅ manifest complete; runtime matrix pending
4 TTS full manifest✅ manifest complete; runtime matrix pending
5 Catalog-driven UI config✅ complete (code + tests green)
6 Family-aware runtime✅ code-complete; per-model load+infer pending-operator
7 CI drift checks✅ complete (verify-catalog-contract.ps1 green)
8 NOTICE + bootstrap✅ complete (NOTICE + attribution check + voice ids)

What “done” is not

  • Container boots with Chatterbox + Qwen3 ASR
  • Task 1 catalog picker shipped
  • Docs marked “phase complete” in archived plans
  • 1/5 TTS shipped models in manifest (7 deferred)

Done = STATE per-model matrix all pass for ASR + TTS inventory + Task 7 CI.