Files
UmbraTrans/docs/audio-system-prompt-v1.md
umbra audio dda079f605 commit audio ingest: apply 0008+0009 migrations, wire Postgres adapter to commit path
- Apply migration 0008_audio_source_import (additive schema for source import)
- Apply migration 0009_translation_import_runs (ledger table for import runs)
- Wire PostgresAudioImportStore into HTTP commit path with org from node credential
- Commit path uses PG store with org from node, no payload org
- Bundle hash 21ce5687… remains frozen until v2; no authority transferred
2026-10-19 04:35:07 -07:00

7.1 KiB

UMBRA AUDIO — METADATA HANDOVER, ACCEPTED FORMAT, AND THE TTS DOCUMENT Prompt to the OpenCode session on the audio system (host umbraaudio-m4)

CONTEXT

You produced ~/audio-read/bundles/dh-bundle/ (manifest.jsonl sha256 21ce568787540cf7164b6ab4028f1caee51996447537022154d1e5768cde87ba). It has been received and independently verified on the controller host:

  • the declared content_hash matches the manifest bytes;
  • your validate.py passes on the good bundle and fails on each broken copy;
  • the controller's accepted-format validator passes: 8884 records, book=1 chapter=32 speaker=55 utterance=4319 render=4477.

Nothing was written to the controller. The confirmation gate is intact.

The controller's answer to your four requests is in three files, delivered alongside this prompt:

  • audio-system-mapping-v1.md (field-by-field mapping, source -> controller)
  • audio-system-manifest-v1.schema.json (the accepted manifest format)
  • validate-audio-manifest.py (the accepted-format validator, run by the controller)
  • audio-system-reply-v1.md (the full reply: verification, decisions, ingest, credential, and the TTS request)

Read those four before acting. This prompt is the instruction; those are the detail.

DECISIONS ALREADY MADE (do not re-open; implement against them)

  1. Format: the same bundle format you already emit, NARROWED. Field names are unchanged. Do not rename anything on the wire. The accepted format is defined by audio-system-manifest-v1.schema.json.

  2. Chapter identity is chapter.id. chapter_index is reading order and a hint; the filename number is neither. Your numbering_basis field is required and is what makes this unambiguous.

  3. The narrator is a role. Both narrator speaker rows and all three spellings (NULL, 'narrator', 'Narrator') resolve to one narrator role for voicing; the source spellings are kept as aliases for audit. This is the controller's one merge, and it is reported on every import. Other speaker rows are NOT merged; casefold_collision_group is stored and surfaced.

  4. A render's bytes are never fetched. Every artifact is recorded integrity='unverified'; content_sha256 is recorded as a claim, not a fact.

  5. media_type is derived from audio_format.container, never from the path extension. The 33 files named .wav that are MPEG audio are the test case.

  6. language_designations empty is accepted as an answer. Target languages are a translation-side decision; do not invent them.

  7. Ingest is file-based first. No credential is required and nothing is pushed. A push endpoint, if built later, will use a scoped service token (dataset:ingest), NOT a node key. No action from you on credentials today.

YOUR NEXT ACTIONS

Action 1 — Confirm the accepted format (short).

Copy audio-system-manifest-v1.schema.json and validate-audio-manifest.py into a copy of your bundle directory and run:

  python3 validate-audio-manifest.py .

Expected: "

: 8884 record(s) accepted. content_hash . book=1, chapter=32, speaker=55, utterance=4319, render=4477", exit 0.

If it fails, report the exact lines. Do not edit the bundle to make it pass unless the failure is a real defect in your generator, and say so if it is.

Note: the validator needs the jsonschema package. If it is not installed on the audio host, it says so and refuses to report acceptance rather than half-checking. Install it into a throwaway venv for the check; do not add it to the audio system's own environment if that would disturb the running system.

Action 2 — Produce the TTS checked document (the blocking one).

You offered this in your reply and the controller needs it to write speak without guessing. Produce it as a checked document with the same standard as the bundle: measured, versioned, hashed, with a note per row where something is unknown rather than a near-match. It must answer:

  1. Provenance: upstream repository and commit; the three commits on top, as a diff or a per-commit summary with purpose; the license.
  2. The model: exact model id(s) (Qwen3-TTS-12Hz-1.7B-VoiceDesign and -Base), which one serves which path, weights source and checksum, on-disk size, and the VRAM/working-set at load and at inference.
  3. The input contract: request fields (text, voice / voice-design, language, the instruct/emotion/pace fields, sample rate), the reference-audio (cloning) path and its format, maximum input length, and whether it streams or returns a whole file.
  4. The output contract: container, codec, sample rate, channels, bitrate for a rendered take, so a render from speak is described the same way your existing renders are.
  5. Determinism: given identical text and voice, is the audio bit-identical? If sampling is involved, what is seeded and what is not.
  6. Language coverage: which languages the model actually speaks, how the language is selected, and where quality is known to be weak.
  7. Voice identity: how a voice_id maps to a speaker, and how tts_engine_used:"qwen" relates to assigned_edge_voice (e.g. "en-CA-ClaraNeural:-100") — is the Edge voice the fallback engine, the reference audio, or the design prompt? Explain the tts_engine_fallback_reason values.
  8. Failure modes: OOM, over-length text, unsupported language — what is returned and how it appears in tts_engine_fallback_reason.
  9. The runtime surface: the HTTP/queue API you expose (or that it is in-process), its auth, and its concurrency limits — so speak on the controller is a client of something defined.

Deliver as a document named tts-engine.md (or .json + a short README) with the measured values, not prose claims. Where a value is unknown, say "unknown" and why; do not estimate it as if measured.

Action 3 — Optional, only if asked: scale totals.

Totals across all projects (books, hours, bytes). The bundle carries per-book counts and byte_size on every render, so extend the build rather than hand over a number you did not measure. Not blocking.

CONSTRAINTS

  • Do not modify the audio system. It is independent and keeps running. This is a read-only metadata export and a documentation task.
  • Do not push anything to the controller. There is no endpoint and no credential by design; the handover is the file.
  • Keep the generator deterministic: sorted JSON keys, fixed record order, so an unchanged project still hashes identically.
  • Every claim in the TTS document must be checkable against the running system. "A validator nobody has seen fail is not evidence" applies here too: if you say the model produces 24 kHz mono, show the ffprobe output.

REPORT BACK

Post a short reply with:

  1. the validator result (Action 1);
  2. the TTS document, or the path where it was written, and any item from the nine you could not measure;
  3. anything in the mapping or the accepted format you believe is wrong — before implementing against it, not after.

The controller will not import the bundle until the accepted-format check passes and the operator confirms. There is no rush and no penalty for an honest "unknown".