One prompt, end to end

What happens between the moment you press enter and the moment the session is measured: sixty verbs, nine hooks, five chained gears, eleven readiness stages, and exactly one arrow that spends.

The board

the whole loop, and where the money is

Everything except one box is a parse, a count, a path check or a set difference. The loop closes on itself: what a merge changes is what the next scan reads.

The bundlebox loop, from a prompt to a merge and back to the scan A prompt or a document enters at the left. bb scan produces findings, bb compile packs them into units, bb route assigns lanes. Those three sit inside a dashed band marked as the free path a cron tick runs every thirty minutes. Only bb run --apply, drawn in red, spawns sessions and spends tokens. Sessions flow down to bb finish check and bb git, and a return wire carries the merge back into bb scan. cron tick · every 30 min · gated by bb recom gate · 0 tokens you a prompt, or a doc bb scan findings, with evidence bb compile units, one window each bb route lanes, in waves bb run --apply the only verb that spends sessions the nine hooks below bb finish the ledger, declared first bb git gated merge
The cron worker runs the free path unattended and stops at lanes: bb run and bb bridge are refused inside a gear, checked when the crontab line is written rather than trusted. Pressing enter yourself enters at you and skips straight to a session.

Every verb

sixty, read off src/cli.js in the order a factory uses them

Each card is one entry in the command table: the name, what it answers, the usage line, and what it does to the world. Two can spend money and only with the flag named on the card. Eleven can change a file a person wrote and only with --apply. The rest read, or write under .bundlebox/.

60 of 60
reads reports; nothing on disk changes records writes under .bundlebox/ only writes --apply can change a file you wrote, dry run until the flag spends can call a paid model, with the flag named
governWhat is the bar, before anything is written?1
bb auditorrecords

the bar, declared before the work: scope, standards, governance, assurance — then checked after it

bb auditor [areas|standards [area]|charter <area>|brief <area>|gate <area>|plan|pack|send <area> <kind>|record <area> <kind> <file>|drift] [--json]
src/auditor/index.js
lookWhat is in this tree?9
bb initwrites --apply

detect languages, agents and gates; write .bundlebox/config.json

bb init [--force] [--json]
src/init.js
bb doctorreads

what this box can run, and which runtime serves each op

bb doctor [--json]
src/doctor.js
bb envreads

what a complete .bundlebox holds, and whether this one does (no tokens)

bb env [--json] | bb env up [--apply]
src/env.js
bb scanrecords

run the local detectors (no tokens)

bb scan [--only a,b] [--json]
src/scan.js
bb findingsreads

list findings

bb findings [--detector x] [--severity s] [--status open|resolved|fixed|wontfix|all] [--limit n] [--json]
src/scan.js
bb explainreads

one finding: evidence and the triage derivation

bb explain <id> [--json]
src/scan.js
bb triagereads

label what closed findings cost, and fit the promotion rule to them (0 model tokens)

bb triage [backfill|calibrate] [--apply] [--json]
src/detectors/index.js
bb oversightrecords

measure the tree against its own medians; findings, guidelines, briefs (no tokens)

bb oversight scan [--trees a,b] [--write] [--json] | report | brief <files...> | guidelines [--build] | thresholds
src/oversight/index.js
bb designlabswrites --apply

the design studio: doctrine, UI research plans, a declared system and the gate that holds it

bb designlabs [status|init|check|tables|plan|collect|intake|sources|principles] [dir] [--apply] [--json]
src/designlabs/index.js
packWhat goes in the window?12
bb compilerecords

turn open findings into packed work units (no tokens)

bb compile [--write] [--max-units N] [--json]
src/compile/index.js
bb contextreads

will these files fit one session? parts table and split

bb context <paths...> [--kind fix|verify|investigate|build|write] [--brief file] [--json]
src/compile/index.js
bb gatesreads

what proves a change here (detected, merged with kernel.gates)

bb gates [--list] [--json]
src/compile/index.js
bb routerecords

pack compiled units into lanes and waves (no tokens)

