v0.13.0 — the zero-trust arc
The zero-trust arc — a CONTAIN kill-switch and its siblings, a prompt-injection TAINT control, plus an automated PROVE anchor.
Six new opt-in, out-of-band controls, each wired fail-closed at the 5 mutation seams — and each fully inert until its env var is set (zero behavior change by default):
- CONTAIN kill-switch (
PROXIMO_CONTAIN_TRIP_PATH) — while the trip file exists, every mutation is refused before the backend call and audited; checked first at every seam, so it overrides every other gate. Reads and dry-run PLAN stay ungated, so DIAGNOSE still works while contained. The operator's real velocity backstop against a hijacked agent. - Independent CONSENT (
PROXIMO_CONSENT_DIR/PROXIMO_CONSENT_TTL_SECONDS) — a mutation proceeds only if an unexpired, single-use grant file for this exact plan was placed out-of-band by a human. Closes self-asserted authorization (confirm=is only the agent's own bool). Honest limit: it's a boundary only if the agent's shell can't write the grant dir. - Arm-time SCOPE gate (
PROXIMO_SCOPE_PATH) — a file-only target allowlist for an armed session; out-of-scope mutations refuse before the backend call, and an unreadable/garbled scope refuses everything. - Arm-LEASE TTL (
PROXIMO_ARM_TTL+PROXIMO_TOKEN_PATH) — armed write-authority auto-expires N seconds after the arm token's mtime. Closes fail-open-over-time; fail-closed on clock skew, a missing token path, or a garbled TTL. - Per-surface ENVELOPE (
PROXIMO_FORBID/PROXIMO_RATE_MAX/PROXIMO_RATE_WINDOW) — a deterministic FORBID denylist (composite matching closes sub-action holes) plus a crash-safe,flock-guarded sliding-window rate wall keyed to physical box identity. Honest limit, stated in the code: the rate reservation file is not tamper-evident — CONTAIN's out-of-band kill is the real backstop. - TAINT — the prompt-injection mitigation (
PROXIMO_TAINT_TRACK/PROXIMO_TAINT_FORBID/PROXIMO_TAINT_REQUIRE_CONSENT/PROXIMO_TAINT_FENCE) — every tool whose return carries guest/external-authored bytes (logs, quarantine mail, exec output, in-guest file reads) is classified, pinned by a completeness test. An adversarial read sets a sticky, file-backed taint marker; once tainted, a pre-declared action set is refused outright (no consent escape) and/or CONSENT becomes mandatory for the in-domain residue. Consent never clears the marker; the fence is advisory and says so. See the rewritten prompt-injection section inSECURITY.mdfor the tiered mitigation and its honest limits.
Also in this release:
- Off-box PROVE anchor (
audit_anchor.py) — automates pinning the audit-ledger head to a write-once path; the export never re-pins to a moved head, so detecting a truncation can't overwrite the good pin. pve_acl_prune— the enforcement counterpart topve_overbroad_grants: revoke a flagged over-broad grant (optionally re-grant narrower), routed through the full spine. 351 → 352 tools.- Security hardening:
proximo.envnow actually loads at startup (closes a footgun that could leave CONSENT silently inert); the PROVE ledger append isO_NOFOLLOW-hardened against symlink redirection; the rate wall is evaluated after consent, so refused mutations spend no budget. - Fixed:
pve_acme_plugin_create/_updatecrashed wheneverdns_apiwas set (param collision — the DNS-plugin ACME path was unusable); golden request-shape sweep now covers every wrapper. - Docs truth-sized:
SECURITY.mdgains the two-deployment trust model and a controls-and-defaults table — which gates are on by default, which are opt-in, and what each honestly holds.
Full suite 5,068 green (3 by-design skips), ruff + pyright clean. Everything here is backward-compatible: with no new env vars set, 0.13.0 behaves like 0.12.0 (plus the acme fix).