A guidance-first build process for working with an LLM instead of being dragged behind one. You decide on a surface outside the chat; plumbbob orients you, runs each step's labor, and then stops and waits for you to advance — the human is the clock, not a lock.
Ridgeline is the line. Plumbbob establishes true before you build. The LLM is a hand, not a head.
This repository was built using Plumbbob v2, dogfooded on its own build under its own loop.
Plumbbob v1 enforced the deciding/executing boundary with a hard file lock (a pre-edit muzzle). v2 replaces the lock with a clock: nothing blocks your edits. Instead, the system does a step's work, then pauses at a verify gate for your approval before it checkpoints. You stay the decider by advancing the clock, not by fighting a wall.
- The human owns convergence — you decide, you approve, you advance.
- The plan lives on durable surfaces (
intent.md,build-log.md), not in the chat. - The boundary is a pause, not a refusal: the system pulls up to a line and waits.
You drive the whole loop from your IDE with eight pb-* skills — no step numbers to remember, no raw CLI to type. /pb-status always names your next move.
| Skill | Does |
|---|---|
/pb-plan |
frame a goal — scaffold the session + author intent's Frame, Decisions, Constraints |
/pb-step |
plan the next increment — a title, a done-when, a seam |
/pb-build |
(optional) implement the planned step, then verify it to the pause |
/pb-verify |
the tick — check → self-review → validate → PAUSE → checkpoint |
/pb-park |
capture an idea without chasing it |
/pb-status |
orient — where you are, what's parked, and the next move |
/pb-harvest |
triage parked ideas at a boundary (blocker / tangent / pivot) |
/pb-reset |
close out — write the report, archive, clear for a fresh goal |
Three optional power moves survive for when you need them: /pb-revert (recover to a checkpoint), /pb-spike (throwaway worktree experiment), and /plumbbob-interrogate (attack the frame for holes).
/pb-plan frame the goal (once)
└ per step:
/pb-status "what's next?"
/pb-step plan the next increment
/pb-build (or DIY) implement it
/pb-verify check → review → PAUSE → checkpoint
/pb-park capture strays mid-build
/pb-harvest triage them at a boundary
/pb-reset report + archive + clear (once)
The pluggable executor. /pb-build is one way to turn a planned step into code — it is optional. Implement by hand, in a vibe session, or with another harness, and run /pb-verify instead: it reads the diff, not the author. Plumbbob is the harness-agnostic spine; how the diff appears is a slot you fill however you like.
- A
plumbbobCLI (TypeScript, run natively by Node ≥ 22.18, zero runtime dependencies) — the dumb mechanical verbs the skills shell out to. You never type it by hand. - One session-gated Claude Code hook —
post-edit.sh, a non-blocking light-feedback pass that injects file-scoped lint into the model's context. (v1's pre-edit muzzle and bash-guard are gone — guidance, not enforcement.) - The eight
pb-*skills plus the optional power moves, eachdisable-model-invocationso you fire every move. - A
.plumbbob/sidecar of flat files:STATE(orientation only),intent.md,build-log.md,checkpoints, andarchive/.
The npm package is plumbbob; it installs the CLI (plumbbob plus a pb shorthand) and ships the hook and skills inside the package.
pnpm add -D plumbbob
pnpm exec plumbbob setup --local # or --project to commit it for a teamThis copies the skills into <repo>/.claude/skills/ (their bin pointed at the project-local binary) and registers the post-edit hook in place under node_modules. Nothing is written under ~.
npm install -g plumbbob
plumbbob setup --globalThis copies the hook and skills under ~/.claude/ and registers them in ~/.claude/settings.json. Restart Claude Code (or reload settings) after install.
The one-word .plumbbob/STATE (DESIGN / BUILD / SPIKE) is read by /pb-status to tell you where you are and what to do next. It no longer gates edits — a wrong state is a mislabeled position on a map, not a locked door. The post-edit hook is session-gated: a repo with no .plumbbob/STATE behaves exactly like plain Claude Code.
Plumbbob commits cheap checkpoint markers (plumbbob: step n done) on your feature branch and reverts to its own recorded SHAs. It never rewrites pushed history; your normal squash-merge collapses the checkpoints at PR time. reset archives plain markdown under .plumbbob/archive/ and never touches git.
pnpm install
pnpm check # tsc, oxlint, ast-grep, vitest, knip, markdownlint
pnpm build # emit dist/ (what the published bin runs)The underlying philosophy — attention as the scarce resource — lives in docs/attention-first-development.md.
Licensed under the Apache License 2.0.