v0.19.1 — self-audit hardening
A self-audit release. We pointed a multi-agent audit at our own v0.19.0 — find → adversarially verify → fix, test-first — and it surfaced 23 real findings. All are fixed here, with no tool-count change (still 365) and the suite at 5447 green. The theme was this project's own failure mode: the code was sound, but some PLAN previews and tool docstrings had drifted from what the code actually does. On-brand for a tool whose whole claim is honest scope — so we held it to its own claim.
🔴 The headline: restore/prune from PBS work again
_check_volid rejected any volume-id with more than one colon — but a PBS archive volid embeds an RFC3339 snapshot time (pbs:backup/vm/100/2026-07-09T02:00:00Z) whose HH:MM:SS carries colons. So pve_restore and pve_backup_delete refused every PBS-backed archive — the disaster-recovery path for the standard PBS deployment — while pve_backup_list happily returned those same volids. The validator now partitions on the first colon (strict storage id, colons allowed in the path). A test had enshrined the wrong rule; it now asserts PBS volids are accepted. Same fix in the storage plane.
Fixed
- Backup-freshness fence — three honesty gaps in the fence itself. Sub-daily schedules (
*:0/30,0/4:00) are parsed instead of assumed daily (a 12h-stale hourly backup now readsstale, notfresh); a permission-collapsed node enumeration (200 + empty) setscomplete: falsewith a flag instead of silently walking one node; and astaleverdict degrades tounknownwhen a covering storage was unreadable (a newer archive may live there). pbs_realm_syncsent underscored parameter names PBS rejects — now translated to the hyphenated wire form (remove-vanished,dry-run); the non-existentscopeparam was dropped.plan_pbs_job_runrated every jobRISK_LOW; a prune run permanently deletes snapshots, so it is nowRISK_HIGH(syncRISK_MEDIUM, verifyRISK_LOW).- Plan completeness:
plan_firewall_options_set, the SDN zone/vnet delete plans, and the alias update/delete plans no longer present a failed current-state read as an emptycurrentwithcomplete: true— a read failure now setscomplete: falseand is disclosed. - VMID collision check is cluster-wide in
plan_create/plan_clone(PVE VMIDs are cluster-unique — a node-scoped check missed a vmid taken on another node), with a disclosed node-scoped fallback. - Ledger coherence: the recorded
plannedentry now carries the wrapper's authoritative target, so planned and executed entries pair under one target. - Doc/preview truth-ups: a
plan_who_object_addwarning printed a literal{ogroup}; six PMG group read-tools said "object group name" where the code requires a numeric ID;pbs_ruledb_rule_actions_listdocumented and ledger-logged an endpoint (.../actions, a 501) the code never calls; PVE tokenexpireis documented as an absolute epoch (not a TTL) and a duration-shaped value now warns it would be already-expired; the BCCoriginalflag and thepmg_quarantine_blocklist_listpmail default are described accurately.
Changed
- PDM is no longer labeled "read-only." The README and the surface comment now say the plane serves reads plus governed fleet control — it registers 13 mutation tools (power / snapshot / migrate). The A2A slice rationale no longer calls
snapshot_delete"reversible" (it removes a restore point permanently; the runtime slice was always correct). - README hero copy: the UNDO claim and "the plan refuses destructive ops" were reworded to match what the code does.
pve_acl_modifynow documentskind='group'(already supported);pmg_statistics_senderdocuments thatorderbyis accepted-but-ignored.
Security
- The control-character/newline freetext guard the access modules use on line-based config fields is now also applied to firewall and HA-rule comment fields (same
cluster.fw/ pmxcfs threat class). SECURITY.mdnow discloses the SCOPE gate's absent-file behavior honestly: a present-but-garbled scope file fails closed, but an absent file reads as no-scope (the transitional armed-not-written window) — unlike LEASE, which fails closed on an absent token.
Install
uvx proximo-proxmox # or: pipx install proximo-proxmox
docker pull ghcr.io/john-broadway/proximo:0.19.1
Verify
The GHCR image is multi-arch (amd64 + arm64), shipped with an SBOM and a sigstore-signed build-provenance attestation:
gh attestation verify oci://ghcr.io/john-broadway/proximo --owner john-broadway
This release changes no capabilities — 365 tools across PVE · PBS · PMG · PDM + in-container exec, the same scoped-token, plan-first, audited surface as v0.19.0.
Full changes: CHANGELOG.md.