bb route [--write] [--max-parallel N] [--agent name] [--run-id id] [--json]
src/route/index.js
bb snapgenrecords

reference tables a session reads instead of searching (no tokens)

bb snapgen build [--only a,b] [--force] | stale | list | show <table> | index | skeleton <file> | blast [--since ref] | callers <symbol> [--json]
src/snapgen/index.js
bb arcrecords

compile the derived symbol tables into one binary index the guards read in microseconds

bb arc [stat] | bb arc build | bb arc lookup <name...> [--under dir] [--shapes exact,prefix,suffix]
src/arc/index.js
bb pinpointrecords

one problem, one focused prompt: where, regions, scope, evidence, gate (no tokens)

bb pinpoint "<problem>" [--files a,b] [--max-files N] [--kind fix|verify|investigate|build|write] [--print] [--json]
src/pinpoint/index.js
bb tokensreads

estimate, ledger, calibrate, profile, prices, budget

bb tokens estimate <paths> | ledger | calibrate [--apply] [--tokens-only] | profile [--probe] | prices | budget [--json]
src/tokens/index.js
bb sieverecords

the input axis: shrink a tool result before it enters the window, and measure it on transcripts that already exist (0 tokens)

bb sieve [status] | bb sieve replay [--limit N] [--json] | bb sieve check <file|-> [--text] | bb sieve spill
src/sieve/index.js
bb janitorwrites --apply

compile the agent's memory: check every anchor, sweep what rotted, place what survives

bb janitor [status|compile|heap|explain <id>|prune|warehouse] [--budget N] [--age-factor N] [--stores a,b] [--verbose] [--json]
src/janitor/index.js
bb slopreads

anti-slop for prose: what a summary says that costs tokens and carries nothing (0 model tokens)

bb slop <file|-> | bb slop fix <file|-> [--apply] | bb slop rules [--json]
src/slop/index.js
bb benchrecords

the ablation benchmark: what a task costs with the factory and without it (no tokens)

bb bench [run [suite]] | init [--limit N] | suites | show | gate [<task>] | swebench run [--n 12] [--repos a,b] [--json] [--cap 10]
src/bench/index.js
proveWhat does the running system do?10
bb genesisrecords

a document or a prompt becomes a world model, a corpus and the briefs that fill it (0 tokens until send)

bb genesis <doc.md|-|--prompt "..."> [--base url] [--name id] | show | plan | pack [--batch 4] | send [surface] [--run --spend] | seed | list
src/genesis/index.js
bb cookbookrecords

run a scenario corpus against the running system; red steps become findings (0 model tokens)

bb cookbook [list|check|select|calibrate|run|board|init] [--persona id] [--base url] [--rpm n] [--only surface] [--budget steps] [--engine kernel|js] [--plan] [--apply] [--json]
src/cookbook/index.js
bb simulaterecords

run a situation profile at rising concurrency and report what the system does (0 model tokens)

bb simulate run [profile] --base <url> [--levels 1,8,32] [--seconds 3] | profiles | show | init <id>
src/simulate/index.js
bb runbookrecords

the running system: is it up, is it answering, what broke since the last call, what is it costing (0 model tokens)

bb runbook [status | up <group> | down <group> | wait <group> | logs [id] | perf | services | groups | init] [--apply] [--wait[=s]] [--force] [--level E] [--grep <rx>] [--sample] [--all] [--json]
src/runbook/index.js
bb viewportrecords

the ports this workspace is served by, as a page: what is listening, for which directory, and whether it answers (0 tokens)

bb viewport [status] [--json] | bb viewport build | bb viewport serve [--port 65432] | bb viewport open
src/viewport/index.js
bb recomrecords

what has already been driven, and whether that answer still holds (0 model tokens)

bb recom [list|check <id>|gate <id> -- <cmd>|repeatable|replay <id>|record --from <file>|refresh <id>|forget <id>|mobile|probes|template] [--apply] [--json]
src/recom/index.js
bb dottyrecords

what the screen showed: a frame for a person, an accessibility summary for the session (0 model tokens)

