@zhushanwen/subagent-core 0.8.0 → 0.9.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.
Files changed (167) hide show
  1. package/dist/{chunk-OL5BK4VN.js → chunk-LZJOEDGQ.js} +455 -203
  2. package/dist/engine-discovery-scan-Da4Dkzsi.d.cts +818 -0
  3. package/dist/engine-discovery-scan-Da4Dkzsi.d.ts +818 -0
  4. package/dist/execution/engine/engine-discovery-scan.cjs +216 -155
  5. package/dist/execution/engine/engine-discovery-scan.d.cts +1 -2
  6. package/dist/execution/engine/engine-discovery-scan.d.ts +1 -2
  7. package/dist/execution/engine/engine-discovery-scan.js +1 -1
  8. package/dist/execution/relay-env.js +5 -4
  9. package/dist/index.cjs +7686 -5894
  10. package/dist/index.d.cts +1876 -1360
  11. package/dist/index.d.ts +1876 -1360
  12. package/dist/index.js +7048 -5493
  13. package/dist.bundle/index.cjs +7747 -5957
  14. package/package.json +4 -4
  15. package/src/__tests__/manifest-store.test.ts +16 -15
  16. package/src/__tests__/robustness-medium-batch1.test.ts +10 -14
  17. package/src/__tests__/robustness-medium-batch2.test.ts +7 -2
  18. package/src/execution/__tests__/alive-store.test.ts +117 -1
  19. package/src/execution/__tests__/batch-finalized.test.ts +206 -0
  20. package/src/execution/__tests__/chat-engine-routing.test.ts +117 -1
  21. package/src/execution/__tests__/{cold-resurrect.test.ts → cold-lookup.test.ts} +133 -33
  22. package/src/execution/__tests__/collect-coordinator-service.test.ts +7 -5
  23. package/src/execution/__tests__/conversation-continuation.test.ts +1452 -0
  24. package/src/execution/__tests__/delivery-methods.test.ts +90 -176
  25. package/src/execution/__tests__/dialog-queue.test.ts +70 -3
  26. package/src/execution/__tests__/dispose-manifest-recovery.test.ts +475 -0
  27. package/src/execution/__tests__/execute-and-await-worktree.test.ts +3 -3
  28. package/src/execution/__tests__/execute-nesting.test.ts +8 -5
  29. package/src/execution/__tests__/execution-record.test.ts +8 -148
  30. package/src/execution/__tests__/finalize-record.test.ts +295 -129
  31. package/src/execution/__tests__/get-record-for-action-restart.test.ts +21 -29
  32. package/src/execution/__tests__/helpers/fake-engine-port.ts +13 -68
  33. package/src/execution/__tests__/helpers/legacy-sidecar.ts +33 -0
  34. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +9 -5
  35. package/src/execution/__tests__/idle-gc.test.ts +60 -0
  36. package/src/execution/__tests__/lifecycle-manager.test.ts +3 -254
  37. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +43 -22
  38. package/src/execution/__tests__/model-config-service.test.ts +111 -0
  39. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +10 -6
  40. package/src/execution/__tests__/notify-ledger.test.ts +42 -1
  41. package/src/execution/__tests__/rebuild-indexes.test.ts +329 -0
  42. package/src/execution/__tests__/record-binding.test.ts +613 -0
  43. package/src/execution/__tests__/record-origin.test.ts +318 -0
  44. package/src/execution/__tests__/record-store-intent-api.test.ts +600 -0
  45. package/src/execution/__tests__/record-store-orphan-revive.test.ts +71 -3
  46. package/src/execution/__tests__/record-store.test.ts +72 -54
  47. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +8 -5
  48. package/src/execution/__tests__/round-supervisor-workflow-origin.test.ts +205 -0
  49. package/src/execution/__tests__/run-orchestration-write-lease.test.ts +293 -0
  50. package/src/execution/__tests__/run-orchestration.test.ts +199 -0
  51. package/src/execution/__tests__/session-file-gc.test.ts +35 -4
  52. package/src/execution/__tests__/session-reconstructor.test.ts +78 -0
  53. package/src/execution/__tests__/state-marker.test.ts +288 -0
  54. package/src/execution/__tests__/stream-sink-retirement.test.ts +8 -5
  55. package/src/execution/__tests__/subagent-actions-core.test.ts +67 -16
  56. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +0 -1
  57. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -11
  58. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +17 -11
  59. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +130 -53
  60. package/src/execution/__tests__/subagent-service.test.ts +17 -215
  61. package/src/execution/__tests__/subprocess-agent-runner-no-progress-killall.test.ts +138 -0
  62. package/src/execution/__tests__/subprocess-agent-runner.test.ts +105 -660
  63. package/src/execution/__tests__/sync-collect-recovery.test.ts +23 -16
  64. package/src/execution/__tests__/terminal-write-latency.test.ts +79 -0
  65. package/src/execution/__tests__/workflow-agent-dispatch.test.ts +782 -0
  66. package/src/execution/alive-store.ts +37 -28
  67. package/src/execution/{cold-resurrect.ts → cold-lookup.ts} +48 -45
  68. package/src/execution/config.ts +1 -1
  69. package/src/execution/conversation-continuation.ts +541 -0
  70. package/src/execution/dialog-queue.ts +60 -12
  71. package/src/execution/engine/__tests__/common/capability-gate.test.ts +1 -1
  72. package/src/execution/engine/__tests__/common/journal-wiring.test.ts +16 -1
  73. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +17 -51
  74. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +0 -5
  75. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +1 -1
  76. package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +5 -9
  77. package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +0 -3
  78. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -3
  79. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -3
  80. package/src/execution/engine/__tests__/registry.test.ts +0 -1
  81. package/src/execution/engine/__tests__/routing.test.ts +0 -1
  82. package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +0 -3
  83. package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +0 -3
  84. package/src/execution/engine/client/__tests__/engine-client-reap.test.ts +212 -0
  85. package/src/execution/engine/client/__tests__/mirror.test.ts +73 -1
  86. package/src/execution/engine/client/__tests__/protocol-closure.test.ts +2 -9
  87. package/src/execution/engine/client/__tests__/remote-engine.test.ts +46 -12
  88. package/src/execution/engine/client/engine-client.ts +81 -25
  89. package/src/execution/engine/client/mirror.ts +9 -0
  90. package/src/execution/engine/client/remote-engine.ts +52 -34
  91. package/src/execution/engine/client/reverse-router.ts +6 -27
  92. package/src/execution/engine/common/__tests__/run-signals.test.ts +79 -0
  93. package/src/execution/engine/common/capability-gate.ts +27 -0
  94. package/src/execution/engine/common/data-dir.ts +3 -2
  95. package/src/execution/engine/common/errors.ts +1 -1
  96. package/src/execution/engine/common/journal-wiring.ts +18 -9
  97. package/src/execution/engine/common/run-signals.ts +83 -0
  98. package/src/execution/engine/d8-compat.ts +1 -1
  99. package/src/execution/engine/host/__tests__/host-bridge.test.ts +3 -18
  100. package/src/execution/engine/host/host-bridge.ts +19 -41
  101. package/src/execution/engine/host/pi-host-binding.ts +5 -5
  102. package/src/execution/engine/port.ts +34 -54
  103. package/src/execution/engine/types.ts +11 -14
  104. package/src/execution/execution-record.ts +15 -47
  105. package/src/execution/finalize-record.ts +94 -197
  106. package/src/execution/idle-gc.ts +9 -3
  107. package/src/execution/lifecycle-manager.ts +25 -361
  108. package/src/execution/lifecycle-predicates.ts +22 -19
  109. package/src/execution/manifest-store.ts +40 -42
  110. package/src/execution/model-config-service.ts +1 -1
  111. package/src/execution/notifier.ts +39 -1
  112. package/src/execution/notify-host.ts +13 -4
  113. package/src/execution/record-entry.ts +20 -2
  114. package/src/execution/record-store.ts +925 -160
  115. package/src/execution/relay-env.ts +8 -3
  116. package/src/execution/round-supervisor/domain.ts +17 -5
  117. package/src/execution/round-supervisor/service-binding.test.ts +89 -53
  118. package/src/execution/round-supervisor/service-binding.ts +71 -21
  119. package/src/execution/round-supervisor/supervisor.ts +23 -9
  120. package/src/execution/service/record-access.ts +547 -0
  121. package/src/execution/service/record-lifecycle.ts +542 -0
  122. package/src/execution/service/run-orchestration.ts +1647 -0
  123. package/src/execution/service/service-bootstrap.ts +111 -0
  124. package/src/execution/service/service-constants.ts +27 -0
  125. package/src/execution/service/session-baselines.ts +401 -0
  126. package/src/execution/service/sync-collect-domain.ts +442 -0
  127. package/src/execution/service/workflow-dispatch.ts +567 -0
  128. package/src/execution/session-file-gc.ts +11 -8
  129. package/src/execution/session-reconstructor.ts +44 -1
  130. package/src/execution/sessions-index.ts +20 -3
  131. package/src/execution/settled-watchdog.ts +86 -43
  132. package/src/execution/state-marker.ts +516 -0
  133. package/src/execution/stream-sink.ts +1 -1
  134. package/src/execution/subagent-actions-core.ts +53 -31
  135. package/src/execution/subagent-service.ts +643 -2980
  136. package/src/execution/subprocess-agent-runner.ts +46 -323
  137. package/src/execution/types.ts +60 -43
  138. package/src/execution/ui-request-handler-factory.ts +5 -0
  139. package/src/execution/worktree-manager.ts +1 -1
  140. package/src/execution/worktree-registry.ts +1 -1
  141. package/src/index.ts +6 -5
  142. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +2 -3
  143. package/src/orchestration/__tests__/agent-call-stream.test.ts +24 -49
  144. package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +4 -4
  145. package/src/orchestration/__tests__/file-run-store.test.ts +5 -7
  146. package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +2 -3
  147. package/src/orchestration/__tests__/run-snapshot.test.ts +27 -43
  148. package/src/orchestration/__tests__/worker-message-pump-workflow-dispatch.test.ts +274 -0
  149. package/src/orchestration/execute-agent-call.ts +1 -1
  150. package/src/orchestration/file-run-store.ts +1 -1
  151. package/src/orchestration/models/ports.ts +20 -13
  152. package/src/orchestration/models/types.ts +11 -13
  153. package/src/orchestration/run-snapshot.ts +18 -22
  154. package/src/orchestration/worker-message-pump.ts +33 -57
  155. package/src/shared/atomic-write.ts +10 -8
  156. package/dist/chunk-T2SYBW3I.js +0 -24
  157. package/dist/engine-discovery-scan-BXLA8y-z.d.cts +0 -1624
  158. package/dist/engine-discovery-scan-BXLA8y-z.d.ts +0 -1624
  159. package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +0 -255
  160. package/src/execution/__tests__/finalized-marker.test.ts +0 -104
  161. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  162. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -488
  163. package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +0 -75
  164. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  165. package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +0 -230
  166. package/src/execution/finalized-marker.ts +0 -70
  167. package/src/execution/tombstone-store.ts +0 -72
