Skip to content

feat: 多 bot 协作派活 + 交付验收(任务进账本、产物要核验、dashboard 看进度)#278

Draft
sensuossss wants to merge 154 commits into
masterfrom
feat/verified-delivery
Draft

feat: 多 bot 协作派活 + 交付验收(任务进账本、产物要核验、dashboard 看进度)#278
sensuossss wants to merge 154 commits into
masterfrom
feat/verified-delivery

Conversation

@sensuossss

@sensuossss sensuossss commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

这个 PR 解决什么

以前一个 bot 把活派给另一个 bot,到底做没做、做得对不对,全靠群里一句「做完了」——没法核实。这个 PR 加了一套可验收交付机制:

  • 派出去的每个任务都进账本botmux dispatch),不是聊天记录。
  • 干活的 bot 必须交产物/证据botmux report),不能只在群里口头说完成。
  • 派活方核验通过才算交付botmux delivery accept/reject):账本是唯一真相,accept 必须留下「核验了什么、跑了什么命令」的硬证据。
  • 支持两层协作:主群里你跟规划 bot 对话,它开一个「目标群」拉一个监管 bot,监管 bot 再把子任务派给干活 bot,并负责核验、催办、汇总——你只在主群看里程碑。
  • dashboard 加了「目标」页:一眼看到每个目标下所有子任务的状态/验收情况。

具体能力

任务账本(核心)

  • 极简 append-only 账本(4 事件 + 幂等 + 物化读模型);worker 不能群里口头说完成,必须带证据 report,由派活方(LLM 充当审核)accept/reject。

两层协作编排

  • 目标群 = 独立群、子任务 = 群级一次派活(用账本 taskId 隔离、不开话题);目标的「章程/目标/状态」存在独立 charter(不污染会话)。

自动兜底

  • 干活 bot 没按规矩交报告时,后台 watchdog(worker 空闲即时 + 5 分钟定时)唤起监管 bot 主动核验产物,不会卡死。
  • 监管 bot 完成后用 daemon 内部通道唤起主群规划 bot(绕过同 bot 自己发消息收不到的限制)。

结构化验收 + 看板

  • 验收标准从自由文本升级成结构化字段(要核验哪些产物文件、跑哪些命令),派活时即时校验非法标准;watchdog 把它渲染成人类可读的清单。
  • dashboard 目标 页 + GET /api/goals(默认 token 门禁,不公开)。

验证

  • pnpm build 绿;pnpm test(unit)5001 passed,仅 3 个 workflow-fanout 因本机 inotify 实例耗尽报 EMFILE——环境问题、非代码,且本分支没碰 workflows 逻辑。
  • 部署到线上后 3 项实跑验证全绿:派非法验收标准会被拒且不落账、目标看板接口鉴权正确且能读真账本、watchdog 渲染清单不再贴原始 JSON。
  • 历轮多 bot 两层 live e2e 全部通过。

同步与冲突

已 merge 最新 master(merge dfebc620),唯一冲突是 dashboard.ts 相邻 import,两侧都保留。现 0 behind / 35 ahead。

Review 分工

  • claude:账本 types/校验/读模型 + 协议 skill + dashboard 前端
  • codex:cli / core(watchdog, dashboard-ipc-server, worker-pool) / 主 dashboard server

- L2-2: acceptanceHint JSON v1 给 3 个可复制模板(单文件/命令/组合)+ dispatch 前 python json.load 自检,防手写 JSON 漏引号/尾逗号导致巡检退化成只能催
- 可信交付: 验收留痕升级为硬规矩——accept 必带 --evidence-checked、能跑命令必带 --ran-command,禁止空证据/看一眼算过;兜底通道(worker 没 report)更要逐条对 acceptanceHint checks 写明结果
…native 唤起)

- L2-5: send --chat-id 主群 → goal notify-parent(L1/L2 同 bot,send 是 self-message 被 guard 挡;notify-parent daemon-native 绕开),补 --summary-file/自动推断 session 说明
- L1-5: 描述改 notify-parent 唤起([goal-parent-notify] 前缀),强调通知只是唤醒、L1 仍须查账本/charter
- L1-4: goal supervise 加 --session-id 建议(填 prompt 顶 <session_id>),让 L2 完成时不论 L1 是话题/群级会话都能精准回定位
- 去掉 watchdog 巡检的 --older-than 5m:daemon 唤醒判据是'任何 dispatched/rejected',skill 却按 5min 年龄过滤→唤起卡 5min 边界时把刚到点任务漏掉、白唤;改为处理 [goal-watchdog] 消息已列出的 pending task(--older-than 只留给 L2-4 主动扫长期卡住)
- 兜底 accept 改 report-then-accept:cli delivery accept 必须挂在一笔 report 上(cli.ts:4696 无 reportId 报错),'worker 没 report 也认'原文直接 accept 执行不了;改为 L2 先补一笔自证 report(把核验当证据)再 accept --report <id>。这是 P0 时 L2 实际做法、被掩盖未写进协议
sensuossss added 30 commits July 8, 2026 15:32
按产品化 P0 词汇表定稿(主控/监管者/执行者/提交结果/交付记录/验收通过/驳回/求助/升级给人/换执行者/目标说明/自动核验):