bb dotty [targets | shot [label] --url <u> | during [label] [--reload] -- <cmd>] [--port 9222] [--json]
src/dotty/index.js
bb mainboardrecords

one board over every view, one ledger under it; and which pipeline stage does not hold

bb mainboard [board|run|gaps|views|check] [--base url] [--only view,view] [--persona id] [--target local|prod] [--json]
src/mainboard/index.js
bb framesreads

a dataframe over the factory's own data, and the evals that turn a measurement into a finding

bb frames [sources|show|check|eval] [--source x] [--where col:op:value] [--group col] [--agg name:fn:col] [--sort -col] [--cols a,b] [--limit n] [--describe] [--markdown] [--json]
src/frames/index.js
bb failsafereads

what is failing now, why, and the operation that closes it (0 model tokens)

bb failsafe [status|why|ops|run <op> [--apply]|rerun|check] [--json]
src/failsafe/index.js
spendWhat costs money, and how much is left?6
bb runspends --apply

execute the routed plan as agent lanes (dry-run by default)

bb run [--plan <run_id>|latest] [--apply] [--pr] [--agent <name>] [--max-parallel N] [--json]
src/run/index.js
bb bridgespends --run --spend

draft a packed call to an agent; send only with --run (and --spend for a paid agent)

bb bridge draft "<problem>" [--reason exhausted|assist|complete|asked] [--files a,b] | send <id> [--run] [--spend] [--allow-near] [--agent name] | list | report [--json]
src/bridge/index.js
bb monitorreads

what this workspace is spending in the current 5-hour block, and how many tokens the box saved it

bb monitor [status|savings|blocks|sessions|guard] [--days n] [--plan pro|max5|max20|custom] [--limit n] [--compact] [--json] [--no-color] [--watch --interval 10] [--write-state]
src/monitor/index.js
bb sessionreads

what a session used and saved (MEASURED vs ESTIMATE)

bb session [id] [--write] | end --session <id> --transcript <path> | list | rm <id> | backfill [--since <date>] [--transcripts N] [--dry-run] [--json]
src/tokens/index.js
bb headroomreads

the wire: local compression proxy

bb headroom start --apply | status | stop | savings | doctor [--json]
src/tokens/index.js
bb agentsreads

which agent CLIs are installed, and the lean flag stack for each

bb agents [--json]
src/run/index.js
shipWhat closes the loop?9
bb finishwrites --apply

the acceptance ledger: derive it from the brief, parse it, run it, re-verify returned work

bb finish init [--apply] [--force] derive GATES.md from the active brief and the detected gates
src/finish/index.js
bb gitwrites --apply

commit, push, draft PR, ready, merge and review, with the workspace rules as code

bb git commit [--lane L01 | --scope a,b] [--apply] | push [--apply] | pr [--lane L01] [--apply] | ready <n> [--apply] | merge <n> [--override-gate] [--apply] | review <n> [--write] | status [--cwd <dir>]
src/git/index.js
bb fixwrites --apply

run local actuators over findings that name one (dry run without --apply)

bb fix [--apply] [--detector x] [--id id] [--force] [--json]
src/scan.js
bb pipelinerecords

run declared gears (pipelines of local verbs) with gates and freshness

bb pipeline run <gear> [--apply] [--verbose] | list | runs [--limit N] | suggest [--json]
src/pipeline/index.js
bb scriptsrecords

index tagged scripts (@tag/@title/@needs/...) and run them with their needs checked

bb scripts scan | list | run <tag> [--apply] | table [--write] [--json]
src/scripts/index.js
bb cronwrites --apply

the unattended worker: the crontab lines that run the free pipeline

bb cron install [--every 30] [--no-gate] [--apply] | status | remove [--apply]
src/cron.js
bb buckmasterrecords

signals, rules, graph, model and memory over transcripts and episodes (python3)

bb buckmaster episodes | signals [--limit N] | rules | recommend | graph | model [--train] [--weights] | memory | recall --about "<text>" [--tier procedural,semantic,episodic] [--useful] | outcomes [--all] | backlog [--json]
src/buckmaster/index.js
bb latherecords

