Skip to content

Holding a Ritual

One review, held properly. In Coming Back to a Project you ran bob ritual due and saw rituals listed as due. This tutorial holds one. You give hello-links a monthly retrospective, watch it come due, and take one run from the empty issue to a closed record that the next run can compare against. Every command below comes from Why BoB Holds Rituals, which also explains why each step is shaped the way it is.

← Tutorials · docs home

Stop You will Where you check it
1 Declare a monthly retrospective for hello-links The manifest, and make check-rituals
2 See it come due bob ritual due
3 Open the run The run issue
4 Gather the evidence, and see what the farm does with it The evidence comment on the run
5 Start the session with its kit bob provision overlay status, and the run issue
6 Hold the session and file what it found The finding and lesson issues
7 Close the run The closed run issue, and bob ritual due
8 Record a portfolio decision for the project The manifest

Allow about an hour and a half. Most of it is Stop 6, the review itself.

  • Finish Your First Product with BoB and Coming Back to a Project. This tutorial reuses the hello-links project and the work those two left behind. A retrospective on a project with no history has nothing to look back on.
  • An operator repo. bob operator show must print one. Ritual schedules live in the project’s manifest there.
  • The laptop, not the farm. A ritual session is attended. The retrospective’s kit, incident, is allowed on every machine role, so Stop 5 is not refused on a laptop.
  • The issue numbers below are examples. The tutorial uses #20 for the run, #21 for the finding and #22 for the lesson. Use the numbers your tracker gives you.

Six words come up at every stop. Here they are in plain terms. The exact definitions, and the full list of rituals, are in the Rituals reference.

  • Ritual. A review that recurs on a schedule, such as a retrospective, a dependency audit or a security review. The names are a fixed list; you choose which ones a project holds and how often.
  • Cadence. How often it is due, written as a duration: P1M is one month after the last run, P3M three months. before-stable-release means before the next stable release instead of on a clock.
  • Run. One holding of a ritual. Each run is a GitHub issue labelled ritual-run, from the moment it is opened until it is closed with its outputs.
  • Evidence packet. The facts a run starts from, such as what closed, what is stuck and what it cost, gathered by collectors and posted as one comment on the run.
  • Kit. A named set of skills, commands and agents that a kind of session needs, loaded for that session only and removed afterwards. A retrospective uses the incident kit. A machine’s role can forbid a kit: the farm, which works unattended, forbids the ones that need a person.
  • Farm-eligible. The ritual’s evidence may be gathered by the farm overnight. The session itself never is: judging what the evidence means needs you.

One more idea explains the rest. Run history is derived, never declared. You never write down when a ritual last ran. BoB reads it from the newest closed run issue. Holding the ritual is the record, so the date cannot drift from what happened, and every machine sees the same history.


A ritual starts as one line in the project’s manifest. Find the operator repo, add the rituals list inside _meta in its provisions/hello-links.json, and run the gate:

Terminal window
bob operator show
{
"_meta": {
"project": "hello-links",
"rituals": [
{ "name": "retrospective", "cadence": "P1M", "why": "a small product that changes fast: look back every month" }
]
}
}
Terminal window
make -C ~/projects/bigbrain check-rituals

What you should see.

  • bob operator show prints the operator repo’s path and the rung that found it.
  • After the edit, provisions/hello-links.json still has its skills, commands and other lists. Only _meta gained rituals.
  • check-rituals prints check-rituals: 8 ritual(s) valid, N project manifest(s) declare rituals and exits 0. N is one more than before your edit.

What just happened. The gate checked your line against the ritual vocabulary: retrospective is a known name, P1M is a valid cadence, and the default kit, incident, is declared. Try a typo such as "cadence": "monthly" and run the gate again. It names the file and refuses the cadence. Put P1M back.

Commit the manifest change in the operator repo, as you would any other manifest edit.

Checkpoint. provisions/hello-links.json declares the retrospective, and make -C ~/projects/bigbrain check-rituals passes.

From the hello-links checkout:

Terminal window
bob ritual due

What you should see. A header with the counts, then one block for the project:

hello-links [declared]
runs from ritual-run issues in <you>/hello-links
DUE retrospective P1M never run [kit incident, farm evidence]

What just happened. [declared] means the schedule came from your manifest, not the liveness defaults. The retrospective has never run, so it is DUE now rather than a month from now. farm evidence means the farm may gather its evidence overnight (Stop 4). The run history came from the project’s issues, and there are none yet.

Checkpoint. bob ritual due lists retrospective as DUE, never run, with kit incident.

A run is an issue before it is a session:

Terminal window
bob ritual open retrospective --dry-run
bob ritual open retrospective

Read the --dry-run output first, then run the second line.

What you should see.

  • The dry run prints would file in <you>/hello-links: ritual: retrospective — hello-links (<today>), the labels ritual-run, ritual:retrospective, and the body.
  • The real call prints filed #20 — ritual: retrospective — hello-links (<today>) and the issue’s URL.
  • On GitHub, the issue body has a header table (project, held date, kit incident, cadence P1M), a Scope line, a Kit line (claude --kit incident), an empty Evidence placeholder, an empty Findings checklist, a Journal section and Delta vs previous run: first recorded run.

What just happened. The run exists before anyone has looked at anything, so the evidence and the session both have somewhere to land. Run the second line again: it is refused (exit 3) and names the open run. One ritual never has two open runs.

Checkpoint. Issue #20 is open with both labels, and a second bob ritual open retrospective names #20 instead of filing another.

Counting what happened is mechanical, so BoB does it before you sit down:

Terminal window
bob ritual prepare 20 --dry-run
bob ritual prepare 20

What you should see.

  • The dry run prints would post to the run, a tally, and the packet body: one section per collector (status-report, cost-churn, aged-issues, memory-audit). Each collector that could not run is listed after it as a gap line with its reason.
  • The real call prints posted the evidence packet on the run, with the comment’s URL.

What just happened. Each collector read the project without changing it: the issues closed since the last look, the cost and churn series, stuck and parked issues, and the memory audit. A collector that could not run is listed as a gap with its reason. It is never a failure. Run prepare again: the comment is replaced, not duplicated.

The farm does this for you overnight. Preview what its nightly pass would pick up for this project:

Terminal window
bob ritual prepare --due --dry-run

It prints a line such as would hello-links retrospective #20: a target that would reuse your open run. On a night when the ritual is due and no run is open, the farm opens one first. You sit down to a run that already has its evidence.

Checkpoint. #20 has exactly one evidence comment, and bob ritual prepare --due --dry-run names #20 as the run it would reuse.

Terminal window
bob ritual run retrospective --dry-run
bob ritual run retrospective
bob provision overlay status
claude

Read the dry run, run the second and third lines, then start Claude Code with the last one.

What you should see.

  • The dry run prints would resume #20 and kit: incident not applied (dry-run). It writes nothing.
  • The real call prints resumed #20, then kit: incident applied to your checkout, the evidence packet read back from the comment (one line per collector, with the number of gaps), previous run: none — this is the first recorded run, and the session brief: six numbered steps that tell Claude to lead the session, ending with the bob ritual close 20 line.
  • bob provision overlay status names the overlay as kit incident, stamped with the run, and lists its items, among them the /retrospective and /incident commands and the lessons-extractor and project-historian agents.

What just happened. The run command checked the kit against this machine’s role first. On a farm worker, a security or vision-planning kit would stop here with exit 3. Then it found the open run instead of opening a second one, and loaded the kit for this session only. claude --kit incident would load the same items, but only bob ritual run stamps them with the run, so that closing the run removes them.

Checkpoint. bob provision overlay status names kit incident and run #20, and Claude Code is open in hello-links with the kit’s commands available.

The deciding is the part only you can do. In the Claude Code session, ask Claude to hold the run on #20. The brief Stop 5 printed has Claude lead: it says what a retrospective is and what your part will be, reads the evidence itself, then brings you one recommended plan (what went well, what was slow, what should change) and one decision: do everything recommended, do part of it, or stop for now. Take your time; this is most of the hour.

Each thing you decide to act on becomes its own issue. In this run, the packet shows that the link-expiry requirement took three coding cycles, because the seed data had no expired link to test against. That is one finding (a requirement) and one lesson:

/requirement Seed data includes an expired link and a link that expires tomorrow. Found in retrospective #20.
/journal lesson Seed data must cover every lifecycle state a requirement adds, before the requirement is built

