transcript-fixer
Corrects speech-to-text transcription errors with dictionary rules and Claude's built-in AI (no external API key required); Native AI Correction is the default, Stage 1 alone is incomplete, and Stage 3 API is only for automation without Claude Code. Builds personalized correction databases, loads person-name ASR variants from the configured global people roster, and reads per-domain contexts for homophones. Before correcting a person name, the agent must consult both the global roster and the owning project's identity roster; project rosters are not auto-loaded, and occurrence frequency is never identity evidence. Use for ASR/STT output with recognition errors, homophones, garbled technical terms, person-name errors, or mixed Chinese/English, and for cleaning transcripts when the user only says "fix this transcript," "clean up these meeting notes," or mentions a garbled name.
1How It Works & Mechanism
Two-stage correction loop: Stage 1 applies known corrections in batches using deterministic dictionary rules; Native AI Correction (built into Claude/Codex, requiring no external key) reads the entire text to fix one-off errors and crystallizes reusable corrections; Stage 3 API is dedicated solely to agent-less automation.
1. Stage 1 applies deterministic, already-known corrections. 2. Native AI Correction reads the complete transcript, fixes one-off errors, verifies uncertain entities, and compounds reusable fixes.
Personalized correction database: SQLite (~/.transcript-fixer/corrections.db) stores dictionaries, context rules, people rosters, and review queues; the directory is permissions-guarded with chmod 0o700 and config with 0o600, while domain context files adhere to the ~/.transcript-fixer/contexts/<domain>.md convention.
# Filesystem security CONFIG_DIR_MODE: Final[int] = 0o700 CONFIG_FILE_MODE: Final[int] = 0o600
Person-name correction gate: Before altering a person's name, the agent must cross-reference both the global people roster and the project's explicit identity roster; the roster strictly stores ASR variants, project rosters are never auto-loaded, and frequency is never accepted as identity evidence.
Before correcting any person name, directly read both the configured global people roster and the owning project's explicit identity roster or alias ledger. … Never use occurrence frequency as identity evidence.
Safe mode + multi-layer matching defense: By default, only low-risk rules are automatically applied, while medium- and high-risk items are deferred to *_needs_review.md and the persistent review queue; matching-phase three-tier checks (superset, common word boundary, and standard word boundary) reject inappropriate matches.
Safe mode is the Stage 1 default: low-risk rules apply; medium/high-risk matches defer to `*_needs_review.md` and the persistent review queue. `Applied: 0` is a valid result, not proof that the transcript is clean.
Review queue + local dashboard: Queue entries follow {file, line, original, suggested, kind, context, evidence}; review-dashboard/server.py serves FastAPI at 127.0.0.1:8767, establishing a read-only connection to the same SQLite database so both the CLI and human reviewers share an identical source of truth.
anchor guards, and audit logging stay the single source of truth — this UI never mutates the database itself. Agent (CLI) and human (this page) are equal writers of the same queue.
AI-enhanced routing (agent-less): Routes to GLM only when Claude/Codex is unavailable—via the Anthropic-compatible endpoint open.bigmodel.cn/api/anthropic, authenticated by x-api-key at /v1/messages, utilizing model GLM-5.2 (fallback to GLM-5-turbo).
API_PROVIDER: Final[str] = "GLM" DEFAULT_MODEL: Final[str] = "GLM-5.2" FALLBACK_MODEL: Final[str] = "GLM-5-turbo" API_BASE_URL: Final[str] = "https://open.bigmodel.cn/api/anthropic" AUTH_HEADER_NAME: Final[str] = "x-api-key"
Evidence chain and closure contract: Corrections require from_text/to_text provenance and asr_note line-mask protection; --close-sidecars reports closed only when all queue lines are adjudicated, rules are deactivated, and the file contains zero pending items (exit 1 open / exit 2 blocked).
`--close-sidecars --input "<absolute-canonical-file>"` reports `closed`: every entry reads applied in the file (or the original form no longer appears anywhere in the ledger-masked transcript) or is answered by a decided queue row for this exact file
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| network | open.bigmodel.cn(GLM/智谱,anthropic 兼容) |
| cli | uv / python3(PEP 723 入口,uv run) |
| package | httpx/filelock/aiofiles(ensure_deps 的共享 venv) |
| package | jieba / rapidfuzz(fix_transcription.py PEP 723 依赖,词边界/模糊匹配) |
| cli | lark-cli(飞书 CLI,音频取证;需已登录 profile) |
| cli | curl / ffprobe / sqlite3(工具链) |
4Recommended Governance & Evidence
- scripts/: Executes local scripts or commands: fix_transcription.py and accompanying utility scripts in the same directory (via uv run)
- scripts/ 或 SKILL.md: Declares dynamic installation of external language package dependencies
- 网络端点: Declares external network access: Stage 2/3 (agent-less API routing) issues POST requests to https://open.bigmodel.cn/api/anthropic/v1/
- 本地工作目录: File read/write operations and artifact outputs: directly edits user's source transcript files (in-place under Native mode) and produces *_stage1.md / *_changes.md / *
5Second-Pass Verification
- [ok] SQLite 数据库与 0o700/0o600 权限 — defaults.py CONFIG_DIR_MODE=0o700/CONFIG_FILE_MODE=0o600;config.py DatabaseConfig/PathConfig __post_init__ 逐目录 mkdir+chmod;默认路径 Path.home()/'.transcript-fixer'/corrections.db。
- [ok] 凭证读取面(GLM/ANTHROPIC key 与 config.json) — config.py from_env 读 GLM_API_KEY/ANTHROPIC_API_KEY/ANTHROPIC_BASE_URL;from_file 读 config.json api.api_key;get_config 全局 env 覆盖 file。无其他 key/token 读取。
- [ok] 网络调用点仅 open.bigmodel.cn(+dashboard 本机) — ai_processor.py _process_chunk url=f'{base_url}/v1/messages' httpx POST;全目录 https?:// 扫描无其他外发端点;astral.sh 仅 ensure_deps 报错文案。
- [ok] 人名门禁(roster 双读/频率非证据) — commands.py 715-719/1330-1333 roster_path = getenv('TRANSCRIPT_FIXER_PEOPLE_ROSTER') or config…people_roster_path 存在;SKILL.md 操作契约原文存在;Stage1 只加载全局 ASR 变体。
- [ok] Safe mode 与 defer 行为 — SKILL.md『Safe mode is the Stage 1 default』;commands.py 1401 附近『Stage 1 defaults to conservative safe mode: only auto-apply low-risk』代码注释相符。
- [ok] review queue 结构(file/line/original/suggested/kind/context/evidence) — SKILL.md 最小条目 JSON 逐字段存在;review_queue.py 以 sqlite 实现(--init 后 db 必须存在)。
- [ok] dashboard 只读连库且仅本机 — server.py _connect_ro 用 'file:{DB_PATH}?mode=ro';uvicorn.run(host='127.0.0.1', port=PORT);docstring『never mutates the database itself』。
- [ok] fetch_minute_audio 网络/CLI 行为 — lark-cli minutes +download --url-only → json 取 download_url → curl -sSL --noproxy '*' 下载;LARK_CLI_NO_PROXY=1 防代理带走凭证。
6Verdict & Scenarios
1621eed101bbd789…