121 lines
9.5 KiB
Markdown
121 lines
9.5 KiB
Markdown
# 唤醒机制 · 角色与情况全表(2026-09-30 20:3x)
|
||||
|
|
|
|||
|
|
> 线:机制线 · 唤醒机制 | 域:`ai1net-dsh-server/`
|
|||
|
|
> 上位:`~/.workbuddy/skills/multi-session-collab/references/architecture.md`(**五主体**唯一权威)|本文件是它在「唤醒」这一块的**展开**
|
|||
|
|
> 兄弟件:`交付物/唤醒-双排期实现方式与状态动作表-20260930.md`(配方+状态表)|`交付物/唤醒-无人值守可行性-20260930.md`(为什么叫不醒旧会话)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 0. 结论:**唤醒轮不是新角色,是「主会话」的定时、不可接续实例**
|
|||
|
|
|
|||
|
|
架构里只有 5 个主体。唤醒轮**不增加第 6 个主体** —— 它扮演的就是「主会话」:
|
|||
|
|
- 与用户那个主会话**职责完全相同**(判断 + 派活);
|
|||
|
|
- 唯一区别:**它不可接续**(用户回不到它;它跑完即死)。
|
|||
|
|
|
|||
|
|
🔴 **一条分界线(本文件最重要的一句)**:
|
|||
|
|
|
|||
|
|
> **派活(写排期、开会话)只属于「会话」** —— 也就是**主会话**和**唤醒轮**。
|
|||
|
|
> **协作程序**(`collabd`)与**投递**:⛔ **永不派活、永不开会话**(architecture §1 硬边界)。
|
|||
|
|
> ⇒ 把唤醒轮误当成"协作程序的一部分"就会得出"它不许派活"的错误结论 —— 它是**会话**,**可以派活**。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 角色卡(谁是谁)
|
|||
|
|
|
|||
|
|
| 角色 | 是不是会话 | 只做什么 | ⛔ 不做什么 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **用户** | — | 看**一个**看板;拍**边界外**的板(授权/放行/花钱/对外承诺) | ⛔ 不管过程、⛔ 不必催进度 |
|
|||
|
|
| **主会话**(可接续) | ✅ 是,**用户对接的那个** | 判断 + 派活 + 接口令(启停唤醒轮)+ 向用户报告 | ⛔ 不做机械判定;⛔ 不搬砖(除非最靠前那步自己就能做) |
|
|||
|
|
| **唤醒轮**(A/B 两条定时排期起的) | ✅ 是,**临时且不可接续** | 抢锁 → 按【状态表】只做 **①接棒 / ②报告并停 / ③退出 / ④按③** | ⛔ 不造活、⛔ 不巡检体检、⛔ 不启自己、⛔ 不接管别人的锁、⛔ **不拍边界外的板** |
|
|||
|
|
| **协作会话**(每棒 worker) | ✅ 是 | 一棒一线、一次一件;**做完即上报** | ⛔ 不跨线;⛔ 不夹带;⛔ 不常驻 |
|
|||
|
|
| **协作程序**(`collabd`) | ❌ 否,程序 | 台账/判定/告警/看板/单例 | 🔴 **⛔ 不派活**(不写排期、不开会话) |
|
|||
|
|
| **投递** | ❌ 否,程序/钩子 | 逐条读队列 ⇒ 有变化就**告诉主会话**;机械判定 | ⛔ 不开会话、⛔ 不派活、⛔ 口令不落盘 |
|
|||
|
|
| **宿主(WorkBuddy 本体)** | ❌ 地基 | 提供四样:**状态**/**调度**(唯一能开新会话的通道)/**事件**(钩子)/**互斥**(域锁) | ⛔ 不是"主体",⛔ 不参与判断 |
|
|||
|
|
|
|||
|
|
### 1.1 🔴 「可接续 / 不可接续」决定了能动多大的手
|
|||
|
|
|
|||
|
|
| | 主会话(可接续) | 唤醒轮(不可接续) |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 能否被用户中途插话 | ✅ 能(用户就在里面) | ❌ 不能(用户不知道它存在) |
|
|||
|
|
| 允许做的判断 | **全部**,含无客观优劣的偏好 | **只允许"机械可判"的**:有客观可判的优劣 ⇒ 自决;没有 ⇒ **必须走 ②** |
|
|||
|
|
| 典型可自决 | 选型、路径、命名、调参、部署、排查方法 | ①接棒(下一步已定死)/③退出 |
|
|||
|
|
| 典型必须停下 | —— | 要不要改方向、要不要花钱、要不要对外承诺、要用户凭据 |
|
|||
|
|
| 产出去向 | 直接回给用户 | 写台账/看板 + 一条报告(用户下次回主会话才看到) |
|
|||
|
|
|
|||
|
|
⇒ **判据一句话**:**这个判断有客观可判的优劣吗?** 有 ⇒ 唤醒轮自己拍;没有 ⇒ ② 停下、报告。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 【核心】完整情况表(情形 → 各角色各干什么)
|
|||
|
|
|
|||
|
|
### A. 目标生命周期层(🔴 用户 09-30 定:唤醒轮从属于目标)
|
|||
|
|
|
|||
|
|
| 情形 | 主会话(可接续) | 唤醒轮(A/B) | 协作程序 / 投递 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **A1 下达「执行 XXX 目标」** | 接口令:定目标 + **启动唤醒轮**(A 即刻启用 + 排 +30 分钟启 B) | 尚未醒 | 记台账 |
|
|||
|
|
| **A2 目标在途·有缺口** | 判断缺口、派关键那棒 | 每 30 分钟醒一次 ⇒ 抢锁 → **①写一行排期接棒** | 投递把变化告诉主会话 |
|
|||
|
|
| **A3 目标在途·暂时无缺口(等外部/等数据)** | 说明在等什么 | **③ 一句话退出**(⛔ 不造活) | 保持台账 |
|
|||
|
|
| **A4 卡在需要用户** | 把"要你做什么"报告到用户面前 | **② 不派棒+报告+把 A/B 一起暂停** | 落 `NEED-USER.md` |
|
|||
|
|
| **A5 目标完成(验收全过)** | 收口:宣布完成,暂停 A/B | 若它先发现 ⇒ **③ 收口 + 暂停 A/B** | 台账置已完成 |
|
|||
|
|
| **A6 目标作废/换目标** | 换 `goal.json`,**删**旧目标的两条排期,按新目标重开一对 | —— | 台账清旧目标 |
|
|||
|
|
| **A7 用户放行/继续** | 重新下「执行 XXX 目标」口令 ⇒ 重新启用 + **校准相位** | 保持 PAUSED 直到被启用(⛔ 不许自启) | 台账恢复 |
|
|||
|
|
| **A8 用户另开新目标(旧目标还在途)** | 🔴 **先处理旧目标**(收口或显式挂起)⇒ 再开新的;⛔ 不许两对唤醒轮同时跑同一项目 | —— | 台账两条并行(须显式) |
|
|||
|
|
|
|||
|
|
### B. 唤醒轮运行时层(抢锁前后)
|
|||
|
|
|
|||
|
|
| 情形 | 主会话 | 唤醒轮 | 备注 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **B1 抢到锁 + ①有缺口** | —— | 写**一行**排期(新棒 id **只从工具返回值取**)⇒ 释放锁 ⇒ 回一句 | 一次只派一棒 |
|
|||
|
|
| **B2 抢到锁 + ②卡在用户** | 用户回话时直接接手 | ⛔ 不派棒;写清"要你做什么";**A、B 一起 PAUSED**;释放锁 | 派了=空转链条 |
|
|||
|
|
| **B3 抢到锁 + ③无缺口** | —— | 一句话结束;**确认无在途目标 ⇒ A、B 一起 PAUSED** | 空转是**正常出口**,不丢人 |
|
|||
|
|
| **B4 抢到锁 + ④判不准** | —— | 按 ③ 处理 | 宁可空转,⛔ 不许造活 |
|
|||
|
|
| **B5 抢不到锁** | —— | **立即结束**(有人正在推进=天然去抖) | ⛔ 不等待/不接管/不删别人的锁(R9) |
|
|||
|
|
| **B6 上一棒的产物没验收/棒死掉了** | 验收并判缺口 | 若"验收这一步"已定死判据 ⇒ 可直接派复验棒(属①);否则 ⇒ ②/③ | 判据看"下一步是否已定死" |
|
|||
|
|
| **B7 两条撞在同一分钟** | —— | 一条抢到、另一条 B5 退出 | 相位漂移的表现,按 §3 校准 |
|
|||
|
|
|
|||
|
|
### C. 机制健康层
|
|||
|
|
|
|||
|
|
| 情形 | 主会话 | 唤醒轮 | 怎么办 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **C1 相位漂移**(两条不再差 ≈30 分钟) | 重做启用(全停 → A 即刻 → B 隔 30 分钟) | 无感 | 查 `automation_update mode=list` 的 `nextRunAt` |
|
|||
|
|
| **C2 宿主重启** | 复查两条状态 | 排期表由宿主持久化,重启后仍按 `next_run_at` 跑 | ⚠️ 已知 `004f6bc2` 的 `next_run_at` 曾**停在过去** ⇒ 重启后必查一次 |
|
|||
|
|
| **C3 排期被误删** | 按 §配方重建一对 | —— | ⚠️ **删除是软删**:`status` 仍是 ACTIVE、只有 `deleted_at` 有值 ⇒ **判"还在不在跑"看 `deleted_at`** |
|
|||
|
|
| **C4 钩子不 spawn** | 查宿主日志 `[HookExecutor] spawn` | 不受影响(唤醒轮走排期,不走钩子) | —— |
|
|||
|
|
| **C5 唤醒轮自己起不来**(会话创建失败) | 查 `automation_runs` 有无 `ACCEPTED` 行 | —— | 排期本身还在,下个整点半再试 |
|
|||
|
|
| **C6 真·全员静止(没人在)** | —— | **这正是唤醒轮存在的意义**:它自己就是一个新会话,不依赖任何"活着的会话" | 这就是唯一能破静默的东西 |
|
|||
|
|
|
|||
|
|
### D. 异常与红线层(⛔ 一律先停手)
|
|||
|
|
|
|||
|
|
| 情形 | 主会话 | 唤醒轮 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| **D1 锁持有者疑似已死/卡住** | 报告用户,**处置权只属用户** | ⛔ **绝对禁止**删锁/接管(R9)=唯一合规是停手+报告 |
|
|||
|
|
| **D2 发现别人正在改的文件** | 归属不明 ⇒ 只报告、不动手 | 同上(R7-边界) |
|
|||
|
|
| **D3 需要用户凭据/审批** | 向用户要 | ② 停下报告(⛔ 不许自己找) |
|
|||
|
|
| **D4 需要重启宿主/改全局配置** | 先问用户 | ⛔ 硬禁止,直接 ② |
|
|||
|
|
| **D5 发现是对外动作(发布/承诺)** | 当轮问用户 | ⛔ 禁止(上一轮同意不算数) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 口径(启停 · 相位 · 锁)
|
|||
|
|
|
|||
|
|
| 项 | 口径 |
|
|||
|
|
|---|---|
|
|||
|
|
| **启动** | A 即刻 `ACTIVE` + 排一条 **+30 分钟**的一次性排期去启用 B(用完即废)⇒ 两条相位差 ≈30 分钟 |
|
|||
|
|
| **停止** | A、B **一起** `PAUSED`(唤醒轮判到 ②/③ 自己停;完成/作废由收口会话停) |
|
|||
|
|
| **重启** | **只有**「执行 XXX 目标」口令能启;⛔ 唤醒轮不许自启 |
|
|||
|
|
| **相位** | = 建立/启用那一刻;`PAUSED` 时为空;⛔ 分钟写不进规则(`BYMINUTE` 被忽略) |
|
|||
|
|
| **互斥** | 两条抢**同一把域锁**(`--domains <项目>/`);⛔ 抢不到就退,⛔ 不接管 |
|
|||
|
|
| **粒度** | 30 分钟(宿主只认 HOURLY/DAILY/WEEKLY/MONTHLY/YEARLY) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 一句速记
|
|||
|
|
|
|||
|
|
> **用户拍边界外的板|主会话(含唤醒轮这个实例)判断+派活|协作会话干活+上报|协作程序管台账|投递管通知 —— 唤醒轮只是"被定时叫起来的主会话",跑完就死、不许自启、不许造活。**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 遗留
|
|||
|
|
|
|||
|
|
1. 🔴 `multi-session-collab/references/architecture.md` **§4 仍写「⛔ 不引入任何周期排期」**(旧定案)⇒ 与本文件冲突,**待更正**。§1 五主体表也宜加一句"唤醒轮=主会话的定时实例"。
|
|||
|
|
2. 其他项目尚未复制配方(用户说的是"后续每个项目")⇒ 照 §配方 三步抄。
|