Skip to content

fix(s39): REQ-083 模型选择框 respawn 竞态 —— 取数诚实自愈 + 点灰行零 respawn - #173

Merged
jinjunnn merged 5 commits into
alphafrom
fix/s39-req083-picker-respawn-race
Jul 12, 2026
Merged

jinjunnn merged 5 commits into
alphafrom
fix/s39-req083-picker-respawn-race

Conversation

@jinjunnn

Copy link
Copy Markdown
Owner

根因(2026-07-10 真机日志定案)

引擎重启窗口(存 Key / 登录 / 激活代理均触发 respawn)内打开模型选择框:一次性拉取 config.providers 被 .catch(()=>{}) 静默吞 → engineModels 空 →

  1. 已配置 BYOK(deepseek/zhipuai)两头落空(不进「需 KEY」区、又无模型行)= 整体消失;
  2. proxyLive() 假 → 代理 13 行全 locked,而账户横幅走 main IPC 仍显示「PRO 会员」= 矛盾画面;
  3. member/balance 态点 locked 行无条件 enableProxy() → 又一次 respawn + renderer reload = 自续循环(报障时段 5 分钟 5 次 respawn,10:42:38.441 上一次完成同一毫秒排入下一次)。

排除项(实证):非端点域名切换(tidelabs.click 200 / ALPHA_BASE_URL 正确),非数据丢失(干净重启后引擎 deepseek 4 + zhipuai 13 + alpha 13 全在)。

修复(全部落 ui-mac 自有文件,main 零改动)

  1. 取数诚实 + 自愈:load 状态机(engineReady/engineStalled)+ 退避重试(1s/2s/4s/8s 封顶,sdk 未就绪同可重试);stalled 态顶置「正在连接引擎…稍后自动恢复」note + configured BYOK 占位行「已配置 · 模型加载中…」(反 C28 placebo;健康路径 ~ms 首拉不闪占位)。
  2. 点灰行不再火上浇油:lockedPickAction 纯函数 —— 仅「引擎在线且代理节点确实缺席」才 activate;引擎不可达一律 no-op。
  3. respawn 后自动恢复:重试循环覆盖,同一弹窗不重开就地补全。

验证

  • alpha-check 全绿;单测 +6(model-picker-logic 全分支),全量 673 绿。
  • 真机 CDP 五阶段断言全 PASS(证据 docs/audits/2026-07-10-s39-req083/,5 png + verify.md):基线 → 拦截取数(note+占位+13 locked)→ 点灰行零 reload/respawn → 解除拦截同一弹窗自愈 → 真杀 sidecar 重复全过 → 恢复基线。
  • main.log 复核:全场仅 1 次 respawn = 主动恢复步;两次故障态点灰行零 respawn(修复前每点一次触发一次)。

回写

  • BACKLOG REQ-083 已登记(本 PR 合入前补 shipped+PR 号回写 commit);CHANGELOG [Unreleased] 已记;S39 契约 + 证据随 PR。
  • UI PR 用户亲验门:dev 已留可用态(登录 PRO + 双 BYOK),待用户 GO 后合并。

🤖 Generated with Claude Code

jinjunnn and others added 3 commits July 10, 2026 11:26
引擎重启窗口内弹窗一次性取数静默失败 → BYOK 已配置供应商整体消失 +
代理全灰,且 member 态点灰行无条件 enableProxy 再触发 respawn,形成
自续循环(2026-07-10 真机日志定案;排除端点域名与数据丢失)。

- 取数改 load 状态机 + 退避重试(1s/2s/4s/8s 封顶,sdk 未就绪同可重试),
  stalled 态顶置「正在连接引擎」note + configured BYOK 占位行(反 C28)
- locked 点击抽纯函数 lockedPickAction:仅「引擎在线且代理确实缺席」才
  activate;引擎不可达一律 no-op(enableProxy 唯一调用点,main 零改动)
