Files
dsh_ai1net_server/交付物/唤醒-需求统一启停-20260930.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

7.6 KiB
Raw Permalink Blame History

需求统一启停控制台(2026-09-30)

起因(用户原话):「使用协作skill后 某个需求 统一管理 各种对应任务和程序的启停,包括协作程序等」 落地物:.workbuddy/collab/goalctl.py(新)+(复用).workbuddy/collab/stop-collab.py。 全文读数均为本机实测,⛔ 无推断。


0. 结论(三行)

  1. 一个需求牵扯的"可启停物"只有四层(实测盘清,别再数):排期层/程序层/总开关层/服务层;钩子层不在可启停范围内(下条)。
  2. 🔴 一个硬事实决定了整个设计形状:钩子是全局注册、跨项目共用的 —— E:/ProgramData/.workbuddy/settings.json 里 12 个 hook,其中还混着别的工作区的 ai1net-decision-laya/bridge/decision_bridge.py(×4 事件)。⇒ ⛔ 不能靠"装卸钩子"来启停某个需求(会连累所有项目)⇒ 只能 开关文件 + 入口早退。
  3. 入口已落地成三条命令:goalctl.py status | start | stop(默认干跑,加 --yes 才真做;写前自动备份)。

1. 清单:一个需求到底牵扯哪些东西(本机实测)

层 具体物 本棒实测状态 谁能改 拦在哪(生效点)
① 排期层 automations 表里的周期排期 3 条,全 PAUSED ⛔ 只有会话(automation_update 工具) 不再起新会话
② 程序层 collabd.config.json 的 wake_enable(协作程序投递总闸) 本棒已置 false ✅ 脚本 程序不再投递(=不再唤醒主会话)
③ 总开关层 goal.json 的 run 段(active/paused) 本棒已置 paused ✅ 脚本 唤醒轮/程序读到即立刻退
④ 服务层 看板 board.py --serve/守护 guard/网关心跳 全停(0 个 / 没在跑 / 登记册 0 条) ✅ 复用 stop-collab.py 写标志 ⇒ 对端优雅退出
— 钩子层 全局 12 个 hook(wb-result-hook.py、lock-guard-hook.py…) 常开、不可装卸 ⛔ 只有全局配置能改 不拦 —— 零 token,且"要不要干活"全在它调的程序内部

剔除项(⛔ 不是启停对象):一次性棒 15 条(schedule_type='once'、next_run_at 空=已耗),它们 status 仍是 ACTIVE 但永远不会再触发。 ⚠️ 判"某条排期还在不在跑"不能只看 status —— 删除是软删(deleted_at 有值、status 照旧 ACTIVE)⇒ 脚本里已按 deleted_at 过滤。


2. 三条硬约束(决定了为什么长这样)

# 约束 后果
① 钩子全局注册、跨项目共用 ⛔ 不装卸钩子;启停只能靠"开关文件 + 入口早退"
② 排期只能由会话改(脚本直改 workbuddy.db 的 automations = 改活库,且宿主是否重读未验) 脚本只打印待办;⚠️ 并给降级保障:漏改时唤醒轮读到 run=paused 会立刻退(一次空跑)
③ ⛔ 不 kill 会话/worker | ⛔ 不重启宿主 | ⛔ 不改全局配置 停服务一律"写标志让对方自己退"(guard.stop)、或停自建看板实例

3. 启停语义:三层同时翻,缺一层就留缝

想要 ① 排期层 ② 程序层 ③ 总开关 ④ 服务层
真停 PAUSED wake_enable=false run=paused stop-collab.py --yes
真启 ACTIVE(+两条相位差 ≈30 分钟) wake_enable=true run=active ⛔ 不自启任何常驻(常驻在本机已判走不通)

为什么三层缺一不可(各自守备范围不同):

  • 排期层 管:会不会起新会话(唯一能产生新交付的通道)
  • 程序闸 管:会不会投递(投递=唤醒活会话,会占主会话一轮 ⇒ 用户体感"卡")
  • 总开关 管:起来了之后该不该干活(兜底 + 人/AI 都直接可读)
  • 🔴 三者互补不重叠:只关程序闸 ⇒ 排期照旧起会话;只停排期 ⇒ 程序照旧投递;只有三个一起翻才是"真停"。

