Files
admin 19101acd65 init: workbuddy_skills 重建,仅收录 session-mechanism
- 按用户指示清空原有 25 技能内容,只提交 session-mechanism(57 文件)
- 附 .gitignore(产物 + 本机凭据)
- 令牌明文已脱敏(历史 .neodata_token 与 pitfalls 引用均不入库)
- 本提交为孤儿提交(父提交为空),历史自此重新开始
2026-10-05 14:13:24 +08:00

176 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多会话执行 · 一页纸(怎么派活、怎么收活、怎么不干等)
> 🔴🔴 **2026-10-03 07:2x 状态块(本条为准,排在下面所有小节之上)——「上报/投递」整套退役**
>
> · ⛔ **投递已真删**(`supervise()` 203→71 行、`wake_enable` true→false)⇒ **§3 里"唯一投递方"那半条作废**、
> §4 的**唤醒会话/跟进会话两类已整套退役**(⇒ **§4 现只剩两类:主会话 + 任务会话**)。
> · ✅ **现行机制只有两条腿**:**接收**=`--report` 写 `tasks.json` 四态台账(唯一权威);
> **处理**=建 `[检查]-…` 排期(`maybe_spawn_check_agent()`,唯一载体=常驻 `--supervise`)。⛔ **没有"推送"这一环**。
> · 🔴 **「常驻投递」这个角色名也别再用** —— 角色本来就叫「**协作程序**」,"常驻"是**运行形态、不是角色名**。
> · ⇒ 逐条改未做(散在 4 份约 200 处);**冲突时以本块 + `architecture.md` 当前结论节为准**。
> 机制细节 ⇒ `SKILL.md` 文首 10-03 状态块;坑 ⇒ `pitfalls.md` P0-35 ~ P0-38。
> ⚠️ **深度以 `references/architecture.md` 为唯一权威**(本文件是**入口与判据**,⛔ 不另立第二份架构)。
> 踩过的坑以 `references/pitfalls.md` 为准;任务图细则见 `references/taskgraph.md`。
## 1 一句话
**派活用自动化(唯一能开新会话的通道)|收结果直读宿主库(0 token)|机械判定下沉到本地只读脚本|AI 只在需要判断时被叫起|用任务图 + 关键路径防干等。**
## 2 四条通道(哪件事走哪条 —— 走错就是最大的浪费来源)
1. **派活 ⇒ 只能走自动化**。宿主钩子**开不了新会话**,这是硬事实;所以「叫起下一个干活的人」只有自动化这一条路。
2. **收结果 ⇒ 直读宿主库**(`automation_runs` 等,宿主已把各线结论写好)。⛔ 不要为了"问一句进展"去叫一个会话 —— 那是 0 收益的开销。
3. **机械判定 ⇒ 下沉到本地只读脚本**(`collabd.py --once` 等)。这类事不需要 AI 判断,⛔ 不要占用会话。
4. **人只看一个看板** ⇒ 只读旁路观测,异步、可延迟,**⛔ 不许影响程序执行**。
## 3 节奏:常驻为主,钩子作补充
- 🔴 **触发源 = 常驻的目标检查 + 投递**(09-29 定案,**2026-10-01 用户再确认**:「**协作与投递一直运行(常驻)**」)。
理由:**⛔ 不是所有队列都由钩子产生** ⇒ 纯事件驱动**会漏**。
- ⛔ **自动任务("当闹钟")方案已废弃**(用户 2026-10-01:「**定时任务的方案已经废弃了**」)⇒ ⛔ 不要再建。
- `collabd.py --once` = **投影轮**(维护队列,**不投递、不推进**)。
- `collabd.py --tick` = **投递轮**,🔴 **唯一投递方 / 唯一推进方** ⇒ **由常驻投递按周期跑**。
- 🟡 **宿主钩子只作补充**(事件驱动的即时性),⛔ **不是主路径,⛔ 不得用它取代常驻**。
## 4 四个"会话类别",别混(🔴 2026-10-01 用户口径 · 由「三个角色」改)
> 🔴 **四类都在同一个工作区**(`config.workspace` 那一个目录),**靠标题两级前缀区分**(第 1 级=角色、第 2 级=任务类别),⛔ **不按 `cwd`、⛔ 不按 `workspaces` 表**。
- **主会话**:🔴 **只管目标和方向**(判断与派活)。它是**解析出来的、不是登记出来的** —— 三层规则全在 `resolve_main()` 一处(见 `architecture.md §7`)。🔴 **只由用户触发**,⛔ 不接机制推送。
- **任务会话**:承接具体活。看板上=**下面那个虚线大框**里那一排(有几个排几个;一个都没有时画**虚线空框**,⛔ 不许省略整层)。
- **唤醒会话**:🔴 三条硬定性 —— **本质还是会话** / **独立会话(⛔ 不在主会话上处理)** / **随需求确定时才创建**。看板上它在**主会话下面那一行(`RW`)左格**、与右格**跟进会话等宽**,靠**位置**区分、位置不变;「还没建」是**正常态**、⛔ 不是故障。
- 🆕 **队列上报的跟进会话**:🔴 用户 2026-10-01 口径 —— **主会话只管目标和方向**,「**队列上报的会话 让专门的 跟进会话处理**」。✅ **投递路由已落地**:按件的类别选「**跟进会话**」(`follow_for_topic()`),**⛔ 绝不投主会话**;连一条跟进都解析不出/已有但不活 ⇒ **喊用户**(⛔ **不降级投主会话**)⇒ 详见 `architecture.md §2.3.0c`。
🔴 **看板上的两个「虚线大框」= 分组,⛔ 不是节点、也⛔ 不是新一层**:
上面那个框住「**主会话 + 唤醒会话 + 跟进会话**」(=**用户那一面 + 机制那一面**),下面那个框住**任务会话**;
**两个大框之间只有一条线 = ① 派活**(⛔ 不再从主会话画多条扇形线出去)。⚠️ 改框宽/改格宽必须**重算框**(框由该排布局现推,⛔ 不写死)。
⇒ 位置、形状、命名沿革与两道自检:`collab-detail.md §0.5.5`;布局常量与两道自检:`architecture.md §2.3.0c-2`。
### 4.1 🔴🔴 **开工清单:主会话开工时**必须**把三类会话建齐**(用户 2026-10-01 明令)
> 用户原话:「**开始会话完成需求的时候,主会话需要创建 唤醒会话 以及根据分工类别 创建 协作会话
> 和 跟进会话呢 不然整个机制跑不起来**」
| 该建什么 | 标题形态 | 少建 ⇒ 断在哪 |
|---|---|---|
| **唤醒会话** | `[唤醒]-<类别>-<具体>` | 没人推 → 需求停在原地(实测 3.5 h 零成果) |
| **任务会话**(**每个分工类别一条**) | `[协作]-<类别>-<具体>` | 没人干 → 该类别解析不出承接者 |
| **跟进会话** | `[跟进]-<类别>-<具体>` | 没人收 → 队列上报全挤回主会话 |
**三条硬约束**:① **只有自动化能开新会话** ⇒ "建会话"=**登记一条自动化**,⛔ 不是自己 spawn;
② 标题**第 2 级必须带方括号**、值取 `goal.json` 的 `topics`(⛔ 用 `short` ⇒ 静默漏管);
③ **"还没建"是正常态**,但**开工就必须建**,看板上如实显示成灰 ○。
⇒ 细则与踩坑:`architecture.md §2.3.0d`。
### 4.1b 🔴🔴 **缺会话 ⇒ 自动拉起**(用户 2026-10-02 口径 · **运行期也要做**,⛔ 不只是开工那一刻)
> 用户原话(触发面,逐字):「**是用户说 使用协作会话方式 完成目标 或 继续完成目标**」
- **触发**:用户说这两句(等价说法「继续执行」也认),**或**队列堵住(投递报 `follow-not-live` / `no-follow-session`)。
- **动作**:**先查齐备度** ⇒ **缺 ⇒ 自动拉起**。
⛔ **不许**写 `NEED-USER.md` 请用户自己去开一条会话 —— 那是把机制该干的活推给人。
- 🔴 **齐备度怎么算(2026-10-02 订正)**:**协作/唤醒按类别**各算一条;**跟进是全类别唯一席位**——
`collabd.py --gap` 对它**不按类别分桶**(桶键恒 `(follow, "")`),一个工作区从头到尾只应有**一条**活的
跟进会话。⛔ 别按类别建出 N 条 `[跟进]-[<类别>]-…`(本棒初版就建错成 2 条,已订正)。
- **判据 + 现成参数**:`python scripts/collabd.py --gap`(只读)⇒ 列出缺口 + 每条该建的排期
(name / prompt / scheduleType / scheduledAt / cwds)。硬缺=**跟进/协作**会话没有活着的;
**唤醒**会话算"软缺"(用户定性「随需求确定时才创建」)。
- **谁执行**:**会话**(`automation_update`)。⛔ 脚本**不许**写 `automations` 表(双红线)
⇒ 这是唯一通路,也是"自动"的全部含义。
- **怎么送到会话**:钩子 `wb-result-hook.py` 在 `UserPromptSubmit` 把缺口**注入当前会话上下文**
(零 token;触发词命中即查,否则 120 s 节流查一次)⇒ 用户照常说那句话即可,**什么都不用做**。
🔴 **「接续会话」⛔ 不是第 5 类,是「形态」**:上面**任一类**撞到阈值(上下文/日志)时,**由它自己**建出下一棒 —— **角色继承被接续的那条**(主会话的接续仍是主会话候选)。详见 `architecture.md §2.3.0b`。
🔴 **接续棒必须带类别**(`接续 · [<类别>] · <具体>` 或标题里出现类别名)——
否则归属判据(角色+**类别子串**)认不出它,它会被**静默漏管**(不进看板、`--ready-next` 也不算它在跑)。
⚠️ 主会话的续棒要**保住 `主控` 前缀**(`主控 · <类别> · 接续自 <id8>`)—— 否则它被判成干活的棒,
主会话候选会**变空**(P0-11 实测踩过)。
### 4.2 🔴🔴 **接续退位:建出下一棒之后,把前棒**退场**(用户 2026-10-01 立)
> 用户原话:「**通过接续会话的时候,如何处理过期的会话,避免越堆越多**」
**为什么必需**:接续=会话自己建下一棒,而**前棒不会自动消失** —— 它在宿主库里永远是
一条 `completed` 记录、标题同族。实测本工作区**已堆 5 条**「接续 · 会话机制合并…」⇒
看板与状态稿每轮都为旧棒占位,**真在跑的棒被埋在里面**(越用越糊)。
**两条退场路径**(⛔ 一条都不许少):
| 路径 | 怎么做 | 什么时候生效 |
|---|---|---|
| **显式**(准确) | 建出下一棒后立刻 `collabd.py --retire self --by <接棒会话id> --why 接续` | **立刻** |
| **窗口兜底** | 自动:`completed` 且超 `session_live_min`(默认 90)分钟未动 | 等窗口到 |
⛔ **两条闸门都绕开 `working`**(在跑的棒一定要摊在版面上)+ **主会话是版面锚点**(⛔ 不按窗口抽掉)。
⛔ **退场 ≠ 删除**:宿主库原样在、`retired.json` 全留痕(**可逆、可追溯**)⇒ 但**必须报数**
(看板/状态稿都会写「已收起 N 条」—— 收起而不说=读者把"收起了"读成"本来就没有",同族红线)。
⚠️ **前棒中途死掉时显式那步不会发生** ⇒ 靠窗口兜底收(同"每小时兜底唤醒"的设计口径)。
### 4.3 🔴 主会话生病了就**换一条**,别指望它自愈
- **哑会话**(诊断日志撞 ~10 MiB ⇒ 宿主拒写 ⇒ **界面永远刷不出内容**)**照样在"活会话"列表里**
⇒ 判据必须是「**活着 ∧ 不哑**」(`_pick_live()` 同时管这两条,`resolve_main` 的**每条路**都得走它)。
- **处置(标准 runbook)**:把 `<sid>.log`(连同 `.log.1`)**改名挪开**(⛔ 不删,用 Python `os.rename`,
⛔ 别用 `mv`)⇒ 宿主数十秒内重建并恢复写入 ⇒ 详见 `references/forensics.md §4`。
⚠️ **它必然复发**(每个会话涨到上限都会重演)⇒ 靠扫描器 + 钩子兜底。
- **换主会话的逃生口**:`collabd.py --declare --role main` —— 🔴 它的语义是「**换**」:
会把**其它登记为 main 的一律降级为 worker**(一个工作区一条主会话)+ **明确说出口**。
⛔ 旧语义是"加",等于**什么也没换**(`_main_sid()` 取第一条 main,而 Python dict
对已存在的键赋值**不改位置** ⇒ 老那条永远排前面,逃生口形同虚设 —— 2026-10-01 实测踩到)。
🔴 **两个极易踩的读数坑**:
1. **唤醒会话的读数源是 `sessions` 表**(标题前缀 `[唤醒]`),⛔ 不是 `automations` 表。
2. 🔴 **自动唤醒任务 / 协作轮的排期名必须带 `[协作]` 前缀** —— 否则会被 `resolve_main` 认成"主会话",**通知投给它自己**。
⚠️ 🔴 **2026-10-02 标注(⛔ 不是口径变更)**:本规则**只在「唤醒用排期」这个代偿形态下才有对象** —— 定案的唤醒时钟是**常驻投递**(⛔ 不开会话、没有排期名);⛔ 别因为这条规则在,就反过来认定「唤醒本该用排期」。
## 5 一次派活要带什么(模板要点)
1. **开工第 0 步:抢域锁**(域按**显式 domain** 切,⛔ 不按 cwd、⛔ 不按工作区)。
2. **本轮只做一件事,做完即停**(无人值守必写;否则它会一路做下去把预算烧光)。
3. **收尾自判**:还有缺口 ⇒ 接下一棒;`blocked` ⇒ ⛔ 不接,改喊用户。
4. 任务细节⛔ **不要抄进 prompt**(prompt 只写"去哪读",⛔ 不复制正文)—— 抄进去等于每轮都全量重发。
## 5.5 🔴 **任务会话的标准动作:六阶段**(用户 2026-10-04 定案)
> 用户原话:「这个是**会话解决问题的步骤**(需求识别、需求调研、方案规划、任务执行、结果验证、归档清理)这几个步骤 **正式执行会话执行任务的流程**」。
> 📌 **来源**:这套六阶段原是 `dsh-workflow §1`「平台改造六阶段」(DSH 平台改造流程);
> 用户把它**收进会话机制** ⇒ 它现在是**任务会话的正式执行流程**,⛔ 不再只是平台改造专用。
**六阶段**(任务会话从接手到收口的标准动作,⛔ 跳步是本机制最常见的失手):
| # | 阶段 | 这一阶段要做什么 | 缺了会怎样(⛔ 后果) |
|---|---|---|---|
| **0** | **需求识别** | 先盘点现状再动手:派活说清「要做什么 / 怎样算成功」,能落到**功能卡 4 问**就落到 4 问 | ⛔ 直接开工 ⇒ 做的是"我以为的",不是"要的" |
| **1** | **需求调研** | **源码级实证优先** ⛔ 禁止只靠文档推断;查清现状与既有约束 | ⛔ 照着过时文档改 ⇒ 改错对象、返工 |
| **2** | **方案规划** | 文档先行;方案定完再动工;🔴 判"该不该问用户"就在此刻(见下) | ⛔ 边做边想 ⇒ 方向错了已写了一半代码 |
| **3** | **任务执行** | 小步推进 + 每步可验;按 §4 派活通道执行,⛔ 不越界抢别的域 | ⛔ 一口气做完 ⇒ 中途错了不知道错在哪 |
| **4** | **结果验证** | **看产出物** ⛔ 不看任务图 `done`(那是两件事,见 §6);能用浏览器验就浏览器验 | ⛔ 拿"标了完成"当"真完成" ⇒ 假收口 |
| **5** | **归档清理** | 文档同步 + 产物落到**本目标的交付物** ⛔ 不散在工作区根 | ⛔ 下棒找不到上棒产物 ⇒ 链条静默断掉 |
🔴 **每个阶段都能撞上"该自己定还是该问用户"** ⇒ 那一刻的判据读
**`references/02-功能优先协作协议.md`**(9 类自决策白名单 / 只准提报用户 3 类 / 语言转换表 / 拆包提报用户)。
⚠️ **最常提报用户的是阶段 2(方案规划)**:功能语义分叉 ⇒ 必须问;技术选型 ⇒ ⛔ 不许问,自己定并记一句"我选了什么(可推翻)"。
📌 **与 `dsh-workflow` 的分工**(⛔ 别把两处当同一件事):
本节 = **任务会话在会话机制里干活的标准动作**(六阶段,落地口径在本包);
`dsh-workflow §1` = **DSH 平台改造的完整手册**(六阶段之外还有红线 R1–R11、并行调度三把锁、档案模板、浏览器验证栈)
⇒ 需要红线 / 锁 / 模板时 ⇒ 读 `dsh-workflow`;⛔ **只做会话内的活,本节足够**。
## 6 反馈协议与唤醒(防"干等"与"空转")
- **反馈协议 = 单条 + 握手**(⛔ 不是群发、⛔ 不是广播)。
- **唤醒 = 三条件合取**才触发(条件见 `architecture.md §2.2`)。
- **需求内闭环**:一个需求内的活由该需求自己的会话闭环收口(定义见 `architecture.md`「需求内闭环」节)。
- 🔴 **防"空转链条"**:**「只是排了下一棒」≠「有成果」**。判完成必须看**产出物**,⛔ 不看任务图节点标了 `done`(那是两件事)。
## 7 任务图(防干等的核心件)
细则 ⇒ `references/taskgraph.md`(文件格式、`collabd.py taskgraph()` 算法、四条派活规则、维护纪律)。
一句话:**关键路径单线化 ⇒ 必须拆**,否则整条链被一个慢节点卡住,其他人全在干等。
## 8 加东西之前必须过的判据
`architecture.md §6`「加东西前必须过的判据(防打转)」。⛔ 没过的就⛔ 不要加。
⚠️ 但**「协作与投递的常驻」是已定案项**,⛔ **不得拿"进程数=0"去否它**(2026-09-30 踩过:丢掉唤醒时钟 ⇒ 用户点破"成摆设")。