Skip to content

v0.46.1: every column, every rollback target, held to its rule

Latest

Choose a tag to compare

@john-broadway john-broadway released this 21 Oct 02:35

Every column, every rollback target, held to its rule.

A patch release: a stricter loader, a stricter rollback target, and tests. No new capability; door contract 1 is unchanged, and the shipped data file is byte-for-byte 0.46.0's.

The loader holds every column to the build's rule. The one data file carries seven cross-column rules the build keeps and the engine reads without a guard: which opt-in lane a gated row is served on, the read that shows a mutation's target, where the plane reports its task, a container command's snapshot net and its rollback. 0.46.0's loader checked that the addresses those columns named existed, and nothing else, so a forged proximo.json.gz with a lane on an ungated row, a read with a read of its own, a state beside a served twin, a mutation with no task to poll or a net on another container's path was served. The loader now holds every column to the build's rule, in the build's own words, and refuses the file whole on the first row that breaks one. The vendor's rows are asked before the shell lane's authored rows whatever the file's order. Every one of the 1,804 rows resolves, plans and executes identically to 0.46.0 through a fake wire.

A rollback's target is the row's own spelling. undo of a container command whose snapshot it captured bound the capture's target to the row's template and refilled it, without coercing the bound values to the vendor's types or comparing the refill to the capture's spelling, so a forged capture with anything in the vmid slot (abc, 0101, +101, 1e2), a trailing slash or a percent-encoded node rolled back. The target is now held to the engine's own rule: the row, its placeholders bound and coerced to the vendor's types, refilled and compared to the capture's spelling; anything that does not round-trip rolls nothing back, with a sentence. A negative or absurdly large vmid still round-trips; a ledger-verified capture is the fix for that, not a tighter spelling check.

Tests that could not fail, and the lens that found them. Lens 3 (over the 0.46.0 branch) named the residuals this release folds; lens 4 went over the fold. Fixed: a raw-door test that asserted the ssh refusal on rows the door never reached, a task-wait test whose UPID named the same node as its path, a secret-column oracle that was the merge rule copied into the test, a surviving mutant filed as equivalent that a trailing slash split, five loader clauses each refused only by a sibling clause, and the named-row lookup whose own cases the new rules had taken. Every fold is a test that dies with its mutant replanted; 1,738 tests. Door contract 1 unchanged.

certifi moves past PYSEC-2026-4320. Raised on 2026-10-20 (GHSA-6q48-6c7w-9gw2): certifi 2026.5.20 bundles emSign root CAs whose intermediate CA keys were compromised. certifi reaches Proximo through httpx (via httpcore); the lock and the hash-pinned exports the image and CI install from move to 2026.10.19, the first release without those roots. The internal CI's audit went red on the release commit before anything public carried it; this is the fold.

Full history for this release, commit by commit, is on the internal mirror; this
public branch carries one squashed commit per release by design.
Every change here is described in CHANGELOG.md.

Where to read more

Install: uvx proximo-proxmox · pip install proximo-proxmox · ghcr.io/john-broadway/proximo:0.46.1