the automation engine: what this workspace did by hand more than twice, as scripts, snippets, boilerplate and completions (LATHE-1, no tokens)

bb lathe what the model holds and what it emitted
src/lathe/index.js
bb consolerecords

one page for this workspace: the pipeline, the window, every session and what it saved

bb console [serve] [--port 7788] | build [--file out.html] | state [--json]
src/console/index.js
wireHow do agents reach it?10
bb wirewrites --apply

install the instructions block, MCP entry and hooks into each agent

bb wire [--agents claude,codex,...|auto] [--apply] [--global] [--json] | bb wire status | bb wire trim [--apply]
src/wire/index.js
bb unwirewrites --apply

remove only bundlebox's blocks, MCP entries and hook rows from each agent

bb unwire [--agents a,b|auto] [--apply] [--global]
src/wire/index.js
bb uptakereads

of everything bb wired in front of the agents, what did the sessions actually reach for (0 tokens)

bb uptake [--since <iso>] [--quiet] [--json] | bb uptake sessions
src/uptake/index.js
bb hookreads

a Claude Code hook handler (stdin JSON in, JSON out, always exit 0)

bb hook session-start|prompt|pre-read|post-tool|pre-compact|session-end
src/wire/index.js
bb mcpreads

serve the zero-token verbs as an MCP server over stdio

bb mcp
src/cli.js
bb kernelwrites --apply

the Rust kernel: status, build from source, or install a release binary

bb kernel [status|ops|build|install [--version v]]
src/kernel-cmd.js
bb selftestreads

the silent-failure checks; each prints its measurement

bb selftest [--json]
src/selftest.js
bb updatewrites --apply

is there a newer bundlebox, and install it

bb update [--apply]
src/cli.js
bb versionreads

print the version

bb version
src/cli.js
bb helpreads

this list

bb help [verb]
src/cli.js
watchIs the work going anywhere, and what can the box not settle alone?3
bb echosreads

the five agents that watch the work rather than the tree: spin, oscillate, drift, diminishing, converge (0 tokens)

bb echos [run] [--only spin,drift] [--limit N] [--json] | bb echos show | bb echos list
src/echos/index.js
bb grapplerecords

the handoff layer: what the box cannot settle, asked once and stored (0 tokens)

bb grapple [observe|status|ask|ratify|harvest|promote|backfill <rev>|priors] [--json]
src/grapple/index.js
bb proxyreads

the doorway: pack, serve and sieve for an agent that has no hook system (0 model tokens of its own)

bb proxy [--agent codex] [--prompt-file f] [--raw] -- <agent command...>
src/wire/index.js

Aliases the table also answers to: gc and memory for janitor, blackice and audit for auditor, scenarios and corpus for cookbook, board and mb for mainboard, dataframes for frames, cc for console, usage for monitor, sg and switchgear for pipeline, learn and bm for buckmaster, bridgeswap for bridge, scripttag and st for scripts, ctx for context.

Every verb takes --json. A module that fails to load is reported by bb help as broken with the first line of its error, and the rest of the table still answers: one bad import must not take the CLI down with it.

One prompt, end to end

nine hooks, in the order they fire

