Appearance
BoB — Big ol' Brain
BoB (Big ol' Brain) is the name for this global Claude Code tooling framework. See bob-identity.md for the full identity definition.
The source repo (BOB_SOURCE, default ~/projects/bigbrain) is the single source of truth for all BoB tooling. It is deployed to ~/.claude/ (BOB_HOME) where Claude Code reads it at runtime.
For the encyclopedic guide, see docs/project-orchestration-handbook.md. The docs are organized by Diátaxis mode — start at docs/index.md.
Architecture
BOB_SOURCE (~/projects/bigbrain) <- Source of truth (git repo)
├── skills/ <- 9 universal skills (auto-loaded globally — the #1132 minimal core)
├── commands/ <- 19 universal commands (symlinked into projects by cdi)
├── agents/ <- 3 universal agents (symlinked into projects by cdi)
├── runbooks/ <- Universal runbooks (procedural ops guides)
├── hooks/ <- 30 hook scripts; 23 wired by settings.json (7 unwired — see hooks-reference.md)
├── registry/ <- NOT auto-loaded — provisioned per-project
│ ├── skills/ <- 57 domain skills (cloudflare-dev, graph-orchestration, etc.)
│ ├── commands/ <- 29 PM/workflow commands (research, deploy, retrospective, etc.)
│ ├── agents/ <- 22 specialist agents (code-reviewer, qa-strategist, etc.)
│ └── runbooks/ <- Domain-specific runbooks
├── provisions/ <- Per-project manifests (one JSON per project)
├── machines.json <- Machine fleet manifest (registry of machines BoB runs on; resolver: scripts/fleet/machine.js) — not to be confused with the **Fleet** project (`~/projects/fleet`), the host-environment layer beneath BoB
├── scripts/ <- CLI scripts, helpers, state-machine engine, dev-lifecycle, fleet/
├── bin/ <- PATH-friendly entrypoints (cdi, cdb, cdp, cdl, cdg, cds, cdprov, warp, cdfork, cdfork-pair, dev-up, dev-health, cdproj, bob, bob-ready, bob-reap, forge-health, forge-queue) + gh (forge-health PATH shim) + bob-shell.zsh (sourceable shell integration)
├── templates/ <- dev.json, seed/, hooks/ — copied (not symlinked) to projects
├── schemas/ <- JSON Schema for manifest, projects, settings
├── profiles/ <- Permission profiles per automation level (supervised, trusted, autonomous)
├── docs/ <- Guides (handbook lives here)
├── Makefile <- IaC verification entry point (make check / test / ci)
└── tests/ <- Schema validator + state-machine + integration tests
BOB_HOME (~/.claude/) <- Runtime directory (deployed)
├── skills/, scripts/, hooks/, etc. <- Synced from BOB_SOURCE by deploy.sh
├── settings.json <- Machine-specific (protected by deploy; its .hooks block is reconciled from source, #1918)
├── settings.local.json <- Machine-specific (protected; holds _automation, _rdb)
└── CLAUDE.md <- Deployed copy (mirrored from source by deploy.sh, #1911)Prime Directive: Everything BoB manages must be declarative, version-controlled, reproducible, idempotent, and observable — with every piece of state owned by exactly one source of truth. See prime-directive.md.
| Type | Source (BOB_SOURCE) | Runtime (BOB_HOME) | Loading |
|---|---|---|---|
| Universal skills | skills/ | Synced by deploy.sh | Auto-loaded globally |
| Universal commands | commands/ | Symlinked by cdi from BOB_SOURCE | Per-project symlinks |
| Universal agents | agents/ | Symlinked by cdi from BOB_SOURCE | Per-project symlinks |
| Universal runbooks | runbooks/ | Synced by deploy.sh | Referenced by absolute path; published as its own docs-site section |
| Registry items | registry/ | Synced by deploy.sh | Provisioned per-project via manifest |
| Hooks | hooks/ | Synced by deploy.sh | Referenced in settings.json |
| Scripts | scripts/ | Synced by deploy.sh | Referenced by absolute path |
| Templates | templates/ | Synced by deploy.sh | Copied to projects, then customized |
Authoring a new skill, command, or agent? See the Authoring a Skill how-to — it covers choosing the right surface (skill vs command vs agent), registering it, provisioning it (
cdprov//provision), promoting it (cdp), and the pre-add validation checklist. Build mechanics live in theskill-creatorandagent-builderskills.
Provisioning: Each project has a manifest at provisions/<project>.json declaring which registry items it needs. Run cdprov or /provision to manage. Universal items are always present; registry items are only loaded when provisioned.
BOB_SOURCE resolution (#1220). provision.sh resolves the source repo via scripts/lib/bob-source-resolve.sh: explicit $BOB_SOURCE env → the script's own checkout (self-relative, requires .git + provisions/) → the checked default ~/projects/bigbrain → a flagged BOB_HOME fallback. Manifests are read from the resolved source, and manifest writes (--init, --init --auto, add/remove apply, interview) are refused with an explicit error when only the BOB_HOME fallback resolved — declared state can never silently land in the deploy target. The #785 staged route resolves through the same lib (_cb_root in config-branch.sh), so staged edits find the source checkout without an exported BOB_SOURCE; its BOB_HOME last resort is still refused by the #787 carve-out.
Single-item fast path (#1478). A single cdprov add/remove <type> <name> of a registry item is mechanical and schema-validated, so at automation Level 2+ the staged review PR is auto-merged instead of waiting on a human: the PR is labelled config-fastpath (audit trail preserved), squash-merged, and the apply steps are chained — BOB_SOURCE fast-forwards, deploy.sh syncs BOB_HOME, cdprov refresh projects the links — so a switch flip feels like one. Guards: the PR must change exactly provisions/<project>.json with a delta of exactly one item across the four item arrays, schema-valid on both sides; any miss (including #791-accumulated multi-item PRs) leaves the PR open for normal review. Level 1 keeps today's PR-for-human flow; BOB_FASTPATH=0 opts out. A failed chained step names itself (MERGE / PULL / DEPLOY / REFRESH) and prints the exact resume command — a landed merge is never rolled back.
Canonical link target (#1475). Registry symlinks are created and compared against LINK_ROOT = ${BOB_HOME:-~/.claude}/registry — the deployed registry — never the source checkout, so cdprov refresh converges to identical link targets regardless of how BOB_SOURCE resolved for the invocation (decision #1484). Only manifest reads/writes ride the #1220 resolution above. An item merged to source but not yet deployed reports "run deploy.sh" rather than linking into the checkout, and any retarget of existing links is reported explicitly ([retarget] per item + summary count), never silent.
Authored vs. derived in consuming repos (#1479). Commit what is authored (CLAUDE.md, dev.json, seed/, .claude/settings.json, real-file tooling); gitignore what is provisioned. cdprov maintains a managed ignore block listing every manifest-derived symlink path (plus settings.local.json), rebuilt on each provisioning write. Placement via _meta.ignore_placement (.gitignore default, .git/info/exclude for no-fingerprint repos); _meta.track_provisioned: true opts out. Drift detection lives in cdprov status ([unlinked]) and the fleet snapshot (unlinked_declared); fresh clones materialize links via cdi + cdprov refresh.
Global-aware provisioning (#412). Project provisioning reads the current machine's resolved global manifest (#414) and is aware of what BOB_HOME already provides: an item that is already global is de-duped (not double-provisioned into the project), and a registry item whose name collides with a global item but diverges in definition is reported as a conflict with a resolution hint (it is still linked so the project isn't silently broken). cdprov status / cdprov --diff report the global-vs-project overlap.
BOB_HOME as a declared surface (#411). ~/.claude (BOB_HOME) is itself a declared, version-controlled surface: provisions/_bob-home.json lists its global skillset. cdprov recognises BOB_HOME via scripts/lib/bob-home-detect.sh and routes to a read-only verify path (reports declared-vs-present items) — it never symlinks registry items into a nested .claude/, never inverts deployed copies, and never touches the protected machine-specific files (settings.json, settings.local.json, CLAUDE.local.md). BOB_HOME stays a deploy target; deploy.sh remains the sync mechanism.
Cross-machine audit (#415). scripts/fleet/audit.js audits any project on any fleet machine from any other, over Tailscale. Two transports: audit.js snapshot publishes this machine's project/provision/health condition to $BOB_FLEET_SNAPSHOTS (default ~/.claude/fleet/snapshots/<id>.json; point it at a synced folder to share); audit.js pull <id|tailscale-name> runs the audit on a remote machine over Tailscale SSH (default the machine-readable snapshot, --cmd to run cdb/rebob/cdprov remotely). audit.js view aggregates live + last-known-cached state across the fleet, marking staleness and unreachable targets. Each snapshot also carries per-project harness_defects: {open, recurrences, unreported, fingerprints[], issues[]} read from the project's warp-drive state file (no forge call), rolled up per machine in summary.harness_defects and fleet-wide by view as a "Harness defects" table — distinct fingerprints, recurrences, unreported count, affected projects (#1838). Optional host layer (#1871, #1925): when this machine's machines.json entry declares host_provider: {id, command} (Fleet on the laptops, thefarm on farm-01 — declared, never discovered from PATH; $BOB_FLEET_HOST_PROVIDER overrides, empty opts out), the snapshot runs <command> status --json and consumes the result by contract — host-status/1 (schemas/host-status.schema.json, owned by bigbrain, deployed to BOB_HOME/schemas/, validated by producers with scripts/fleet/host-status-validate.js; fleet-status/1 is a profile of it). Provider-defined sections land in host.sections summarised to {ok, drift} (na: true = not measured), Fleet's five stay addressable as host.<name>, and view rolls them up as a "Host drift" table with columns from the union of reported sections plus PROVIDER. No provider means no host key; a declared provider that is missing / fails / times out (BOB_FLEET_HOST_TIMEOUT_MS, default 20000) is host.error, never a failed snapshot, and summary.host_drift (#1921) is carried either way. The document wins over the exit code (exit 3 = drift with a full document; verdict: error surfaces its error). Ownership seam: bob-identity.md. Prerequisite for inbound audits: a machine must accept SSH — macOS has Remote Login off by default, so farm→Mac pulls require enabling it on the Mac.
Dev/test/deploy readiness (#446). Each snapshot also grades every managed project's promotion readiness via scripts/fleet/readiness.js — a static, side-effect-free probe that reads declared config (dev.json, package.json, wrangler.toml, CI workflows, provisioned skills) and never executes dev-up or a deploy (an audit must stay cheap). For each project it reports the detected stack, the deploy path (cf / external / none), the current implicit promotion behavior (ci-on-push / manual / none), and grades the dev, test, and deploy stages as working / partial / broken / n-a (n-a — legitimately absent, e.g. a CLI repo has no dev server — is distinct from broken). audit.js view rolls these up per-machine and fleet-wide (working/applicable, broken flagged) in both the human table and --json.
Per-machine resolution (#414). The BOB_HOME verify path identifies the current machine via scripts/fleet/machine.js whoami (#413's resolver) and selects the most-specific global manifest — _bob-home.<machine-id>.json → _bob-home.<role>.json → _bob-home.json (base). cdprov --diff against ~/.claude shows the convergence delta for this machine (would-add for declared-but-missing, would-remove for present-but-undeclared); it is deterministic and idempotent, and deploy.sh applies the actual sync.
Orchestrator (#157 family). Registry items declare orchestrator metadata in their frontmatter (applies_to.stacks, applies_to.project_types, recommended_for, category, default, required_with). The recommendation engine at scripts/orchestrator/recommend.js reads that metadata and produces a manifest from (stack, project type, capabilities) — supplied by the interview, or inferred from docs/vision.md + README + code by infer-profile.js (#1877/#1878; precedence: interview > code > vision for stack/type, the vision contributes capabilities; every field carries file:line evidence). explain.js gives each recommended item a why: line and flags unsupported manifest items as would-remove — report-only (#1879); cdprov reconcile applies the delta through the staged-PR / fast-path route (#1880); /vision and /groom nudge when the vision implies an unprovisioned item (#1881). When the user asks "what should I provision?" or "is X applicable to this project?" — that's the orchestrator's question. Full reference: docs/orchestrator-guide.md, consolidated in its Inference from vision and code section (#1873).
Deploying: Run scripts/deploy.sh to sync BOB_SOURCE → BOB_HOME. Use --dry-run to preview, --first-run on initial setup. Machine-specific files (settings.json, settings.local.json, CLAUDE.local.md) are never overwritten. The one reconciled section inside a protected file is settings.json's .hooks block (#1918): source-declared hook wiring converges on every deploy via scripts/fleet/settings-hooks-reconcile.js — backup first, every change named, machine-specific keys untouched, intentional local hooks kept under _hooks_local, undeclared hooks reported but never pruned. See hooks-reference.md.
CLI
| Command | Purpose |
|---|---|
cdi | Initialize a project with BoB tooling; when no manifest exists it offers one-shot auto-provisioning (cdprov --init --auto) — interactive prompt, or the --auto-provision flag for scripted runs (#1161) |
cdb | Dashboard — view tooling and project symlink status; a project whose warp-drive state records hand-compensated automatic behaviour shows harness-defects: N open (M recurrences) (#1838); a project graded by bob ready shows its last ready: READY / NOT READY (blockers) verdict (#1922) |
cdp | Promote a local item to the global source |
cdl | Link a global item into a project |
cdprov | Provision a project from its manifest (add / remove / status / diff / refresh / init; init --auto — one-shot detect→write→refresh via the orchestrator engine, no prompts, #506; --init infers the profile from docs/vision.md + code by default and feeds recommend.js --profile, --no-infer = stack-only, #1878; output is explainable — a why: line per item from the evidence, and unsupported manifest items surfaced as would-remove but never removed by a provisioning write; diff --json emits the explain.js document, #1879; reconcile [--apply] [--allow-remove] (alias --diff --infer) re-infers and applies the would-add/would-remove delta through the same staged-PR / fast-path route — dry run by default, idempotent, removals never applied without --allow-remove, #1880). Single-item add/remove at automation L2+ fast-paths end-to-end — auto-merged config-fastpath PR + chained deploy/refresh (#1478) |
cdproj | Provision/reconcile the project's linked GitHub Project (v2) from a template (init / update / status / reset / item / backfill). See gh-projects.md. |
cdg | Generate a project dashboard |
cds | Dashboard server (auto-port per project) |
cdfork | Fan out parallel /warp-drive sessions into git worktrees + tmux windows. See cdfork.md. |
cdfork-pair | Cross-repo contract-driven parallel mode |
swarm | Run the full agent-swarm loop as one command (decompose → approve → capped dispatch → gate → integrate → summary). Composes #577–#581. See swarm-decompose.md. |
warp | Observe / control warp-drive from a regular terminal (warp status, warp stop, warp config; warp viz opens the live session graph page in the browser, #1552). Integration-branch streams: warp session start/end/status + warp finalize (#268). |
dev-up / dev-health | Run /dev-up lifecycle / health probe from a regular terminal |
bob-reap | Reap regenerable working-tree residue per the project's reap.json (dry-run default, --apply to delete; keep-list + liveness guards). See bob-reap.md. |
forge-health | Report forge availability, classified from real gh call outcomes (operational / degraded / unreachable / unknown). Exit code is the answer (0/3/4/5). Fed by the bin/gh PATH shim, which classifies every invocation transparently, serves issue reads from a durable per-project cache when the API is degraded (#1749), and spools undeliverable issue mutations to a write-ahead queue that replays on recovery (#1750). See forge-health.md. |
bob ready | Converge a project to warp-drive-ready on any machine, idempotently and with no prompts: host check → cdi -y → cdprov refresh (or --init --auto when no manifest exists) → bootstrap-labels.sh → port band → dev.json/checks.json validation, ending READY / NOT READY with the fix per blocker; exit 0/1, --dry-run, --json = project-ready/1. The last verdict persists to .claude/.project-ready.json, carried by the fleet snapshot (project_ready) and shown by cdb (#1922). Also bin/bob-ready and make ready ARGS=<dir>. See bob-ready.md. |
bob preflight | The warp-drive preflight gate (#1923) as a command: bob doctor + bob ready --dry-run folded into one warp-preflight/1 verdict. Non-mutating; --converge applies bob ready first, then re-checks. A failure files (or bumps, by fingerprint) one todo naming each fix; exit 0 pass · 1 fail · 3 engine error (fails closed). /warp-drive runs it as its preflight phase (engine-fired, blocked on failure, cheap host re-check at every chunk/segment boundary) and cdfork fork --from-issues runs it once before fanning out. See warp-drive.md. |
bob doctor | Is this machine's BOB_HOME what deploy.sh would produce? Grades every deploy-managed surface (list derived from deploy.sh itself), every symlink under BOB_HOME + the project's .claude/ (dangling / foreign-home targets fail), the toolchain (node/jq/gh, forge shim first on PATH, bob-shell.zsh guard) and settings hook convergence — exit 0/1/2, --json = bob-host-drift/1. Same engine as make check-host (in make check, CI-skipped) and the fleet snapshot's summary.host_drift / view "BOB_HOME drift" table (#1921). See verification-system.md. |
forge-queue | Inspect and drain the durable write-ahead queue of issue mutations the forge could not take (status / list / show / resolve / replay; replay is dry-run default, --apply delivers). Filled by the same bin/gh shim, drained automatically on the first successful call after a recovery (#1750). See forge-health.md. |
bob-mirror | Reconcile and publish to each repo's declared second git host (resolve / reconcile / publish / status; dry-run default). Topology lives in mirrors.json. See mirror-remote.md. |
claude (shell wrapper) | Intercepts -a1 / -a2 / -a3 (automation level) and -rdb (Telegram), exec's the real claude CLI. Shipped as bin/bob-shell.zsh, sourced by one guarded .zshrc line (#1195) |
Verification (Makefile)
bash
make check # deps + schemas + symlinks + hooks + provisions + abs-paths (#1924) + host
make test # state-machine + schema-validator + integration tests
make ci # check + test (what GitHub Actions runs)
make help # full target listCRITICAL: Hooks Receive JSON via stdin
There are NO magic variable substitutions. Hooks receive ALL data via stdin as JSON.
bash
# RIGHT — Read JSON from stdin:
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')| Hook Type | Extract Field |
|---|---|
| Bash PreToolUse | tool_input.command |
| Edit/Write PreToolUse | tool_input.file_path |
| Bash PostToolUse | tool_input.command, tool_response (object = success, Error: Exit code N string = failure — no exit code field; #1831) |
Requires jq. Template: ~/.claude/templates/hooks/command-hook.sh. Full hook table: Hooks Reference. Test fixtures for hook payloads are captured from session transcripts (tests/fixtures/hooks/), never authored from memory — a hook that passes against an invented shape can be dead in a live session (#1831).
Temporal Accuracy (Timelord)
All PM commands must verify dates via ~/.claude/skills/timelord/scripts/now.sh before writing. Never trust memory for dates — session context can become stale across midnight or long sessions.
Date formats: Files: YYYY-MM-DD, Prose: human-readable, Timestamps: ISO 8601. Week convention: ISO (Monday=1).
Work Tracking
All work is tracked via GitHub Issues on each project's repo. No local PM files or indexes.
Do not create REQ-*.md, SOL-*.md, BUG-*.md, RISK-*.md, or any PM document files. Do not create REQUIREMENTS-INDEX.md, SOLUTIONS-INDEX.md, backlog.md, or traceability-matrix.md. The full forbidden-pattern list is in handbook §15.3.
Product Hierarchy
Vision & Strategy (docs/vision.md) /vision — living doc: why, who, where
└── Business case (label: business-case) /business-case — justify investment (above capability)
└── Capability (label: cap) /capability — feature spec, user stories
└── Requirement (label: req) /requirement — acceptance criteria, testable work
└── Warp-drive chunks automatic — individual commits
Use case (label: use-case) /use-case — a scenario; decomposes via "Realizes #NN"
└── → Capability (broad) or Requirement (narrow)| Level | Format | Command | Contains |
|---|---|---|---|
| Vision | docs/vision.md | /vision | Product vision, strategy, principles, non-goals, roadmap |
| 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 via Realizes #NN |
| Reporting | GitHub Issue | /journal | Decisions, lessons, session summaries |
| Bug | GitHub Issue (bug) | gh issue create --label bug | Bug reports |
| TODO | GitHub Issue (todo) | auto-created by warp-drive timeout | Human action items; add the completed label to signal the action is done (canonical done-signal — see TODO lifecycle below) |
The vision doc is a living document, not an issue — it doesn't get "closed." Capabilities trace back to the vision. Requirements link to their parent capability via Part of #NN in the Notes section. Capabilities track child requirements as a checkbox list. A business case (business-case) sits above capability — it justifies investment, and the capabilities realizing its recommended option link back via Part of #NN. A use case (use-case) captures a concrete scenario and decomposes into a capability (broad) or requirement(s) (narrow), each realizing issue linking back via Realizes #NN.
Priority labels: p1-critical / p2-high / p3-medium / p4-low
Workflow: cap + approved → ready to break into requirements. req + approved → picked up by /warp-drive.
TODO lifecycle (completed done-signal): A todo issue is a human action item an agent hands back when it hits a human-only blocker. The completed label is the canonical done-signal: adding completed to a todo means the human performed the action, so downstream tooling (warp-drive / groom / /what-next) may resume the work the todo was gating — no re-prompt needed. A todo closed without completed means the action was cancelled or became moot — downstream tooling must not resume the gated work. Closing alone is therefore never a resume signal; only the completed label is. The standard label set (including completed) is bootstrapped into every repo via scripts/bootstrap-labels.sh (the label-bootstrap path cdi/project-init runs), so new projects start with the full set.
Autonomous Development Workflow
When the user asks "what next?", "what should we work on?", or similar — check GitHub Issues via gh issue list --label approved on the relevant repo (or run /what-next).
When the user asks for a status report or is returning to a project after time away — run /what-next --report (alias: /status): an on-demand standup that prepends a backward-looking catch-up (recent activity, capability status, a data-derived health line) to the same ranked next-work list. Terminal-only by default; --file (or /status --file) additionally files the report as a status-report-labelled GitHub Issue. Never auto-filed, no local files.
At automation Level 2/3, the /warp-drive command orchestrates the full cycle: work discovery → code → document → test → commit → report → merge/PR → continue. Only prompt for project decisions (architecture, ambiguity, new deps, scope expansion).
For parallel work clusters across a repo, use cdfork (or the /cdfork slash command) to fan out N warp-drive sessions into isolated git worktrees + tmux windows. Subcommands: cdfork fork <branches...>, cdfork fork --from-issues [N], cdfork status, cdfork drop <branch>, cdfork pair for cross-repo contract-driven mode. Pinch points (config sync, lockfiles, migrations, compiled assets, deploy) must NOT be fanned out — label such issues serial-only so --from-issues excludes them.
See warp-drive.md and cdfork.md for the full references.
Dev Environment Lifecycle (IaC)
Every project can declare its dev environment in a dev.json manifest at the project root. The /dev-up command (and bin/dev-up from a regular terminal) reads this and orchestrates: start server → run migrations → seed data → provision test users → health check → report URL.
On-demand: Run /dev-up anytime to bring a project's dev environment to fully testable state.
Warp-drive integration: When dev.json exists, warp-drive automatically calls dev-up before the first chunk, verifies health between chunks, and auto-recovers on failure. Dev health failure is a blockable event.
Seed data convention: Projects use a seed/ directory with idempotent scripts. Seed data must cover ALL lifecycle states the domain defines (not just fresh records). New features include seed data in the same commit.
Standardized test users: seed/users.json defines test users provisioned via pluggable auth adapters (d1, sqlite, supabase, script, custom). The superuser (admin@test.local / admin123) is consistent across all projects.
See dev-lifecycle.md for the full reference.
Remote Decision Bridge
Toggle RDB mode via /rdb on or the -rdb startup flag. When RDB is enabled (_rdb.enabled: true in settings.local.json), use ask_remote for ALL decisions — never fall back to AskUserQuestion. When the user says they're stepping away, going AFK, or going remote, treat that as /rdb on. Use notify_remote for status updates during autonomous work. /rdb off switches back to terminal prompts.
Reporting (GitHub Issues)
| Type | Label | Created By |
|---|---|---|
| decision | decision | /journal decision or warp-drive reporting |
| lesson | lesson | /journal lesson or warp-drive reporting |
| session | session-summary | /session-summary or warp-drive session end |
| status report | status-report | /what-next --report --file (or /status --file) — on-demand point-in-time snapshot requested by a human, never auto-filed |
Memory Conventions
These conventions refine the harness's file-based memory behavior. The default is to overwrite a memory file in place when a fact changes. That is correct for project and reference memories (the current state is all that matters), but destructive for feedback and user (preference) memories, where why and when a preference changed is itself worth keeping.
Archive-on-supersede (mandatory for feedback and user memories). When the value of a feedback or user-preference memory changes, do not overwrite the prior value silently. Instead:
- Write the new value as the memory body, as usual.
- Preserve the prior value under a
## Historyblock at the end of the file, as a dated, superseded entry. - Stamp the change with today's ISO date (sourced via timelord — never from memory).
This keeps the episodic evolution of a preference legible: a returning session can see not just what the preference is, but what it was and when it changed.
## History format
Append (newest first) one bullet per supersede to a ## History section:
markdown
## History
- **YYYY-MM-DD** — Superseded. Prior value: "<the previous value, verbatim or summarized>". Reason: <one line on why it changed>.project / reference memories may overwrite in place and do not need a ## History block (though they may use one if the change history is genuinely useful).
The most recent ## History date counts as a memory's last-touched date for /memory-audit — a recently-superseded memory is fresh, not stale, even if the file mtime is older (e.g. after a deploy that rewrote mtimes).
Workaround provenance (defect: tag, #1837)
A feedback or project memory that describes a workaround for a BoB defect — "the hook didn't fire, advance by hand", "do it manually until X works" — is provisional by nature: it must expire when the bug is fixed, or the project keeps applying the workaround as a habit. Tag it with the defect it compensates for, as a frontmatter field:
markdown
---
name: warp-drive-commit-pitfalls
description: committing → reporting did not auto-advance
defect: paulirv/bigbrain#1830
metadata:
type: feedback
---defect: <owner>/<repo>#<n> (top-level, or under metadata:) names the tracking issue. /memory-audit resolves each tagged issue through the gh shim (cached per project; an unreachable forge counts as open) and:
- flags a tagged memory whose defect is closed as
workaround-stale— stale: verify the fix, then delete the memory (or drop the workaround from it); - flags an untagged
feedback/projectmemory whose prose reads as a workaround ("didn't fire", "do it manually", "advance by hand") asuntagged-workaround— file the bug if none exists, then tag the memory.
When the fix lands, delete the workaround memory (or record the retirement under ## History) rather than leaving a rule that no longer holds. The same tag drives loop-note retirement — see Workaround provenance in the loop-memory reference.
Worked example
A user previously preferred terse commit bodies, then changed their mind. The memory is not overwritten destructively — the prior preference is archived with the date it changed:
Before (feedback_commit_verbosity.md):
markdown
---
name: commit-verbosity
description: how detailed commit bodies should be
metadata:
type: feedback
---
Keep commit bodies terse — a one-line subject is usually enough; skip the body unless the change is subtle.
**Why:** The user reviews commits on mobile and finds long bodies noisy.
**How to apply:** Default to subject-only commits; add a body only for non-obvious changes.After the preference flips to detailed bodies (changed 2026-06-19):
markdown
---
name: commit-verbosity
description: how detailed commit bodies should be
metadata:
type: feedback
---
Write descriptive commit bodies — explain the *why* and the trade-offs, not just the *what*. A bare subject line is not enough for non-trivial changes.
**Why:** The user now relies on `git log` for project history and wants the reasoning captured at commit time.
**How to apply:** Default to a subject plus a body that explains motivation and any alternatives considered.
## History
- **2026-06-19** — Superseded. Prior value: "Keep commit bodies terse — subject-only unless the change is subtle." Reason: user shifted to using `git log` as the durable project record.