Repository navigation
v0.3.0
v0.3.0 — 2026-09-15
The release that looks at the input axis, asks whether any of the wiring was
ever used, and stops publishing a green workflow over a red job.
Two verbs came from a second read of caliper
and Chisle — the first pass took an
ablation and a losses column from them, and walked past the half of each that
mattered more. docs/prior-art.md records both rounds, including what was
deliberately not taken.
Added
-
bb sieve— the input axis. Every other verb in this box shrinks what a
session is asked to read. This one shrinks what it reads because it ran a
command. A tool result is billed when it arrives and again on every later turn,
because the whole window is re-sent, so shrinking it once is paid back every
turn that follows. Three tiers:scrub(lossless — ANSI, blank runs, repeated
lines),dedup(byte-identical to this tool's previous output in this
session),elide(head + tail, with error-looking lines carried out of the
middle).Read,EditandWriteare absent from the allowlist by
construction — their output is the text a later exact-match edit is written
against — and the elided middle spills to disk so recovery is a grep rather
than a re-run of a command that may not be idempotent. Installed by
bb wire --applyas aPostToolUsehook.Off by default, and the measurement is why.
bb sieve replaypushes real
transcripts through the same pure transform for nothing. Across four
workspaces on one box the saving ran 1.8%, 15.9%, 18.7% and 34.1% of all tool
output — the largest sample, 29 sessions, is the 1.8% — and in all four it was
almost entirely the lossyelidetier;scrubanddeduptogether never
reached 3% of the win. So there is no lossless default worth shipping, and the
lossy one buys a benefit that depends entirely on what a workspace's sessions
run. The replay reports the split by tier; the default does not guess. -
bb uptake— installed is not used.bb wire statusreports that the
instructions block, the MCP entry and the hooks are installed. The block is
billed in every window of every session whether the agent obeys it or not, so
a surface nothing reaches for is the most expensive kind of dead code this
factory can write — and nothing could see it. This reads the transcripts for
evidence that each surface was reached for, against the moment it was for:
pinpointonly against sessions that opened five or more distinct files,
tablesonly against sessions that ran a search. A file opened withsed -n
counts exactly as much as one opened withRead, because which of the two a
session uses is a harness setting and not a fact about the work. Heredoc
bodies are stripped before a command is read — without that, every document
this box writes about itself reads as a session that ran half the CLI.The three surfaces that arrive in the system prompt — the block, the
SessionStartcontext, the read guard — are reported as not observable,
with the reason, and never as 0%. A transcript cannot answer for them, and a
number meaning "nothing was checked" is the one thing this box does not print. -
docs/agents.md. Integrating bundlebox into all ten agents it knows,
wiring one it does not, and driving agents as lanes. The surfaces, the six
hooks, the nine MCP tools, thecustom_commandtokens, and what bounds a
lane.
Fixed
-
Windows CI was red and could not fail a build.
the kernel and the JS engine agree about a run step with body keysfailed on all three
windows-latestjobs for as long as the log history goes back, while
continue-on-errorkept the workflow green over it. Two defects, and the test
was catching the first correctly:- The two engines picked different shells.
src/cookbook/engine.js
hard-codedbash -lc; the kernel had already decided in
kernel/src/gate.rs::shellthat Windows gets cmd.exe, because hard-coding
bash there turned every command into a spawn error rather than a verdict.
Every GitHub Windows runner ships git-bash, so the JS engine found one and
passed while the kernel used cmd.exe and failed — one corpus, two shells. - The test was a probe of shell quoting. It built
node -p "JSON.stringify({\"screen\":…})", and bash and cmd.exe do not agree about
\". The payload now goes to a script file and the command is
node emit.js.
The shell a command runs under is one fact and now has one implementation,
exec.shellCmd, mirroring the Rust line for line. It replaced four
hard-codedbash -lcsites and one inline duplicate. Consequence, stated
rather than discovered later: a piped command on Windows now loses
set -o pipefailin the JS engine as it already did in the kernel — the
documented gap, in both engines instead of in one. - The two engines picked different shells.
-
src/bridge/index.jsrecorded a gate that never ran as a gate that
failed. Its acceptance command hard-coded bash, so on a box without one
spawnSyncreturned a null status, which read asaccepted: 0— the exact
misreadingkernel/src/gate.rswarns about in its own comment. -
bb runbook upcould not spawn on a non-Linux box. The no-cage fallback
hard-coded bash. Its otherbash -lc, the one handed tosystemd-run, is
deliberately unchanged and now says so: that branch is gated on
useSystemd(), and a box reaching it has bash by construction. -
bb failsafe run <op> --applyhad the same hard-coded shell. -
Tool results carry their tool. Every transcript reader — claude, codex,
gemini, opencode — now records the producing tool's name and id on each
result. A result was an anonymous blob before, which an allowlist cannot work
against.
Changed
-
Windows gates.
continue-on-erroris gone from the matrix. It was
best-effort while the shells disagreed; with that fixed, a Windows break is a
failed build again rather than a green workflow over a red job. Every step
afternpm test— the scan, the doc-drift check, the corpus validation — ran
on Windows for the first time in the process, because the job had never got
past the tests to reach them. -
A guard against the next hard-coded shell. The defect recurred four times
because each caller reached forbash -lcon its own and nothing was
watching. A test now walkssrc/for the literal argv form and fails on any
hit not allowlisted with a stated reason. It found thebridgesite the
moment it was written. The allowlist is checked for rot in the same test: an
entry that no longer matches is an entry permitting nothing.
Corrected
- One workspace is not a calibration. On bundlebox's own transcripts the
ESTIMATEandMEASUREDtoken figures for the sieve agreed to 0.2%, which
read as a result about the estimator. Across three other workspaces they
diverge by up to 58%.docs/prior-art.mdrecords the correction beside the
claim.