Written-by: Chief ## 现在的问题 卡上有 handoff 契约(`core/src/host/tasks.js`:`handoff{from,to,reason,at}`、`reworkOf`、`lease`、`evidence`,角色队列有 cap / claim / release),但**跑活的是固定 workflow 图**:节点和边就是交接,一张图一条链。今天的 7 张图(FlyBot 的 issue 快线、PR 快线、变脏修复线、Triage 线;bot-social 的实现线、合并线、分诊线)里,没有任何节点读卡上的 `handoff`。 后果有两个: - 每加一个仓库或一类活就得多画一条线。2026-10-30 bot-social 少一条实现线,4 张 `agent-ready` 单空转了几个小时,直到 Chief 手工把线建出来。 - Chief 成了单点:读盘、判断该谁接、再挑一条线派;一拍漏了就得靠看板补账。跑活的那一层不知道下一步该归谁。 ## 要的(owner 定义,2026-10-30) 任务在 worker 之间的流转由 **handoff 规定的路由规则**决定,Chief 只派一次: 1. **只派一次。** Chief 把任务派进第一个角色的池子(role queue),写清开局 `handoff.to`。此后每一步都不回 Chief。 2. **谁干完谁写 handoff。** 一个 worker 干完自己那段,写一条 handoff(`to` = 下一个角色,`reason`、`evidence` = 它跑过的命令与结果),卡落进目标角色的池子。例:Dev 写完代码并自己检查好了,就把卡放进 review 的池子。 3. **目标角色按自己的准入规则收或退。** 每个角色有一套准入规则(它自己的门禁):从池子里 claim 一张卡后,决定**处理**,还是**打回给产出者**(`reworkOf` 指回原卡,`handoff.to` 指回 Dev,reason 写清缺什么)。打回不经过 Chief。 4. **末端保留仓库特异的门禁。** 入队 / 合并这一步各仓不同(CI context 名、合并方式),保持为参数化的门禁节点,不进路由层。 5. **固定线退化成预设模板。** Triage→Dev→Reviewer→Enqueue 就是默认 handoff 链;仓库差异变参数,而不是再画一张图。现有 7 张图在本单里**不删**,作为 fallback 保留。 ## 本单的范围(第一片,能跑通一个闭环即可) - 路由层:读卡的 `handoff.to` → 在对应角色的池子里找一个空闲 worker → 唤醒它并 claim 这张卡;没有空闲 worker 就留在池子里,不丢。 - 准入规则:角色的 accept / return 判定落成可配置的一条规则(先支持「收」与「打回给产出者」两种),打回时生成 `reworkOf` 卡并指回产出者。 - 一个端到端用例:一条链上跑 Dev → Reviewer →(Reviewer 打回)→ Dev 重做 → Reviewer 收 → 末端门禁。用测试替身,不接真 GitHub。 - 文档:`docs/subsystems/workflow.md`(或 tasks.md)写清路由与准入规则、和固定图的关系。 ## 验收(可执行) 1. 派一次(一张卡,`handoff.to=dev`),产出者写 handoff 到 reviewer 后,**不需要任何主管动作**,这张卡出现在 reviewer 池子里,`handoff.from=dev`、`evidence` 有值。 2. reviewer 能从池子里 claim 而不再需要新的一次派单;打回时产生一张 `reworkOf=<原卡>` 且 `handoff.to=<产出者>` 的卡,产出者能接着做。 3. 角色下没有空闲 worker 时卡留在池子里不丢;有 worker 出现后被取走。 4. 现有 7 张固定图不受影响(回归测试全绿);`npm run verify` 绿。 5. 新增单测覆盖路由判定与打回路径,且断言在没有该实现时失败。 ## 不做(留给后续) - 池子的 UI(看板上先按现有投影显示)。 - 删掉固定线、把 7 张图全改成模板。 - 跨仓库参数化的门禁库。 - 多人(多个 owner)之间的路由。
Activity
Birfy commentedon Oct 30, 2026
Written-by: Triage
分诊结论:ready —— 打
agent-ready(原标签只有 enhancement,area:automation)。范围按正文 owner 2026-10-30 定义,不重开:
core/src/host/tasks.js的 handoff 契约 +core/src/host/task-drive.js(读 card.handoff.to → 在目标角色池找空闲 worker 唤醒并 claim;无空闲则留在池里)。注意core/test/task-route.test.js已有 Workflow: group-like chat with Bot flowchart + assign tasks to a pipeline #1318 的“显式 owner 变更”路由监听,不要回归或互相覆盖。plugins/workflow/src/service.js+template.js(角色规则可配置,先支持“收”与“打回给产出者”;打回写reworkOf指回原卡、handoff.to指回产出者)。docs/subsystems/workflow.md(docs/subsystems/tasks.md不存在,正文的“或 tasks.md”按 workflow.md 落地)。红先测试(没有实现时失败):
core/test/task-route.test.js或新增core/test/task-handoff-route.test.js:写 handoff 后目标池出现卡且 from/evidence 有值;无空闲 worker 时不丢、worker 出现后被取走;return 生成 reworkOf 卡并指回产出者。plugins/workflow/test/:accept/return 判定 + 末端门禁参数化用例;现有 7 张固定图回归(graph/run/strict-release-dag)必须保持绿。验收即正文 5 条(派一次闭环、无主管动作、打回直达产出者、无空闲不丢、现有图回归 + verify 绿)。风险档由 merge-gate 按 diff 计算,Triage 不手打 risk:*。
chore(patches): regenerate ds-bot patches for the handoff route (#1775)
chore(patches): fold the handoff route into the existing patch series (…
feat(host): route a card by its own handoff (ThinkFlowLab#1791)