umbra audio 4781468181 Test the property that replaced the one a policy used to prove
The old file proved a policy refusing a row. With no shared table there is no
policy and nothing to refuse, so the tested property is gone rather than
rewritten - and Umbratools_2.md 5.0 says outright that this trade should be
noticed rather than discovered later. This commit is the noticing.

What is proved instead is stronger, not differently shaped. A statement with no
organization in hand asks for `projects` unqualified and is told the relation
does not exist: not zero rows, an error. That is a different claim from "the
policy filtered it", because a policy that was silently not enforced returned
zero rows and looked fine - which is the failure G2 was, and the reason the old
test had to run as a non-owner role to mean anything.

The new tests keep the non-owner discipline for the part that needs it. Naming
another tenant's schema is refused outright; repointing the search path at it
and using an ordinary name finds no table at all, because a role without USAGE
on a schema does not see its contents when names are resolved. That second one is
the outcome an application actually experiences, so both are asserted rather than
the convenient one.

Positive cases are here because a suite that only proves refusal passes just as
happily against a database where every write is refused: a write that must be
allowed is performed and then counted in both tenants.

What the file cannot prove is written down in its docstring rather than left to
be assumed. The application owns every tenant schema, so it can reach another
tenant's tables by naming that schema, and schema-per-tenant cannot change that
with one role serving every tenant. What it changes is that there is no shared
relation to reach through, and reaching another tenant means writing down another
organization's name - one call site in tenancy.py rather than a predicate in
every query.
2026-10-03 13:33:34 -07:00

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; see umbratrans_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_dump custom-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.

Description
UmbraTrans control system: repository, API, and compute substrate.
Readme Apache-2.0 3 MiB
Languages
Python 75.5%
JavaScript 10.7%
PLpgSQL 6.2%
HTML 3.4%
CSS 2.2%
Other 2%