session-mechanism: 修复钩子静默失效 + 3 处判据缺陷;禁「变相征询」

1) stop-dialog-guard: session_budget() 早退路径返回 2 值、末尾返回 3 值,调用方按 3 值解包
   ⇒ transcript > 64 MiB 时每轮 ValueError。因 fail-open(异常仍 exit 0),
   宿主零报错、install.py --verify 只判 rc=0 ⇒ 假绿;实测 86 条 EXCEPTION,
   死掉的是整条(水位/收口、接续机制起点、预算告警、门禁自检、路径自检)。

2) session-rules-check 三处判据:
   · hook_reg  按旧文件名找 ⇒ 合并成 prompt-guards.py 后每轮假红 ⇒ 改为一组可接受名
   · snap_sync 拿 mtime 当内容判据 ⇒ 连续 4 天假红 ⇒ 改为复用抽取器本体比对内容
               (变异对照:截断快照能报 fail,非恒绿)
   · mem_ptr   只查全局技能根 ⇒ 工作区自带技能被判悬空 ⇒ 改查「全局 ∪ 工作区」

3) pitfalls 新增 P0-95(改判据必须重跑变异对照;fail-open + 只看 rc=0 = 假绿温床)

4) 回复排版核心块新增「变相征询同样禁止」(先只报不动/等你发话/我倾向X你看呢
   这类不带选项的待定清单,一律按待拍板项写:问题+说明+各候选优缺点+倾向)
This commit is contained in:
admin committed 2026-10-06 22:27:03 +08:00
1 parent 19101acd65
commit 64dd82073b
21 files changed
+8444 -4523

No files matched your search

