Issue
在 Bonsai 里,issue 不是数据库里的一行,而是一篇笔记,放在项目或领域的 Issues/ 文件夹下面:
1_Projects/<项目>/Issues/12.md
文件名就是编号。编号在这个项目里唯一,有了就不改,标题改了文件名也不跟着变。看板上每一张卡片都是这样一篇笔记。
没有第二份数据库。看板、issue 页、AI 通过 MCP 调 list_issues,读的都是这些文件。你可以在笔记编辑器里打开它、搜索它,在别的笔记里用 [[…]] 链接它。项目归档,它一起归档。
issue 里写的东西本来就是知识:为什么做、做到什么算完、过程中拍过哪些板、学到了什么。它和项目笔记住在一起,AI 来干活时只需要去一个地方找。
现在能用到哪一步。 下面的字段、正文、看板和 自动推进 都已经在用。issue 页顶部列出全部字段,可以直接改:状态、类型、优先级选了就存;负责人、Goal、blocked by、仓库、分支、base、PR 改完点一次「保存」。review 轮数和结论只显示,由 reviewer 写。issue 的「属性」对话框打开的也是这一排字段。界面上叫「状态」(英文是 Status),front matter 的键仍然是
state。
字段:这件事的事实
front matter 只记这件事本身。一个做到一半的 feature 大概是这样:
---
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
---
| 字段 | 意思 | 谁写 |
|---|---|---|
type | 哪一类事,指向你的一篇 类型笔记:Goal、Feature、Bug、Task…… | 你,或建它的 AI |
state | 走到流程的哪一步。能填什么由类型笔记定 | 你和 agent,按流程 |
priority | urgent、high、medium、low,或者不写 | 你 |
owner | 负责人。一定是人,从头到尾不变。新建时不填,就用项目或领域笔记的 owner | 你 |
goal | 属于哪个目标:同一项目里一篇 Goal 的编号 | Planner 或你 |
blocked_by | 要等哪几篇关闭才能开始,逗号分隔的编号 | Planner 或你 |
repo | 代码在哪个仓库,owner/repo。不写就用项目笔记里登记的仓库 | Planner 或你 |
branch、base、pr | 分支、它基于的分支、PR(owner/repo#123) | 派发时定,agent 写回 |
状态的键叫 state 而不是 status,因为 status 在 知识格式 里是只由服务端写的键。只有界面上显示的字叫 Status。
项目或领域的主笔记本身也可以写 owner(在笔记的「属性」对话框里改,或用 set_properties)。新建 issue 没填负责人时就用它;网页上新建、而项目也没写 owner 时,负责人是建的人自己。
不记的东西
几样常见的东西故意不在 issue 里:
- 模型和执行端。 用哪个模型写在
7_Self/_Agents/的角色笔记里,派到哪台电脑写在类型笔记的 Automation 行里。它们是「这一类事怎么做」的规则,不是这件事的事实。换模型改一篇角色笔记,所有 issue 一起跟着变。 - assignee。 卡片上的「现在轮到谁」是算出来的:在 Agent’s turn 时,是这一步 Automation 行派的角色;在 Your turn 时,就是
owner。agent 参与之后它每小时都在变,所以不存。旧笔记里的assignee会被当成owner读。 - run 和 CI。 一个 run 正在跑还是跑完了,是此刻的状态,Bonsai 在别处记。PR 合没合、CI 绿没绿,以 GitHub 为准,issue 里只放
pr这个指针。
所以一篇 issue 很轻,就像和 AI 开一段对话:你不用先填一张表,说清楚要什么就行。
正文:给你读,也给 AI 读
新建 issue 时,正文从类型笔记的 ## Template 开始。内置模版有四节,顺序按你打开 issue 时的需要排:
| 小节 | 写什么 | 谁写 |
|---|---|---|
| Description | 要做什么、为什么现在做、可测的验收标准、AI 必读的笔记链接 | 你(或 Planner),AI 不能改验收标准 |
| Decisions | 等你拍板的事:一个决定一个小标题,几个选项,推荐的那个标出来,最后永远有「其他」 | agent 提,你在 issue 页点选 |
| You should know | 这一轮你最该知道的几行,值得留下的标「值得记住」 | agent,每次 run 结束整节重写 |
| Log | 每次 run 一小节:日期、角色、第几轮、做了什么 | agent,只追加 |
Goal 类型的 Description 里没有验收标准,换成一张 Plan 表,列出拆出来的子 issue。每一节的写法见 Issue 类型 的 Template 部分。
它怎么往下走
一篇 issue 自己不知道下一步,它的 type 知道。
- 类型笔记 列出这一类 issue 的状态,规定每个状态属于哪个 Turn,以及到了 Agent’s turn 的状态派哪个角色、做完能去哪、最多几轮。
- 看板 按 Turn 分列,Your turn 在最左边,打开就看到在等你的事。
- 自动推进 在 issue 进入 Agent’s turn 的状态时派出对应的角色,做完交到下一步;到了 Your turn 就停下等你。它只看
type、state和 run,不读正文,不判断代码好坏。
内置 Feature 的一生:
Ready → Developing → Reviewing → Review PR → Deploying to Staging → Verify Staging → Deploying to Production → Done
粗体轮到 agent,斜体轮到你。
Goal:带着一串 issue 的 issue
Goal 也是一篇 issue,只是 type: Goal。子 issue 用 goal: <编号> 指回它,用 blocked_by 写出彼此的先后。
- 你建一篇 Goal,写一句完成条件和为什么。它停在 Draft。
- 在 Goal 旁边打开对话,这段对话就是 Planner。它读项目和代码,建好子 issue,填好 Plan 表,然后停下。
- 你在 Goal 页上点「批准」。整个目标只需要这一次批准。
- 自动推进接手:依赖都已关闭的子 issue 开始做,同时最多两篇(项目里可以调)。
- 子 issue 全部关闭,Goal 也关闭。
每一篇子 issue 照样会在 Review PR、Verify Staging、Needs Decision 停下等你。批准 Goal 不等于交出后面的每一次合并。
始终在你手里的
- 写验收标准,批准 Goal 的拆分。
- 在 Decisions 里拍板。
- 审 PR、验收 staging,也就是 Your turn 里的每一步。
- 收尾:Done、Canceled、Duplicate 由你来改,自动推进从不替你关 issue。
- 改规则:类型笔记和角色笔记放在
_开头的文件夹里,AI 的任何授权都写不了。
issue 关闭时,distill 角色把 You should know 里标了「值得记住」的几行写回项目笔记,下一次来这个项目的 AI 就从这里接着读。
下一步:Issue 类型 讲一种类型怎么写。