This is what bb wire --apply installs. Every row runs local code against artefacts already on disk, and the only thing it can spend is the few hundred tokens it chooses to put in the window.

  1. SessionStart30sbb hook session-start

    In a workspace that was never inited, this runs bb init inline — detection over the tree, well inside the budget — and detaches the artefact build, which is minutes of scanning and indexing and is not a hook's to spend. The returned line says it is still building rather than implying the environment is ready.

    Then the rot notice: which lines in the memory just loaded no longer resolve. The claim is already in the window, stated with the confidence it earned the day it was true, so the correction arrives beside it.

    Fired again with source: compact, right after a compaction, it is the first observable moment the window can be corrected. The narrative goes back first — the task, the scope, the files already edited, the last commands, the gate still open — read off the record the guards wrote, never off the summary. Then the rules, verbatim. Two caps, because truncating one joined band would cut whichever came second, and neither is the right one to lose.

    → window · ≤600 tok what this box holds, and what no longer exists → after a compaction · ≤1200 + ≤700 tok the record, then the rules

  2. UserPromptSubmit15sbb hook prompt

    If the round before was a compaction and no SessionStart answered it, the same two bands go back here. It fires once per compaction, not once per prompt: the marker records which compaction has already been answered, and on which hook.

    Otherwise, when the prompt is a task, the hook runs bb pinpoint rather than suggesting it: measured on this tree at 0.47s against a 15s budget, because every input it reads is a stored artefact. A suggestion was measured too, and it loses to the model's own habit about three times in four. A brief already standing for the same prompt is reused, never rebuilt.

    What enters is the map, about 300 tokens: the files, the symbols, the verdict. The quoted regions stay on disk until a read asks for one.

    → window · ≤1000 tok the located, budgeted brief

  3. PreToolUse · Read10sbb hook pre-read

    If pinpoint already located a region in this file, the read is denied and the reason carries the range to read instead. The model needs a read of a file before it will edit it, so blocking the scope blocks the change — and the denial names the read that is allowed.

    Otherwise the file is priced against what the window has left, and an oversized open comes back with an offset and a limit.

    ✕ denied · ≤900 tok read this range, not the file

  4. PreToolUse · Grep | Bash10sbb hook pre-search

    A declaration search is the case where the answer is not merely cheaper to look up, it is already written down: symbols-*.md is a name / file / line index rebuilt by fingerprint. The denial hands back the matching rows and the search never runs.

    What is not denied matters as much. A string literal, a call site, a comment, a pattern no declaration index can answer: the tables have no rows for it and the search goes through untouched. And the same words over a different file are a different search: the duplicate key carries the target, because keyed on the words alone it refused a second file as already answered, twice in one afternoon.

    ✕ denied · ≤500 tok the rows, instead of the walk

  5. PreToolUse · Write | Edit10sbb hook pre-write

    The one blocking check grapple adds, at the one moment the agent has committed nothing: a write outside the scope list the standing brief declared.

    In observe phase it records the verdict it would have returned and emits nothing — no decision, no bytes — so the session behaves exactly as it did before grapple existed, and those recorded verdicts are the base rate the enforce phase is gated on. A guard nobody measured is a guard nobody can defend turning on.

    ✕ denied · ≤900 tok out of scope — in enforce only

  6. PostToolUse15sbb hook post-tool

    bb sieve rewrites an oversized tool result before the window is billed for it twice, keeping the head, the tail and every error-like line, and leaving the full output on disk to grep.

    The command shape is appended for bb lathegit commit, never the message. Mining that order out of the transcripts took four minutes of wall clock for 4.8 seconds of CPU; this hook is already running on every tool call, so forty bytes here is the cheapest place in the system to learn the same fact. A shape log also cannot carry a secret somebody passed on a command line.

    Markdown the session writes into the tree is slop-checked, advisory only: a document is the only artefact here that charges rent, and a hook that rewrites your sentence unasked is worse than the sentence. And sixty bytes go to grapple's counters, no decision attached: everything bb grapple scores as drift is read back from this row.

    → window · ≤300 tok a shrunk result, and the rule it broke

  7. PreCompact30sbb hook pre-compact

    Emits nothing, deliberately. Whether this hook's stdout reaches the window after the summary is written cannot be observed from here, and a mitigation built on a guess silently does nothing.

    What it does instead is freeze the record: the narrative is written now, so what goes back after the summary describes the same moment the summary does and not a later one. Then the marker, and the next observable event — SessionStart with source: compact, or the next prompt — does the work.

    · silent a frozen page and a marker on disk

  8. Stop30sbb hook stop

    The fourth verification layer, and the only one that is not the work reviewing itself. It executes nothing. What it can say is whether the ledger this work declared is still sitting there with gates unmet — the one question a session about to report "done" cannot answer about itself. Silent where no ledger was declared, because a workspace that never set a bar has not failed to meet one.

    ✕ not done the gates still open

  9. SessionEnd120sbb hook session-end

    The transcript is folded into the ledger and the session is priced: tokens billed and turns taken, measured, against what the local path displaced. Saved is reported as two different things — cache reads and wire trims are measured, displaced turns are counted per episode and multiplied out, and the line says which is which.

    Then sleep-time compute. None of it reaches a window — the session is over — and the session that paid for the turns should not pay for learning from them.

    • grapple observethe open questions, the labels it can attach, and the drift score
    • lathe learnthe habits, off the shapes the post-tool hook recorded rather than the transcripts — 1.4s measured. Writing into scripts/ stays behind its own flag: a hook that adds files to somebody's repository unasked is a hook they turn off
    • echosspin, oscillate, drift, converge, over the sessions on disk. It files findings, so the next session opens with them in bb findings
    • janitor buildthe memory heap recompiled for whoever opens next. A failed refresh costs the next session a fresher heap, never the session that is ending

    → you tokens used · tokens saved · turns · peak window

