Skip to content

Project Orchestration Handbook

The encyclopedic guide to running projects with BoB (Big ol’ Brain). For humans and agents.

This handbook is the human-facing how-to. For under-the-hood architecture and internals, see project-management-reference.md. For deep dives on individual subsystems, see the See Also section.


BoB (Big ol’ Brain) is a global Claude Code tooling framework. Skills, agents, slash commands, hooks, scripts, and templates live in a single source-of-truth git repo and get distributed to every project via deploy + symlink.

When someone says Bob, BoB, big brain, or big ol’ brain, they mean this framework. See bob-identity.md for the full identity definition.

BOB_SOURCE (~/projects/bigbrain) <- Source of truth (git repo)
│ scripts/deploy.sh (sync)
BOB_HOME (~/.claude/) <- Runtime (Claude Code reads here)
│ cdi (per-project init: symlinks)
.claude/ (in each project) <- Project-level entry points
Layer Location Purpose
BOB_SOURCE ~/projects/bigbrain Edit here. One git repo. Single source of truth.
BOB_HOME ~/.claude Where Claude Code reads at runtime. Synced from src.
Project <repo>/.claude/ Per-project symlinks to BOB_HOME items + local items

Everything BoB manages must be declarative, version-controlled, reproducible, idempotent, and observable — with every piece of state owned by exactly one source of truth.

Full text and approved patterns: prime-directive.md.

Every project’s vision lives in docs/vision.md. Everything below the vision lives in GitHub Issues — capabilities, requirements, bugs, decisions, lessons, session summaries, and TODOs. There are no REQ-*.md, BUG-*.md, SOL-*.md, or PM index files. If someone tries to create one, stop them.

Type Source path Loading model
Universal skill BOB_SOURCE/skills/ Auto-loaded everywhere by Claude Code
Universal command BOB_SOURCE/commands/ Symlinked into each project’s .claude/commands/ by cdi
Universal agent BOB_SOURCE/agents/ Symlinked into each project’s .claude/agents/ by cdi
Universal runbook BOB_SOURCE/runbooks/ Referenced by absolute path; not symlinked
Registry skill BOB_SOURCE/registry/skills/ Provisioned per-project via manifest (provisions/<project>.json)
Registry command BOB_SOURCE/registry/commands/ Same — opt-in per project
Registry agent BOB_SOURCE/registry/agents/ Same — opt-in per project
Hook BOB_SOURCE/hooks/ Wired up in ~/.claude/settings.json by event
Script BOB_SOURCE/scripts/ Invoked by absolute path from skills, commands, hooks, or shell
Template BOB_SOURCE/templates/ Copied (not symlinked) into projects, then customized
Provision manifest BOB_SOURCE/provisions/ Declares which registry items a project gets

Moved to a tutorial — see Getting Started.

Moved — see Getting Started.

3.2 Deploying changes from BOB_SOURCE → BOB_HOME

Section titled “3.2 Deploying changes from BOB_SOURCE → BOB_HOME”

deploy.sh is the only sanctioned way to update ~/.claude/. Direct edits to ~/.claude/ are anti-pattern — you’d lose them on the next deploy.

Terminal window
scripts/deploy.sh --dry-run # Preview what would change
scripts/deploy.sh # Apply
scripts/deploy.sh --first-run # First-deploy mode (cleans up legacy .git/ in BOB_HOME)
scripts/deploy.sh --force # Skip confirmation prompts

Machine-specific files are protected and never overwritten:

  • ~/.claude/settings.json
  • ~/.claude/settings.local.json
  • ~/.claude/CLAUDE.local.md
Terminal window
cd <project>
cdi # Idempotent — safe to re-run

Creates <project>/.claude/ with symlinks to:

  • commands/ from ~/.claude/commands/
  • agents/ from ~/.claude/agents/
  • hooks/ referenced in settings.json
  • Templates (copied, not symlinked)

Skills are not symlinked — they’re auto-loaded globally from ~/.claude/skills/.

3.4 Provisioning registry items (cdprov + /provision)

Section titled “3.4 Provisioning registry items (cdprov + /provision)”

Each project has a manifest at BOB_SOURCE/provisions/<project>.json declaring which registry skills, commands, and agents it uses (in addition to the universal set).

Terminal window
cdprov # Apply manifest — create symlinks to match
cdprov --status # What's in manifest vs. what's actually linked
cdprov --diff # Dry run — show planned changes
cdprov --refresh # Re-sync symlinks (drop stale, add missing)

Inside Claude (/provision):

/provision status
/provision add skill cloudflare-dev
/provision add command deploy
/provision add agent code-reviewer
/provision remove skill seo-auditing
/provision diff
/provision init # Bootstrap a manifest for a new project

Manifest shape (provisions/<project>.json):

{
"_meta": { "project": "myproj", "stack": ["cloudflare-workers", "d1"] },
"skills": ["cloudflare-dev", "d1-expert"],
"commands": ["deploy", "research"],
"agents": ["code-reviewer", "code-debugger"],
"runbooks": []
}

Validate against schemas/manifest.schema.json.

3.4a Universal vs registry — and how to promote between tiers

Section titled “3.4a Universal vs registry — and how to promote between tiers”

Every command, skill, and agent lives in exactly one of two tiers. This is the single most important distinction to internalise — most “why isn’t my command showing up?” confusion comes from not knowing which tier an item is in.

