Bonsai
Documentation pages
Concepts
Documentation

Issues

In Bonsai an issue is not a row in a database. It’s a note in the Issues/ folder of a project or area:

1_Projects/<project>/Issues/12.md

The file name is the number. Numbers are unique within the project and never change; rename the issue and the file stays put. Every card on the board is one of these notes.

There’s no second database. The board, the issue page and an agent calling list_issues over MCP all read the same files. You can open an issue in the note editor, search it, and link to it from any note with [[…]]. When the project is archived, its issues go with it.

What goes into an issue is knowledge: why the work matters, what counts as done, which calls were made, what was learned. It lives next to your project notes, so an agent only has to look in one place.

What works today. The fields, the body, the board and Automation below are all live. The top of the issue page lists every field and lets you edit it in place: status, type and priority save as soon as you pick; owner, goal, blocked by, repository, branch, base and PR save together with one Save. Review round and verdict are shown but only the reviewer writes them. The Properties dialog of an issue opens the same fields. The UI calls the step “Status”; the front matter key stays state.

Fields: the facts

The front matter records only this piece of work. A feature halfway through looks like this:

---
type: Feature
state: Reviewing
priority: high
owner: Guoliang
goal: 9
blocked_by: 10, 11
repo: livewithbonsai/Bonsai
branch: issue/12-cache-hint
pr: livewithbonsai/Bonsai#89
---
FieldMeaningWritten by
typeWhat kind of work, pointing at one of your type notes: Goal, Feature, Bug, Task…You, or the agent that creates it
stateWhich step of the workflow it’s on (shown as Status). Allowed values come from the type noteYou and agents, following the workflow
priorityurgent, high, medium, low, or nothingYou
ownerThe person responsible. Always a human, never changes. Left out when creating, it’s the project or area note’s ownerYou
goalThe goal it belongs to: the number of a Goal issue in the same projectThe Planner or you
blocked_byIssues that must close first, as comma-separated numbersThe Planner or you
repoThe code repository, owner/repo. Leave it out to use the project note’s repositoryThe Planner or you
branch, base, prThe branch, the branch it’s based on, and the PR (owner/repo#123)Set at dispatch, written back by the agent

The key is state, not status, because status is a server-only key in the knowledge format. Only the label you see says Status.

The project or area main note can carry its own owner too (set it in the note’s Properties dialog or with set_properties). A new issue created without an owner takes it; one created on the web in a project without an owner gets whoever created it.

What an issue leaves out

A few things you might expect are deliberately not in the issue:

  • Model and machine. The model lives in a role note under 7_Self/_Agents/; which computer runs it lives in the type note’s Automation row. They’re rules about how this kind of work gets done, not facts about this issue. Change one role note and every issue follows.
  • Assignee. The “whose turn” on a card is computed: in the agent’s turn it’s the role the Automation row dispatches; in your turn it’s the owner. With agents involved it changes every hour, so it isn’t stored. An assignee line in an older note is read as owner.
  • Runs and CI. Whether a run is going right now is the present, not a fact, and Bonsai tracks it elsewhere. Whether the PR merged or CI passed is GitHub’s fact; the issue only keeps the pr pointer.

So an issue is light, like starting a conversation with an agent: you don’t fill in a form, you say what you want.

Body: for you and for the agent

A new issue starts from its type note’s ## Template. The built-in template has four sections, ordered by what you need when you open an issue:

SectionWhat goes thereWritten by
DescriptionWhat to do, why now, testable acceptance criteria, links to notes the agent must readYou (or the Planner); agents can’t change the acceptance criteria
DecisionsCalls that need you: one heading per decision, a few options, the recommended one marked, always an “Other”Agents propose, you click on the issue page
You should knowThe few lines you most need from this run; anything worth keeping is marked “worth remembering”Agents, rewritten after every run
LogOne entry per run: date, role, round, what happenedAgents, append only

A Goal’s Description has a Plan table listing its child issues instead of acceptance criteria. See the Template part of Issue types for each section’s format.

How it moves

An issue doesn’t know its next step. Its type does.

  • The type note lists the states, puts each in one of the four Turns, and says which role to dispatch in each agent state, where that role may move the issue, and how many rounds it gets.
  • The board groups issues by Turn with Your turn on the far left, so what’s waiting for you is the first thing you see.
  • Automation dispatches the role when an issue enters an agent state and hands it on when the role is done; in your turn it stops and waits. It reads only type, state and the runs, never the body, and doesn’t judge the code.

The life of a built-in Feature:

Ready → Developing → Reviewing → Review PR → Deploying to Staging → Verify Staging → Deploying to Production → Done

Bold is the agent’s turn; italic is yours.

Goals: an issue that carries others

A Goal is an issue too, with type: Goal. Child issues point back with goal: <number> and record their order with blocked_by.

  1. You create a Goal with one line on what done looks like and why. It sits in Draft.
  2. You open a chat beside it. That chat is the Planner: it reads the project and the code, creates the child issues, fills the Plan table, and stops.
  3. You click Approve on the Goal page. That’s the only approval the goal needs.
  4. Automation takes over: children whose dependencies are all closed start, two at a time by default (adjustable per project).
  5. When every child is closed, the Goal closes.

Each child still stops at Review PR, Verify Staging and Needs Decision for you. Approving a Goal doesn’t sign away every merge after it.

What stays with you

  • Writing acceptance criteria and approving a Goal’s split.
  • Making the calls in Decisions.
  • Reviewing the PR and checking staging: every step in your turn.
  • Closing: Done, Canceled and Duplicate are yours; Automation never closes an issue for you.
  • Changing the rules: type notes and role notes live in folders starting with _, which no agent permission can write.

When an issue closes, the distill role writes the “worth remembering” lines from You should know back into the project notes, so the next agent on the project starts from there.

Next: Issue types shows how to write a type.