The caps are per emission, not per session. Every band declared in src/wire/hooks.js added together is 6,100 tokens, and the two largest fire once per compaction — against reads and searches it routinely denies for more than that on their own. bb wire status reads the hook log for events the bb on PATH did not recognise, because an installed guard that an older binary silently ignores looks exactly like one that is working.

What the hooks read

every answer is already on disk

No hook computes anything expensive. Each one serves a file that a gear built earlier, which is why a 15-second budget is never close to spent.

ArtefactBuilt byServed to
.bundlebox/out/snapgen/bb snapgen buildpre-search — the declaration rows that replace a walk
.bundlebox/out/arc/bb arc buildpinpoint — every declaration as one binary index
.bundlebox/out/pinpoint/bb pinpointprompt and pre-read — the map, then the quoted regions
.bundlebox/var/brief.jsonthe prompt hookthe standing brief, so a repeated prompt is not re-located; pre-write, for the scope list
.bundlebox/var/narrative/the pre-compact hooksession-start and prompt — the record of the work, put back after a compaction
.bundlebox/var/findings.jsonbb scanprompt and compile — what is open, with evidence
.bundlebox/var/episodes.jsonlbb buckmastersession-end — turns displaced per verb
.bundlebox/var/sessions/bb tokens ledgersession-end and bb monitor — the bill, and the window left
.bundlebox/var/calls.jsonlthe post-tool hookbb lathe — the shapes this box repeated
.bundlebox/grapple/the post-tool and pre-write hooksbb grapple — the verdicts it would have returned, and the drift it scores
.bundlebox/out/janitor/bb janitor, at session endsession-start and prompt — the rot notice, and the rules restated in full
.bundlebox/auditor/<area>/bb auditor charterthe bar an area declared, before the work, by hand

The three on their own clock

janitor · auditor · snapgen

Three things here are not stages in the tick. Each has its own trigger, writes its own artefact, and is read back somewhere else entirely — which is the part that is easy to lose.

janitor — the memory compiler · triggered at SessionEnd

A compiler, not a cleanup script, for one reason that shows up in every verb: a cleanup script answers "is this tidy", and a compiler answers "does this build", which is a question with a failing answer. A rule whose file no longer exists is an ERROR. Two live rules that contradict each other is an ERROR, and neither is silently dropped.

1 · parsefour stores → typed objects
2 · resolveevery anchor → live, drifted or dead
3 · marktranscripts → reachability, promotion
4 · sweepcontradiction, quarantine, age-out
5 · compacttype-aware merge; rules never rewritten
6 · placerank, deal around the dead zone, pin rules
7 · emitWINDOW.md, HEAP.md, heap.jsonl, diagnostics
one orderEvery pass reads and writes the same IR, and the order is not a preference.
Touch pointReadsDoes
SessionStartdiagnostics.jsonthe rot notice: which lines in the memory just loaded no longer resolve
SessionStart (compact)the narrative, RULES.mdthe record of the work goes back, then the rules in full
UserPromptSubmitthe markerthe same two bands, when no SessionStart answered the compaction
PreCompactthe recordfreezes the narrative and writes the marker, so the restate fires once
SessionEndthe four storesrecompiles the heap for the next session, on the sleep-time budget

