docs(voice-packs): runbook, index link, and the log entry
The page a new operator needs: what the three required files are and who reads each one, how a pack is built (with the extractor's usage text verbatim, because the flags are not guessable and there is no -o), the 10-second gate and where it fires twice, how to add a fourth voice including the warm hook that registers a pack without restarting the engine, and the engine-bump procedure for when the artifact sizes move. Plus the host census as of 2026-10-18 — the trial packs carry no artifacts and their manifest is the trial's own schema, so the builder's first real run is a --force migration — and the three gaps left open on purpose: no curated ICL transcript, no 16 kHz variant, no loudness pass. Linked from the Dankclaw services list; log entry appended oldest-first.
This commit is contained in:
1 parent
3824d03ac5
commit
2427fc448f
3 files changed
+305
No files matched your search
@@ -2441,3 +2441,56 @@ every restart since the cutover.
|
||||
`~/.harbor/compose.opennotebook.yml` pins the deprecated `-single` image,
|
||||
carries no encryption key and injects the whole harbor env — left untouched,
|
||||
read-only, as the record of what not to copy.
|
||||
|
||||
## 2026-10-18 — voice-pack builder: the 10-second source-material gate becomes code
|
||||
|
||||
- Third slice of the voice stack (after the façade and the engine decision):
|
||||
`scripts/build-voice-pack.sh` turns a source recording plus a crop offset into
|
||||
a deployable pack — `reference.wav` (24 kHz mono `pcm_s16le`, 18–25 s), the
|
||||
engine's own `reference.spk` (8,192 B) + `reference.rvq` (5,456–6,864 B) made
|
||||
from it, and `manifest.json` provenance. Tracked tunables in
|
||||
`scripts/voice-packs.env`: pack list, per-voice source/offset/duration/pinned
|
||||
source sha256, extractor path and engine commit, artifact arithmetic. New runbook
|
||||
[[Voice Packs]].
|
||||
- **The gate is the product.** The project-wide invariant — no voice material
|
||||
from the first 10 s of a sample file — had only ever been a sentence in
|
||||
`scripts/frank-tts.env`. An offset inside it now exits 1 before a directory is
|
||||
created, and the same assertion runs again against the manifest that was just
|
||||
written, next to the recorded sha256, so a pack cannot carry a forbidden crop
|
||||
even if the env file is edited into nonsense. `10` stays a constant in the
|
||||
builder; the env file carries offsets, never the law.
|
||||
- **The extractor's contract was read, not guessed:** `qwen-codec` in qwentts.cpp
|
||||
`5916bf7c` takes `--model <codec gguf> --talker <base talker gguf> -i <wav>`
|
||||
with an optional `--device`, has **no `-o`** and names both artifacts next to
|
||||
the input with the extension swapped. So the WAV is staged under its final stem
|
||||
and `reference.wav` — the file the façade gates on — is moved into place
|
||||
**last**, after the artifacts and the manifest: a failed extractor leaves a
|
||||
directory that is not a voice. `--force` retires an existing pack whole to
|
||||
`.AGENTTRASH/` instead of touching bytes; nothing in this script deletes.
|
||||
- Sizes are arithmetic, so they are checked: 16 codebooks × 11 bits = 22 B per
|
||||
12.5 Hz frame (`22 × floor(samples/1920)`) and `enc_dim 2048 × f32` = 8,192 B.
|
||||
That makes the **effective crop window 19.84–25 s**, narrower than the WAV
|
||||
law's 18–25 s, and a too-short crop is refused before the extractor runs. An
|
||||
engine bump that changes either number fails the build by design; the bump
|
||||
procedure is in [[Voice Packs]].
|
||||
- Verified against reality, not against the model: the pinned `narrator1` crop
|
||||
(98.739–118.636 s of `audiosample.mp3`, sha256 `2299510…`) comes out of a
|
||||
`--dry-run` at 955,378 B / 19.897 s with 5,456 B of `.rvq` planned — byte-for-byte
|
||||
the trial's hand-cut numbers — and all three pinned source digests match the
|
||||
files on disk.
|
||||
- Seam: `tests/voice_pack_unit.bats` (13 tests) — refusal inside the forbidden
|
||||
region creates nothing, a legal crop builds the whole pack, `ffprobe` on the
|
||||
generated reference, manifest round-trip through `jq` with a sha that matches
|
||||
the source, re-run-without-`--force` leaves every byte alone, `--force` retires
|
||||
rather than deletes, `--dry-run` needs no extractor, a wrong-sized artifact
|
||||
from a bumped engine cannot publish a voice, and every crop in the tracked pack
|
||||
list clears the invariant. `qwen-codec` is stood in by a stub with the real
|
||||
tool's I/O shape, so no engine, no GPU, no network, no fleet host. Suite green:
|
||||
**416/416** (`./tests/run.sh`, wall 77 s) — 403 before this branch.
|
||||
- Deliberately NOT done: no transcript in the manifest (ICL wants a curated
|
||||
`ref_text`; the trial's machine transcripts were wrong, and the engine
|
||||
registers WAV-only voices anyway), no 16 kHz variant (arm A is native 24 kHz),
|
||||
no loudness pass (not in the pack law), and no pack built on the host — the
|
||||
three sources still live on the workstation and the engine GGUFs have not been
|
||||
fetched to `/home/dank/models/Qwen3-TTS-GGUF` yet, so the first real run is a
|
||||
host step.
|
||||
Reference in new issue
Block a user