PLUMBBOB
API
Home Docs GITHUB
{{ grp.title }}
{{ it.label }}
The CLI is the mechanical layer the /pb-* skills shell out to. In normal use you never type it by hand.
CLI · ADVANCED

Verbs

The lower-level layer the /pb-* skills shell out to — most people never type it. Reach for it to script the loop, drive it from another host, or control the mechanical steps directly. Invoke as plumbbob <verb> (also pb). Every verb is a pure function that writes to stdout/stderr and returns an exit code; the only process.exit is the bin entry. Every session verb accepts --build <slug> to target a specific build. Each row is a verb, its synopsis, and what it does.

VERB · SYNOPSIS WHAT IT DOES
{{ r.name }}
{{ r.synopsis }}
{{ r.does }}

Which build a verb acts on resolves in order: --build <slug> → the active-build cursor in STATE → the sole build in builds/ → a refusal with a hint. help and version round out the surface.

CLI · ADVANCED

Flags

The gate-narrowing flags map straight onto checkride's own flags. On the check override path (a custom "check" command) they are warned-and-ignored. checkpoint's gate takes no flags — the commit gate is always the full run.

check flags

FLAGEFFECT
{{ f.flag }} {{ f.effect }}

Flags on the other verbs

FLAGONEFFECT
{{ f.flag }} {{ f.verb }} {{ f.effect }}
CLI · ADVANCED

Exit codes

The 1-vs-2 distinction is a promise a caller can branch on: a failed check ("the work isn't done") is a different thing from the gate itself breaking ("fix the harness"). Never trust green or red until you know the gate ran.

0
Success. For check (and checkpoint's gate), 0 means the heavy check was green. A run where every slot skipped refuses rather than passing vacuously.
1
A refusal or failure. A guard tripped (no session, a step already in flight, a bad argument), a red check, or an unknown verb. check propagates the underlying command's non-zero code.
2
The gate itself broke. checkride couldn't run at all — e.g. a malformed checkride.config.json. Fix the harness before trusting green or red; do not treat it as "checks failed".
NO VACUOUS GREEN
A gate that passes because nothing ran is worse than a red one — it lies. PlumbBob's check refuses a run where every slot skipped, so "green" always means "something was actually verified".
THE SIDECAR

The .plumbbob/ sidecar

The sidecar splits into a tracked artifact plane and an untracked control plane. The artifact plane — settings.json and every builds/<slug>/ folder — is committed, so a build's record rides its branch into the PR. The control plane stays git-excluded via info/exclude, not .gitignore — nothing PlumbBob-specific is imposed on the repo. A session is live iff STATE is present.

.plumbbob/ — tracked artifact plane + untracked control plane
.plumbbob/
STATE untracked — session sentinel (presence = live) + the active-build cursor
settings.json tracked — project defaults: {} (or {"check": "…"}); start seeds it empty
settings.local.json untracked — optional personal, per-worktree overrides
agents/ tracked — optional user-authored agents, one dir each
<name>/agent.json the manifest
builds/
<slug>/ slugs are YYYY-MM-DD-<title>, so ls sorts chronologically
intent.md tracked — canonical intent (rides the branch into the PR)
build-log.md tracked — live ledger + park list
checkpoints tracked — "baseline <sha>", "plan <sha>", "step N <sha>"
report.md tracked — written at finish
harness.json tracked — optional per-step agent slot bindings
STEP untracked — the in-flight step number (its presence = BUILD)
SEAM untracked — the step's declared paths (awareness, not a lock)
SPIKE untracked — marker, present while a spike fork is open
handoff.json untracked — step-scoped agent-run ledger, cleared at checkpoint
TRACKED — RIDES THE PR
There's no separate archive copy: the tracked build folder already is the record, and merges into main with the branch. The "what did we decide, and why" survives the squash-merge.
START --LOCAL — FULLY UNTRACKED
Repos that won't track a tool folder opt into the old flat layout: artifacts at the sidecar root, the whole .plumbbob/ excluded — at the cost of the build record dying with the worktree.
THE SIDECAR

Settings

Settings live in a tracked settings.json at the sidecar root — optional JSON, so a missing or malformed file contributes nothing rather than wedging the tool. A value resolves from a CLI flag first, then settings.json, then a built-in default.

the known keys
// settings.json (tracked project defaults; start seeds it empty)
{} // all defaults: no "check" key → checkride is the gate

// or set any of these keys in one object:
{
"check": "npm test", // override the gate with any shell command
"agents": { "after": ["reviewer"] }, // project-wide slot bindings
"agentTimeout": 120 // kill an agent after N seconds (0/absent = off)
}
{{ k.key }}
{{ k.body }}

The per-worktree active-build cursor is not a setting — it lives in the untracked STATE file, so your settings.json stays purely declarative.

THE SURFACE YOU DRIVE · START HERE

The twelve skills

This is the interface you actually use. Every skill is disable-model-invocationyou fire every move. Claude Code namespaces them under the plugin, so the real command is /plumbbob:pb-plan; the short form /pb-plan is for readability. The CLI verbs are the lower-level layer these shell out to — reach for them only to script the loop or drive it from another host.

{{ c.name }}
{{ c.does }}
{{ c.icon }}
{{ c.group }} takes: {{ c.takes }}
{{ c.detail }}
{{ g.title }}
{{ g.body }}