+110 -6
View File
@@ -23,6 +23,19 @@ last_change: 2026-10-05 10:5x · 🔴🔴 **`lifecycle` 判定收敛为「单一
| 三 | **10-05** | **主会话/任务会话/检查会话** | **常驻程序** | ✅ **现行** |
🔴 **任务会话 = 旧称「执行会话」,同一个角色**(⛔ 不是第四类)。
🔴🔴 **2026-10-05 用户定案**:**「协作 全部 改为执行」**(连说两遍)⇒ **新建前缀一律 `[执行]`**,包内现行文案一律用「**执行**」(旧「协作」只作历史沿革保留)。
🔴🔴🔴 **2026-10-05 追加定案(同一话题,用户逐字)**:「**兼容个毛线,今天兼容一个明天兼容一个 过不了一周就成大杂烩了**」
⇒ **本包禁用「兼容」二字描述任何前缀/字段**。凡看见旧前缀,**必须一句话答出"删了会坏在哪"**;
答不出 ⇒ **它就是该删的**(不许以"兼容"为由留)。
· ✅ **留得住的唯一理由 = 历史行解析正确性**:`[协作]`/`[协作目标]`/`[任务会话]` 三条**不许删** ——
实测(2026-10-05 跑 `board.py::_role_of_title()`)删任一条 ⇒ 存量旧标题行解析成 `role=""`
⇒ **看板画不出、派活漏管,且不可逆**。⇒ 这是"**删了会坏**",⛔ **不是"兼容"**。
· ⛔ **不许进「活类别表」**:`session-rules-check.py::ROLES_LIVE` **只有 `[执行]`**。
旧前缀只出现在**扫描面** `SESS_PREFIXES`(捞历史行用)+ `_PFX` 映射表(解析用)。
· 🔴 **机制层闸门(已落地,防"明天又长一条")**:`session-rules-check.py` **第 ⑬ 项自检**
—— 扫**活排期名**与**活会话标题**,出现旧前缀 ⇒ **当场 fail**(判据只扫"活件",⛔ 不扫注释/考古段)。
变异对照已跑:全 `[执行]`⇒ok|混 1 条 `[协作]`⇒fail|混 1 条 `[任务会话]`⇒fail|历史行不以旧前缀开头⇒ok。
🔴 **改名落地位置**:发源地 `collabd.py::_gap_plan()` 的 `_zh = {"worker": "执行"}`(**唯一出处**)+ 文首提示词模板 9 处 + 本文件现行规范句。
🔴 **待办(未做)**:一/二代旧词在包内仍有 ~174 处(`collabd.py` 37、`board.py` 27、`board.html` 28、`selftest.py` 22、`goalctl.py` 15…)。
⛔ **改名不能盲替换**,先分三类:① 注释/文档 ⇒ 可直接改;② `selftest.py` 的 `@case` 标题 ⇒ 改了会断 `-k` 用例引用;③ 看板显示文案 ⇒ 改了用户可见,且可能有字面判据(`board.py:191` 那条就是防两处漂移的)。→ 待办清单 `references/manifest.md`。
· **本包自身**:`install.py`(干跑/安装/校验)+`references/manifest.md`(清单);⛔ 包外**不应**有第二套会话机制代码。
@@ -43,6 +56,30 @@ agent_created: true
⚠️ 那篇里还有**文档四条规则**(分类索引/结论在最前/历史倒排·新的在前/单条 ≤6 KB)——
**⛔ 只写进工作区日志的规矩 = 没立**(10-04 实证:一条红线立在对的地方,换会话照样读不到)。
## 🔴🔴 第 0 步:加载门槛(2026-10-05 立 · ⛔ 这是**第一条**,在十条禁令之前)
> **判据(一句话)**:**用户说了触发句 ⇒ 第 0 步是先加载本技能,然后才动手。⛔ 没有"我大概知道"这条捷径。**
**触发句(命中任一条即须加载)**:`使用任务会话完成 X 目标` / `使用执行会话完成 X 目标` / `继续 X 目标` /
`用执行会话完成 X` / `派任务会话` / `建任务会话` / 任何"让我去把某个目标做完/接着做"的表述。
**⛔ 禁止的三种"跳过理由"**(都真实发生过):
| 跳过理由 | 为什么不算数 |
|---|---|
| 「我已经很熟这套机制了」 | 熟悉 ≠ 现行。机制 10-03/10-04/10-05 连续改过三轮(会话类别、常驻形态、术语),**记忆里的版本大概率是旧的**。 |
| 「上下文里已经有规则片段了」 | 片段 ≠ 全文。**只读片段最容易漏「自决策白名单」这一节**(见下)。 |
| 「注入通报里说本轮不需要」 | 🔴🔴 **用户原话 > 注入通报**。通报是机制层的**旁路信号**,⛔ 不能拿它反驳用户当轮的明确指令。 |
🔴🔴 **最关键的一条(2026-10-05 实测栽过)**:**用户明确说了"使用任务会话完成目标",就不许再回头问"要不要建任务会话"。**
- 用户原话:「**任务会话的目的不就是 建立任务会话执行嘛,不然我调用任务会话技能干什么**」
- 用户原话:「**我想知道你哪来的这么多问题啊,你去执行不行啊,会话技能里面没有告诉你自决策的规则和机制嘛**」
- ⇒ 说这句话**本身就是授权**:直接建排期、拉起任务会话。把"怎么执行"当待拍板项 = 把已授权的事重新要一遍签字。
**自决策白名单(九类,命中即永不问)** —— 全文在 `references/02-功能优先协作协议.md` §2:
技术选型/实现路径/命名/调参/部署/排查/版本/兼容降级/文档技术内容。
**只准提报三类**:① 功能语义分叉(做 A 还是做 B,影响用户看到什么)② 红线门禁 ③ 超出决策边界(花钱、对外承诺、要凭据)。
## 🚨 十条禁令(2026-10-05 立 · ⛔ 每条都栽过,栽一次就重来一遍)
> 用户 2026-10-05 原话:「**你不要给我知道了,你给我记下来,每次都是知道了,知道了,过一会儿又忘了**」。
@@ -71,10 +108,66 @@ agent_created: true
**三条线各归各的(⛔ 别混谈)**
1. **派活线**:主会话 → 任务会话。排期名 `[协作]-[<类别>]-<具体>`。🔴 **不受总开关影响**(开关只挡常驻)。
1. **派活线**:主会话 → 任务会话。排期名 `[执行]-[<类别>]-<具体>`。🔴 **不受总开关影响**(开关只挡常驻)。
2. **检查线**:常驻 → 检查会话。排期名 `[检查]-[结果检查/目标检查]-…-第N棒`。🔴 **受总开关管**。
3. **常驻线**:一工作区一条 `collabd.py --supervise` + 看板**全局只一条**(端口 20099)。
**🔴🔴 目标口径(2026-10-05 用户定案 · ⛔ 这是"关注哪个目标"的唯一判据)**
> 用户原话逐字:**「一个工作区 历史的旧的目标会有很多个,当前要求完成什么目标 就因该关注和检查那个目标」**
> **「一个工作区 同时只能执行一个目标,如果要切换目标,需要用户确认,然后切换和关注检查切换后的目标」**
拆成**两条硬规矩**:
1、**同时只有一个"当前目标"** —— `tmp/supervise-inbox/goal.json` = **唯一当前目标的载体**(⛔ 不存在"多目标并行")。
历史旧目标**移到 `tmp/supervise-inbox/goals/` 归档**(⛔ 不许原地堆在 `goal.json` 里)。
2、**切目标 = 用户确认的动作** —— 「声明新目标」**不是**随便覆盖;**必须先问用户**,得到确认才切,切完**关注和检查的是切换后的那个**。
⛔ **机制不许自作主张换目标**(同 `lifecycle` 那条铁律:**宁可等,不可动**)。
✅ **三条落点现状(2026-10-05 已全补,⛔ 别再照抄旧缺口表)**:
| 项 | 现状 |
|---|---|
| 当前目标载体 | `goal.json`(单文件,✅ 天然只有一个) |
| 切目标需确认 | ✅ `declare` 加**确认闸** —— 标题变了 ⇒ **默认拒绝**(rc=3),必须带 `--switch-goal` |
| 旧目标归档 | ✅ 换目标时**整份**存 `goals/<旧标题≤40字>__<时间>.json` + 新目标留 `_前身目标` 指针(⛔ 不再靠人手写) |
🔴 **改前取证结论**(P0-78 留档):① 载体**本就满足**;② 归档**零实现**(全文搜 `goals/` 零命中 ⇒ 那份归档件是**手工造的**);③ 确认闸**零实现**(`declare` 直接覆盖 `title`)。
⚠️ **加闸带出的连带缺陷**:`declare` 没给 `--title` 时**回落成工作区名** ⇒ 把"纯细化"误判成"换目标" ⇒ 已修成「没给 ⇒ 保持现有标题」。
📂 全文 ⇒ `references/pitfalls.md` **P0-78**;⚠️ `lifecycle` 那条独立铁律 ⇒ **P0-79**(从 P0-77 拆出)。
**🔴🔴 换目标的正确动作(⛔ 照这个做,别自己发明)**
1、**先问用户** —— 「当前目标是 X,要放弃它换成 Y 吗?」(⛔ 机制不许自作主张换目标)。
2、用户**确认后**才执行:
```
python .workbuddy/collab/goalctl.py declare --title "<新目标>" --switch-goal --yes
```
3、**紧接着同步 `lifecycle`**(🔴 `declare` **不碰它**,不同步 ⇒ 检查机制会空转):
```
python .workbuddy/collab/collabd.py --set-life 进行中 --by "主会话"
```
4、切完**关注和检查的是切换后的新目标** —— 旧目标已归档,⛔ 不再建它的检查会话。
⚠️ **只细化同一目标**(补 `--why`/`--kpi`/改错别字)⇒ **不带 `--switch-goal`**,正常放行(⛔ 不该被拦)。
⚠️ `--switch-goal` ⛔ **不等于** `--yes`:前者=「用户已同意换目标」,后者只是「干跑转真写」。**混用 = 伪造用户授权**。
**🔴🔴 机制新建会话「用哪个模型」(2026-10-05 用户点破 · P0-80)**
> 用户原话:**「为什么 vibe-product 检查进程 创建的 执行和检查会话没有使用 主会话相同的模型」**
一句话判据:**机制另建会话时,模型与思考档一律「跟本区主会话」—— ⛔ 不许在代码里写死。**
- **改前事实**:`collabd.py::create_check_schedule()` 的 INSERT 里**字面写死** `"space-bunny"` + `model_is_thinking=0`
⇒ 机制建的 49 条会话/9 条排期全是 `space-bunny`,而**主会话是 `deepseek-v4.1-flash`(thought=high)**。
- **两条建会话的路,模型来源不同(⛔ 修的时候别只修一条)**:
· **常驻直连 SQLite**(`create_check_schedule()`)⇒ 这次已改成**取本区主会话**;
· **会话侧走 `automation_update`** ⇒ 天然跟主会话同档(宿主默认)。
- ✅ **现在的实现**:`collabd.py::preferred_model(cwd)` —— 取 `sessions` 里**人开的**(`is_background_automation <> 1`)、
**本区**、**最近一条**的 `model` + `thought_level`;取不到才回落常量,且**必打日志**(⛔ 不许静默)。
⚠️ **必须排除 `bg=1`** —— 否则会取到"机制自己上次建的那条" ⇒ **自我强化**,永远锁死在历史值上。
- 🔴 **配套判据**(`session-rules-check.py` ⑧):报「**机制建的排期模型 ≠ 本区主会话模型**」。
⚠️ 扫描面**必须含 `once`** —— 机制建的排期全是 `once`,旧判据只扫 `recurring` ⇒ **一条都看不见**(恒绿)。
**常驻的唯一管理入口**:`python collabctl.py <status|on|off|ensure>`(加 `--out <文件>` 取结果)
**用户可见入口(双击)**:`会话机制-一键开关.bat`(工作区根 + 桌面各一份)= 启动/全部停止/看状态
@@ -255,7 +348,7 @@ agent_created: true
> **(现在不需要上报机制了、之前已经去掉 唤醒会话和跟进会话机制)**」—— 本轮是**把代码与文档对齐到已有口径**。)
>
> **已落地(现算)**:
> · 角色表 `collabd.py::parse_session_name()` 与 `board.py::_role_of_title()` **两处同款**收到 `主/协作`
> · 角色表 `collabd.py::parse_session_name()` 与 `board.py::_role_of_title()` **两处同款**收到 `主/执行`
> ⇒ `[唤醒]`/`[跟进]` **判空**(旧 `sessions` 行不删,但不再是活类别,也**不会被当主会话候选**)。
> · 主会话候选排除元组**两处**收到 `("worker",)`。
> · `follow_for_topic()` **短路退役**(恒返回 `why="follow-retired"`、`sid=""`)⇒
@@ -343,7 +436,7 @@ agent_created: true
└─ 🔴 实测依据:`collabd.py` 文首「处理 = 建检查会话排期 …… 由常驻 --supervise
每 2 轮判一次,是这条腿的**唯一载体**」⇒ **没有常驻 ⇒ 检查会话永远建不出来**
第 1 层:检查会话([结果检查]/[目标检查]) ← 常驻建的,⛔ 你自己建不了
第 2 层:任务会话([协作]-…) ← ⛔ **只有主会话在第①步建一轮**,之后不再建
第 2 层:任务会话([执行]-…) ← ⛔ **只有主会话在第①步建一轮**,之后不再建
```
🔴 **因此开工第 0 步的真顺序是**:
@@ -432,9 +525,20 @@ agent_created: true
| 文档 | 谁写 | 什么时候写 | 谁读 |
|---|---|---|---|
| `<目标目录>/目标执行状态.md` | **目标检查会话** | 核对完目标状态后 | 下一个检查会话/用户 |
| `<目标目录>/<棒次>_<事项>_<日期>.md` | **任务会话(协作棒)自己** | 本轮做完时(=`--report done` **之前**) | 检查会话照 `artifact` 读 |
| `<目标目录>/<棒次>_<事项>_<日期>.md` | **任务会话(执行棒)自己** | 本轮做完时(=`--report done` **之前**) | 检查会话照 `artifact` 读 |
| `tasks.json` | `--report`(机器) | 每次状态转移 | 全部环节 |
🔴🔴 **目标目录的完整形态(2026-10-05 用户定案,逐字:「`<工作区根>/执行会话/目标-xxx-xxxxxx/` 改成这样」)**:
```
<工作区根>/执行会话/目标-<简称或标题前缀≤20字>-<sha1(title)前6位>/
```
- **加了一层 `执行会话/`** —— ⛔ 目标文件夹**不再直接散在工作区根**(用户诉求:根目录干净、历史目标归拢一处)。
- 单一真源:常量 `_GOAL_DIR_PARENT = "执行会话"` + `goal_dir_name()`(⛔ 别在调用方各拼一遍)。
- ⚠️ 短哈希算的是 **`title`(全量标题)**,⛔ 不是 `short` ⇒ **改标题 = 换目录名**(存量里已有漂移案例,见 `pitfalls.md`)。
- ⚠️ **域目录不受影响**:独立域仍是「工作区第一层目录」;`执行会话/` 是**目标文件夹的父层**,⛔ 不参与域键计算。
🔴 **落点是死的**:执行产物的 `--artifact` **必须**指进 `<目标目录>/` 里
(⛔ 不许写回 `交付物/`、`docs/`、工作区根 —— **那正是「到处找」的由来**)。
⚠️ **落点=软判据**(`artifact_dir_ok()` 只**提示**):存量里有落在别处但有效的产物,
@@ -653,12 +757,12 @@ agent_created: true
· ① 原话逐字:「**这个会话和协作会话的技能包 运行的第一件事 ,就应该是检查清楚 所有会话规划是否配置完整且生效,然后标记一个状态**」
· ② 原话逐字:「**就应该是检查清楚 所有会话规则机制 是否配置完整且生效, 不是规划 是 规则**」⇒ 对象 = **规则机制**(钩子 / 闸门 / 技能指针 / 常驻 / 编排…),⛔ 不是"排期规划"。🔴 首版按①的字面做成「会话规划体检」、**只查排期那一面** ⇒ 当天实测出的三类失效(钩子注入指向**已退役技能名** / 快照**写进幽灵目录** / **每轮注入的记忆**里指针悬空)**一条都查不到** ⇒ 旧脚本已退役到 `<WS>/归档/技能包-旧件-20261002/`,**同包内只剩一个入口**(两个入口 = 「在册 ≠ 生效」本身)。
⇒ **怎么跑**:`"$PY" "<本包>/scripts/session-rules-check.py" [--ws <工作区>]` —— ✅ **已接进工作区 `state.py`**(跑状态快照就自带这一段,⛔ 不必另记一条命令)。
⇒ **查三类、十二项**:**A 机制装没装好** ① 关键钩子在册 ② 钩子脚本路径存在 ③ 钩子注入里引用的技能名**是否还存在** ④ 钩子**真在被调用**没(闸门日志新鲜度)|**B 规则载体同没同步** ⑤ **每轮注入的记忆**里引用的技能名存在 ⑥ 常驻规则快照**不比权威旧**|**C 编排在不在跑** ⑦ 唤醒 / 跟进两台**周期钟**(缺 = 没人推 / 没人收)(⚠️ 其中「唤醒」这台是**代偿形态** —— 定案的唤醒时钟=**常驻投递**(⑩ 那一项查的才是它);「唤醒排期在册」⛔ **不等于唤醒时钟已就位**,两件事要分开读)⑧ 排期绑的模型**会不会被服务端拒**(`model_is_thinking=0` + flash 系 ⇒ 每触发必拒,2026-10-02 实测)⑨ `cwds` **归属同形**(错一字面 ⇒ 裂组且自我强化)⑩ **投递(常驻)**心跳 ⑪ 三类会话**当前有没有活的** ⑫ 有没有「**从未运行**就失效」的一次性排期。
⇒ **查三类、十二项**:**A 机制装没装好** ① 关键钩子在册 ② 钩子脚本路径存在 ③ 钩子注入里引用的技能名**是否还存在** ④ 钩子**真在被调用**没(闸门日志新鲜度)|**B 规则载体同没同步** ⑤ **每轮注入的记忆**里引用的技能名存在 ⑥ 常驻规则快照**不比权威旧**|**C 编排在不在跑** ⑦ 唤醒 / 跟进两台**周期钟**(缺 = 没人推 / 没人收)(⚠️ 其中「唤醒」这台是**代偿形态** —— 定案的唤醒时钟=**常驻投递**(⑩ 那一项查的才是它);「唤醒排期在册」⛔ **不等于唤醒时钟已就位**,两件事要分开读)⑧ 排期绑的模型**会不会被服务端拒**(`model_is_thinking=0` + flash 系 ⇒ 每触发必拒,2026-10-02 实测)+ 🔴🔴 **机制建的排期模型是否与「本区主会话」同值**(2026-10-05 加,P0-80 —— 此前 `collabd.py` 把模型**写死**成 `space-bunny`,而主会话是 `deepseek-v4.1-flash` ⇒ 「同一件活在两种模型上跑」;⚠️ 该判据**扫描面必须含 `once`**,机制建的排期全是 `once`,只扫 `recurring` 就恒绿)⑨ `cwds` **归属同形**(错一字面 ⇒ 裂组且自我强化)⑩ **投递(常驻)**心跳 ⑪ 三类会话**当前有没有活的** ⑫ 有没有「**从未运行**就失效」的一次性排期。
⇒ **标记**:结论写成 `<WS>/.workbuddy/collab/session-rules.json`(`verdict` = `ok`/`warn`/`fail` + 逐项 `detail`)—— 后续会话与看板**读它**,⛔ 不靠人复述。
🔴 **为什么必须是第一件事**:2026-10-02 实测——排期**都在册**、模型**都可用**、cwds **都同形**,**却三类会话一条活的都没有**(=配置在、机制没在跑);同一天还查出钩子注入文本指着**已合并退役的技能名**、常驻快照脚本**写到没人读的幽灵目录** ⇒ 全是「**看着有配置、其实没生效**」。这类状态**不问就不会知道**,等它表现成"卡住"时已经晚了。
🔴 **判据本身也要能报出问题**:⑨ / ⑫ 这两项(以及 `cwds` 判据的边界)用**合成样本 + 四个变异体**做过红绿对照(夹具 `<WS>/tmp/rules-check-mutate.py`,跑完即弃)—— 变异体=判据恒空 / 判据放宽成"同父目录即报" / 把"从未运行"当"跑完了" / 不排除"还有下次触发"的排期,**逐一按预期报红**。⛔ **别拿"实跑一次没报错"当验收** —— 判据恒空时那次实跑**同样是绿的**。
⛔ **只标记、不设卡**:体检 `rc≠0` 也照常开工 —— 它的职责是**把状态问清楚**,不是拦人。
- 🔴🔴 **开工清单:主会话开工的第 0 步不是"派活",是"把三类会话摆好"**(用户 2026-10-01 明令:「**开始会话完成需求的时候,主会话需要创建 唤醒会话 以及根据分工类别 创建 协作会话 和 跟进会话呢 不然整个机制跑不起来**」)⇒ 建 **唤醒会话** `[唤醒]-<类别>-<具体>`(少建=**没人推**,需求原地静着)+ **每个分工类别一条任务会话** `[协作]-<类别>-<具体>`(少建=**没人干**)+ **跟进会话** `[跟进]-<具体>`(少建=**没人收**)。🔴 **跟进会话是全局唯一席位、⛔ 不按类别各建一条**(2026-10-02 用户订正);它是**收口者**:任务会话干完活把**待核对状态**写进执行队列,上报给**这固定的一个**跟进会话处理。⚠️ **只有自动化能开新会话** ⇒ "建会话"=登记一条自动化,⛔ 不是自己 spawn;标题**第 2 级必须带方括号、值取 `goal.json` 的 `topics`**(⛔ 用 `short` ⇒ 静默漏管)。细则 ⇒ `architecture.md §2.3.0d`。
- 🔴🔴 **开工清单:主会话开工的第 0 步不是"派活",是"把三类会话摆好"**(用户 2026-10-01 明令:「**开始会话完成需求的时候,主会话需要创建 唤醒会话 以及根据分工类别 创建 协作会话 和 跟进会话呢 不然整个机制跑不起来**」)⇒ 建 **唤醒会话** `[唤醒]-<类别>-<具体>`(少建=**没人推**,需求原地静着)+ **每个分工类别一条任务会话** `[执行]-<类别>-<具体>`(少建=**没人干**)+ **跟进会话** `[跟进]-<具体>`(少建=**没人收**)。🔴 **跟进会话是全局唯一席位、⛔ 不按类别各建一条**(2026-10-02 用户订正);它是**收口者**:任务会话干完活把**待核对状态**写进执行队列,上报给**这固定的一个**跟进会话处理。⚠️ **只有自动化能开新会话** ⇒ "建会话"=登记一条自动化,⛔ 不是自己 spawn;标题**第 2 级必须带方括号、值取 `goal.json` 的 `topics`**(⛔ 用 `short` ⇒ 静默漏管)。细则 ⇒ `architecture.md §2.3.0d`。
- 🔴🔴 **缺会话 ⇒ 自动拉起**(用户 **2026-10-02** 口径,逐字:「**是用户说 使用协作会话方式 完成目标 或 继续完成目标**」)
⇒ 用户说这两句(或队列堵住)时:**先查三类会话齐不齐、活不活**;**缺 ⇒ 机制自己补建排期把它拉起来**,
⛔ **不许把"你去开一条会话"甩给用户**(旧行为=写 `NEED-USER.md` 喊人开会话,本条**取代**它)。