@@ -1,34 +1,32 @@
1
- // src/runtime/execution/alive-store.ts
1
+ // src/execution/alive-store.ts
2
2
  //
3
- // .alive sidecar 生产者 + pid 探活。
3
+ // .alive sidecar:跨进程写权声明的生产者 + pid 探活。
4
4
  //
5
- // 子进程启动时写 .alive(pid+id+startedAt),心跳检测时读它 + isProcessAlive
6
- // 判活。finalize/cancel 收尾时 remove。与 .cancelled/.finalized 构成三件套。
7
- //
8
- // 设计对齐 tombstone-store:单文件 sidecar、best-effort I/O、无全局 index。
5
+ // [U4a / D3 v7] 角色重定义(D3d 模块头权威表述):
6
+ // - 宿主 resurrect/接管归口写:写权声明 acquire(markResurrected/acquireWriteLease)
7
+ // / release(markFinalized/markCancelled/markIdleArchived 内部删);
8
+ // - 判活 = pid 单判据(findForeignLiveInstance:self-pid 排除 + isProcessAlive,
9
+ // 软超时已退役——谱系 #12,跨轮保留 × startedAt 一次性不刷新的组合下超时会
10
+ // 误判在持声明陈旧)。
11
+ // 写/删动作均经 RecordStore 意图原语归口(G1:本模块不直接面向调用方,write/remove
12
+ // 是 store 内部写面的实现件)。
9
13
 
