Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,59 @@
# Changelog

All notable changes to bestASR are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow SemVer.

## [Unreleased]

## [0.12.0] - 2026-07-10

### Added

- **MCP async job mode (#86)**: `transcribe` accepts an opt-in `async` flag and
returns a `job_id` immediately; new read-only tools `transcribe_status` and
`transcribe_result` (bounded long-poll, 25 s cap) poll it. Jobs live in a
bounded in-memory registry (TTL eviction + a global sweep on every start) and
share the same single-flight serialization as synchronous transcribes.
- **macOS GUI dual-track bundle (#87)**: new SwiftUI `bestasr-gui` app (drag &
drop / file picker, language/effort/format pickers persisted across launches,
honest stage+elapsed progress, transcript preview + reveal-in-Finder) and
`scripts/release-app.sh`, which assembles, signs, notarizes, and **staples**
a `bestASR.app` carrying the GUI, `bestasr-mcp`, and the CLI as
`bestasr-cli` (default APFS is case-insensitive — a `bestasr` entry would
overwrite the `bestASR` GUI executable). First offline-Gatekeeper-verifiable
bestASR artifact, published as `bestASR-0.12.0.zip` on the v0.12.0 release.
- **LibriSpeech English benchmark corpora (#88)**: test-clean + dev-clean,
8 corpora / 48 utterances, source tarballs and converted artifacts digest-
pinned end to end; `references/asr-benchmark-landscape.md` records the cited
dataset/license/methodology survey behind the pick.

### Fixed

- **External-adapter watchdog hang (#91)**: a spurious `Process.isRunning`
false right after launch could skip the timeout watchdog entirely, leaving an
unbounded `waitUntilExit()` (a 1-hour CI hang). The loop is now gated on a
`terminationHandler`-driven exit latch installed before `run()`, so it can
exit only via real process exit or the SIGTERM→SIGKILL deadline branch.
- **bash 3.2 empty-array crash in release/install scripts**: expanding an empty
`"${BUILD_ENV[@]}"` under `set -u` aborts on stock macOS bash — which killed
the build exactly on the recommended Xcode-toolchain path. Guarded in
`release-app.sh`, `release-mcp.sh`, and `install.sh`; the app version parse
is now scoped to the `BestASRVersion` enum and semver-asserted.

## [0.11.0] - 2026-07-08

### Added

- **MCP server surface (#80, #84)**: `bestasr-mcp` speaks MCP over stdio
(official swift-sdk), linking BestASRKit directly so engine pipeline caches
persist across tool calls; v1 tools: transcribe / recommend / list_backends /
list_models / corpus_add. Tool errors are loud and typed; transcribes are
single-flight serialized.
- **Plugin bundles the MCP server (#85)**: the Claude Code plugin auto-downloads
a Developer ID-signed, notarized `bestasr-mcp` from GitHub Releases
(che-mcps wrapper pattern); `scripts/release-mcp.sh` builds, signs,
smoke-tests under hardened runtime, notarizes, and publishes it.

### Added
- mlx-audio catalog measured (#65): seven families live-probed, revision-pinned, and benchmarked — canary 1b / granite-speech 2b / voxtral-realtime 4b hit en WER 3.8% (front-tier), vibevoice-asr 9b reaches zh CER 17.7%; nemotron-asr and moonshine verified; qwen2-audio measured (chat-style output inflates WER honestly). qwen3-asr and mega-asr fail in the mlx_audio loader ("All arrays must have the same shape"); distil-whisper lacks its processor config; mms / voxtral mini-3b / qwen3-forcedaligner have no mlx conversion. mlx candidates are now addressed family/size end-to-end (bare-size collision trapped the benchmark report).

Expand All @@ -17,9 +69,6 @@
### Changed
- **Breaking (output format)**: diarized speaker prefixes are now human-readable — SRT/VTT cues read `Speaker 1: text` (was `[SPEAKER_1] text`) and txt lines use the same `Speaker N: ` form; enrolled names render as `Name: `. JSON keeps the internal `SPEAKER_N` label. Downstream parsers of the old bracket form must update. (#54)

All notable changes to bestASR are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow SemVer.

## [0.10.0] - 2026-07-06

### Added
Expand Down
47 changes: 47 additions & 0 deletions changelog/20260710_v0.12.0-async-gui-watchdog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 2026-07-10 — v0.12.0:async MCP 工具 + 首顆 stapled bestASR.app + watchdog 修正

## 出貨(GitHub Release v0.12.0,四個 assets)

- **MCP async job mode(#86,PR #89)**:`transcribe` 增加 opt-in `async` 參數
→ 立即回 `job_id`;新增唯讀工具 `transcribe_status` / `transcribe_result`
(bounded long-poll,25 s cap)。`JobRegistry` actor:TTL 逐出 + 每次 start
全域 sweep(registry 有界)、與同步路徑共用 SingleFlight 序列化。
- **macOS GUI dual-track bundle(#87,PR #93)**:SwiftUI `bestasr-gui`
(`BestASRGUICore` 可測 session 狀態機 + thin views;拖放/檔案選擇、
語言/effort/格式選項持久化、stage+elapsed 誠實進度、結果預覽 + Finder 顯示)。
`scripts/release-app.sh`:universal build → bundle 組裝 → Developer ID
nested-first 簽章 → notarize → **staple + validate** → zip。CLI 在 bundle 內
改名 `bestasr-cli`(預設 APFS 不分大小寫,`bestasr` 會覆寫 GUI `bestASR`——
smoke test 首跑即抓到,issue 原佈局不可行)。
- **LibriSpeech 英文標準語料(#88,PR #90)**:test-clean + dev-clean 各 4 組
×6 utterances(8 corpora / 48 utterances),來源 tarball 與轉檔產物全程
SHA-256 pin;`references/asr-benchmark-landscape.md` 收錄 cited survey
(license/access 矩陣、WER/CER 方法論)。
- **ExternalProcessEngine watchdog 修正(#91,PR #95)**:`Process.isRunning`
啟動期 race 會讓 watchdog 零迭代跳過 → 無界 `waitUntilExit()`(CI 上掛滿
stub 的 3600 s)。改用 `terminationHandler` 驅動的 `ExitLatch`(run() 前掛好)
作為迴圈條件——迴圈只能經「真的退出」或 deadline kill 離開;hung-adapter
測試 stub 3600 s → 15 s(regress 成本從 1 小時壓到秒級)。

## 程式檔變更(今日)

- `Sources/BestASRKit/Engines/ExternalProcessEngine.swift` — ExitLatch watchdog
- `Tests/BestASRKitTests/ExternalEngineTests.swift` — stub 降 15 s
- `Sources/BestASRKit/Models/DataModels.swift` — `BestASRVersion.current` → 0.12.0
- `scripts/release-app.sh` / `scripts/release-mcp.sh` / `scripts/install.sh` —
bash 3.2 空陣列 `set -u` guard(`${arr[@]+...}`;verify #87 HIGH,三處同款潛伏 bug 一次掃除)
與 enum-scoped + semver-asserted 版本 parse

## 發布動作

- `release-mcp.sh 0.12.0`:notarize Accepted → Release v0.12.0(`bestasr-mcp` + sha256)
- `release-app.sh`:notarize Accepted → **staple 驗證通過**(首顆離線可驗證 artifact)
→ `bestASR-0.12.0.zip` + sha256 上傳同一 release
- `/plugin-update bestasr`:marketplace + plugin 0.11.0 → 0.12.0

## 維運

- Spectra changes `mcp-surface` / `mcp-transcribe-async` / `add-librispeech-corpus` /
`gui-app-dual-track` 歸檔(PR #92、#94),living specs 同步(新 `mcp-surface`、
`gui-app` capability spec;corpora 增 LibriSpeech requirement)。
- Issues #86 / #87 / #88 / #91 均以完整 closing summary 手動關閉;backlog 歸零。
Loading