Repository navigation
v0.7.1
v0.7.1 — 2026-09-22
The release that draws the factory's own numbers and then puts the server where
something can find it.
v0.7.0 aimed the locate. This one answers the question that follows: is the
aimed locate worth anything, and can anyone install it. Seven figures now come
off the runs already on disk, including the one arm bundlebox loses. And bb mcp — nine tools that until now nothing outside this repository could
discover — has a registry record, a plugin manifest and a CI job that publishes
both.
Measured
SWE-bench Verified, 100 instances, both arms counting tokens over text on disk,
neither calling a model:
| bare | packed | |
|---|---|---|
| context per task | 8.7k | 2.8k (−67.5%, 3.1x) |
| gold files in scope | 24.6% (31/126) | 64.3% (81/126) |
| instances with every gold file | 26/100 | 61/100 |
| files put in front of the model | 10 read whole | 6.8 in scope |
| assembling the window | 246ms | 8.9s |
The last row is the arm bundlebox loses, and it is drawn rather than dropped.
6.6s of the 8.9 is the first-visit symbol space, which a workspace pays once
rather than per task; on a tree already scanned the same row reads 38ms against
1.6s.
Derived from those counts at vendor list prices, no request sent: $43.59
against $14.17 per 1,000 tasks on Opus 5.
Added
docs/benchmark/index.html — the runs as a page.
scripts/benchmark-page.mjs draws it from what is already on disk: SWE-bench
Verified at n=100, this repository's own open findings, the 142-run store and
the price table. A number it derives rather than reads says DERIVED where it
appears, and the prefill rate behind the only time estimate is a control the
reader sets. The trend shows savings falling from ~98% to ~67% on 2026-09-19
with the cause named — 1cdb60a re-modelled the bare arm to open one 80-line
range per hit instead of reading matched files whole, so the step is the
baseline getting stricter, not the tool getting worse. Served at
https://blackswanalpha.github.io/bundlebox/docs/benchmark/
A clock per arm. bb bench arm and runTask stamped one seconds across
both arms together, so the question a session waits on had no answer per arm.
bare_ms and packed_ms are carried through the SWE-bench rows and summed
into the totals.
The server is discoverable. server.json is the official MCP registry
record and package.json carries the matching mcpName, which is how the
registry verifies the package and the record have one publisher.
.claude-plugin/ makes the repository installable with
/plugin marketplace add blackswanalpha/bundlebox, carrying the MCP entry and
both skills. smithery.yaml declares the stdio start command, listed local
because bundlebox reads the repository it is started in. The README gains a
copyable mcpServers block for agents bb wire does not manage.
release.yml publishes the registry record. A new mcp-registry job, after
npm because the registry reads the published tarball to check mcpName. It
holds no secret: login github-oidc exchanges the runner's own token, and
GitHub grants io.github.<owner>/* to workflows in that owner's repositories.
The rule the file already had is unchanged — the job sits below release, so
its failure ends there.
Fixed
The locate baseline counted rows its own guard would refuse. It read
measured, recall 0 over 20 exception rows. Fifteen of those twenty were rows
nothing acts on: 8 files that did not exist when the brief was written, 5 test
files, 1 path outside the workspace, 1 artefact under .bundlebox/.
writeVerdict exempts the last three outright, so the denominator and the
guard the figure is read to decide disagreed about what a row is. excluded()
now applies the guard's own four rules, markCreated stamps each edit with
whether git says the file arrived after its brief, and the exclusions are
tallied and named so the smaller sample is auditable. The baseline reads
unknown: 5 rows over 2 briefs, under its own 12/4 floor.
An import edge can name a file. Two of the five surviving rows were never
named for "close the loop on a verified scenario" — neither word is in the
statement, so nothing lexical could reach them, while src/genesis/practice.js
was in the scope the ranker chose and imports both directly. neighbours
spreads a share of the leader's score along out edges and they return at
candidate 3 and 7. Named, never budgeted: rankDetailed reports them
separately, so the opening scope is identical to before at about fifteen tokens
each. A 24-instance SWE-bench A/B is identical in every cell, because those
instances are Python and this graph carries 4 Python import edges — it proves
no regression and nothing more.
The bench scenario cost one run per open finding. bench init derives its
suite from the open findings, so the corpus paid whatever this repository
happened to owe that week. At 12 findings a run took 37.7s against the corpus's
20s cap and the step that ran it twice took 75s — red on every main build since
v0.7.0. The suite is pinned at two tasks, 5.0s, and the step that re-ran the
whole thing for determinism is gone: ci.yml already asserts it on the full
suite across both arms with no timeout, and asserts more than the step did.
The corpus reads 58 passed, 0 red.
Checks
npm run lint 290 files, 0 errors
npm test 0 fail
npm run expert:test 71 tests, OK
cookbook run 58 passed, 0 red, 0 blocked, 0 empty
ablation gate bare 218652, packed 28187, 87.1% over 12 task(s)