session-mechanism:主会话只能由用户开(撤掉"排期建主会话"那条路)
用户报障:「技能中没有任何创建主会话的机制,除非是创建接续会话」。
病灶:supervise-persistence.md §〇 早期把「定时任务创建主会话」与「用户手动
创建主会话」并列成两种合法场景,SKILL.md §⑥ 顺着抄了一遍 ⇒ 读到的人会理解成
"这条路是允许的",于是照做。
实测事故(mcn-aigc-ontology 2026-10-14 07:31):init_workspace 装机制后建出
recurring 排期 [主]-super-i卡片采集-主会话(FREQ=DAILY;BYHOUR=09),prompt 里
写着「你是本工作区的主会话……要推进就直接建 [执行] 排期拉起任务会话」——
主会话的口径被套到了一条排期身上。排期开出来的会话恒是任务会话那一档
(is_background_automation=1)⇒ 台账里多一条"主会话",用户那边没多窗口。
改动:
- SKILL.md §⑥:改成「形态只有一种:主会话由用户手动开」,⛔ 排期拉不出主会话
- supervise-persistence.md §〇:表格两列改一列 + 新增事故回放小节
- supervise-persistence.md §八:删掉「B · 定时任务创建主会话」整行
- architecture.md §1:新增《主会话怎么来:只能由用户手动开》段
- session-rules-check.py:新增判据 ⑬ main_sched(扫排期名以 [主] 开头或含
"主会话" ⇒ ACTIVE 报 fail、非 ACTIVE 报 warn);扫描面 recurring 与 once 全含
- SKILL.md 体检清单:十二项 → 十三项,补 ⑬ 变异对照记录
判据验收(非恒绿):喂 mcn 区真数据三种输入 —— 原样 PAUSED ⇒ warn;
伪造成 ACTIVE ⇒ fail;无此类排期的区 ⇒ ok。
同批带上的既有改动:supervise-launch.py 路径相对化 + 三级取值(禁回落 ~)。
This commit is contained in:
1 parent
aa89ee0333
commit
053a6a6723
5 files changed
+178
-24
No files matched your search
@@ -108,6 +108,14 @@
|
||||
|
||||
**宿主(WorkBuddy 本体)=地基,⛔ 不是第 6 个主体**。它只提供四样:**状态**(三张只读表)/**调度**(自动化排期=**唯一能开新会话的通道**)/**事件**(钩子)/**互斥**(域锁)。
|
||||
|
||||
🔴🔴 **主会话怎么来:只能由用户在 WorkBuddy 里手动开**(2026-10-14 重申,用户原话「**技能中没有任何创建主会话的机制**」)。
|
||||
· **⛔ 排期开不出主会话** —— 排期拉起的会话恒是任务会话那一档(`is_background_automation=1`);
|
||||
它顶着 `[主]-…` 的名字也**不是主会话**:台账里多一条,**用户那边根本没多窗口** ⇒ 让人误以为"机制自己创建了一个主会话"。
|
||||
· **排期只用于派活与检查两条线**:`[执行]-[<类别>]-<具体>`(主会话派活)/`[检查]-[结果检查/目标检查]-…-第N棒`(常驻建)。
|
||||
· **接续会话**是主会话撞阈值时**由它自己建出来的形态**(角色继承被接续那条),⛔ **不是**"机制建主会话"的又一条路。
|
||||
· 判据:`session-rules-check.py` ⑬(`main_sched`)—— 报本区有没有「顶着主会话名字」的排期。
|
||||
· 实测事故 ⇒ `supervise-persistence.md §〇`(mcn-aigc-ontology 2026-10-14 07:31)。
|
||||
|
||||
🔴 **职责硬边界(2026-09-29 用户定案)**:**「投递(通知主会话)」唯一属于投递** —— 目标检查**只维护队列/台账与投影**,⛔ **不做任何投递**。
|
||||
· 理由:两条路径各自判重 ⇒ 同一内容**成对重复投递**(实测:同 hash 秒级两次)⇒ 每次投递都往主会话**会话队列里压一条** ⇒ 压满即"卡死假象"(22:53 那次事故的根因)。
|
||||
· 🔴 **2026-09-30 更新**:常驻程序的投影轮(`--once`)必须传 `mutate=False`,**⛔ 不许消费队列**(否则"消费掉却不投递" ⇒ 通知永远发不出去)。详见 **§4.2**。
|
||||
|
||||
@@ -22,19 +22,41 @@
|
||||
> + 2026-10-05/06 的 P0-72/P0-73/P0-74 实测。
|
||||
|
||||
|
||||
## 〇、🔴🔴 先分场景:两种"长期"不是一回事
|
||||
## 〇、🔴🔴 先分场景:长期在线的会话只有一种
|
||||
|
||||
**两种都要长期在线,但它们要的东西不同** —— ⛔ 别混用,混用就会出现
|
||||
"看起来在跑、其实随时会死"或"该停时还在跑"。
|
||||
**要长期在线的会话只有一种:用户在 WorkBuddy 里手动开的那条主会话。**
|
||||
⛔ **排期按点拉起主会话这条路不存在** —— 它是本档早期版本自己推演出来的形态,**2026-10-14 已判定作废**。
|
||||
(本档 §八 验收表里那行「B · 定时任务创建主会话」同批作废,⛔ 别照做。)
|
||||
|
||||
| | **场景 A · 用户手动创建主会话** | **场景 B · 定时任务创建主会话** |
|
||||
|---|---|---|
|
||||
| 典型形态 | 用户在 WorkBuddy 里自己开一条 `[主]-…` 会话,盯着它推进 | 排期按点拉起 `[主]-…`(`recurring`,如 `FREQ=HOURLY;INTERVAL=1`) |
|
||||
| 会话寿命 | **随用户何时收工**(可能几分钟,也可能几小时) | 跑完即 `completed`,**与下一跳之间有静默窗** |
|
||||
| 🔴 **对"常驻"的硬要求** | ⛔ **不能靠会话活着** —— 一收工就没人拉 ⇒ **必须脱离会话** | ✅ 会话自己周期性回来 ⇒ 但**每跳之间仍有空窗** ⇒ **同样要脱离会话** |
|
||||
| 唯一合格载体 | **计划任务**(第一~三节) | 同左(⛔ **排期代替不了载体** —— 排期只是"谁按点喊一次",喊完会话就结束) |
|
||||
| 怎么验它真活着 | 心跳 `pid` 活 ∧ `ts` 距今 < 90 s + `round` 递增 | 同左,⚠️ **且要静置 ≥ 12 分钟**(⛔ 短观察证明不了事) |
|
||||
| 谁负责"目标完成后关它" | 常驻主循环见 `guard.stop` 即收工(第七节) | 同左 —— ⛔ **排期不会帮你关** |
|
||||
| | **唯一场景 · 用户手动打开主会话** |
|
||||
|---|---|
|
||||
| 典型形态 | 用户在 WorkBuddy 里自己开一条 `[主]-…`(或 `主控 · …`)会话,盯着它推进 |
|
||||
| 会话寿命 | **随用户何时收工**(可能几分钟,也可能几小时) |
|
||||
| 🔴 **对"常驻"的硬要求** | ⛔ **不能靠会话活着** —— 一收工就没人拉 ⇒ **必须脱离会话**(计划任务,见第一~三节) |
|
||||
| 唯一合格载体 | **计划任务**(第一~三节) |
|
||||
| 怎么验它真活着 | 心跳 `pid` 活 ∧ `ts` 距今 < 90 s + `round` 递增 |
|
||||
| 谁负责"目标完成后关它" | 常驻主循环见 `guard.stop` 即收工(第七节) |
|
||||
|
||||
### 🔴🔴 为什么⛔ 不能"用排期拉起主会话"(2026-10-14 实测事故)
|
||||
|
||||
> **一句话**:**主会话只能由用户开**(`SKILL.md`《三类会话》类别表逐字:「主会话 | **用户手动开** | 管目标与方向、派活 | 用户关窗」)。
|
||||
> 排期开出来的会话**恒是任务会话那一档**(`is_background_automation=1`)⇒ 它一出生就**不是主会话**,
|
||||
> 却顶着 `[主]-…` 的名字 ⇒ **台账里多一条"主会话",用户那边根本没多窗口** ⇒ 报"机制自己创建了一个主会话"。
|
||||
|
||||
**事故回放**(mcn-aigc-ontology,2026-10-14 07:31):
|
||||
1. 用户 07:12 手动开 `9e069caf`「加载会话技能」= 该区真主会话。
|
||||
2. 07:30 `init_workspace.py` 装机制、常驻拉起,顺手把 `9e069caf` 登记进 `goal.json`。
|
||||
3. **07:31:11 建出一条 `recurring` 排期** `[主]-super-i卡片采集-主会话`(`FREQ=DAILY;BYHOUR=09;BYMINUTE=0`),
|
||||
prompt 逐字写着「你是本工作区的主会话……要推进就直接建 `[执行]` 排期拉起任务会话」
|
||||
—— **这是"主会话"的口径,被套到了一条排期身上**。
|
||||
4. ⇒ 该排期每天 09:00 会开出一条**顶着主会话名头的任务会话**;长期跑 ⇒ 台账里主会话越积越多。
|
||||
5. **处置**:该排期已置 `PAUSED`(`automation_update`,零删除可逆)。
|
||||
|
||||
**为什么会有人这么干**:本档 §〇 早期表格把「定时任务创建主会话」与「用户手动创建主会话」**并列成两种合法场景**,
|
||||
`SKILL.md` §⑥ 也顺着写了「用户手动创建主会话 / 定时任务创建主会话」。
|
||||
读到这里的人(或 AI)会理解成「排期建主会话 = 允许的」,于是照做。
|
||||
⇒ **2026-10-14 已把这两处一并改掉**(本档 §〇 表格 + `SKILL.md` §⑥ 那句),
|
||||
⛔ 保留本事故回放只为留痕,⛔ 不表示这条路还存在。
|
||||
|
||||
### 🔴 常态口径(2026-10-04 用户定案,当场订正)
|
||||
|
||||
@@ -405,14 +427,18 @@ $p = Get-Process -Id <pid> -ErrorAction SilentlyContinue # $null = 已死
|
||||
(⛔ 别把跨区自愈当载体的替代品:它要求本区常驻先活着)。
|
||||
|
||||
|
||||
## 八、按场景对照(选哪条 / 怎么验 / 常见坑)
|
||||
## 八、对照(怎么验 / 常见坑)
|
||||
|
||||
| 场景 | 主会话怎么来 | 常驻载体 | 目标完成后谁关 | 常见坑 |
|
||||
|---|---|---|---|---|
|
||||
| **A · 用户手动创建主会话** | 用户自己开 `[主]-…`,盯着推进 | 计划任务 → `pythonw` → `supervise-launch.py` | 常驻见 `guard.stop` → 优雅退出 | 🔴 用户一收工就没人拉 ⇒ 若没装载体,常驻会在会话结束时**静默死掉**(看板还显示"在线") |
|
||||
| **B · 定时任务创建主会话** | 排期 `recurring` 到点拉 `[主]-…` | 同上(⛔ **排期代替不了载体**) | 同上 | 🔴 **`once` 排期过期即哑**(`next_run_at=None`、界面仍显示 ACTIVE)⇒ **静默窗内无人**;🔴 排期跑完即 `completed`,**下一跳之前是空窗** |
|
||||
| **唯一 · 用户手动创建主会话** | 用户自己开 `[主]-…`,盯着推进 | 计划任务 → `pythonw` → `supervise-launch.py` | 常驻见 `guard.stop` → 优雅退出 | 🔴 用户一收工就没人拉 ⇒ 若没装载体,常驻会在会话结束时**静默死掉**(看板还显示"在线") |
|
||||
|
||||
**共同判据(两种场景都一样,⛔ 每次改完都验)**:
|
||||
> 🔴🔴 **2026-10-14 撤掉一行**:原表里还有一行「**B · 定时任务创建主会话**」(排期 `recurring` 到点拉 `[主]-…`)。
|
||||
> **该行已作废** —— 主会话**只能由用户开**(见 §〇 事故回放),排期开出来的会话恒是任务会话那一档。
|
||||
> 那行里唯一还有价值的读数留在这里:🔴 **`once` 排期过期即哑**(`next_run_at=None`、界面仍显示 ACTIVE)
|
||||
> ⇒ **静默窗内无人**;🔴 排期跑完即 `completed`,**下一跳之前是空窗**。
|
||||
|
||||
**共同判据(⛔ 每次改完都验)**:
|
||||
1. `State` = **`Running`**(或 5 分钟窗内 `Ready`);
|
||||
2. `LastTaskResult` = **`267009`**(长驻中);⛔ `1` 也是信号(秒退);
|
||||
3. 心跳 `pid` 活 ∧ `ts` 距今 **< 90 s** ∧ `round` 递增;
|
||||
|
||||
Reference in new issue
Block a user