/retrospective knows it is inside this run because #20 is an open ritual:retrospective run issue. It writes no summary issue of its own, files each action item as a req, bug, task or todo, and links them on #20, the one record bob ritual close reads.

What you should see.

  • /requirement files issue #21, labelled req.
  • /journal lesson files issue #22, labelled lesson.

What just happened. A finding is work, so it goes where work goes: the queue. A lesson is knowledge, so it goes where knowledge is searched: the lesson label. Neither one is written into the run issue’s body by hand. The close links them.

Checkpoint. #21 (req) and #22 (lesson) exist, and each names #20.

Exit Claude Code. The weekly email is still waiting on its todo, which is a known item rather than a new finding, so it closes as no-action:

Terminal window
bob ritual close 20 --finding 21 --no-action "the weekly email waits on its own todo" --journal 22 --dry-run
bob ritual close 20 --finding 21 --no-action "the weekly email waits on its own todo" --journal 22
bob provision overlay status
bob ritual due

What you should see.

  • The dry run prints would close the run with 1 finding(s) filed, 1 no-action; 1 journal link(s), a delta vs nothing — first recorded run line with #21 as new, and the closed body. It writes nothing.
  • The real call prints the same lines starting closed, and kit overlay restored.
  • bob provision overlay status reports no overlay.
  • bob ritual due now shows the retrospective as UPCOMING, due a month from today, with last run #20.

What just happened. The close checked that every finding links a bug, req, task, security or todo issue or has a reason, and that every journal link is a lesson or a decision. Try the dry run with --journal 21 in place of --journal 22: it is refused, because #21 is a requirement, not a lesson, and the run stays open. The real close then wrote the sections, closed the issue and removed the kit. Next month’s run will compare its findings with these: resolved, recurring or new.

Checkpoint. #20 is closed, its body links #21 and #22, the overlay is gone, and bob ritual due dates the next retrospective from today.

Once a quarter, the portfolio review asks of every project at once whether it is still worth its attention: invest, maintain, park or archive. It is held on bigbrain, not in hello-links. You do not need to hold one to practise its last step, which writes a project’s status into its manifest. A changed status also needs its reason on record, as a decision issue. From the hello-links checkout:

/journal decision hello-links moves from maintain to invest: it is the product we are growing this quarter
Terminal window
bob ritual decide hello-links park
bob ritual decide hello-links invest --apply

File the decision in Claude Code first. Then run the two shell lines. The first only reports; the second writes.

What you should see.

  • /journal decision files an issue labelled decision.
  • bob ritual decide hello-links park prints would decide hello-links: maintain → park, then _meta.rituals: the dormant default (dependency-audit P6M, docs-review P3M) — replaces 1 declared ritual(s): retrospective P1M, then nothing written — pass --apply.
  • bob ritual decide hello-links invest --apply prints decided hello-links: maintain → invest, and a reminder to commit the manifest.
  • provisions/hello-links.json in the operator repo now has "portfolio": "invest" in _meta, and still declares the retrospective.

What just happened. A project with no declared status is maintain. The park report shows what parking would cost: the monthly retrospective would be replaced by the dormant schedule, a dependency audit every six months and a docs review every three, and the farm would stop preparing its evidence. archive would also set _meta.active: false, and an archived project has no rituals at all. You chose invest, which keeps the schedule you declared. Commit the manifest change in the operator repo. In a real portfolio review, the run’s close checks that the manifest declares what the run decided, and that the decision issue is linked from its row.

Checkpoint. provisions/hello-links.json declares "portfolio": "invest" and the retrospective, and the decision issue exists with the decision label.


You held a ritual from start to finish. It was declared in the manifest, dated from its own issue, prepared before you sat down, held with its kit and closed with every output linked. Then you recorded where the project stands in the portfolio, which decides which rituals it keeps. Nothing about it lives only in the conversation. Next month, bob ritual due shows it due again, the farm gathers its evidence, and the delta tells you whether this month’s finding stayed fixed.

Next tutorial: A Night on the Farm — Hand one project to the farm for a night and read what it did in the morning: what the farm is, making work farm-eligible, reaching the farm over the tailnet, one tick watched from a laptop, and the morning read.