Every read is age-capped at janitor.max_age_hours, 168 by default. The stale guard matters more here than anywhere: a hook that quoted a week-old diagnostics file as though it described the tree right now would be making exactly the mistake the resolve pass exists to catch. Exit codes: 0 clean · 10 warnings · 11 errors · 30 the compiler itself failed.

auditor — the bar, declared first · triggered by hand

Every other verb here answers "what is wrong with what was written". This one answers the question that comes before it — what is in scope, what bar it has to meet, who decides when it does not, and what counts as proof — and it answers while changing the code is still cheap.

bb auditor driftcharters that need re-deriving, reviews describing a tree that has moved
bb auditor planareas with no declared bar, and the reviews worth writing, ranked
bb auditor packthe briefs. Stops here: sending is a decision

The audit gear declares on: ["hand"] — it is the one gear no cron line reaches, because a governance bar nobody chose is not a bar. The split everything turns on: a charter is living and is re-derived when the area moves, a review is dated and is never edited. Mixing those two destroys the only thing a review is for.

snapgen — the tables · triggered by fingerprint

Each table is a set difference, a parse or a count over the workspace, rebuilt only when its inputs change. In the orient gear it carries skip_if_fresh against a walk of the source, so a tick over an untouched tree rebuilds nothing.

bb snapgen stalewhich tables are behind their inputs
bb snapgen buildlayout, symbols-*, INDEX.md
pre-searchthe rows that replace a walk of the tree
pinpointsymbolHits: where-is-it, from a table that already exists

This is the one artefact a session is told to read instead of searching, and the only one the guards will deny a tool call on behalf of. A declaration search is the case where the answer is not merely cheaper to look up — it is already written down.

The gears running underneath

a declared pipeline, as data

A gear is an ordered list of verbs with a gate in front of each stage. Every built-in gear is free and local: run and bridge are refused inside one, checked when the crontab line is written rather than assumed. factory chains five of them, every 30 minutes, and stops at lanes.

intake — what is wrong

Ends holding lanes: the last point before anything spends.

bb scanevery detector
bb oversight scansize and fan-in, only when something was found
bb fixwhat the actuators could close for free. Dry run: a stage gets its own flags, never the gear's --apply
bb compile --writefindings → units packed to a window
bb route --writeunits → lanes. Stops here: running them is a decision

orient — what a session gets handed instead of searching

Everything the nine hooks above serve from.

bb snapgen buildthe reference tables
bb arc buildthe tables, compiled to one index
bb oversight guidelinesthe guidelines block
bb pinpoint gapseach finding as a located brief
bb buckmaster recommendthe fired rules, as lines you can paste

measure — what it all cost

The half of the loop that decides whether any of the rest was worth running.

bb tokens ledgerfold the transcripts into the ledger
bb session listthe sessions measured so far
bb buckmaster episodesturns displaced per verb

buckmaster — train on all of it

The one thing every gear writes is the episode table, which is how the model trains by the factory being used. The one gear here with a runtime dependency: bb buckmaster is the CLI half of the Python expert system in expert/, reached through src/core/expert.js. Without python3 ≥ 3.9 every sub-verb warns and returns 2, and the tick carries on — the zero-token path never touches this module. What is lost is the learning, not the factory.

bb buckmaster signalsper-session signals off the transcripts
bb buckmaster ruleswhich signals crossed a threshold
bb buckmaster memorywhat the factory came to believe
bb lathe buildscripts, snippets and completions for the habits

watch — fold what was spent

Last in the chain, and it used to be missing: the tick folded the ledger and rebuilt nothing, so the one page this workspace has showed whenever somebody last ran it by hand.

bb tokens ledgerfold every transcript
bb monitor statusthe block, the burn rate, which clock runs out first
bb console buildthe page, with the state embedded

full runs on the slower line, every 6 hours, ungated: situation → ops → intake → orient → scenarios → watch → buckmaster. It is the one that needs a service up, so the recom gate — which answers from the tree, the config and the head commit — would not see it coming.

What fires what

