Doctor says where near-root exec lands.
ct_exec and the node shell (node_probe, node_logs) do not travel over the API. They ride ssh <target> pct exec, or run pct on the box Proximo runs on, scoped by the CT allowlist. So the machine the API reads and the machine a near-root command lands on can differ, and until now nothing said so. Running the smokes against a test Proxmox node found a config whose API url named that test node while its ssh target and allowlist still named production: a client that believed it was on the test node and called ct_exec would have landed in a production container.
0.40.0 makes proximo doctor say where the shell lands:
exec_lands_onis reported whenever any shell feature is on: the ssh target, or this host for on-host mode.- SPLIT TARGET is flagged when the API host and the landing host are not the same machine. The flag names both machines and every shell feature that rides the target, and its remedy is followable as written: an IP is a valid ssh target, and
localwhen the API is this host. - Names for the same machine count as one. The ssh target is resolved through ssh's own config (
ssh -G: local, no connection, no DNS), an IP literal compares by address rather than spelling, and this host is every address bound to an interface plus every/etc/hostsname for one of them, read from procfs and the file with no binary and no DNS. Loopback against127.0.0.1, an alias against its address, and a node's own LAN address or FQDN against local exec all stay quiet. - The stated limit is the real one. DNS is not consulted, so a remote name and its address still read as different. The flag says so.
The check was cut four times. An adversarial review broke the first cut for comparing config stores instead of hosts; a second review broke the rebuild in seven places; the third cut came from running the deployed package against our own production config and watching it fire forever on an ssh alias; the fourth from the same fire on an on-host deployment's own address. Each cut is in CHANGELOG.md.
Also in this release:
- A shadow flag compares values the way the gate reads them. 0.39.1 named every file key the process environment shadows with a different value, and compared raw bytes, so the same allowlist ids in a different order read as a change. Now every key whose gate builds a set (
PROXIMO_CT_ALLOWLIST,PROXIMO_AGENT_ALLOWLIST,PROXIMO_TOOLS,PROXIMO_TOOLSETS,PROXIMO_SURFACES, and every face'sPROXIMO_<face>_ALLOWED_HOSTS) compares as its gate enforces it, pinned against the gate's own function. A mode keyword such asdynamicstays a single token, never a set, becausedynamicstarts the facade anddynamic,dynamicrefuses to start. Every other key keeps string semantics on purpose. - The TLS warning counts a pinned fingerprint.
PROXIMO_VERIFY_TLS=falsewith a fingerprint warned that the backend would refuse to start, and then the backend started, because the guard never counted the fingerprint. A pinned fingerprint is the option the refusal itself recommends first for a self-signed PVE, and the warning now names it first.doctorcarried the same false claim and now shows the pin.
908 tools, unchanged. No breaking change, no new tool surface.
Where to read more
- Running the preflight and reading its flags: docs/SETUP.md
- Every tool with typed inputs: docs/TOOLS.md
- Verifying the artifacts you just pulled (image signature, SBOM, PEP 740 provenance): VERIFY.md
- Full change detail: CHANGELOG.md
Install: uvx proximo-proxmox · pip install proximo-proxmox · ghcr.io/john-broadway/proximo:0.40.0