The UmbraTrans controller asked (commit 70c23fd) for machine-readable metadata
about the audio system, in a specified layout, with a validator that ships with
the request so the sender can check its own work. That request is answered here.
scripts/build_controller_bundle.py emits that bundle: one real book (Deal
Hunter), 8,884 records, no media, no credentials, no hostnames. It passes the
controller's own validator, exit 0.
Three things in this system will break a mapping that does not know them, and
the bundle's real purpose is to say so precisely rather than to look tidy:
* A chapter has THREE numbers. The database row id is what filenames use,
chapter_index is reading order, and the distribution track number is a third
thing again. Only the row id survives an edit. Front and back matter are
numbered with roman numerals in the MP3 filenames.
* The narrator is written three ways, and the most common way is nothing at all.
1,803 utterances have a NULL speaker_name, meaning narrator; 614 say
"narrator" and 15 say "Narrator". A join that skips nulls loses most of the
narration silently. Utterances now carry speaker_name_raw, the resolved name,
and speaker_resolution, and the two spellings are not merged - that is a
decision for whoever owns speaker identity, not something an export should do
quietly.
* A .wav file is not always a WAV. 30 of the 91 voice reference files are MPEG.
Every render reports the container measured from the bytes, with
extension_matches_container, so a reader cannot be misled by the name.
A validator proves the bundle is internally consistent; it cannot prove the
bundle is true. scripts/audit_controller_bundle.py re-measures every hash, byte
size, duration and count against the project on disk - 66,011 claims, all
holding. It caught two real defects in the first draft of this bundle, including
one of my own: produced_at was stamped with the build time, which is a claim
about the audio that nothing supported.
The validator was also run against seven deliberately broken bundles to confirm
it can fail. A validator nobody has seen fail is not evidence of anything; those
cases are now tests.
scripts/audio_controller_connect.py runs the T01-T10 suite: 4 pass, 1 fails,
5 are blocked. T04 fails honestly - there is no ingest endpoint, and nothing was
pushed. T05-T08 are blocked because the controller's own plan sequences ingest
after the metadata arrives; a proposed contract is included rather than an
invented endpoint. T02 is blocked: no node key or service token is configured
here, and an operator has to supply one.
Two corrections to the node profile, which the controller reads: it claimed the
web UI has no authentication (a session gate was added 2026-10-09) and that the
controller host is offline (it is reachable and serving umbratrans-web 0.1.0).
Full suite 751 passed, 8 failed - the same pre-existing pronunciation and
accent failures, unchanged. ruff and mypy clean on everything added.