@shgroup/dsh-serenity-hooks 1.94.0 → 1.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.94.0",
3
+ "version": "1.95.0",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——14 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档,deepseek-ai/deepseek-harness)。",
6
6
  "engines": {
@@ -8,14 +8,34 @@
8
8
  * 调度器只掌握**会话 live 与否**,而 **`live ≠ 在跑`**——
9
9
  * 一条会话可以 live 而空闲(本会话此刻就是活的反例)。
10
10
  *
11
- * ## 怎么夹出来(用**既有的**两个契约事件,不需要新宿主能力)
11
+ * ## 怎么夹出来(用**既有的**契约事件,不需要新宿主能力)
12
12
  *
13
13
  * | 事件 | 动作 | 出处 |
14
14
  * |---|---|---|
15
- * | `agent/created` | 标记「在跑」 | `host/contract.ts`(dsp 已在 `seams/context.ts` 订阅)。⚠️ v0.1.7 前名为 `agent/session-start`;新事件 `@mode = serial` ⇒ 处理函数须快速返回 |
16
- * | `agent/turn-stopping` | 清除标记 | `host/contract.ts:277`(dsp 已在 `trajectory/rebuild.ts:442` 等 4 处订阅) |
17
- * | `agent/disposed` | **清该载体的项** | `host/contract.ts:280` |
18
- * | `session/disposed` | **清该载体的项** | `host/contract.ts:283` |
15
+ * | `agent/status` = `running` | 标记「在跑」;`idle` ⇒ 清除 | 宿主 `AgentLoop.setPhase`:`emit("agent/status", { status })`,**只在状态真的变化时发** |
16
+ * | `agent/turn-stopping` | 清除标记 | `host/contract.ts`(dsp 已在 `trajectory/rebuild.ts` 等 4 处订阅) |
17
+ * | `agent/disposed` | **清该载体的项** | `host/contract.ts` |
18
+ * | `session/disposed` | **清该载体的项** | `host/contract.ts` |
19
+ *
20
+ * ## 🔴🔴 D243(2026-10-24):**⛔ 不许用 `agent/created` 标记「在跑」**
21
+ *
22
+ * **修前**:`agent/created` 也 `markTurnRunning(...)`。**为什么这是错的** —— 该事件是
23
+ * `AgentRegistry.announce(agent, source)` 发的,而 `source` 明确包含 **`resume`**:
24
+ * 宿主**每次重启**都会把 persisted 会话重新载入并 announce ⇒ 每个被**载入**的会话都被打成"在跑",
25
+ * 而**它那一轮早随旧进程死掉了** ⇒ `turn-stopping` 永不到达 ⇒ 该假标记活满 `TURN_TTL_MS`(30 min)。
26
+ *
27
+ * **代价(两个面,都已实测)**:
28
+ * - **面一**:CRO 守卫拿它否决唤起 ⇒ **重启后聋 30 分钟**(guard 已在自己域绕开)。
29
+ * - **面二**:`cognitive_trajectory interrupted` 拿它当排除集 ⇒ **把最该被接走的会话藏起来**
30
+ * (实测:判据命中 5 条,生产入口报「检查 5 · 命中 0」)。
31
+ *
32
+ * **判据**:`agent/created` 证明的是「**载体被发布了**」,**不是**「有轮次在跑」。
33
+ * 「载入」与「在跑」互不蕴含(与 D225 同族:*字段名/字面形态不是语义*)。
34
+ * ⇒ **唯一权威 = `agent/status`**(宿主 `status` getter:`phase.kind === 'idle' | 'maintenance'`
35
+ * 才是 idle,其余皆 running),且它在**每次真实状态跃迁**时发 —— 正是我们要的粒度。
36
+ *
37
+ * **代价与兜底**:删掉 `agent/created` 后,本表在"宿主重启后、某会话真正开跑之前"为空
38
+ * ⇒ 落到文件尾那条**便宜**的误判方向(报"没跑"),不会被拿来藏会话。
19
39
  *
20
40
  * ## 🔴 清理设计(**这是本模块最容易被做坏的地方**)
21
41
  *
@@ -50,7 +70,7 @@
50
70
  */
51
71
  /** 一次「在跑」记录的 TTL(见文件头的方向性判据) */
52
72
  export declare const TURN_TTL_MS: number;
53
- /** 标记「在跑」(`agent/created` + `agent/status=running` 调用) */
73
+ /** 标记「在跑」(**唯一**生产调用点 = `agent/status=running`;另供测试与 CRO 自检置位) */
54
74
  export declare function markTurnRunning(sessionId: string, nowMs: number, turn?: number | null): void;
55
75
  /** 清除「在跑」(`turn-stopping` / disposed 调用) */
56
76
  export declare function clearTurnRunning(sessionId: string): void;
@@ -80,10 +100,13 @@ export declare function __resetCroTurnsForTest(): void;
80
100
  * 装配追踪(`index.ts` apply 调用):订阅四个既有事件 + 拆卸。
81
101
  *
82
102
  * **为什么订阅四个而不是两个**(R↓):
83
- * · 前两个(`agent/created` / `turn-stopping`)负责**语义**——"在不在跑";
103
+ * · 前两个(`agent/status` / `turn-stopping`)负责**语义**——"在不在跑";
84
104
  * · 后两个(`agent/disposed` / `session/disposed`)负责**生命周期**——
85
105
  * 载体没了必须清项,否则表按载体只增(本模块的头号风险)。
86
106
  *
107
+ * 🔴 **D243:`agent/created` 已于 2026-10-24 从订阅清单中移除**(原先共 5 个)。
108
+ * 理由与代价见**文件头 D243 段**;一句话:它是「载体被发布」的信,不是「轮次在跑」的信。
109
+ *
87
110
  * ⚠️ **失败不抛**:任一事件通道缺失 ⇒ 响亮日志 + 该订阅跳过(**apply 不可成为启动单点**,
88
111
  * 与 `registerDeepseekVisionPatch` 等既有装配同款纪律)。
89
112
  *
package/lib/index.js CHANGED
@@ -8438,14 +8438,34 @@ function registerDisposer(ctx, label, cleanup) {
8438
8438
  * 调度器只掌握**会话 live 与否**,而 **`live ≠ 在跑`**——
8439
8439
  * 一条会话可以 live 而空闲(本会话此刻就是活的反例)。
8440
8440
  *
8441
- * ## 怎么夹出来(用**既有的**两个契约事件,不需要新宿主能力)
8441
+ * ## 怎么夹出来(用**既有的**契约事件,不需要新宿主能力)
8442
8442
  *
8443
8443
  * | 事件 | 动作 | 出处 |
8444
8444
  * |---|---|---|
8445
- * | `agent/created` | 标记「在跑」 | `host/contract.ts`(dsp 已在 `seams/context.ts` 订阅)。⚠️ v0.1.7 前名为 `agent/session-start`;新事件 `@mode = serial` ⇒ 处理函数须快速返回 |
8446
- * | `agent/turn-stopping` | 清除标记 | `host/contract.ts:277`(dsp 已在 `trajectory/rebuild.ts:442` 等 4 处订阅) |
8447
- * | `agent/disposed` | **清该载体的项** | `host/contract.ts:280` |
8448
- * | `session/disposed` | **清该载体的项** | `host/contract.ts:283` |
8445
+ * | `agent/status` = `running` | 标记「在跑」;`idle` ⇒ 清除 | 宿主 `AgentLoop.setPhase`:`emit("agent/status", { status })`,**只在状态真的变化时发** |
8446
+ * | `agent/turn-stopping` | 清除标记 | `host/contract.ts`(dsp 已在 `trajectory/rebuild.ts` 等 4 处订阅) |
8447
+ * | `agent/disposed` | **清该载体的项** | `host/contract.ts` |
8448
+ * | `session/disposed` | **清该载体的项** | `host/contract.ts` |
8449
+ *
8450
+ * ## 🔴🔴 D243(2026-10-24):**⛔ 不许用 `agent/created` 标记「在跑」**
8451
+ *
8452
+ * **修前**:`agent/created` 也 `markTurnRunning(...)`。**为什么这是错的** —— 该事件是
8453
+ * `AgentRegistry.announce(agent, source)` 发的,而 `source` 明确包含 **`resume`**:
8454
+ * 宿主**每次重启**都会把 persisted 会话重新载入并 announce ⇒ 每个被**载入**的会话都被打成"在跑",
8455
+ * 而**它那一轮早随旧进程死掉了** ⇒ `turn-stopping` 永不到达 ⇒ 该假标记活满 `TURN_TTL_MS`(30 min)。
8456
+ *
8457
+ * **代价(两个面,都已实测)**:
8458
+ * - **面一**:CRO 守卫拿它否决唤起 ⇒ **重启后聋 30 分钟**(guard 已在自己域绕开)。
8459
+ * - **面二**:`cognitive_trajectory interrupted` 拿它当排除集 ⇒ **把最该被接走的会话藏起来**
8460
+ * (实测:判据命中 5 条,生产入口报「检查 5 · 命中 0」)。
8461
+ *
8462
+ * **判据**:`agent/created` 证明的是「**载体被发布了**」,**不是**「有轮次在跑」。
8463
+ * 「载入」与「在跑」互不蕴含(与 D225 同族:*字段名/字面形态不是语义*)。
8464
+ * ⇒ **唯一权威 = `agent/status`**(宿主 `status` getter:`phase.kind === 'idle' | 'maintenance'`
8465
+ * 才是 idle,其余皆 running),且它在**每次真实状态跃迁**时发 —— 正是我们要的粒度。
8466
+ *
8467
+ * **代价与兜底**:删掉 `agent/created` 后,本表在"宿主重启后、某会话真正开跑之前"为空
8468
+ * ⇒ 落到文件尾那条**便宜**的误判方向(报"没跑"),不会被拿来藏会话。
8449
8469
  *
8450
8470
  * ## 🔴 清理设计(**这是本模块最容易被做坏的地方**)
8451
8471
  *
@@ -8483,9 +8503,9 @@ const TURN_TTL_MS = 18e5;
8483
8503
  /**
8484
8504
  * 进程内的「正在跑」表(键 = 载体 dsh 会话 id)。
8485
8505
  *
8486
- * ⚠️ **仅内存**:进程重启即空 —— 这是**可接受的**,因为重启后宿主会重发
8487
- * `agent/created`(或至少下一次 `turn-stopping` 会清掉残留),且空表 = "没有在跑",
8488
- * 落到上面那条**便宜**的误判方向。
8506
+ * ⚠️ **仅内存**:进程重启即空 —— 这是**可接受的,且是刻意选的**:
8507
+ * 空表 = "没有在跑" ⇒ 落到上面那条**便宜**的误判方向(漏排是硬故障、多排是常态成本)。
8508
+ * 🔴 **D243**:刻意**不**在重启后用 `agent/created` 去"补"这张表 —— 那会把「载入」当「在跑」。
8489
8509
  */
8490
8510
  const runningBySession = /* @__PURE__ */ new Map();
8491
8511
  /** 取载体 id(事件 payload 的 `agent` 面;取不到 ⇒ null) */
@@ -8493,7 +8513,7 @@ function sessionIdOf$2(agent) {
8493
8513
  const id = agent?.session?.id;
8494
8514
  return typeof id === "string" && id !== "" ? id : null;
8495
8515
  }
8496
- /** 标记「在跑」(`agent/created` + `agent/status=running` 调用) */
8516
+ /** 标记「在跑」(**唯一**生产调用点 = `agent/status=running`;另供测试与 CRO 自检置位) */
8497
8517
  function markTurnRunning(sessionId, nowMs, turn = null) {
8498
8518
  if (!sessionId) return;
8499
8519
  runningBySession.set(sessionId, {
@@ -8541,10 +8561,13 @@ function runningCarriersOf(boundSessionIds, nowMs, ttlMs = TURN_TTL_MS) {
8541
8561
  * 装配追踪(`index.ts` apply 调用):订阅四个既有事件 + 拆卸。
8542
8562
  *
8543
8563
  * **为什么订阅四个而不是两个**(R↓):
8544
- * · 前两个(`agent/created` / `turn-stopping`)负责**语义**——"在不在跑";
8564
+ * · 前两个(`agent/status` / `turn-stopping`)负责**语义**——"在不在跑";
8545
8565
  * · 后两个(`agent/disposed` / `session/disposed`)负责**生命周期**——
8546
8566
  * 载体没了必须清项,否则表按载体只增(本模块的头号风险)。
8547
8567
  *
8568
+ * 🔴 **D243:`agent/created` 已于 2026-10-24 从订阅清单中移除**(原先共 5 个)。
8569
+ * 理由与代价见**文件头 D243 段**;一句话:它是「载体被发布」的信,不是「轮次在跑」的信。
8570
+ *
8548
8571
  * ⚠️ **失败不抛**:任一事件通道缺失 ⇒ 响亮日志 + 该订阅跳过(**apply 不可成为启动单点**,
8549
8572
  * 与 `registerDeepseekVisionPatch` 等既有装配同款纪律)。
8550
8573
  *
@@ -8574,16 +8597,11 @@ function registerCroTurnTracking(ctx) {
8574
8597
  console.log(`[serenity-hooks] ✗ CRO turn 追踪未装配(${event} 不可用): ${String(err?.message ?? err)}`);
8575
8598
  }
8576
8599
  };
8577
- on("agent/created", (payload) => {
8578
- const id = sessionIdOf$2(payload?.agent);
8579
- if (id) markTurnRunning(id, Date.now());
8580
- });
8581
8600
  on("agent/status", (payload) => {
8582
8601
  const p = payload;
8583
8602
  const id = sessionIdOf$2(p?.agent);
8584
8603
  if (!id) return;
8585
- const turn = typeof p.turn === "number" ? p.turn : null;
8586
- if (p.status === "running") markTurnRunning(id, Date.now(), turn);
8604
+ if (p.status === "running") markTurnRunning(id, Date.now());
8587
8605
  else if (p.status === "idle") clearTurnRunning(id);
8588
8606
  });
8589
8607
  on("agent/turn-stopping", (payload) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.94.0",
3
+ "version": "1.95.0",
4
4
  "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档)。",
5
5
  "license": "MIT",
6
6
  "repository": {