4. 用法

PY="E:/ProgramData/.workbuddy/binaries/python/versions/3.13.12/python.exe"
"$PY" .workbuddy/collab/goalctl.py                     # 状态台(只读,四层一次列清)
"$PY" .workbuddy/collab/goalctl.py stop                # 干跑:列出会做什么
"$PY" .workbuddy/collab/goalctl.py stop  --yes         # 真停
"$PY" .workbuddy/collab/goalctl.py start --yes         # 真启
"$PY" .workbuddy/collab/goalctl.py start "新目标名" --yes  # 启 + 改名

驱动口径(=用户已定的那条):启停由 「执行 XXX 目标」这道口令驱动 —— 下口令 ⇒ start;目标完成或有阻碍 ⇒ stop。⛔ 唤醒轮自己不许把自己启回来。

状态台实际输出(本棒读数)

【总开关】run = paused
         目标 = 本机(桌面客户端)内的多会话协作
         目标状态 = 三路全过
         队列 = {'done': 4}
【② 程序闸】wake_enable = False
           钩子链最后唤起 = tick 2 分钟前 / once 4 分钟前
【① 排期层】周期排期 3 条(**这才是启停对象**)/一次性棒 15 条(已耗,⛔ 不是启停对象)
   ⚪ 1eaf45c3  PAUSED   [协同监管 · 心跳……]
   ⚪ 16bec5ce  PAUSED   [本机协作]-唤醒轮B
   ⚪ caca9a89  PAUSED   [本机协作]-唤醒轮A
⇒ 一句话:这个需求现在是 **停着**

5. 本棒实际做了什么

  1. 新增 .workbuddy/collab/goalctl.py(状态台 + start/stop;默认干跑、写前备份到 .workbuddy/collab/bak-goalctl-<日期>/、⛔ 从不删文件)。
  2. 接进唤醒轮:两条提示词都加了第 0 步"先读总开关" —— run=paused ⇒ ⛔ 不派活、⛔ 不改文件、⛔ 不自启,一句话结束(="停"的兜底)。
  3. 按已定口径落成一致状态:A/B 从未 ACTIVE(没下过"执行 XXX 目标"口令)⇒ 正解就是停 ⇒ 执行 stop --yes: run=paused/wake_enable=false/服务层全停/排期 2 条本已 PAUSED。
  4. 🔴 顺手修掉一个真 bug(会致"误判完成"):原实现把任务图按"默认点"读 tmp/supervise-inbox/taskgraph.json —— 该文件根本不存在 ⇒ 三路并集少一路 ⇒ 可能把"未完成"看成"已完成"。现改为按配置 taskgraph 解析(交付物/任务图.json,18 节点全 done);并给读不到单独打标(⛔ 不许读不到就判完成)。

6. 已知边界(诚实说,⛔ 别当它能做到)

  • ⛔ 做不到"一秒内把所有在跑的会话停下" —— 会话不可 kill(用户明令)。能做的只有「不再叫新的 + 起来了不干活」。
  • ⚠️ 排期层脚本改不了 ⇒ 必须由会话执行;有 run=paused 兜底,但那一轮仍会被起一次(成本=一次空会话)。
  • ⚠️ 一个工作区当前只有一份 goal.json ⇒ "需求"与"工作区"目前是 1:1。若将来一个工作区要并行多个需求,得把开关做成多份(本棒不做)。
  • ℹ️ wake_enable=false 只关投递:程序的投影、看板、台账照常(零成本),所以"关"没有副作用。
  • ℹ️ ④ 服务层里网关心跳已被判死能力(桌面端硬编码 CODEBUDDY_DISABLE_CRON=1)⇒ 那一项是"名存实亡",stop 只是顺手清登记册。

7. 图

见同目录 唤醒-需求统一启停-20260930-图.html(① 四层清单图:标出钩子层"不可启停";② 三层守备图:各层各拦什么)。