Tier Source folder Who gets it How it lands in a project
Universal commands/, skills/, agents/, runbooks/ Every project, automatically cdi symlinks commands/agents in; skills auto-load globally
Registry registry/commands/, registry/skills/, … Only projects that opt in Listed in provisions/<project>.json, then cdprov links it

Registry is an à-la-carte menu: with 30+ registry skills and ~17 registry commands, you don’t want cloudflare-dev loaded into a non-Cloudflare project. So registry items are opt-in, declared per-project. Universal items carry a context cost in every project, so default new items to registry and promote only the ones that are genuinely needed everywhere.

The end-to-end flow — what links what:

edit in BOB_SOURCE → deploy.sh (sync to ~/.claude) → cdi (universal symlinks)
→ cdprov (registry symlinks, per manifest)

deploy.sh copies files into the runtime dir but links nothing into projects. cdi links the universal set. cdprov links the registry items a project’s manifest names. A registry item that no manifest references is linked into no project — even after deploy.

Promote registry → universal (the item should be in every project):

Terminal window
cd ~/projects/bigbrain
git mv registry/commands/<name>.md commands/<name>.md # the tier IS the folder
scripts/deploy.sh # sync to ~/.claude
# then re-run `cdi` in each existing project to pick up the new symlink;
# new projects get it automatically. Remove the item from any provisions/*.json
# that listed it — it's now universal, so an explicit opt-in is redundant.

Demote universal → registry (the item is only needed by some projects): reverse the move (git mv commands/<name>.md registry/<name>.md), deploy.sh, then add the item to the manifest of each project that still needs it and cdprov --refresh. Projects not naming it lose the symlink on their next cdi/refresh.

The tier of an item is defined entirely by which folder holds it — promotion and demotion are just a git mv plus a re-link. There is no separate registration step.

Terminal window
cd ~/projects/bigbrain
git pull # Get upstream changes
scripts/deploy.sh --dry-run # Always preview first
scripts/deploy.sh # Apply
make check # Verify nothing broke
  • <project>/.claude/CLAUDE.local.md — project notes that don’t get checked in.
  • ~/.claude/CLAUDE.local.md — global notes that don’t sync.

These are loaded into context but never deployed or committed.

make is the IaC verification layer. Run any of these from BOB_SOURCE:

Target What it checks
make check All of: deps + schemas + symlinks + hooks + provisions
make check-deps node, jq, git, make versions
make check-schemas All *.json configs against JSON Schema definitions
make check-symlinks Every symlink across registered projects resolves
make check-hooks Every hook script in settings.json exists and is executable
make check-provisions Each project’s actual symlink state matches its manifest
make test Schema validator unit tests + warp-drive state machine tests + integration
make ci check + test (what GitHub Actions runs)
make doctor Diagnostic dump for triaging weirdness
make help Print all targets

Current test counts (run make test for the live numbers):

  • Schema validator: 34 unit tests
  • Warp-drive state machine: 99 transition tests
  • Integration tests for all check scripts: 13

make ci is what GitHub Actions runs on push and PR to master. CI skips check-symlinks and check-provisions because those scan local project directories that don’t exist on the runner.

Doc-link sweep: the doc-keeper auditor’s broken_relative_link rule (scripts/doc-keeper/audit.js, run via make docs-check) validates every relative .md/.txt link across README.md, CLAUDE.md, and docs/**/*.md (excluding docs/archive/**, which is frozen historical content). It supersedes the former standalone check-doc-links.sh, removed in #462 as dead tooling.


Vision & Strategy (docs/vision.md) /vision
└── Business case (GitHub Issue, business-case) /business-case — justify investment (above cap)
└── Capability (GitHub Issue, label: cap) /capability
└── Requirement (GitHub Issue, req) /requirement
└── Warp-drive chunks automatic — individual commits
Use case (GitHub Issue, label: use-case) /use-case — a scenario; Realizes → cap/req
└── → Capability (broad) or Requirement (narrow)
Level Format Command Contains
Vision docs/vision.md /vision Why, who, where, principles, non-goals, roadmap. Living doc.
Business case GitHub Issue (business-case) /business-case Problem, options, cost/benefit, risk, recommendation, success metrics
Capability GitHub Issue (cap) /capability User stories, success metrics, requirements checklist
Requirement GitHub Issue (req) /requirement Description, acceptance criteria (checkboxes), priority, notes
Use case GitHub Issue (use-case) /use-case Actor, goal, scenario, success criteria; decomposes to cap/req
Bug GitHub Issue (bug) gh issue create --label bug Bug reports
TODO GitHub Issue (todo) auto-created by warp-drive timeout Human action items

Two issue types bracket the capability spine without being part of the linear cap → req decomposition:

  • Business case (business-case, /business-case) sits above capability — it justifies investment before capabilities are spawned. Its recommended option is realized by one or more capabilities, each carrying Part of #NN (where NN is the business case) in its Notes, exactly as a requirement links to its capability. The vision-doc fold-in of an approved recommendation is deferred to grooming; /business-case never edits docs/vision.md.
  • Use case (use-case, /use-case) captures a concrete scenario (actor, goal, main/alternate flows, success criteria) and decomposes into the work that realizes it — a capability (broad: multiple actors/steps) or requirement(s) (narrow: one actor/goal). Each realizing issue carries Realizes #NN (where NN is the use case) in its Notes, and inherits the use case’s area:<slug> so the whole scenario tree is one warp-drivable workstream.

Query the traceability with gh issue list --label use-case, gh issue list --label business-case, and gh issue list --search "Realizes #NN".

Label Meaning
business-case Business case — investment justification above capability
cap Capability
req Requirement
use-case Use case — a scenario that decomposes into cap/req
bug Bug report
todo Human action item
approved Ready to work — picked up by /warp-drive
in-progress Being worked on
blocked Waiting on something
implemented Code done, awaiting verification
serial-only Excluded from cdfork --from-issues (pinch points)
area:<slug> Workstream tag — batches issues for one module/feature/capability (see Area labels)
decision Architecture decision (created by /journal decision)
lesson Lesson learned (created by /journal lesson)
session-summary Session summary (created by /session-summary)
p1-critical / p2-high / p3-medium / p4-low Priority
  1. /capability creates an issue (label cap).
  2. Break it into requirements with /requirement (label req, with Part of #NN linking back to the capability).
  3. Add approved when a requirement is ready to work.
  4. /warp-drive picks the highest-priority req + approved issue not in progress.
  5. When done, warp-drive flags it implemented and moves on.

Within a single repo, issues for distinct workstreams — a new module, a feature, a capability rollout — are intermixed. An area:<slug> label tags every issue belonging to one workstream so the whole cluster can be listed and warp-driven as a unit without hand-picking issue numbers (#260).

  • Convention. Slugs are kebab-case workstream names: area:billing, area:baz, area:seebod. Labels use a reserved colour (#5319E7) and an Area: <Name> description so the namespace is visually distinct and observable. Scope is within a single repo — each project tracks its own issues on its own repo.

  • Hierarchy fit. A capability owns its area:<slug> (derived from its title); its child requirements inherit the same label so the Capability → Requirement tree is warp-drivable as one unit.

  • Idempotent provisioning (Prime Directive). Create/reconcile a label on demand with the helper — it never duplicates or clobbers:

    Terminal window
    ~/.claude/scripts/area-labels.sh ensure billing # create/refresh area:billing (accepts a name too)
    ~/.claude/scripts/area-labels.sh list # list existing area:* labels
    ~/.claude/scripts/area-labels.sh slugify "Billing & Invoicing" # -> billing-invoicing
  • Status overview per workstream (the gh issue list recipe):

    Terminal window
    ~/.claude/scripts/area-labels.sh issues billing # open issues in the area
    ~/.claude/scripts/area-labels.sh issues billing --state all
    # equivalent raw form:
    gh issue list --label "area:billing" --state open
  • Warp-drive batching. /warp-drive --area <slug> narrows discovery to req + approved + area:<slug> — see the warp-drive guide.

  • Expectation & drift check (#527). Every open cap and req should carry an area:<slug> label (other issue types — bugs, todos — take one when a workstream is meaningful, but it is not required). /capability and /requirement assign one at creation; to catch anything that slipped through, run the audit (also wired into /what-next Step 5):

    Terminal window
    ~/.claude/scripts/area-labels.sh audit # lists open cap/req missing area:* (exit 3 on drift)

The following filename patterns are forbidden. They predate the GitHub Issues migration. Do not regenerate them:

  • REQ-*.md, SOL-*.md, BUG-*.md, RISK-*.md, INC-*.md, CR-*.md, UXR-*.md, STATUS-*.md
  • REQUIREMENTS-INDEX.md, SOLUTIONS-INDEX.md, backlog.md, traceability-matrix.md
  • .claude/project-management/, .claude/requirements/, .claude/journal/decisions/ (or lessons/, sessions/)

If a tool emits any of these, treat it as a bug and fix the tool.

Some work cannot be parallelized. Mark these requirements serial-only so cdfork --from-issues skips them:

  • Config / settings sync
  • Lockfile bumps
  • DB migrations
  • Compiled-asset rebuilds
  • Deploy steps

Every project can declare its dev environment in dev.json. The /dev-up command (and bin/dev-up from a terminal) reads it and brings the environment to a fully testable state — server, migrations, seed data, test users, health check.

Full reference: dev-lifecycle.md.

Lives at the project root. Sample at templates/dev.json. Schema at schemas/dev.schema.json.

{
"server": { "command": "npm run dev", "port": 5173, "health": "/api/health" },
"migrations": { "command": "npm run migrate:dev", "auto_run": true },
"seed": { "directory": "seed/", "runner": "node", "order": "alphabetical" },
"auth": { "adapter": "d1", "users_file": "seed/users.json" },
"access": { "localhost": "http://localhost:5173" }
}

cdi allocates every project a deterministic 10-port band so multiple dev servers coexist without collisions. Two-tier, single source of truth:

  • Ledger (authoritative): BOB_SOURCE/provisions/ports.json, version-controlled, managed by scripts/port-ledger.js. base = 5200 + slot*10; slot from an FNV-1a hash of the project name. Sub-offsets: +0 vite, +1 wrangler, +2 cds dashboard, +3..9 reserved.
  • Projection (derived): cdi writes a marked, regeneratable block into dev.json (_bob_ports + server.port) and the vite/wrangler configs — never hand-edited; lossless and idempotent.

Name-hash is the default proposal; the ledger only records and arbitrates collisions (deterministic next free band). Explicit non-default pins (e.g. nanaawards 5180) are retrofit-backfilled and preserved. The legacy cds ~/.claude/dashboard-ports.json registry is folded into the ledger and retired. Inspect with cdb --ports / cds --ports. Full reference: dev-lifecycle.md → Port Allocation.

Fleet backfill (#198). Projects provisioned before #197 have no band yet. make port-migrate (or node scripts/port-fleet-migrate.js) is a one-shot, idempotent migration that walks every provisioned project (provisions/*.json), allocates each its band via the same allocator as cdi, writes the ledger, and regenerates the marked projection blocks. It backfills only un-allocated projects, never reassigns an existing band, aborts loudly before any write on a pin collision, and is a verified no-op on a second run. Always review make port-migrate-dry first. deploy.sh runs it idempotently (honouring --dry-run) and non-fatally on each deploy.

Command Purpose
/dev-up Full lifecycle (server + migrations + seed + users + health)
/dev-up --check Health probe only
/dev-up --skip-seed / --skip-users / --skip-server Partial run
/dev-up --regen-seed Discard cached seed and regenerate
bin/dev-up Same, from a regular terminal
bin/dev-health Shortcut for dev-up --check
  • Seed scripts live in seed/ — alphabetical execution order.
  • Seed data must cover all lifecycle states the domain defines (not just fresh records).
  • New features include their seed updates in the same commit.
  • Seed coverage gate: scripts/dev-lifecycle/check-seed-coverage.sh.

seed/users.json declares test users, provisioned via pluggable auth adapters.

Adapter Use when…
d1 Cloudflare D1 (SQLite)
sqlite Local SQLite
supabase Supabase auth
script Custom provisioning script
custom Inline command in provision_command

The superuser is consistent across every project: admin@test.local / admin123.

When dev.json exists, warp-drive automatically:

  1. Calls dev-up before the first chunk
  2. Verifies health between chunks
  3. Auto-recovers on dev failure
  4. Treats dev health failure as a blockable event

The day-to-day cycle when you’re at the keyboard.

/start-work → branch off
… code …
/commit → create a commit
/journal → optional: capture a decision/lesson
/pr → optional: open a PR
/finish-work → merge + cleanup
/session-summary → close the session as a GitHub Issue

Creates a new branch with a sensible name. Argument: feature | fix | docs | refactor | tooling | chore.

Stages and commits with a generated message. The commit skill enforces:

  • No commits to master/main (use /start-work first)
  • Pre-commit hooks run (don’t bypass with --no-verify)
  • Commit message reflects the why, not just the what

Pushes branch and opens a PR with requirement traceability — links back to the GitHub Issue(s) the branch addresses.

Subactions: /pr create, /pr template, /pr link.

Merges current branch to master (Level 3) or opens a PR (Level 2), runs cleanup, deletes the local branch.

Create a journal entry as a GitHub Issue. Three types:

Subcommand Label
/journal decision <name> decision
/journal lesson <name> lesson
/journal session <name> session-summary

End-of-session writeup as a GitHub Issue. Captures what shipped, what’s next, decisions, lessons.

Built-in Claude Code commands you’ll use alongside

Section titled “Built-in Claude Code commands you’ll use alongside”
Command Purpose
/review Code review of pending changes
/security-review Security review of pending changes
/init Initialize a CLAUDE.md from existing codebase
/clean_gone Clean up local branches that are gone on the remote
/commit-push-pr Commit, push, and open PR in one go (built-in plugin)
/loop Run a slash command on a recurring interval
/schedule Cron-style scheduling for recurring agents

Level Name Start with Default behavior
1 Supervised claude / -a1 Confirm every tool that can change state
2 Trusted Dev claude -a2 Auto-approve safe ops; PRs instead of direct merges
3 Autonomous claude -a3 Minimize prompts; merge directly to master

Switch mid-session with /automation level <N>. See profiles/{supervised,trusted,autonomous}.json for the exact permission profiles.

7.2 /warp-drive — the autonomous development loop

Section titled “7.2 /warp-drive — the autonomous development loop”

This replaces /auto-loop. /auto-loop is legacy and will be removed.

/warp-drive # Discover next approved requirement, work it
/warp-drive 42 # Work on issue #42 specifically
/stop-warp-drive # Graceful stop

What it does each cycle:

  1. Discover work (gh issue list --label approved --label req)
  2. Plan implementation
  3. Code (chunked: max 3 acceptance criteria per commit)
  4. Test
  5. Update issue (flip ACs, add labels)
  6. Commit + journal
  7. Merge (L3) or open PR (L2)
  8. Ask “continue?” → loop or stop

Full deep-dive: warp-drive.md.

Run from any shell — no Claude session needed:

Terminal window
warp status # Phase, current chunk, recent activity
warp stop # Abort the loop from outside
warp config # Show _workflow settings (incl. session_merge)
warp help # All commands

Integration-branch streams (#268). Accumulate several requirements onto one branch and ship them once, instead of a merge per requirement:

Terminal window
warp session start integration/feature-x # create + check out the session branch
# ...run /warp-drive over the cluster; each requirement merges into the session branch...
warp session status # show resolved branch config
warp finalize --dry-run # preview the ship
warp finalize # L2: one consolidated PR / L3: rebase+merge to main
warp session end # clear the session branch (git branch left intact)

The merging phase switches to local-accumulate automatically when a session branch is set and _workflow.session_merge is local (the default); set it to pr to keep per-requirement PRs. See the warp-drive guide.

7.4 /what-next — discover work without committing

Section titled “7.4 /what-next — discover work without committing”

Reads project state and proposes the next sensible work item. Use it when you’re not sure where to pick up.

/what-next

Inside Claude — graceful stop with proper cleanup. Don’t kill the session with Ctrl-C; let the skill flush state cleanly.

When you’re away from the keyboard, RDB routes all decisions to Telegram via ask_remote/notify_remote.

/rdb on # Decisions go to Telegram
/rdb off # Back to terminal prompts
/rdb status # Current state

Going AFK? Saying “I’m stepping away” is treated as /rdb on automatically.

  • claude -a3 -rdb (or -a2 -rdb)
  • /warp-drive started
  • Phone has Telegram open
  • Laptop plugged in and won’t sleep
  • At least one req + approved issue exists
  • Warp-drive does 3 strikes on failed fixes before escalating.
  • Failures escalate to a Telegram prompt (RDB) or terminal (no RDB).
  • “Type ‘skip’” or “do whatever you think is best” are valid responses.
  • Repeated escalations create a todo-labeled issue for human follow-up.

7.9 Declarative loop primitive (generic “do X until Y”)

Section titled “7.9 Declarative loop primitive (generic “do X until Y”)”

Warp-drive is a loop hardcoded to the dev cycle. For any other iterate-until-done loop — fix-until-tests-pass, refactor-until-lint-clean, or “keep running this agent against this check until it passes” — use the declarative loop primitive (#424): a manifest (goal + agent + evaluator + stop_condition + guardrails) run by a single reusable runner.

Terminal window
node ~/.claude/scripts/loop/run.js ~/.claude/templates/loops/fix-until-tests-pass.json

Guardrails are mandatory (max_iterations at minimum) and breaches halt as blockable events, reusing warp-drive’s budget_exceeded semantics. Cost telemetry reuses the warp-drive token/cost model. Provision it as the skills/loop-primitive registry item. Full reference: loop-primitive.md.


cdfork fans out N parallel /warp-drive sessions, one per branch, in isolated git worktrees + tmux windows. Tmux + git are the state — no daemon, no DB. If the orchestrator dies, your worktrees and commits survive.

Full reference: cdfork.md.

Command Purpose
cdfork fork <branch>... Spawn one warp-drive per named branch
cdfork fork --from-issues [N] Auto-pick N approved requirements; fan out
cdfork status [--json] List worktrees + tmux + warp-drive state
cdfork drop <branch> [--force] Tear down a worktree + tmux window
cdfork drop --all [--force] Tear down every cdfork worktree for this repo
cdfork pair --contract <p> --backend <r> --frontend <r> --branch <n> Cross-repo contract-driven mode
cdfork-pair ... Standalone shape of cdfork pair
cdfork help Show command summary

For a repo at /path/to/<repo>/:

/path/to/<repo>.worktrees/<branch>/

Sibling, not nested — keeps Composer, Bundler, npm, etc. from getting confused.

8.3 When to use cdfork vs. a single warp-drive

Section titled “8.3 When to use cdfork vs. a single warp-drive”
Use cdfork when… Use single /warp-drive when…
Multiple independent issues are approved Single issue or tightly-coupled work
Work clusters don’t touch the same files Issues touch shared config/migrations
You want to maximize throughput while AFK Linear progression matters
You have CPU + RAM to spare Single-threaded resource constraint

8.4 What cdfork --from-issues actually does

Section titled “8.4 What cdfork --from-issues actually does”
  1. Runs gh issue list --label approved --label req (excluding serial-only)
  2. Picks the top N (default 3) by priority + age
  3. Derives a branch name per issue (e.g. req-42-add-auth)
  4. Spawns one worktree + tmux window + warp-drive per branch

Designed for headless splits where backend + frontend share a contract. Anchor use case: nanawall.com Drupal-headless migration.

Terminal window
cdfork pair \
--contract ~/contracts/api-spec.yaml \
--backend ~/Sites/nanawall-api \
--frontend ~/Sites/nanawall-web \
--branch feat/product-listing

Two worktrees, two tmux windows, both warp-drives anchored to the same contract path.

Tool Why Install
git Worktrees brew install git
tmux Window management brew install tmux (NOT installed by default)
claude Spawned in each window Claude Code CLI
gh --from-issues brew install gh
jq Status JSON, issue filtering brew install jq

Preflight runs before any worktree is touched and fails fast on missing deps.


What Command Label
Architecture decision /journal decision <name> decision
Lesson learned /journal lesson <name> lesson
Session writeup /session-summary or /journal session <name> session-summary
Bug report gh issue create --label bug bug
Human action item auto-created by warp-drive timeout todo

Think git fsck for project management. Examines ground truth (git log, file system, codebase) and reconciles all PM artifacts against it.

/rebob

Use it after long absences, before/after major refactors, or when state feels off.

9.3 /trace-mining — outer improvement loop

Section titled “9.3 /trace-mining — outer improvement loop”

Analyzes past session journals to extract failure patterns, identify recurring harness gaps, and propose targeted improvements.

/trace-mining

Output feeds back into BoB — surfacing missing skills, broken hooks, or workflow friction. Pair with gh issue list --label lesson to mine accumulated learnings.

9.4 Registry-only continuous-improvement commands

Section titled “9.4 Registry-only continuous-improvement commands”

Provision and use as needed (not universal — opt-in per project):

  • /research — Manage research projects (questions, sources, findings, decisions). Also available as a universal skill (research).
  • /retrospective — Standard / start-stop-continue / 4Ls retros.
  • /standup — Daily standup format.
  • /status — Status reports at quick / weekly / monthly cadence.

9.5 Automatic self-healing (warp-drive session end)

Section titled “9.5 Automatic self-healing (warp-drive session end)”

At session_ending, warp-drive runs scripts/warp-drive/trace-mine-session.sh to close the improvement loop without manual effort. Since #295 it mines the warp-drive state history, not the issues you filed:

  • What counts as a finding — genuine execution friction recorded by the state machine: tests_failed / merge_failed / push_failed events, retry_count, more than one coding↔testing cycle (coding_cycles), no_work, and phase stalls (longest inter-transition gap over max_phase_minutes). Each finding is tagged with an action bucket: coding reliability (root-cause), merge/process (config), harness/capability (stall), or process.
  • No friction → no issue. A clean session is skipped silently ({"skipped":true,...}) — the common case. This is the key difference from the old behavior, which always emitted an issue that merely re-listed the chunk reports/decisions filed during the session.
  • Context, not findings. Issues filed during the session (decision, risk, lesson, bug-deferred) and the session summary are listed under a Context section for cross-reference — they are no longer presented as findings.
  • When friction is found, the miner files a warp-drive-labelled issue on the BoB repo titled self-healing: session friction from <project> #<req>.

This complements the on-demand /trace-mining (§9.3): the automatic miner flags per-session friction; /trace-mining analyses patterns across many sessions.

9.6 Model tiering in multi-agent workflows

Section titled “9.6 Model tiering in multi-agent workflows”

When you orchestrate work with the Workflow tool (agent() / parallel() / pipeline()), make asymmetric model tiering the default: spend a cheap, fast model on wide exploration and reserve a strong model for selective judgment. This is a convention, not a new capability — agent(prompt, {model, effort}) already accepts per-call overrides. Source: the “Self-Improving Loop” external-validation lesson (#264) — cheap breadth, expensive judgment.

The convention.

Stage role Examples Default tier
Finder / explorer / sweep — wide, shallow, parallel, disposable find bugs, grep logs, enumerate call-sites, map a subsystem cheap: model: 'haiku' or low effort
Verify / judge / critic / synthesize — narrow, deep, decisive adversarially refute a finding, score competing designs, write the final answer strong: model: 'opus' (or omit to inherit) + high effort

Economic rationale. Finders run in bulk and most of what they surface is noise — paying premium per-token to generate candidates is wasteful. Judgment runs on the small filtered set where correctness actually matters, so that is where the strong model earns its cost. A pool of cheap finders feeding a few expensive verifiers gets most of the quality of an all-strong fleet at a fraction of the spend.

Inheritance caveat. When you pass no model/effort, the agent inherits the session model (the resolved main-loop model) and session effort — which is almost always the right default. Only override when you’re confident a different tier fits the stage: drop finders to haiku/low, lift the hardest verify/judge stages to high effort. Don’t set model “just because”; an unnecessary override is how you accidentally run a 200-agent sweep on the expensive tier.

Canonical example — find → verify with explicit per-stage tiers:

// Cheap, parallel finders sweep each dimension; each finding is then verified
// by an expensive, skeptical judge. The pipeline runs verify-as-soon-as-found.
const results = await pipeline(
DIMENSIONS,
// FIND (cheap breadth): wide net, low cost, tolerant of false positives
d => agent(d.prompt, {
label: `find:${d.key}`, phase: 'Find',
model: 'haiku', effort: 'low', // <-- cheap tier
schema: FINDINGS_SCHEMA,
}),
// VERIFY (expensive judgment): adversarially refute each candidate
review => parallel(review.findings.map(f => () =>
agent(`Adversarially verify — try to REFUTE: ${f.title}`, {
label: `verify:${f.file}`, phase: 'Verify',
model: 'opus', effort: 'high', // <-- strong tier
schema: VERDICT_SCHEMA,
}).then(v => ({ ...f, verdict: v }))
))
)
const confirmed = results.flat().filter(Boolean).filter(f => f.verdict?.isReal)

The same shape applies to judge panels (cheap candidate generation → strong scoring), loop-until-dry discovery (cheap finders → strong dedup/synthesis), and multi-modal sweeps (cheap per-modality search → strong completeness critic). Keep the breadth cheap; keep the gate strong.


Moved to reference — see Glossary.

Moved to reference — see Glossary.

Moved to reference — see Glossary.

Moved to reference — see Glossary.

Moved to reference — see Hooks Reference.

BOB_SOURCE/
├── skills/ # Universal skills (auto-loaded)
├── commands/ # Universal slash commands
├── agents/ # Universal subagents
├── runbooks/ # Universal runbooks
├── registry/
│ ├── skills/ # Opt-in skills
│ ├── commands/ # Opt-in commands
│ ├── agents/ # Opt-in agents
│ └── runbooks/ # Opt-in runbooks
├── provisions/ # Per-project manifests (one JSON per project)
├── hooks/ # All hooks; wired in settings.json
├── scripts/ # CLI scripts, helpers, engines
├── bin/ # PATH-friendly entrypoints
├── templates/ # Copied (not symlinked) into projects
├── schemas/ # JSON Schema for manifest, projects, settings
├── profiles/ # Permission profiles per automation level
├── docs/ # Guides (this file lives here)
├── tests/ # `make test` targets
├── claude-init.sh # cdi
├── claude-dashboard.sh # cdb
├── claude-promote.sh # cdp
├── claude-link.sh # cdl
├── settings.json # Default settings shipped to BOB_HOME
├── CLAUDE.md # Default project instructions
├── README.md
├── Makefile
└── bob-identity.md

A typical project has:

my-project/
├── .claude/ # Created by cdi — symlinks into BOB_HOME
│ ├── commands/ # Symlinks
│ ├── agents/ # Symlinks
│ ├── settings.json # Project-specific overrides (optional)
│ └── settings.local.json # Machine-specific, gitignored
├── CLAUDE.md # Project instructions (committed)
├── CLAUDE.local.md # Local notes (gitignored)
├── docs/
│ └── vision.md # The living vision doc
├── dev.json # Dev environment manifest
├── seed/ # Seed scripts + users.json
└── ...

Do not create these — they predate the GitHub Issues migration:

.claude/project-management/ ✗
.claude/requirements/ ✗
.claude/journal/decisions/ ✗ (use /journal decision)
.claude/journal/lessons/ ✗ (use /journal lesson)
.claude/journal/sessions/ ✗ (use /journal session)
REQ-*.md SOL-*.md BUG-*.md ✗
RISK-*.md INC-*.md CR-*.md ✗
UXR-*.md STATUS-*.md ✗
REQUIREMENTS-INDEX.md ✗
SOLUTIONS-INDEX.md ✗
backlog.md ✗
traceability-matrix.md ✗

15.4 BOB_HOME (~/.claude/) — runtime only

Section titled “15.4 BOB_HOME (~/.claude/) — runtime only”

Synced from BOB_SOURCE by deploy.sh. Don’t edit directly. Files protected from overwrite:

  • ~/.claude/settings.json
  • ~/.claude/settings.local.json
  • ~/.claude/CLAUDE.local.md

15.5 Documentation filename conventions (docs/)

Section titled “15.5 Documentation filename conventions (docs/)”

Files under docs/ follow one mechanical naming rule so the directory greps and globs predictably, the docs site renders stable URLs, and contributors (and warp-drive) never have to guess casing.

Rule Decision
Case lowercase only
Word separator - (kebab-case)
Character set [a-z0-9-] only — no underscores, spaces, accents, em-dashes
Extension .md for prose, .json for data. .txt / .markdown are not allowed
Date stamps ISO 8601 suffix: <topic>-YYYY-MM-DD.md (e.g. doc-audit-2026-05-07.md)
Acronyms lowercased — pm-cheatsheet, iac-audit, bob-identity
Subdirectories lowercase, plural where applicable: audits/, archive/, research/
Suffix patterns *-guide.md for “explain X”, *-reference.md for reference docs
Frontmatter title independent of the filename — the docs-site engine uses title for display, the slug for the URL

Reserved names (exempt): README.md, index.md, _index.md, CHANGELOG.md, CONTRIBUTING.md, LICENSE. These follow conventional uppercase and are skipped by the linter.

Canonical regex (basename minus extension): ^[a-z0-9]+(-[a-z0-9]+)*$ with extension in {md, json}.

Why:

  • Slug collapse — under flat serving PM-CHEATSHEET.md and pm-cheatsheet.md can produce the same URL (and engines like Starlight lowercase slugs); lowercasing eliminates the collision and keeps links engine-portable.
  • Case-insensitive filesystems — macOS APFS treats Foo.md and foo.md as the same file. A single casing rule avoids silent git mv no-ops and cross-machine drift. (When renaming, git mv -f through a temp name clears the no-op hurdle.)
  • Greppability — one rule means callers can link and search without second-guessing casing.

Not part of the convention: numbered ordering prefixes (01-foo.md) — use the docs-site engine’s nav-ordering config (e.g. Starlight’s sidebar.order frontmatter) instead; mixing the two is the worst outcome. There is no filename-length budget — long descriptive names like project-orchestration-handbook.md are fine.

Scope & enforcement: This convention covers docs/ (excluding docs/archive/**, which is frozen historical record). It is enforced two ways:

  • make check-doc-naming (script: scripts/checks/check-doc-naming.sh) — wired into make check; fails CI on any non-reserved docs/** file outside the rule.
  • The doc-keeper auditor emits a filename-violation drift category so violations also surface in /doc-audit reports.

The same lowercase-kebab rule is applied to the code-side item directories (agents/, registry/{skills,agents,commands}/, runbooks/, provisions/) by the sibling linter make check-filename-conventions (scripts/checks/check-filename-conventions.sh, #238-241), with framework-reserved carve-outs (SKILL.md, _default.json, …). Skill bundle assets (LICENSE.txt, *.pdf, scripts inside a skill dir) are not policed — only item/dir names are.

15.6 Test & inspection artifacts (.bob-artifacts/)

Section titled “15.6 Test & inspection artifacts (.bob-artifacts/)”

Ephemeral test/inspection output — Playwright screenshots, DOM snapshots, scratch captures — goes in a single per-project directory: .bob-artifacts/. Never the repo root or scattered /tmp paths (#253).

  • cdi idempotently adds .bob-artifacts/ and .playwright-mcp/ (the Playwright MCP default output dir) to the project’s root .gitignore, so these artifacts never get accidentally committed.
  • The webapp-testing skill writes screenshots there; verify/run flows should follow the same convention.
  • Backfill an existing project (or clean stray root screenshots) with scripts/clean-artifacts.sh <project> — idempotent: it relocates loose root-level screenshots into .bob-artifacts/ and ensures the .gitignore entries.

Symptom Run this
“Is BoB healthy?” make check
“Are my project’s symlinks ok?” cdb then cdb --check <project>
“What is provisioned in this project?” cdprov --status
“Does the manifest match reality?” cdprov --diff
“Why is warp-drive stuck?” warp status
“Is the dev env healthy?” bin/dev-health or /dev-up --check
“Hook script missing?” make check-hooks
“JSON config invalid?” make check-schemas
“Stale state across the system?” /rebob
“Lessons accumulating? Patterns?” /trace-mining
File Owner Notes
<project>/.warp-drive-state.json warp-drive engine Current chunk, phase, history
<project>/.autoloop-state.json (legacy) auto-loop Will be removed
~/.claude/settings.local.json machine _rdb.enabled lives here
Problem Fix
Hooks aren’t firing make check-hooks; verify ~/.claude/settings.json references existing scripts
Symlinks point to nowhere cdprov --refresh (re-link) or cdprov --prune (drop dangling/cross-machine; dry-run first); fleet-wide: make repair-fleet then make check-fleet (#303)
Warp-drive won’t start Check warp status; ensure at least one req + approved issue exists
Telegram silent (RDB on) Check ~/.claude/settings.local.json for _rdb.enabled: true; type something in terminal
/auto-loop did weird things Stop using /auto-loop — switch to /warp-drive
Got prompt to create REQ-NNNN.md Stop. That’s a regression. File a bug — work tracking is GitHub Issues
Tests stuck in fix loop Warp-drive 3-strikes-out automatically; let it escalate
cdfork worktree won’t drop cdfork drop <branch> --force; if that fails, manually git worktree prune
Deploy refuses to overwrite something That’s by design — settings.json, settings.local.json, CLAUDE.local.md are protected

Every BoB-managed project can be automatically versioned — conventional-commit-driven semver bumps, git tags, CHANGELOG.md, and GitHub Releases — provisioned from one source of truth rather than hand-copied CI (capability #275).

Tool: commit-and-tag-version (maintained fork of standard-version). release-please was considered and deferred (see the versioning guide).

Enable it — versioning is an opt-in manifest capability (like gh_project); it copies template files rather than symlinking:

// provisions/<project>.json
"versioning": { "enabled": true, "main_branch": "main" }
Terminal window
cdprov refresh # copies auto-release.yml + .versionrc.json + commitlint config,
# merges package.json (release script + devDependency)

The orchestrator recommends versioning by default for every project and picks a push trigger-path filter per project type (docroot/** for cms, the full source surface for framework, src/**+package.json for apps/libraries, no filter for research/mixed). An existing versioning block is always preserved on re-run, so enabled:false opt-outs and customizations survive.

A merge to the main branch then bumps the version, rewrites the changelog, tags vX.Y.Z, and publishes a GitHub Release — loop-guarded against the chore(release) commit. Conventional-commit enforcement ships as config (#278).

Heads-up: the workflow pushes the release commit/tag directly to the main branch via GITHUB_TOKEN; enabling branch protection without a bot exception breaks it. Full detail, bump rules, and the per-type path table: versioning.md.


  • bob-identity.md — What “BoB” means
  • prime-directive.md — IaC principles, approved patterns, anti-patterns
  • warp-drive.md — Full warp-drive deep-dive
  • cdfork.md — Full cdfork deep-dive
  • dev-lifecycle.md — Full dev env lifecycle reference (also covers the docs-site lifecycle, #153)
  • orchestrator.md — Registry metadata contract, recommendation engine, interview question bank (#157 family)
  • gh-projects.md — GitHub Projects v2 integration: the cdproj CLI, profiles, canonical fields, manifest opt-in, warp-drive/command integration, backfill (#210 family)
  • versioning.md — Automated semantic versioning: commit-and-tag-version, the versioning manifest block, per-project-type trigger paths, provisioning, branch-protection caveat (#275 family)
  • vision.md — BoB’s own vision document
  • project-management-reference.md — Under-the-hood architecture (note: predates GitHub Issues migration; due for its own audit)
  • branch-config.md — Branch detection / configuration
  • automation-behavior.md — How automation levels behave
  • backup-recovery.md — Backup & recovery
  • new-machine-setup.md — Setup on a fresh machine
  • verification-system.mdmake check deep-dive
  • token-monitoring.md — Token usage observability
  • pm-conventions.md — PM conventions (redirect stub; original archived 2026-05-07)
  • doc-audit-2026-05-07.md — Documentation audit methodology and gap list (use as a template for the next reconciliation cycle)
  • archive/ — Frozen historical PM docs (2026-02-pm/, 2026-05-pm/). Each archive subdir is dated and immutable; superseded docs leave a redirect stub at the original path. Excluded from the published docs site; browse on GitHub.

Last updated: 2026-05-07 — reconciled with doc audit (#144). Changelog: disambiguated cdr (Claude Disaster Recovery, not legacy reqs-index) in §13.1; surfaced live test counts and the doc-link sweep script in §3.7; added doc audit and archive subtree to §17 See Also.