10
14
  import * as fs from "node:fs";
11
15
 
12
- import type { AliveMarker } from "./types.ts";
16
+ import { getLogger } from "../core/logger.ts";
13
17
 
14
- // ============================================================
15
- // 常量
16
- // ============================================================
18
+ import type { AliveMarker } from "./types.ts";
17
19
 
18
- /**
19
- * .alive marker 的软超时(1h,自 record-store.ts 迁移为共享常量):超过此时长的
20
- * alive 视为陈旧——pid 复用窗口有限([防] 缩短窗口降误判),且长时间 marker 多半
21
- * 是异常退出后的残留。v8.5 D 透明重生的异进程探针复用同一判据(findForeignLiveInstance)。
22
- */
23
- export const ALIVE_SOFT_TIMEOUT_MS = 3_600_000;
20
+ const logger = getLogger("subagents");
24
21
 
25
22
  // ============================================================
26
23
  // 公开函数
27
24
  // ============================================================
28
25
 
29
26
  /**
30
- * 在 sessionFile 旁写 .alive sidecar(单行 JSON)。
27
+ * 在 sessionFile 旁写 .alive sidecar(单行 JSON,跨进程写权声明 acquire)。
31
28
  * 覆盖写——同一 sessionFile 只有最后一个 alive marker 有意义。
29
+ * 失败原样上抛(IO 错不吞——acquire 失败 = 双写风险敞口,调用方响亮处理,D3c)。
32
30
  */