- 单测 +6(全量 673 绿);真机 CDP 五阶段断言全过:两类断网点灰行零
  respawn、同一弹窗不重开自愈(证据 docs/audits/2026-07-10-s39-req083/)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jinjunnn

Copy link
Copy Markdown
Owner Author

2026-07-12 真机验收(用户委托复跑)—— 结论 NO-GO(stage 5 FAIL)

复跑 7-10 五阶段脚本(分支 = PR + merge origin/alpha 0bdaec31,dev + CDP 9222,真实登录态 PRO + 双 BYOK):

Stage 0–4 全 PASS:基线 30 可选 / 19 BYOK;拦截取数 → note + BYOK 占位 ×2 + 13 locked;故障态点灰行零 respawn 零 reload;解除拦截同一弹窗自愈;真杀 sidecar 重复全过。修复的三点承诺在「请求失败」路径全部成立。

Stage 5 FAIL(新发现,7-10 当天此步为绿):retrySidecar 恢复后 respawned 引擎僵死——无鉴权请求秒回 401(中间件活着),带鉴权 /config/providers 永不返回(捕获请求挂起数分钟无 resolve/reject;新发 6s 超时请求 TimeoutError)。弹窗取数无超时 → .then/.catch 均不触发 → 状态机永不进 stalled → 无 note、无占位、13 行全灰、BYOK 消失、不自愈——用户可见症状原样复现(用户当场撞见并截图)。

根因两层:

  1. 弹窗盲区(本 PR 补丁范围):load 状态机只覆盖 reject/error,未覆盖 hang。修复 = 取数加 AbortSignal.timeout(超时视作可重试失败 → stalled note + 重试循环),renderer-only。
  2. 引擎层(单独立项):respawn 后鉴权路由悬挂。7-10 同脚本在旧引擎 stage 5 全绿;本分支已 merge 上游 sync(7c2e8b73)——疑引擎/sidecar 层新问题,与本 PR 无关但被本次验收暴露。

处置:dev 已重启恢复全绿基线(30 可选 / 0 灰 / 19 BYOK,数据零丢失——变灰是运行时僵死不是数据问题)。补丁就绪后随本 PR 更新再走亲验门。

2026-07-12 委托真机验收发现 stage5 FAIL:respawn 后请求「悬挂」(连接被接受、响应永不来,
非确定性 1/6),fetch 既不 resolve 也不 reject → 状态机进不了 stalled → 全灰假象且不自愈。

- picker 取数带 AbortSignal.timeout(ENGINE_FETCH_TIMEOUT_MS=10s):悬挂 → 超时 → 既有重试
  循环(stalled note + 占位),abort 同时关闭死连接;单测 +2
- 验收 harness 固化进仓(复盘病灶 1):packages/ui-mac/scripts/verify-picker-respawn.ts,
  新增 hang 注入阶段(尊重 abort signal)+ 恢复收敛轮询 + 断言硬失败;复验 14/14 PASS,
  证据 docs/audits/2026-07-12-s39-req083-reverify/
- 引擎冒烟机械化(复盘病灶 2,ADR-020 欠账):scripts/engine-smoke.sh + sync-upstream 新步
  (boot→probe→kill→reboot→probe),每日 sync 后引擎运行时破 = workflow 红
- 残余:引擎 respawn 悬挂竞态单独立项追踪;UI 面已由超时兜底(最坏 = 诚实提示 + 自动恢复)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r-respawn-race

# Conflicts:
#	docs/BACKLOG.md
@jinjunnn

Copy link
Copy Markdown
Owner Author

2026-07-12 复验(补丁后)—— 全绿,GO 收口

亲验门:用户 2026-07-12 委托验收并指示「将 S39 处理掉」= GO。dev 实例已留全绿可用态。

@jinjunnn
jinjunnn merged commit f34beb0 into alpha Jul 12, 2026
4 checks passed
@jinjunnn
jinjunnn deleted the fix/s39-req083-picker-respawn-race branch July 12, 2026 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant