Skip to content

v0.7.0 — with-device: the shared-bench claim, as a binary

Pre-release
Pre-release

Choose a tag to compare

@avrabe avrabe released this 05 Sep 11:16
· 53 commits to main since this release
v0.7.0
0312ec3

⚠️ Superseded — do not use

with-device 0.2.0 in this release reports exit 0 for commands it never ran. Mode flags
were matched across the whole argv, so any wrapped command containing -h, --help, -V,
--version, --status or --self-test hijacked the invocation: the device was claimed and
released around nothing, and the caller got success.

$ with-device d --registry reg.yaml -- echo --version
with-device 0.2.0     # its OWN version
rc=0                  # and SUCCESS

Its --self-test was green throughout — it only ever wraps sleep, true and kill -9, so the
entire bug class sat outside every path it walks. Fixed in 0.2.1; see AFD-084.

with-device — jess's first shipped binary

jess has cut releases before, but never a binary: v0.6.0 and earlier were findings and
artifacts. This release exists because the shared bench needed a tool that a second agent could
run, and that varve could pin — neither of which a script sitting in the repo tree allows.

What it is

Two agents share one physical bench (an STLINK-V3, a Pixhawk 6X-RT). The failure with-device
prevents is not "both want the probe" — it is the silent one. Two readers on a single tty
each receive a subset of the stream and neither errors. Measured on the real board:

ONE reader alone     : 66,872 B in 5.0 s
TWO readers together : 37,787 B + 40,053 B

Each got about half, and nothing reported a fault. That is indistinguishable from a flaky USB
link — the worst possible thing to have sitting in a safety campaign's evidence.

The claim is an flock(2) held for exactly the lifetime of the wrapped command, so a crash
releases it. No stale-lock reaper, no release step to forget.

with-device <device>... [--purpose <text>] [--wait <s>] -- <command>...
with-device --status [--format json]
with-device --self-test

Exit codes: 2 usage (including an unregistered device name — a typo must not create its own
lock and exclude nobody), 3 device busy with nothing run, otherwise the wrapped command's own
status.

Multi-device claims are deadlock-free — negative-controlled, not asserted

The original rationale was sorted acquisition (Dijkstra's resource hierarchy). The self-test —
two processes racing for the same two devices in opposite order — passed first run. Removing
the sort showed that was the wrong explanation:

variant opposite-order pair
as shipped 0,0 in 2.1 s — pass
sort removed, rest intact 0,0 in 2.1 s — still passes
sort removed and hold-and-wait restored 3,3 in 15.1 s — a real cycle

The load-bearing mechanism is no hold-and-wait: on contention the claimant drops every lock
it already holds before retrying. Sorting stays as defence in depth and the module header now
says which of the two the test can actually see. Recorded as AFD-083.

Assets

with-device-0.2.0-<triple>.tar.gz for x86_64-unknown-linux-gnu,
aarch64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-apple-darwin, plus
SHA256SUMS.txt. Pin it the way you pin any PulseEngine tool:

release:pulseengine/jess@v0.7.0!with-device-0.2.0-<triple>.tar.gz!with-device

Known scope limit: aarch64-unknown-linux-gnu is cross-built and its self-test is skipped
in the release job — that asset ships unexecuted. It is the Raspberry Pi target, so it wants a
real run on aarch64 before it is trusted there. Every other target is built and self-tested on a
host that runs it.

Zero third-party dependencies — flock(2) is declared with a bare extern "C" — which is what
makes it reasonable to carry inside a signed varve layer (pulseengine/varve#130).

Falsification statement

If with-device is what it claims, then: a second claimant on a held device exits 3 having run
nothing; a device whose holder was kill -9'd is immediately claimable; an unregistered name is
refused rather than silently locked; and two processes claiming the same two devices in opposite
order both complete promptly. Each is asserted by --self-test, which runs on every PR. If any
one of those fails, this release is wrong.