Asks for what is needed to write a correct mapping, in a form that can be verified rather than read. Two documents: docs/audio-system-data-request.md - what to send, in what format, and why that format. docs/audio-system-bundle-validator.py - ships *with* the request rather than after it, so the sender can check their own work before it travels. Standard library only: whoever runs it runs it on the audio system, and adding a dependency to someone's working machine to validate a file is not a reasonable thing to ask. That means the schema checking is the subset possible without a library - a smoke alarm, not an inspector - and the file says so rather than implying more. The reasoning behind the format is the substance. Prose cannot be validated: every mismatch is something a human has to notice, and the ones that get missed are the interesting ones - derived chapter order, two fields that mean slightly different things, a path relative to something unspecified. A validator that names the record and the field turns a round trip into a checklist, and reports every problem rather than stopping at the first, because a validator that stops at the first failure makes a three-round-trip conversation. Also asks for the things that are cheapest to supply and most expensive to guess: the vocabulary table (guessing terminology is how a mapping looks correct and reads the wrong field), which fields are derived (a derived chapter order treated as authoritative will disagree the first time somebody reorders a chapter by hand), and what the TTS engine actually is - fork or patch, what changed, whether it loads a model and how big. That last one decides whether a 48 GB CPU-only node can run it at all, so the speak work function cannot be written until it is answered. Explicitly not asked for: media files, source code, screenshots, or anything the sender would have to reconstruct. "We do not record this" is a complete answer and far better than an estimate presented as fact. The validator was itself tested against a deliberately broken bundle, which is the only way to know a check can fail. It caught a dangling reference, a unitless duration, two unanchored paths and a planted credential, and passed a correct bundle. Two flaws in it were found that way and fixed: it reported the same path problem twice, and every credential twice, because a tool whose only job is to be trusted about specifics loses credibility the first time it says the same thing twice. 704 passed, 4 skipped - no product code touched.
UmbraTrans local bootstrap workspace
This workspace contains the unprivileged agent-comm server requested by the Oldbox handoff. It does not contain the UmbraTrans application source: no application bundle was present locally. A staged archive, if present, is left untouched.
Layout
agent_comm/— Python 3.11+ standard-library, stdio-only MCP server.agent_comm/tests/— dependency-free unit tests.umbratrans_web/— phase-1 account/user-management backend slice (FastAPI, Argon2id, sessions, admin routes, in-memory and local JSON development repositories). It does not connect to PostgreSQL; seeumbratrans_web/README.md.umbratrans_web/migrations/— proposed, unapplied phase-1 identity SQL and its rollback.opencode.json— non-secret OpenCode registration for the confirmed NAS2 mailbox.agent-comm.local.example.json— non-secret local fallback registration..env.example— non-secret environment template.DATA-SEPARATION.md— development/production boundary.
Confirmed NAS2 mailbox
The oldbox desktop account mounted NAS2 netbackup through its user GVfs session and confirmed the UmbraTrans directory readable, searchable, and writable. The server requires the explicit NAS deployment mode, the enclosing GVfs mount, and an affirmative mount confirmation:
/run/user/1002/gvfs/smb-share:server=nas2.local,share=netbackup/UmbraTrans/agent-mailbox
Run read-only health checks:
cd /home/umbra/src/UmbraTrans
AGENT_COMM_MODE=nas \
AGENT_COMM_NAS_MOUNT=/run/user/1002/gvfs \
AGENT_COMM_NAS_CONFIRMED=1 \
AGENT_COMM_ROOT='/run/user/1002/gvfs/smb-share:server=nas2.local,share=netbackup/UmbraTrans/agent-mailbox' \
/home/umbra/.local/bin/uv run python -m agent_comm --check
If the user GVfs session is absent, do not guess another path or broaden share permissions. Use the private local fallback documented in agent-comm.local.example.json, or have a privileged operator restore the confirmed user mount.
The server speaks newline-delimited MCP JSON-RPC over stdin/stdout. It opens no network socket and never executes queued instructions.
OpenCode registration
opencode.json contains the exact NAS configuration and paths only. It must never contain passwords, tokens, private keys, or other secrets. A Mac-side reader still needs separate configuration and verification before an outbox message can be considered received.
Development workflow
The project uses uv and a workspace-local virtual environment:
cd /home/umbra/src/UmbraTrans
/home/umbra/.local/bin/uv sync --python /usr/bin/python3
/home/umbra/.local/bin/uv run python -m unittest discover -s agent_comm/tests -v
/home/umbra/.local/bin/uv run ruff check .
/home/umbra/.local/bin/uv run ruff format --check .
/home/umbra/.local/bin/uv run python -m compileall -q agent_comm
make check
The tests cover schema and size validation, atomic no-overwrite writes, restrictive modes, path traversal, symlink refusal, secret-pattern redaction, inbox processing, and read-only initialization.
The account-management slice has its own targets:
cd /home/umbra/src/UmbraTrans
/home/umbra/.local/bin/uv run pytest umbratrans_web/tests
make web-check
Its tests use the in-memory repository and generated per-run passwords; they never read a production configuration, never connect to a database, and contain no credential material.
Backups
scripts/umbratrans_backup.sh is installed root-owned as /usr/local/sbin/umbratrans-backup and scheduled by the enabled umbratrans-backup.timer. It writes only to the confirmed NAS2 netbackup/UmbraTrans/backups tree:
- PostgreSQL:
pg_dumpcustom-format logical dump, never a live data-directory copy. - Configuration: PostgreSQL configuration files only.
- Workspace: source/configuration archive excluding
.venv, Git internals, runtime data, local mailboxes, and secret-bearing files.
Each file is staged outside the share, published with an atomic rename as umbra, checksummed, and verified after publication. Retention is 30 days for PostgreSQL/configuration/manifests and 14 days for workspace archives; stale temporary files older than one hour are removed. The timer fails closed if the user GVfs mount is absent and does not mount or broaden the NAS share.
The current first-run backup set is present under:
/run/user/1002/gvfs/smb-share:server=nas2.local,share=netbackup/UmbraTrans/backups
Check timer status with systemctl status umbratrans-backup.timer and the last run with journalctl -u umbratrans-backup.service.