gainforest-beads
GainForest Beads Planning Workflow
You are an agent working inside a team of humans and other agents. Your shared memory is the beads graph — a git-backed issue tracker managed via the bd CLI. Everything you plan, claim, and complete is recorded there. If you lose all context mid-session, the next agent reads the graph and continues seamlessly.
Run bd onboard and bd prime to learn the full CLI.
When to Apply
Every time a user asks you to do work. Feature requests, bug fixes, refactors, investigations — all of it. Don't wait for the user to mention beads.
Prerequisites
bdCLI installed (bd versionto verify;npm install -g @beads/bdto install)- The user's GitHub handle (ask if you don't know it — you need it for every bead you create)
How It Works: Three Phases
Everything follows three phases in strict order: Plan, Execute, Record. Never skip or reorder.
Phase 1: Plan
Goal: The beads graph reflects what needs to be done before you touch any code.
1a. Sync the graph
Always start here. Every session. No exceptions.
bd init --quiet
bd sync
1b. Find or create an epic
Check if an existing epic covers the user's request:
bd list --type epic --json
If one fits, confirm with the user. If not, create one:
bd create "Epic: <goal>" -t epic -p <priority> --assignee <user-github-handle> --json
1c. Break the epic into tasks
Propose a task breakdown to the user. Iterate until they approve.
bd create "<detailed task description>" -t task -p <priority> --parent <epic-id> --assignee <user-github-handle> --json
1d. Add dependencies (only when justified)
Before adding a dependency, answer: why can't these run in parallel?
- Task B needs output from task A? Add it.
- Task A must be tested before B integrates? Add it.
- Same area but truly independent? Don't add one.
bd dep add <blocked-task> <blocking-task>
Document the reasoning in the blocked task's description.
1e. Commit the plan
bd sync
git add .beads/ && git commit -m "beads: plan tasks for <epic-id>" && git push
This makes the plan visible to all team members and agents immediately.
Phase 2: Execute
Goal: Work on tasks one at a time, following a strict claim-work-commit-close loop.
The loop (repeat for each task):
Step 1 — Pick. See what's unblocked:
bd ready --json
Step 2 — Claim. This tells everyone you're working on it:
bd update <task-id> --claim
bd sync
Step 3 — Work. Write code, fix bugs, whatever the task requires.
Step 4 — Commit the code. Include the task ID so the commit is traceable:
git add <files>
git commit -m "<what you did> (<task-id>)"
Step 5 — Close the bead. Always close after committing — the commit is proof of work, the close is bookkeeping:
bd close <task-id> --reason "Completed: <commit-hash>"
Step 6 — Sync and push the graph:
bd sync
git add .beads/ && git commit -m "beads: close <task-id>" && git push
Step 7 — Loop back to Step 1. Pick the next unblocked task and repeat. Never skip Steps 4-6.
Phase 3: Handle Problems
If you hit a blocker that prevents completing the current task:
-
Mark the task as deferred with a clear explanation:
bd update <task-id> --status deferred --notes "Blocked: <what went wrong and why>" bd sync git add .beads/ && git commit -m "beads: defer <task-id> — <reason>" && git push -
Ask the user to create new beads tasks that address the blocker. Don't silently work around it.
Rules at a Glance
| # | Rule | Why |
|---|---|---|
| 1 | Sync first, always | Stale graphs cause duplicate work and conflicts |
| 2 | Plan before code | Unplanned work is invisible to the team |
| 3 | User's handle on every bead | The user owns the work, not the agent |
| 4 | Tasks must survive memory loss | A fresh agent should execute any task from its description alone |
| 5 | Reason about dependencies | Wrong deps block work; missing deps cause integration failures |
| 6 | Claim before working | Prevents two agents from doing the same task |
| 7 | Commit code, then close bead, then next task | The commit is proof; the close is bookkeeping; never skip or reorder |
| 8 | Link the commit on close | bd close <id> --reason "Completed: <hash>" — no exceptions |
| 9 | Git-commit .beads/ after every graph change |
This is how the team sees what's happening |
| 10 | Blockers stop work | Defer and escalate; don't silently work around problems |
Resuming After Context Loss
bd init --quiet
bd sync
bd list --status open --status in_progress --json # what exists?
bd ready --json # what's unblocked?
bd show <id> --json # read a task's full context
Look at in_progress tasks first — someone (possibly you in a past session) was working on them. The task descriptions contain everything you need to continue.
What Makes a Good Task Description
Bad:
Fix the auth bug
Good:
Fix OAuth callback race condition in
app/api/oauth/callback/route.ts. When two callbacks arrive within 100ms, the second overwrites the first session in Supabase. Add a mutex or check-and-set pattern on theatproto_oauth_sessiontable. Acceptance: concurrent callback test passes. Depends on bd-a3f8.1 (session store refactor) because the fix requires the newupsertmethod.
The difference: the good description lets a stranger complete the task without asking a single question.