five triggers · three of them wired

Sixty verbs. Nobody types most of them. Five things can fire a verb, and two of the five are declared in the source and read by nothing.

A hook fires it, inside a session

VerbHookCondition
initSessionStartno .bundlebox in a dir that looks like a project — detection inline, build detached
janitor readSessionStartdiagnostics.json under 168h → the rot notice
the narrative, janitor readSessionStart (compact), UserPromptSubmitthe round after a compaction → the record of the work, then RULES.md in full
pinpointUserPromptSubmitthe prompt is a task and wire.auto_pinpoint
snapgen, arc readPreToolUse · Read, Grep|Bashthe tables have rows for what the call is asking
grapplePreToolUse · Write|Edita write outside the standing brief's scope
sievePostToolUseresult over the threshold, sieve.enabled
slopPostToolUsea markdown write into the tree
finishStopa ledger exists with gates unmet
tokens, sessionSessionEndwire.measure_sessions
grapple, lathe, echos, janitor buildSessionEndeach behind its own config flag

Cron fires it

LineGateWhat it reaches
*/30 * * * *bb recom gate cron/factoryscan, oversight, fix, compile, route, snapgen, arc, pinpoint, buckmaster, tokens, session, bench, triage, echos, lathe, monitor, console
0 */6 * * *ungatedthe same, plus runbook, viewport, failsafe, doctor, cookbook, mainboard, frames

Both under one flock, so they never overlap. Neither can reach run or bridge: unsafeVerbs() walks the chain and refuses to write the crontab line, rather than trusting that a gear stayed free. The gate runs 48 times a day so that the pipeline does not.

The agent fires it

Nine MCP tools, and the model decides when: bb_pinpoint, bb_context, bb_snapgen, bb_findings, bb_scan, bb_oversight_brief, bb_explain, bb_tokens_estimate, bb_session.

Nothing fires it

Twenty-six verbs wait to be typed. Most should: wire, unwire, kernel, update, cron and init change the box, and a box that reconfigures itself on a timer is worse than one that does not. The ones worth noticing are the free ones nobody is reminded of — env, context, gates, uptake, simulate, dotty, designlabs, scripts, proxy, headroom, agents, explain, findings.

the one readersrc/cron.js:100 filters gears for on: "cron". It is the only code in the tree that reads gear.on at all.
declaredpost-commitintake carries it. No git hook is installed, so a commit is scanned by the next half-hour tick and not before.
declaredsession-startorient carries it. The hook detaches bb init's build instead, and never runs a gear.
declaredsession-endmeasure and watch carry it. The hook runs its own list, so monitor status and console build wait for cron.

A trigger name that nothing dispatches on is a schedule somebody believes in. The factory already learned this once — situation, ops and scenarios declared cron for months while no chain reached them, which is why the reachability check at cron.js:100 exists. It checks one of the five names.

Is the box ready for any of this

bb pipeline · eleven stages, each with an exit criterion

A stage is not done because it ran once. It is done when its output exists, is fresh against its inputs, and asserts something. Every stage before agent is free.

01Genesisis there a world model to work against?bb genesis <doc.md>
02Situationhave the local detectors looked at what is on disk?bb scan
03Orientis the free context a session opens with built and fresh?bb pipeline run orient
04Corpusis there a scenario corpus, and does it assert anything?bb genesis pack
05Scenarioshas the corpus been run against the system since it last changed?bb cookbook run
06Simulationdoes it still hold at more than one caller?bb simulate run smoke
07Pinpointis the worst open finding packed to one window?bb pinpoint "<title>"
08Agentis the work packed and budgeted before anything opens a session?bb compile --write
09Monitordoes the box know what the current window has left?bb tokens ledger
10Echosis the work itself going anywhere?bb echos
11Shipis there a command that proves a change, and a clean way out?bb git status
cost0 tokensEvery stage on this board is free. The first thing that spends is what stage 08 hands to a session.

Stage 10 is the only one that asks about the work rather than the artefacts. Every stage above it checks that something was derived and is still fresh; none of them checks whether the sessions are converging.