## 来源 PR #186 修复 #127 时的 subagent 审查发现(存量交错行为,非该 PR 引入,该 PR 客观收窄了伤害面)。 ## 位置 `apps/desktop/src/link-runtime-supervisor.ts` start() 的 catch 分支 + exit handler 的 restartTimer。 ## 问题 健康等待期内子进程崩溃时的交错: 1. exit handler 触发:`child=null`、publish offline、**调度 restartTimer(1-2s 后再 start)** 2. timer 触发 start#2 → 重新 fork 进程#2 → 进程#2 上线 3. 旧 start#1 的 `waitForLinkHealth` 仍在轮询同一端口,**拿到新进程#2 的健康响应** → `child !== running` → throw `link_runtime_exited_during_start` 4. catch#1:`isCurrent()` 仍 true(start 不 bump `operationGeneration`,两代 start 共享 generation)→ `stopping = true` 落在**健康的** running2 头上,且 `publish("crashed")` 可能盖掉 start#2 的 online(publish 非 online 分支还会清 currentCredentials,拖累 diagnose) 确定性后果:running2 之后真崩溃时,exit handler 走 stopping 分支 → 只 publish offline、不计数、**不自动重启**,自愈链路被毒化。 ## 建议 - start 代际隔离:每次 start() bump `operationGeneration`(或 catch 里发现 `child` 已被更新 start 接管时跳过 `stopping=true`/publish) - 注意与 #126 修复的 starting 守卫协同(守卫依赖 phase,代际 bump 不影响守卫语义) ## 关联 - #126/#127(PR #186 已修各自的直接问题) - 审查报告另记:stop() 的 1.5s kill 等待窗口内,并发 enable()/restart() 可穿过守卫再 fork(需 1.5s 内连点,低概率)
来源
PR #186 修复 #127 时的 subagent 审查发现(存量交错行为,非该 PR 引入,该 PR 客观收窄了伤害面)。
位置
apps/desktop/src/link-runtime-supervisor.tsstart() 的 catch 分支 + exit handler 的 restartTimer。问题
健康等待期内子进程崩溃时的交错:
child=null、publish offline、调度 restartTimer(1-2s 后再 start)waitForLinkHealth仍在轮询同一端口,拿到新进程refactor(agent): make capability routing demand-driven #2 的健康响应 →child !== running→ throwlink_runtime_exited_during_startisCurrent()仍 true(start 不 bumpoperationGeneration,两代 start 共享 generation)→stopping = true落在健康的 running2 头上,且publish("crashed")可能盖掉 start#2 的 online(publish 非 online 分支还会清 currentCredentials,拖累 diagnose)确定性后果:running2 之后真崩溃时,exit handler 走 stopping 分支 → 只 publish offline、不计数、不自动重启,自愈链路被毒化。
建议
operationGeneration(或 catch 里发现child已被更新 start 接管时跳过stopping=true/publish)关联