33
31
  export function writeAliveMarker(sessionFile: string, marker: AliveMarker): void {
34
32
  const alivePath = `${sessionFile}.alive`;
@@ -62,14 +60,20 @@ export function readAliveMarker(sessionFile: string): AliveMarker | undefined {
62
60
  }
63
61
 
64
62
  /**
65
- * 删除 sessionFile 旁的 .alive sidecar
66
- * best-effort:不存在不抛(finalize/cancel 收尾调,sidecar 可能已被清理)。
63
+ * 删除 sessionFile 旁的 .alive sidecar(写权声明 release)。
64
+ * best-effort:不存在不抛(finalize/cancel 收尾调,sidecar 可能已被清理);
65
+ * 存在但删除失败(权限/磁盘错)warn 留痕——release 失败 = 残留声明可能误拦异宿主,
66
+ * 排障需要线索(D3a:泄漏窗 = 至宿主退出,已接受但必须可见)。
67
67
  */
68
68
  export function removeAliveMarker(sessionFile: string): void {
69
69
  try {
70
70
  fs.unlinkSync(`${sessionFile}.alive`);
71
- } catch {
72
- void 0; // best-effort
71
+ } catch (err) {
72
+ const code = (err as NodeJS.ErrnoException).code;
73
+ if (code === "ENOENT") return; // 不存在 = 已释放(幂等终态,正常)
74
+ logger.warn("[subagents] alive marker release failed (stale lease may block foreign hosts)", {
75
+ detail: { sessionFile, error: err instanceof Error ? err.message : String(err) },
76
+ });
73
77
  }
74
78
  }
75
79
 
@@ -95,18 +99,23 @@ export function isProcessAlive(pid: number): boolean {
95
99
  }
96
100
 
97
101
  /**
98
- * [v8.5 D] 异进程活实例探针:sessionFile 是否仍有「另一进程」的活跃实例。
102
+ * [v8.5 D → D3c/D3b v7] 异进程活实例探针:sessionFile 是否仍有「另一进程」持有的
103
+ * 写权声明。调用方在 resurrect / fork-from 前必须经此确认无他方持有,防双写同一
104
+ * session jsonl。
99
105
  *
100
- * 三判据与 record-store buildRecord 分支 3 同源(readAliveMarker + isProcessAlive +
101
- * 软超时):marker 存在 && pid 存活 && 未超软超时才返回 marker;其余返回 undefined
102
- * (视为确死/陈旧,允许透明重生)。调用方在 resurrect 前必须经此确认源进程确死,
103
- * 防双写同一 session jsonl。
106
+ * 判据 = **pid 单判据 + self-pid 排除**(D3 v7,谱系 #12:软超时退役——跨轮保留 ×
107
+ * startedAt 一次性不刷新的组合下,>1h idle 的在持声明会被误判陈旧,探针超时放行
108
+ * 开双写窗):
109
+ * - marker.pid === process.pid → undefined(self-pid 排除:本进程的自有声明视同
110
+ * 无 foreign——消除本进程被自己 marker 拦死的重试死锁,D3c);
111
+ * - marker.pid 活(isProcessAlive)→ marker(他方在持,拦截);
112
+ * - pid 死 / marker 缺失/损坏 → undefined(确死/无声明,放行)。
104
113
  */
105
- export function findForeignLiveInstance(sessionFile: string, now: number = Date.now()): AliveMarker | undefined {
114
+ export function findForeignLiveInstance(sessionFile: string): AliveMarker | undefined {
106
115
  const marker = readAliveMarker(sessionFile);
107
116
  if (!marker) return undefined;
117
+ if (marker.pid === process.pid) return undefined;
108
118
  if (!isProcessAlive(marker.pid)) return undefined;
109
- if (now - marker.startedAt >= ALIVE_SOFT_TIMEOUT_MS) return undefined;
110
119
  return marker;
111
120
  }
112
121
 
@@ -1,14 +1,16 @@
1
- // [D4-③ 冷路径复活职责轴] message action 冷查/复活链(原 SubagentService 私有的
2
- // findColdLookupCandidate / assertReconnectAllowed / resurrectColdRecord /
3
- // coldLookupForAction + isReconnectableClosed 判定)整体搬移至 record-store 邻接处
4
- // (行为逐字节等价:搬移 + 依赖注入,不重写逻辑)。变化轴:改跨重启重建 /
5
- // 透明重生回边 / 可重连守卫语义,只改本文件;Service getRecordForAction 保留
6
- // 归属校验编排(内存未命中分支委托 coldLookupForAction)。
1
+ // [D4-③ 冷路径查询职责轴 / H1 U6 改名] message action 冷查链(原 SubagentService
2
+ // 私有的 findColdLookupCandidate / assertReconnectAllowed / resurrectColdRecord /
3
+ // coldLookupForAction + isReconnectableClosed 判定,W3 后寄居 cold-resurrect.ts)。
4
+ // [H1 U6] cold-resurrect.ts 随 chat 域退役改名落位本文件:其中「跨重启磁盘重建无条件
5
+ // chatMode=true」的升级语义已迁 Continuation D4 revive 格 + D5 gate
6
+ //(conversation-continuation.ts reviveOrThrow / subagent-actions-core messageHandler
7
+ // 双写点),本文件只保留冷查定位 / 可重连守卫 / 磁盘重建注册链——UF-1 跨重启续聊
8
+ // 绑定链(getRecordForAction → coldLookupForAction → 绑定重建 → Continuation)的
9
+ // 宿主侧解析承载。变化轴:改跨重启重建 / 透明重生回边 / 可重连守卫语义,只改本文件;
10
+ // Service 的 getRecordForAction 保留归属校验编排(内存未命中分支委托 coldLookupForAction)。
7
11
 
8
- import * as fs from "node:fs";
9
-
10
- import { findForeignLiveInstance, writeAliveMarker } from "./alive-store.ts";
11
- import { createRecord, resurrectClosed } from "./execution-record.ts";
12
+ import { findForeignLiveInstance } from "./alive-store.ts";
13
+ import { createRecord } from "./execution-record.ts";
12
14
  import type { StatusFilter } from "./record-store.ts";
13
15
  import type { ExecutionRecord, SubagentRecord } from "./types.ts";
14
16
  import { isReconnectableFinalReason, ResurrectDeniedError } from "./types.ts";
@@ -19,16 +21,22 @@ import { isReconnectableFinalReason, ResurrectDeniedError } from "./types.ts";
19
21
  export const COLD_LOOKUP_SCAN_LIMIT = 1000;
20
22
 
21
23
  /** 冷查/复活的依赖注入(Service 侧供给,store 查询 + 归属上下文)。 */
22
- export interface ColdResurrectDeps {
24
+ export interface ColdLookupDeps {
23
25
  /** store 的 idToFile 索引直查(light 快照)。 */
24
26
  findLightById: (id: string) => SubagentRecord | undefined;
25
27
  /** store 的磁盘全扫(内存未命中 / 索引未热时兜底)。rootFilter 恒 undefined
26
28
  * (冷查不做 root 过滤——归属校验在候选定位之后,见 coldLookupForAction)。 */
27
29
  collectRecords: (limit: number, statusFilter: StatusFilter, rootFilter: undefined) => SubagentRecord[];
28
- /** 重建 record 注册进内存 store */
30
+ /** 重建 record 注册进内存 store。([U2a/B4] register 已收编进 markResurrected
31
+ * ——生产链不调用(resurrect 回边经 markResurrected 幂等再注册);保留供编排层
32
+ * 显式性与测试断言。) */
29
33
  register: (record: ExecutionRecord) => void;
30
- /** 重建后的 transition entry 上报(live ≡ reload 等价性)。 */
34
+ /** 重建后的 transition entry 上报(live ≡ reload 等价性——纯投递副作用,留编排层)。 */
31
35
  reportRecordTransition: (record: ExecutionRecord) => void;
36
+ /** [U2a/B4] 透明重生回边原语(store.markResurrected,D3c 规格):acquire-first
37
+ * 三件套(写 .alive 写权声明 → 删 .state → 删 .finalized legacy)+ resurrectClosed
38
+ * 内存翻回 + register,单 try 域原子收敛;任一步失败响亮抛错中止主流程。 */
39
+ markResurrected: (record: ExecutionRecord, wasClosed: boolean) => void;
32
40
  /** 当前所属根 session id(归属校验用,运行时可变——initSession 建立)。 */
33
41
  getSessionRootId: () => string | null;
34
42
  /** 本进程嵌套基线 recordId(直接父校验用;根进程 undefined)。 */
@@ -43,12 +51,13 @@ export interface ColdResurrectDeps {
43
51
  * 异进程实例(父进程重启后旧子进程尚存的窗口),resume 会 spawn 第二个 pi 子进程
44
52
  * 写同一 session JSONL(本代码最忌惮的双写者形态,v4 A-5/P7 事故模式)。closed 候选
45
53
  * 的同款守卫已在 assertReconnectAllowed(v8.5 D);本守卫闭合 running 候选的防御
46
- * 不对称。marker 的 pid 是子进程 pi pid(非父进程),本进程持有的 running record
47
- * 恒在内存(archive 才移出),可达本冷查分支的 running 候选必然来自磁盘重建——
48
- * 探针命中即拒绝(ResurrectDeniedError,与 closed 候选守卫同异常类型,错误含 pid
49
- * 与恢复指引)。 */
54
+ * 不对称。marker 的 pid 是**宿主进程** pid(D3d 失实注释修正:写者 = 宿主的写权声明
55
+ * acquire——resurrect 回边 / running 接管 / spawn 锚点确立,非子进程 pi 自写),本
56
+ * 进程持有的 running record 恒在内存(archive 才移出),可达本冷查分支的 running
57
+ * 候选必然来自磁盘重建——探针命中即拒绝(ResurrectDeniedError,与 closed 候选守卫
58
+ * 同异常类型,错误含 pid 与恢复指引)。 */
50
59
  function findColdLookupCandidate(
51
- deps: ColdResurrectDeps,
60
+ deps: ColdLookupDeps,
52
61
  id: string,
53
62
  allowReconnect: boolean,
54
63
  ): SubagentRecord | undefined {
@@ -106,7 +115,7 @@ function assertReconnectAllowed(found: SubagentRecord, id: string): void {
106
115
 
107
116
  /** 磁盘候选重建为可变 record 并 register + 上报(coldLookupForAction 步骤 4)。 */
108
117
  function resurrectColdRecord(
109
- deps: ColdResurrectDeps,
118
+ deps: ColdLookupDeps,
110
119
  found: SubagentRecord,
111
120
  id: string,
112
121
  ): ExecutionRecord {
@@ -121,10 +130,11 @@ function resurrectColdRecord(
121
130
  rootSessionId: found.rootSessionId,
122
131
  parentRecordId: found.parentRecordId,
123
132
  depth: found.depth,
124
- // [v4 A-3] 跨重启恢复入口——message 路径磁盘重建无条件置 chatMode=true(现状机制,
125
- // V3 方案 A 方向兑现)。改动此处必须带 S3 回归场景(跨重启 message 续聊验证)。
126
- // V3 SP-5 探针定案:机制已存在,本注释即定案,不再悬置。
127
- chatMode: true,
133
+ // [v4 A-3 → H1 U6 / D4-D5] 水合保留持久化 chatMode(UF-1 绑定 sidecar 的身份域
134
+ // 投影,record-store buildRecord 已承载):磁盘上是什么就是什么。原「无条件置
135
+ // chatMode=true」的升级语义迁 Continuation D4 revive 格 + D5 gate 双写点
136
+ //(one-shot 跨重启重建 chatMode=false 后收到 message → gate 放行 → 升级置位再续聊)。
137
+ chatMode: found.chatMode === true,
128
138
  controller: new AbortController(),
129
139
  });
130
140
  record.sessionFile = found.sessionFile;
@@ -135,29 +145,22 @@ function resurrectColdRecord(
135
145
  // 隔离——正是 worktree 要防的并发写冲突场景)。close 不受影响(closeChatIdle 走
136
146
  // doFinalizeRecord,泄漏的 worktree 由 reaper 兜底回收)。
137
147
  record.hadWorktree = found.worktree === true;
138
- // [v8.5 D] 透明重生回边:独立函数不走 tryTransition 单向语义(closed 单向性对正常
139
- // 执行流完整保留);准入唯一依据 = A sidecar 真实死因 可重连集。死亡语义位由
140
- // resurrectClosed 清除;register 后立刻上报 transition entry,live/reload 视图同步
141
- // 翻回 running(等价性由 applyEntry reducer 保证,对齐 SP-2 重建即报告先例)。
148
+ // [U2a/B4 → D3c] 透明重生回边整体收编 store.markResurrected:acquire-first 顺序
149
+ // (写 .alive 写权声明 .state 删 .finalized legacy)+ resurrectClosed 内存
150
+ // 翻回 + register,单 try 域原子收敛。准入唯一依据 = A 档 sidecar 真实死因 ∈ 可重连
151
+ // 集(守卫已在上方跑完);reportTransition(entry 上报)留本编排层(纯投递副作用,
152
+ // 失败不破坏状态一致性)。
153
+ // 两种接管形态统一 acquire(D3c):closed 候选(wasClosed=true)三件套全量;running
154
+ // 候选接管(跨重启磁盘重建,wasClosed=false)跳过删终态位(无 .state 可删)**仍
155
+ // acquire marker**——「接管即声明」,现状此路径不写 marker 的 B/C 双写窗随归口消灭。
156
+ // 失败语义 = 响亮抛错中止主流程(§3.4):acquire 失败 = 双写风险敞口,禁止
157
+ // best-effort 吞错续跑(旧「单 try 吞错后继续 resurrectClosed + register」形态随
158
+ // 归口消灭);acquire-first 顺序保证失败时终态位未删、磁盘保持旧形态(可重试)。
142
159
  const wasClosed = found.status !== "running";
160
+ deps.markResurrected(record, wasClosed);
143
161
  if (wasClosed) {
144
- // [review MF-8] 磁盘终态位同步翻转:record-store buildRecord 分支 2(.finalized
145
- // 存在 closed)优先级高于 .alive 活态分支 3,重生若不删 sidecar,任何磁盘扫描
146
- // (异进程 / reload / session-reader)都会把本进程内存里 running 的 record 报成
147
- // closed/disconnected——破坏 live ≡ reload,且为跨进程二次 resurrect 开门。
148
- // best-effort 对齐 BC-4 语义;.alive 刷新为当前进程(后续 resume spawn 会覆盖写)。
149
- if (record.sessionFile) {
150
- try {
151
- fs.rmSync(`${record.sessionFile}.finalized`, { force: true });
152
- writeAliveMarker(record.sessionFile, { pid: process.pid, id, startedAt: Date.now() });
153
- } catch (_e) {
154
- void _e; // best-effort:sidecar 翻转失败不阻断重生主流程
155
- }
156
- }
157
- resurrectClosed(record);
158
- }
159
- deps.register(record);
160
- if (wasClosed) {
162
+ // 重生后立刻上报 transition entry(live/reload 视图同步翻回 running,等价性由
163
+ // applyEntry reducer 保证,对齐 SP-2 重建即报告先例)。
161
164
  deps.reportRecordTransition(record);
162
165
  }
163
166
  return record;
@@ -169,7 +172,7 @@ function resurrectColdRecord(
169
172
  * @throws ResurrectDeniedError 可重连候选被 worktree/异进程活实例守卫拦截
170
173
  * @throws Error parentRecordId 跨层不匹配(direct parent 错误,与外层校验同文案) */
171
174
  export function coldLookupForAction(
172
- deps: ColdResurrectDeps,
175
+ deps: ColdLookupDeps,
173
176
  id: string,
174
177
  allowReconnect: boolean,
175
178
  ): ExecutionRecord | undefined {
@@ -1,4 +1,4 @@
1
- // src/runtime/config/config.ts
1
+ // src/execution/config.ts
2
2
  //
3
3
  // 全局配置(~/.pi/agent/subagents/config.json)。
4
4
  // 仅保留 maxConcurrent(pool 大小)。模型解析已退化为「主 agent model 优先」,