@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.
- package/dist/{chunk-OL5BK4VN.js → chunk-LZJOEDGQ.js} +455 -203
- package/dist/engine-discovery-scan-Da4Dkzsi.d.cts +818 -0
- package/dist/engine-discovery-scan-Da4Dkzsi.d.ts +818 -0
- package/dist/execution/engine/engine-discovery-scan.cjs +216 -155
- package/dist/execution/engine/engine-discovery-scan.d.cts +1 -2
- package/dist/execution/engine/engine-discovery-scan.d.ts +1 -2
- package/dist/execution/engine/engine-discovery-scan.js +1 -1
- package/dist/execution/relay-env.js +5 -4
- package/dist/index.cjs +7686 -5894
- package/dist/index.d.cts +1876 -1360
- package/dist/index.d.ts +1876 -1360
- package/dist/index.js +7048 -5493
- package/dist.bundle/index.cjs +7747 -5957
- package/package.json +4 -4
- package/src/__tests__/manifest-store.test.ts +16 -15
- package/src/__tests__/robustness-medium-batch1.test.ts +10 -14
- package/src/__tests__/robustness-medium-batch2.test.ts +7 -2
- package/src/execution/__tests__/alive-store.test.ts +117 -1
- package/src/execution/__tests__/batch-finalized.test.ts +206 -0
- package/src/execution/__tests__/chat-engine-routing.test.ts +117 -1
- package/src/execution/__tests__/{cold-resurrect.test.ts → cold-lookup.test.ts} +133 -33
- package/src/execution/__tests__/collect-coordinator-service.test.ts +7 -5
- package/src/execution/__tests__/conversation-continuation.test.ts +1452 -0
- package/src/execution/__tests__/delivery-methods.test.ts +90 -176
- package/src/execution/__tests__/dialog-queue.test.ts +70 -3
- package/src/execution/__tests__/dispose-manifest-recovery.test.ts +475 -0
- package/src/execution/__tests__/execute-and-await-worktree.test.ts +3 -3
- package/src/execution/__tests__/execute-nesting.test.ts +8 -5
- package/src/execution/__tests__/execution-record.test.ts +8 -148
- package/src/execution/__tests__/finalize-record.test.ts +295 -129
- package/src/execution/__tests__/get-record-for-action-restart.test.ts +21 -29
- package/src/execution/__tests__/helpers/fake-engine-port.ts +13 -68
- package/src/execution/__tests__/helpers/legacy-sidecar.ts +33 -0
- package/src/execution/__tests__/helpers/subagent-service-mocks.ts +9 -5
- package/src/execution/__tests__/idle-gc.test.ts +60 -0
- package/src/execution/__tests__/lifecycle-manager.test.ts +3 -254
- package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +43 -22
- package/src/execution/__tests__/model-config-service.test.ts +111 -0
- package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +10 -6
- package/src/execution/__tests__/notify-ledger.test.ts +42 -1
- package/src/execution/__tests__/rebuild-indexes.test.ts +329 -0
- package/src/execution/__tests__/record-binding.test.ts +613 -0
- package/src/execution/__tests__/record-origin.test.ts +318 -0
- package/src/execution/__tests__/record-store-intent-api.test.ts +600 -0
- package/src/execution/__tests__/record-store-orphan-revive.test.ts +71 -3
- package/src/execution/__tests__/record-store.test.ts +72 -54
- package/src/execution/__tests__/recursive-visibility-baseline.test.ts +8 -5
- package/src/execution/__tests__/round-supervisor-workflow-origin.test.ts +205 -0
- package/src/execution/__tests__/run-orchestration-write-lease.test.ts +293 -0
- package/src/execution/__tests__/run-orchestration.test.ts +199 -0
- package/src/execution/__tests__/session-file-gc.test.ts +35 -4
- package/src/execution/__tests__/session-reconstructor.test.ts +78 -0
- package/src/execution/__tests__/state-marker.test.ts +288 -0
- package/src/execution/__tests__/stream-sink-retirement.test.ts +8 -5
- package/src/execution/__tests__/subagent-actions-core.test.ts +67 -16
- package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +0 -1
- package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -11
- package/src/execution/__tests__/subagent-service-parent-guard.test.ts +17 -11
- package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +130 -53
- package/src/execution/__tests__/subagent-service.test.ts +17 -215
- package/src/execution/__tests__/subprocess-agent-runner-no-progress-killall.test.ts +138 -0
- package/src/execution/__tests__/subprocess-agent-runner.test.ts +105 -660
- package/src/execution/__tests__/sync-collect-recovery.test.ts +23 -16
- package/src/execution/__tests__/terminal-write-latency.test.ts +79 -0
- package/src/execution/__tests__/workflow-agent-dispatch.test.ts +782 -0
- package/src/execution/alive-store.ts +37 -28
- package/src/execution/{cold-resurrect.ts → cold-lookup.ts} +48 -45
- package/src/execution/config.ts +1 -1
- package/src/execution/conversation-continuation.ts +541 -0
- package/src/execution/dialog-queue.ts +60 -12
- package/src/execution/engine/__tests__/common/capability-gate.test.ts +1 -1
- package/src/execution/engine/__tests__/common/journal-wiring.test.ts +16 -1
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +17 -51
- package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +0 -5
- package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +1 -1
- package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +5 -9
- package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +0 -3
- package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -3
- package/src/execution/engine/__tests__/model-prompt.test.ts +0 -3
- package/src/execution/engine/__tests__/registry.test.ts +0 -1
- package/src/execution/engine/__tests__/routing.test.ts +0 -1
- package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +0 -3
- package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +0 -3
- package/src/execution/engine/client/__tests__/engine-client-reap.test.ts +212 -0
- package/src/execution/engine/client/__tests__/mirror.test.ts +73 -1
- package/src/execution/engine/client/__tests__/protocol-closure.test.ts +2 -9
- package/src/execution/engine/client/__tests__/remote-engine.test.ts +46 -12
- package/src/execution/engine/client/engine-client.ts +81 -25
- package/src/execution/engine/client/mirror.ts +9 -0
- package/src/execution/engine/client/remote-engine.ts +52 -34
- package/src/execution/engine/client/reverse-router.ts +6 -27
- package/src/execution/engine/common/__tests__/run-signals.test.ts +79 -0
- package/src/execution/engine/common/capability-gate.ts +27 -0
- package/src/execution/engine/common/data-dir.ts +3 -2
- package/src/execution/engine/common/errors.ts +1 -1
- package/src/execution/engine/common/journal-wiring.ts +18 -9
- package/src/execution/engine/common/run-signals.ts +83 -0
- package/src/execution/engine/d8-compat.ts +1 -1
- package/src/execution/engine/host/__tests__/host-bridge.test.ts +3 -18
- package/src/execution/engine/host/host-bridge.ts +19 -41
- package/src/execution/engine/host/pi-host-binding.ts +5 -5
- package/src/execution/engine/port.ts +34 -54
- package/src/execution/engine/types.ts +11 -14
- package/src/execution/execution-record.ts +15 -47
- package/src/execution/finalize-record.ts +94 -197
- package/src/execution/idle-gc.ts +9 -3
- package/src/execution/lifecycle-manager.ts +25 -361
- package/src/execution/lifecycle-predicates.ts +22 -19
- package/src/execution/manifest-store.ts +40 -42
- package/src/execution/model-config-service.ts +1 -1
- package/src/execution/notifier.ts +39 -1
- package/src/execution/notify-host.ts +13 -4
- package/src/execution/record-entry.ts +20 -2
- package/src/execution/record-store.ts +925 -160
- package/src/execution/relay-env.ts +8 -3
- package/src/execution/round-supervisor/domain.ts +17 -5
- package/src/execution/round-supervisor/service-binding.test.ts +89 -53
- package/src/execution/round-supervisor/service-binding.ts +71 -21
- package/src/execution/round-supervisor/supervisor.ts +23 -9
- package/src/execution/service/record-access.ts +547 -0
- package/src/execution/service/record-lifecycle.ts +542 -0
- package/src/execution/service/run-orchestration.ts +1647 -0
- package/src/execution/service/service-bootstrap.ts +111 -0
- package/src/execution/service/service-constants.ts +27 -0
- package/src/execution/service/session-baselines.ts +401 -0
- package/src/execution/service/sync-collect-domain.ts +442 -0
- package/src/execution/service/workflow-dispatch.ts +567 -0
- package/src/execution/session-file-gc.ts +11 -8
- package/src/execution/session-reconstructor.ts +44 -1
- package/src/execution/sessions-index.ts +20 -3
- package/src/execution/settled-watchdog.ts +86 -43
- package/src/execution/state-marker.ts +516 -0
- package/src/execution/stream-sink.ts +1 -1
- package/src/execution/subagent-actions-core.ts +53 -31
- package/src/execution/subagent-service.ts +643 -2980
- package/src/execution/subprocess-agent-runner.ts +46 -323
- package/src/execution/types.ts +60 -43
- package/src/execution/ui-request-handler-factory.ts +5 -0
- package/src/execution/worktree-manager.ts +1 -1
- package/src/execution/worktree-registry.ts +1 -1
- package/src/index.ts +6 -5
- package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +2 -3
- package/src/orchestration/__tests__/agent-call-stream.test.ts +24 -49
- package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +4 -4
- package/src/orchestration/__tests__/file-run-store.test.ts +5 -7
- package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +2 -3
- package/src/orchestration/__tests__/run-snapshot.test.ts +27 -43
- package/src/orchestration/__tests__/worker-message-pump-workflow-dispatch.test.ts +274 -0
- package/src/orchestration/execute-agent-call.ts +1 -1
- package/src/orchestration/file-run-store.ts +1 -1
- package/src/orchestration/models/ports.ts +20 -13
- package/src/orchestration/models/types.ts +11 -13
- package/src/orchestration/run-snapshot.ts +18 -22
- package/src/orchestration/worker-message-pump.ts +33 -57
- package/src/shared/atomic-write.ts +10 -8
- package/dist/chunk-T2SYBW3I.js +0 -24
- package/dist/engine-discovery-scan-BXLA8y-z.d.cts +0 -1624
- package/dist/engine-discovery-scan-BXLA8y-z.d.ts +0 -1624
- package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +0 -255
- package/src/execution/__tests__/finalized-marker.test.ts +0 -104
- package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
- package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -488
- package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +0 -75
- package/src/execution/__tests__/tombstone-store.test.ts +0 -73
- package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +0 -230
- package/src/execution/finalized-marker.ts +0 -70
- package/src/execution/tombstone-store.ts +0 -72
|
@@ -1,34 +1,32 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/execution/alive-store.ts
|
|
2
2
|
//
|
|
3
|
-
// .alive sidecar
|
|
3
|
+
// .alive sidecar:跨进程写权声明的生产者 + pid 探活。
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
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
|
|
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
|
-
|
|
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
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
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
|
|
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-③
|
|
2
|
-
// findColdLookupCandidate / assertReconnectAllowed / resurrectColdRecord /
|
|
3
|
-
// coldLookupForAction + isReconnectableClosed
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
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
|
|
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
|
|
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
|
|
47
|
-
*
|
|
48
|
-
*
|
|
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:
|
|
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:
|
|
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]
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
chatMode
|
|
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
|
-
// [
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
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
|
-
//
|
|
145
|
-
//
|
|
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:
|
|
175
|
+
deps: ColdLookupDeps,
|
|
173
176
|
id: string,
|
|
174
177
|
allowReconnect: boolean,
|
|
175
178
|
): ExecutionRecord | undefined {
|
package/src/execution/config.ts
CHANGED