Renumber spec 001 decision placeholders to D-040–D-051; record the Danish publication

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-30 01:47:27 +01:00
1 parent 30969e86b7
commit 0632f7843b
71 files changed
+244 -236

No files matched your search

+8 -8
View File
@@ -11,7 +11,7 @@ stdio — one JSON object per line, no framing beyond that:
"audio_path": "/tmp/...", "language": "en" | null,
"task": "transcribe" | "translate",
"mode": "file" | "live", # optional, default "file"
"prompt": "Maxwell, Voices of the Void" | null} # optional (D-WS2a)
"prompt": "Maxwell, Voices of the Void" | null} # optional (D-048)
stdout <- {"type": "segment", "id": "1", "start": 0.0, "end": 4.2,
"text": " Hello world."} # 0..n of these
stdout <- {"type": "done", "id": "1", "cancelled": false}
@@ -26,7 +26,7 @@ container decoding happens here. Requests are processed strictly one at a
time; a reader thread keeps consuming stdin meanwhile so `cancel` can
interrupt the segment loop of the request in flight.
Decoding strategy by mode (Decisions.md D-WS5a):
Decoding strategy by mode (Decisions.md D-047):
"file" faster-whisper's BatchedInferencePipeline with its Silero VAD
(vad_filter=True, VAD_PARAMETERS): silence is dropped, speech is cut
into <= 30 s chunks and BATCH_SIZE chunks decode per forward pass.
@@ -62,18 +62,18 @@ import sys
import threading
SAMPLE_RATE = 16000
BATCH_SIZE = 8 # D-WS5a: VAD chunks decoded per batched forward pass
# D-WS5a: Silero VAD tuned for file mode. faster-whisper's batched default
BATCH_SIZE = 8 # D-047: VAD chunks decoded per batched forward pass
# D-047: Silero VAD tuned for file mode. faster-whisper's batched default
# (threshold 0.5, 400 ms padding) dropped quiet and overlapped speech —
# deletions nearly doubled on en_alien; 0.2 / 800 ms brought WER back to the
# sequential decoder's level. min_silence_duration_ms stays at VadOptions'
# 2000 ms default (a dict replaces the pipeline's 160 ms preset).
VAD_PARAMETERS = {"threshold": 0.2, "speech_pad_ms": 800}
# "Names and terms" vocabulary hint (D-WS2a). Twins of normalizeHint /
# "Names and terms" vocabulary hint (D-048). Twins of normalizeHint /
# fitHintToBudget in src/lib/hint.ts — change both together; parity is tested
# in tests/hint-parity.test.ts. Whisper would allow 223 tokens; 120 is the
# measured cap at which small models are not garbled (D-WS2a).
# measured cap at which small models are not garbled (D-048).
PROMPT_TOKEN_BUDGET = 120
_CONTROL_CHARS = re.compile("[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]")
@@ -215,7 +215,7 @@ def main():
)
if mode == "live":
if prompt_ids:
# D-WS2a: token ids, already cut to the budget by the
# D-048: token ids, already cut to the budget by the
# same rule as the browser engine.
options["initial_prompt"] = prompt_ids
segments, _info = cached_model.transcribe(
@@ -241,7 +241,7 @@ def main():
# `segments` is a generator: inference happens during iteration,
# so segments stream out (and cancel can cut in) while later ones
# are still being decoded — per segment in live mode, per batch of
# BATCH_SIZE speech chunks in file mode (D-WS5a).
# BATCH_SIZE speech chunks in file mode (D-047).
for segment in segments:
if request_id in cancelled:
was_cancelled = True