- ORCHESTRATE_SKILL 新增「对人说话用产品词」指引段:skill 手册保留内部词保证 bot
  操作精确,但 bot 发给人的一切内容(对齐提案/升级理由/汇总/播报补充)一律翻译成
  产品词——治理双读者问题,不是把操作手册改成人话。
- goals.ts 显示层「自动对账」label/kind →「自动核验」(eb4aebc6 已改 title,本笔补齐)。
- dispatch.ts 分工缺省角色「执行」→「执行者」。
- cli.ts dispatch/report --help 说明段产品词化(命令名/参数名不动)。

tsc/build/相关测试(50+182)/diff --check 全绿。
narration.ts+goal-watchdog.ts 的 mode:'自动对账' 类型字面量涉及已入库数据兼容,留给 codex 判断。
# Conflicts:
#	src/core/dashboard-ipc-server.ts
#	src/daemon.ts
P1 第 3 件(契约与 codex 已钉):systemRisk 行给「重派/升级给人」、blocked 行给
「处理求助/升级给人」按钮,与既有轻量唤醒按钮并列(.attn-action 同款式,零新 CSS)。

点击构造 [panel-action v1] 文本块(action/taskId/reason/instruction,reason 预填
disposition.reason 稳定码)POST 到既有 /api/goals/:goalChatId/decision——dashboard
不直接写账不直接派活,由监管者核对交付记录后执行真命令并留痕,归因干净。
按钮态:下发中…→已下发 ✓/失败(title=错误);no_supervisor 给人话报错。

tsc/build 绿;产物落 chunks/goals-*.js(React 迁移后 code-splitting)。
L2 侧 [panel-action v1] 识别指引由 codex 补。
master merge 带入的全局 button 规则(inline-flex+align-items:center+justify-content:center)
打到 .gb-goal 复合卡片按钮上:子行收缩成内容宽并居中 → 长标题溢出卡片两侧、badge 行错位。
显式回 align-items:stretch + justify-content:flex-start 抵住基线。

修完暴露第二层:goal 变多后 .gb-rail 超过 max-height,flex 把每张卡 shrink 压扁,
foot 行被挤出卡外——.gb-goal 加 flex:none,超高走 rail 滚动不压卡。

.attn-row 同样吃到基线的 justify-content:center,虽有 flex:1 子项兜着未显性崩,
补 flex-start 防御(不是每行都保证有伸缩子项)。

playwright 1440/670 双视口验证:top 行宽=卡内宽、零溢出,截图目检通过。
静态资产磁盘现读,build 后刷新即生效,无需重启 daemon。
取消态(对齐 7517377 语义):
- goal 卡片:分数/百分比分母剔除 cancelled(3/8 非 3/10),frac hover 注明数量,
  进度条加灰段 gb-seg-cancelled,badge「N 已取消」(quiet 灰)
- 任务行:⏹ tag 带原因、gb-pill-cancelled 灰徽章、整行降透明度存档感
- 详情:取消块(原因/操作人/时间/未验收提交数/同任务号重派可重开),
  终态不给决策框(曾升级过的任务 escalation view 仍在须显式排除),时间线加取消步骤

缺项目环境(对齐 3d4108a 的 reason=help:missing_repo):
- 注意力带摘要槽显示「缺少项目:<repo>」(该行无提交摘要,槽位复用零新 CSS)
- 按钮按契约给三个:准备环境=resolve-help / 换执行者=switch-worker / 升级给人;
  [panel-action v1] 的 instruction 按 missing_repo 对症定制并带上 repo

skill(ORCHESTRATE):L2-3.5 逐任务 action 补第 6 条 delivery cancel——
何时取消/accepted 不可取消/同任务号重派可重开/worker 走 help 不自我取消;
panel-action 段补 help:missing_repo 对症释义。

tsc/build 绿;builtin-skills 19/19;playwright mock 数据视觉验证两屏通过。
① goal 全部任务取消时 frac 显示「—」不再 0/0
② missing_repo 在任务表/详情统一显示「缺项目环境」(helpKindLabel 用与
   attention.ts 同款 blocker 前缀判定,kind=access 不再误标「缺权限」)
③ missing_repo 行已有三个对症处置按钮,去掉重复的「通知监管者」
④ skill「归灰存档」→「显示为灰色已取消状态」,用户词只留「取消」一套

playwright mock 复验三处(—/缺项目环境/无 wake)+ builtin-skills 19/19。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant