统一唤醒出口 · 两个拨钟方,一个出口

用户口径:「自动任务(符合条件时)是通过 协作程序去唤醒 主会话,这样流程统一」
判据:「唤醒(投递)」这个动作只有一个出口 = 协作程序;区别只在"谁拨这一下"。

① 统一后的流程 ① 宿主钩子(事件) 有会话在动时 ⇒ 够用 ② 自动任务(时钟) 谁都没动 ⇒ 只拨钟 协作程序 唯一唤醒出口 判条件 + 投递 主会话 reply 唤醒 (与投协作会话同一通道) 🔴 降级(唯一例外):闹钟报「没有可唤醒的对象」(main-not-live/no-main-session/no-live-session) ⇒ 拨钟方**自己就是那个会话** ⇒ 抢域锁 + 按状态表干活。省掉的只是一次投递,判断规则仍来自同一张状态表。 ⚠️ 但 `target-busy`(主会话**已经在跑**)⛔ **绝不能降级** —— 降级=同一件事干两遍。

自动任务**不自己判条件、不自己派活、不起新会话** —— 它只跑 goalctl wake(⇒ collabd --tick)。

② 判定三分 —— 「符合条件时」就是这么判的 闹钟输出 含义 拨钟方动作 ✅ http 2xx 已投递 ⇒ 主会话被唤醒 结束 ✓ - / same-item / too-soon 条件不符(没变化/刚投过) 结束(零打扰) ⏸ target-busy 主会话**已经在跑** 结束 ⛔ 禁降级 ⛔ disabled 本需求已停(wake_enable=false) 结束 🔴 main-not-live / no-main-session / no-live-session **没有可唤醒的对象** 降级:自己干 🔴 no-token / no-gateway 异常(没跑在宿主进程树里?) 报告并结束

🔴 最关键是**别把 `target-busy` 和「没有可唤醒的对象」混了** —— 前者是"已经在跑"(别插手),后者是"没人可跑"(要我顶上)。

③ 两条会静默坏的易错点(本轮实测) ① 唤醒轮不能让自己被认成「主会话」 兜底判据=本工作区「最近活动 + 标题不含 [协作]」;刚起的唤醒轮活动必然最新 ⇒ 必然被选中 ⇒ 投给自己 ⇒ 主会话永远收不到 ✓ 修法:排期名带 [协作](原名 [本机协作]-… 里没有 [协作] 这个子串)—— 已改 ② 主会话标题必须以「主控」开头,⛔ 不能加方括号 代码判 startswith("主控");实测有标题写成 [主控]-[机制线]-… ⇒ 判 False ⇒ 只能靠"最近活动"兜底 ⇒ 谁更新一下就可能把它顶掉

两条都会**静默**出错(不报错、不告警,只是"通知永远到不了主会话")—— 所以必须当硬约束记住。