Agent-First PSQL v0.8.1: The Release Check Reads the Right Stream
v0.8.0's own release smoke test still read errors from stdout, so it failed the binary build after publishing and shipped v0.8.0 without downloadable binaries. v0.8.1 fixes the check — including a secret-leak assertion that had started passing against an empty string — and moves it into the release gate so it runs before anything irreversible.
v0.8.0 changed where events go: a finite query now sends its result to stdout
and its diagnostics to stderr. The tests were updated for that. One script was
not — afpsql’s own release smoke test, which builds the release binaries and
checks that afpsql-readonly refuses what it should refuse.
That script captured only stdout:
output="$($READONLY "$@")"
if [ "$status" -eq 0 ] || ! grep -q '"code":"invalid_request"' <<<"$output"; then
Under the new routing the rejection is on stderr, so $output was empty and the
check failed. The binary was correct; the check was looking at the wrong stream.
The part that mattered more
A failing check is loud. The quiet one was three lines further down, where the smoke test writes a canary secret into a config file and asserts it never comes back out:
if grep -q "$canary" <<<"$config_output"; then
With $config_output empty, that assertion passed no matter what. A test that
had been verifying a secret does not leak had become a test that verifies
nothing — and it would have kept reporting success. v0.8.1 checks both streams,
because “the secret must not appear in the output” was never a claim about one
file descriptor.
The redirect checks moved the same way: the runtime error is a diagnostic, so it
is --stderr-file that must receive it, and a new case asserts that
--output-to stdout moves that same error into --stdout-file instead.
Why it escaped the gate
release-smoke ran in exactly one place: the Release workflow, which runs
after cargo publish. So v0.8.0 published successfully, then failed while
building its platform binaries — leaving a real crates.io release with no
downloadable artifacts and no Homebrew or Scoop update.
This was the second gate hole in one release. The first was CI running
cargo test --tests without --features db-tests, so every live-PostgreSQL
test reported as ignored; v0.8.0 fixed that by moving the test entrypoint into
the project as scripts/test.sh and having CI call it. But all still did not
run the release smoke, so the smoke kept its old privilege of being checked only
where failure is expensive.
all now runs it. The rule the gate is converging on: if a check can fail a
release, it has to be able to fail the gate first.
Upgrading
v0.8.1 is a drop-in for v0.8.0 — no CLI, protocol, or behavior changes. It exists
so the platform binaries, Homebrew formula, and Scoop manifest for this line
actually ship. If you installed v0.8.0 from crates.io, nothing about your setup
is wrong; if you were waiting on brew or scoop, v0.8.1 is the version they
point at.