Skip to content

Release 0.6.1: the gate survives a pipe, and history is opt-in - #15

Merged
Zenofex merged 1 commit into
mainfrom
fix/gate-verdict-survives-pipe
Sep 27, 2026
Merged

Zenofex merged 1 commit into
mainfrom
fix/gate-verdict-survives-pipe

Conversation

@Zenofex

@Zenofex Zenofex commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Read the second item before upgrading. It changes a default.

scan --gate-critical could report success on a capture that trips the gate

Measured on the 0.6.0 release binary, piping into head with output over the 64 KB pipe buffer, on a log with telnet exposed:

Binary three runs
0.6.0 exit 1, 0, 0
this branch 1, 1, 1, 1

A CI job piping through head or tee would go green on a device with a critical exposure, non-deterministically.

Cause was ordering: the output write ran before the gate check, so a broken pipe propagated up and main.rs turned it into exit 0 before any verdict was evaluated. That handler is right that a reader closing the pipe is not an error, but it must not become a verdict. The pipe error is now swallowed at the write site only; the gates decide on findings alone. Any other write error is still fatal, and manpage | head still exits 0 silently.

Scan history is now opt in

If you relied on it, it has stopped. Enable with bootintel config set history true or BOOTINTEL_HISTORY=1.

It was on by default with an opt-out. That is the wrong default for a tool whose pitch is that it uploads nothing. bootintel doctor disclosing it on a fresh machine is what prompted the change. no_history still means off, and an explicit off beats an explicit on so a machine-wide opt-out cannot be re-enabled by a config file.

On the version number

Numbered 0.6.1 by request. I flagged that a changed default is not really PATCH under the policy in CHANGELOG.md, and that someone upgrading will find history silently stopped. The warning is the first thing in the changelog entry rather than implied by the digit.

Testing notes

My first attempt to reproduce the pipe bug used the default 361-byte output, well under the pipe buffer, so both binaries returned 1 and it looked unreproducible. Inflating with --context exposed it. Four tests failed when the history default inverted, correctly, and were updated to assert the new contract rather than weakened.

310 tests pass, clippy clean under -D warnings, rustfmt clean, cargo deny check all ok.

scan --gate-critical could report success on a capture that trips the gate.
Measured on the 0.6.0 release binary, piping into head with output over the
64 KB pipe buffer: exit 1, then 0, then 0, on a log with telnet exposed. A CI
job piping through head or tee would go green on a device with a critical
exposure, non-deterministically, which is the worst direction for a gate to
fail.

Cause was ordering. The output write ran before the gate check, so a broken
pipe propagated up and main.rs turned it into exit 0 before any verdict was
evaluated. That handler is right that a reader closing the pipe is not an
error, but it must not become a verdict. The pipe error is now swallowed at the
write site only, and the gates decide on findings alone, which do not depend on
whether anyone was still reading. Any other write error is still fatal, and
manpage | head still exits 0 silently.

Scan history is now opt in. It was on by default with an opt-out and a one-time
notice, which is the wrong default for a tool whose pitch is that it uploads
nothing: a record of every log path a consultant analysed should not appear on
disk because nobody said no. `bootintel doctor` disclosing it on a fresh
machine is what prompted this. no_history and BOOTINTEL_NO_HISTORY still mean
off, so anyone who had opted out stays opted out, and an explicit off beats an
explicit on so a machine-wide opt-out cannot be re-enabled by a config file.

Numbered 0.6.1 by request. I flagged that a changed default is not really PATCH
under the policy at the top of CHANGELOG.md, and that someone upgrading will
find history silently stopped. The warning is therefore the first thing in the
0.6.1 entry rather than implied by a version digit.

Two things the testing changed. My first attempt to reproduce the pipe bug used
the default 361-byte output, well under the pipe buffer, so both binaries
returned 1 and it looked unreproducible; inflating with --context exposed it.
That is the second time today a negative result was an artefact of too small a
test. And four tests failed when the history default inverted, correctly, and
were updated to assert the new contract rather than weakened.

Verified on the built binary: four consecutive piped gate runs all exit 1;
manpage | head exits 0; no history file by default; one when
BOOTINTEL_HISTORY=1; `config list` shows the new key. 310 tests pass, clippy
clean under -D warnings, rustfmt clean, cargo deny all ok.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Zenofex
Zenofex merged commit f028b7b into main Sep 27, 2026
11 checks passed
@Zenofex
Zenofex deleted the fix/gate-verdict-survives-pipe branch September 27, 2026 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant