fix(session-mechanism): 目标检查空闲阈值 3 → 2 分钟,并清掉四处过时说明

- `CHECK_IDLE_MIN` 由 3 改为 2(2026-10-18 用户令;此前 20 → 10 → 6 → 3)
- 同一文件里 4 处说明文字仍写着「静默 ≥20 分钟」,与参数不符(10-07 改参数时未同步)
  ⇒ 一律改为 2 分钟,含检查会话提示词里给会话看的那句「已静默 ≥N 分钟」
- 闸门数量口径统一:4 处「四道闸」改为「六道闸」(实际列的是六条)
- 已同步到工作区运行副本并重启常驻,md5 双端一致
This commit is contained in:
admin committed 2026-10-18 21:13:42 +08:00
1 parent 489da5f854
commit 1a37314519
1 file changed
+11 -11
+11 -11
View File
@@ -17,7 +17,7 @@
🔴 **2026-10-03 起本程序的真实现行口径**(用户原话「现在的机制是 协作程序接收和处理队列」): 🔴 **2026-10-03 起本程序的真实现行口径**(用户原话「现在的机制是 协作程序接收和处理队列」):
· **接收** = `--report` 把任务会话的执行状态写进 `tasks.json`(四态台账,唯一权威)。 · **接收** = `--report` 把任务会话的执行状态写进 `tasks.json`(四态台账,唯一权威)。
· **处理** = 建**检查会话排期**(`maybe_spawn_check_agent()`,四道闸)让会话去读队列干活 · **处理** = 建**检查会话排期**(`maybe_spawn_check_agent()`,六道闸)让会话去读队列干活
—— 常驻 `--supervise` 每 2 轮判一次,是这条腿的**唯一载体**。 —— 常驻 `--supervise` 每 2 轮判一次,是这条腿的**唯一载体**。
· **推送** = **没有这一环**。队列变化不再自动通知任何人,要落事得**显式建任务会话**。 · **推送** = **没有这一环**。队列变化不再自动通知任何人,要落事得**显式建任务会话**。
@@ -27,7 +27,7 @@
(网关发现仍在读,只是不再拿它发消息)。 (网关发现仍在读,只是不再拿它发消息)。
用法(🔴🔴 **2026-10-03 投递退役后的现行口径**;⛔ 已废弃「用自动任务当闹钟」): 用法(🔴🔴 **2026-10-03 投递退役后的现行口径**;⛔ 已废弃「用自动任务当闹钟」):
🔴 **判据:常驻(`--supervise`)现在只干两件事** —— 🔴 **判据:常驻(`--supervise`)现在只干两件事** ——
① **检查会话建排期**(唯一建排期的地方;四道闸在 `maybe_spawn_check_agent()` 内); ① **检查会话建排期**(唯一建排期的地方;六道闸在 `maybe_spawn_check_agent()` 内);
② **写心跳**(`supervise-heartbeat.json` + `.log`)——「常驻在不在」的唯一机读判据。 ② **写心跳**(`supervise-heartbeat.json` + `.log`)——「常驻在不在」的唯一机读判据。
⛔ **它不再投递、不再唤醒**:那两段已真删(收件人已退役)⇒ **留着常驻的唯一理由是 ①**。 ⛔ **它不再投递、不再唤醒**:那两段已真删(收件人已退役)⇒ **留着常驻的唯一理由是 ①**。
⚠️ 载体结论(2026-10-02 23:0x 实测订正,推翻更早的"没有进程能一直活着"): ⚠️ 载体结论(2026-10-02 23:0x 实测订正,推翻更早的"没有进程能一直活着"):
@@ -2136,7 +2136,7 @@ TASK_EVENTS = INBOX / "tasks-events.jsonl" # 只作审计(append-only,⛔
TO_MAIN = INBOX / "TO-MAIN.md" # 投递给主会话的通知(投影 · 供人/AI 直接读) TO_MAIN = INBOX / "TO-MAIN.md" # 投递给主会话的通知(投影 · 供人/AI 直接读)
TASK_STATES = ("pending", "running", "done", "blocked") # 需求台账四态:待执行/执行中/已完成/有阻碍 TASK_STATES = ("pending", "running", "done", "blocked") # 需求台账四态:待执行/执行中/已完成/有阻碍
QUEUE_IDLE_MIN = 5 # 唤醒**限流桶**(分钟):同一状态下最多每 **5** 分钟发一次(2026-09-30 用户拍板:30→10→**5**);⛔ 触发条件是 supervise() 的**四条件**(不是计时器) QUEUE_IDLE_MIN = 5 # 唤醒**限流桶**(分钟):同一状态下最多每 **5** 分钟发一次(2026-09-30 用户拍板:30→10→**5**);⛔ 触发条件是 supervise() 的**四条件**(不是计时器)
CHECK_IDLE_MIN = 3 # 🔴🔴 2026-10-07 用户三度拍板:**20 → 10 → 6 → 3 分钟**(10-08 02:4x 第三次) CHECK_IDLE_MIN = 2 # 🔴🔴 2026-10-18 用户令:**3 → 2 分钟**(此前 20 → 10 → 6 → 3,10-07/08 三度调整)
# 原话一:「把检查程序的等待时间由 20分钟 改为 10分钟」;原话二:「检查程序的等待时间改为6分钟」(当日 18:25)。 # 原话一:「把检查程序的等待时间由 20分钟 改为 10分钟」;原话二:「检查程序的等待时间改为6分钟」(当日 18:25)。
# 「检查程序」判"已经静默够久、可以建检查会话"的阈值(`queue-empty` 那条闸)。 # 「检查程序」判"已经静默够久、可以建检查会话"的阈值(`queue-empty` 那条闸)。
# ⚠️ 改这个数必须**一起改三处**,否则文案与判据打架: # ⚠️ 改这个数必须**一起改三处**,否则文案与判据打架:
@@ -4470,14 +4470,14 @@ CHECK_PROMPT_RESULT = (
+ _CHECK_TAIL_A + _CHECK_TAIL_B + _CHECK_TAIL_A + _CHECK_TAIL_B
) )
# 【目标检查】—— 队列**空**且静默 >3 分钟时:核对目标完成状态(阈值=`CHECK_IDLE_MIN`,2026-10-07/08 三度调整:20 → 10 → 6 → 3) # 【目标检查】—— 队列**空**且静默 >2 分钟时:核对目标完成状态(阈值=`CHECK_IDLE_MIN`,现 2 分钟;2026-10-18 由 3 改 2)
CHECK_PROMPT_GOAL = ( CHECK_PROMPT_GOAL = (
"**【目标检查会话 · 第 %d 棒】**本轮只做这一件事:**核对目标完成状态**,**做完即停**。\n" "**【目标检查会话 · 第 %d 棒】**本轮只做这一件事:**核对目标完成状态**,**做完即停**。\n"
"\n" "\n"
"目标:%s\n" "目标:%s\n"
"\n" "\n"
"## 一、为什么是你(🔴 触发条件已满足,不必重判)\n" "## 一、为什么是你(🔴 触发条件已满足,不必重判)\n"
"**所有会话都已结束** + **队列为空** + **已静默 ≥3 分钟** + **本项目没有别的待执行排期**。\n" "**所有会话都已结束** + **队列为空** + **已静默 ≥2 分钟** + **本项目没有别的待执行排期**。\n"
"\n" "\n"
"## 二、🔴 先读这五样,⛔ **只读这五个文件**,读完直接判断(⛔ 别到处找信息)\n" "## 二、🔴 先读这五样,⛔ **只读这五个文件**,读完直接判断(⛔ 别到处找信息)\n"
"> ⚠️ **不要在本工作区里到处翻文件**:2026-10-03 实测,检查会话因无边界地找资料\n" "> ⚠️ **不要在本工作区里到处翻文件**:2026-10-03 实测,检查会话因无边界地找资料\n"
@@ -4963,7 +4963,7 @@ def maybe_spawn_check_agent(reason: str) -> dict |None:
| reason | 排期名 | 触发条件 | 它的职责 | | reason | 排期名 | 触发条件 | 它的职责 |
|---|---|---|---| |---|---|---|---|
| `sessions-ended` | `[结果检查]-…` | 会话全结束 + **队列非空**(⛔ 不要求静默 20 分钟) | **跟进任务会话执行结果** ⇒ 判断是否**创建对应任务会话**继续完成目标,并创建 | | `sessions-ended` | `[结果检查]-…` | 会话全结束 + **队列非空**(⛔ 不要求静默) | **跟进任务会话执行结果** ⇒ 判断是否**创建对应任务会话**继续完成目标,并创建 |
| `queue-empty` | `[目标检查]-…` | 会话全结束 + **队列为空** + 静默 **≥20 分钟** | **核对目标完成状态** ⇒ 判断是**建任务会话**接着做、还是**改目标状态**(已完成),并执行 | | `queue-empty` | `[目标检查]-…` | 会话全结束 + **队列为空** + 静默 **≥20 分钟** | **核对目标完成状态** ⇒ 判断是**建任务会话**接着做、还是**改目标状态**(已完成),并执行 |
⇒ ⛔ **它们不是同一件事的两种触发**,⛔ 不许共用一个 prompt:前者面对"有活没人干", ⇒ ⛔ **它们不是同一件事的两种触发**,⛔ 不许共用一个 prompt:前者面对"有活没人干",
@@ -4987,7 +4987,7 @@ def maybe_spawn_check_agent(reason: str) -> dict |None:
⚠️ **配对必需**:只加这道闸而没有「谁去置阻碍」= 白加 ⇒ 出口见 `CHECK_PROMPT_RESULT` 第 3 条 ⚠️ **配对必需**:只加这道闸而没有「谁去置阻碍」= 白加 ⇒ 出口见 `CHECK_PROMPT_RESULT` 第 3 条
(**结果检查会话**是唯一能看见 `blocked` 的那条腿;目标检查要"队列为空"才触发、永不触发)。 (**结果检查会话**是唯一能看见 `blocked` 的那条腿;目标检查要"队列为空"才触发、永不触发)。
② **所有会话都结束**了(含主会话 · 用户第②条) ② **所有会话都结束**了(含主会话 · 用户第②条)
③ **队列状态要对得上 reason**:`queue-empty` 必须队列空 + 静默 ≥20 分钟; ③ **队列状态要对得上 reason**:`queue-empty` 必须队列空 + 静默 ≥2 分钟;
`sessions-ended` 必须队列**非空**(⛔ 队列也空 ⇒ 那是 `queue-empty` 那条的事,⛔ 不重复建) `sessions-ended` 必须队列**非空**(⛔ 队列也空 ⇒ 那是 `queue-empty` 那条的事,⛔ 不重复建)
④ 🔴🔴 **本工作区没有别的「待执行」排期**(用户 2026-10-03 新增判据,见 `ws_pending_schedules()`) ④ 🔴🔴 **本工作区没有别的「待执行」排期**(用户 2026-10-03 新增判据,见 `ws_pending_schedules()`)
⑤ **同名排期未在册**(去抖) ⑤ **同名排期未在册**(去抖)
@@ -6239,7 +6239,7 @@ def supervise(st: dict, deliver: bool = True, mutate: bool = True) -> dict:
🔴 与用户口径「**协作程序接收和处理队列**」的关系(本条为准,2026-10-03): 🔴 与用户口径「**协作程序接收和处理队列**」的关系(本条为准,2026-10-03):
· **接收** = `--report` 写 `tasks.json`(`task_report()`)—— **原样保留,仍是活的**。 · **接收** = `--report` 写 `tasks.json`(`task_report()`)—— **原样保留,仍是活的**。
· **处理** = 建排期派任务会话(`maybe_spawn_check_agent()`,由 `--supervise` 循环 · **处理** = 建排期派任务会话(`maybe_spawn_check_agent()`,由 `--supervise` 循环
每 2 轮判一次,四道闸在函数内)—— **原样保留,仍是活的**。 每 2 轮判一次,六道闸在函数内)—— **原样保留,仍是活的**。
· **被删的只是"把队列变化推给某个会话"这一步** —— 它没有收件人,留着就是空转。 · **被删的只是"把队列变化推给某个会话"这一步** —— 它没有收件人,留着就是空转。
⚠️ `deliver` / `mutate` 两个参数**只为兼容现有三处调用点的签名**(`--once` 传 ⚠️ `deliver` / `mutate` 两个参数**只为兼容现有三处调用点的签名**(`--once` 传
@@ -6670,7 +6670,7 @@ def main() -> int:
life, pend, idle, _all_sessions_idle())) life, pend, idle, _all_sessions_idle()))
# 🔴🔴 试算必须与 `maybe_spawn_check_agent()` 的闸**逐条对齐**(2026-10-04): # 🔴🔴 试算必须与 `maybe_spawn_check_agent()` 的闸**逐条对齐**(2026-10-04):
# · `sessions-ended`(队列非空)⇒ **不受目标状态限制**; # · `sessions-ended`(队列非空)⇒ **不受目标状态限制**;
# · `queue-empty` ⇒ 须目标「进行中」+ 静默 ≥20 分钟。 # · `queue-empty` ⇒ 须目标「进行中」+ 静默 ≥2 分钟。
# ⛔ 这里若仍写"必须进行中"⇒ **试算说不会建、实际会建**(判据自相矛盾)。 # ⛔ 这里若仍写"必须进行中"⇒ **试算说不会建、实际会建**(判据自相矛盾)。
_why_now = why or "queue-empty" _why_now = why or "queue-empty"
_will = False _will = False
@@ -6901,8 +6901,8 @@ def main() -> int:
# 🔴🔴 2026-10-02 用户拍板方案 A:**检查会话建排期**(唯一建排期的地方在此)。 # 🔴🔴 2026-10-02 用户拍板方案 A:**检查会话建排期**(唯一建排期的地方在此)。
# 两条触发源(用户第①②条): # 两条触发源(用户第①②条):
# ① **任务会话全部结束** ⇒ 一次性读队列 → 建检查会话整体检查 # ① **任务会话全部结束** ⇒ 一次性读队列 → 建检查会话整体检查
# ② **队列为空** ⇒ 静默 ≥20 分钟 → 建检查会话核对目标状态 # ② **队列为空** ⇒ 静默 ≥2 分钟 → 建检查会话核对目标状态
#⛔ 四道闸全在 `maybe_spawn_check_agent()` 里(目标须「进行中」+会话全结束+ #⛔ 六道闸全在 `maybe_spawn_check_agent()` 里(目标须「进行中」+会话全结束+
# 静默时长+同名去抖);⛔ 建排期**只一条**,⛔ 不在循环里连建。 # 静默时长+同名去抖);⛔ 建排期**只一条**,⛔ 不在循环里连建。
try: try:
if _rd % 2 == 0: # 🔴 每 2 轮判一次(周期 30s ⇒≈60s) if _rd % 2 == 0: # 🔴 每 2 轮判一次(周期 30s ⇒≈60s)