Repository navigation
fix(desktop): 后台落库的错误提示关闭后正确标记已处置 - #6251
Conversation
错误落库时任务不在视图里(或之后离开过视图),live 横幅转为历史错误卡时 连 errorPersistId 一起清掉了;main 输入投影随后把同一错误重新点亮,横幅 已没有对应的错误行 id,点关闭只清界面、不写 dismissed,切走切回或刷新后 尾部错误提示又出现。Orca Worker 出错时用户多停在 Lead 视图,最常碰到; 普通任务后台出错同样中招。 hand-off 到历史时保留 errorPersistId,被重新点亮的横幅沿用同一行 id, 关闭即可标记 dismissed。绑定照旧由新一轮启动、投影清空错误或新的 persistId 收掉;不改 main、不改落库,不产生新的错误行。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 052f7c4d6e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
[Medium impact] 本次修改未发现阻碍合并的问题。
|
device-link 控制端断线期间会漏收被控端的新一轮启动、新错误与落库信号, 重连投影只带错误文案;保留旧 errorPersistId 会让关闭新错误时标记旧行。 远程任务交给历史时照旧清掉绑定(与修复前一致),本机任务仍保留。 远程判定取会话来源设备的粘滞值,覆盖 relay 重连时来源映射暂空的窗口。 补测试:交给历史后保留的旧绑定在新一轮启动时清掉;远程任务重连投影 带来的新错误不沿用旧行;修正一条标题与内容不符的用例。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18981b7d8a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
前两版在交给历史时保留 errorPersistId,但投影只有错误文案、没有错误 代次:远程断线期间漏收的新一轮、scheduler 发送前失败直接换掉错误等, 新错误可能不经过新一轮启动就顶替旧错误,保留的绑定会被错用,关闭标掉 的是旧行(review P1 ×2)。 改为不保留绑定(交接逻辑恢复为修复前),在 disposeLiveErrorPersist 没有绑定、也没有在途补写时,按已加载历史的最后一条认领:未处置的 error 行且文案与 live 横幅一致才标记 dismissed;对不上就只清界面。 文案口径抽成 liveErrorBannerText,与 error 事件写横幅同源,HTTP 状态 后缀不落库故比较前去掉。远程任务经 dismissErrorMessageFor 走隧道写, 一并修好。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
|
@codex review |
|
@greptileai review |
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
MagicLizi
left a comment
There was a problem hiding this comment.
复审发现 1 条 P1,需修复后再合并:
- apps/desktop/src/renderer/lib/makerChatStore.ts:15849-15867:当前兜底只按“已加载历史的最后一条 error 行 + 文案匹配”来认领落库行。若旧错误 A 已交给历史,随后新错误 B 与 A 的 message/reason 相同,且 B 的持久化通知尚未到达,用户关闭 B 时会把 A 标记为 dismissed;B 随后落库但未被标记,刷新后仍会再次出现。PR 描述已承认这个边界,但用户可见结果并不等价。请改为使用明确的错误代次/行身份,或等匹配的 B 完成落库后再执行 dismiss,并补覆盖该时序的回归测试。
当前 CI 已通过,现有讨论已处理;修复后请重新请求 review。
review P1:旧错误 A 已交给历史后,投影点亮同文案的新错误 B(无绑定), B 落库前用户关闭,兜底只能看到尾部的 A,B 落库后未处置,刷新复现。 关闭/重试走兜底时登记意图(横幅文案 + 当时的队列快照);之后第一条 不属于当前横幅的错误落库信号到达时,读权威历史找到该行,未处置且 文案一致就标 dismissed(远程经隧道写),用一次即作废。新一轮启动、 新队列项、本窗口发送/插话/UI 触发、投影出现文案不同的新错误、 /clear/删除/归档/驱逐时作废。有绑定或在途补写的路径不变。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
|
@MagicLizi 感谢复审,P1 已在 6ecf389 处理,采用「等匹配的 B 完成落库后再执行 dismiss」(仅 renderer,不改 main / 投影 / device-link 协议):
PR 描述的修复、测试、未验证项与风险已同步更新,麻烦再看一下。 |
|
@greptileai review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ecf389293
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
dismissErrorTailMessage 失败时只回滚 errorDismissed,disposedErrorPersistId 仍让尾部错误提示被跳过,用户无处再关、重启后复现(review P2)。失败且标记仍是这一行时清回 null,尾部提示重新出现;会话已清掉或已换行时不动。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e998aad66
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
关闭请求返回前,在途的同文案投影会把刚关掉的横幅重新点亮;落库信号若绑到它就走不到补标,横幅随后被清掉而该行仍未处置(review)。意图有效期内同文案横幅只可能是重亮,此时不绑定,交给 claimDisposedLiveErrorRow 补标。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
|
@greptileai review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f90bc63cb
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
sendMessage / steerMessage / sendUiTrigger 原在入口就作废意图,随后若被 remoteClearInFlight、远程 scope、canStartComposerSteer、beforeEnqueue 或 Agent 切换在途拒绝,不产生新一轮却已丢了意图,关掉的错误落库后补标不了(review P2)。改到各 core 过完本端拒绝点、确定交给 coordinator / 远程 outbox 的位置再作废;仍在 enqueue 之前,避免直接派发的同文案新错误先落库被错标。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 419e5e5185
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
|
@greptileai review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 419e5e5185
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- 本端乐观排进队列、主进程还没收下的项不算「队列增长」,已有暂停队列时发送被 beforeEnqueue 拒绝也保留意图(Greptile review)。 - 本机插话改为主进程受理或物化进队列后才作废意图,主进程拒绝且未物化时保留; 远程插话仍在本端 outbox 收下时作废(Codex review)。 Signed-off-by: fmfsaisai <fmfsaisai@gmail.com>
|
@codex review |
|
@greptileai review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 16ef75ca40
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
MagicLizi
left a comment
There was a problem hiding this comment.
PR #6251 审查报告(head 16ef75c / base 3110cfd / main)
改动面:apps/desktop/src/renderer/lib/makerChatStore.ts(+217/-24)、
apps/desktop/src/renderer/__tests__/makerChatStoreTextDeltaBatching.test.ts(+483)、
apps/desktop/src/renderer/__tests__/deviceLinkControllerScenarios.test.ts(+86)。
Findings
- 无 P0/P1。
- 未阻断观察(P2 级,不作为打回依据,仅记录):
claimDisposedLiveErrorRow一次性消费关闭意图:若在补标目标落库前先读到另一条
error 行(文案对不上),意图即作废,真正那一行可能漏标。属「用一次即作废」的既定
取舍(makerChatStore.tsclaimDisposedLiveErrorRow注释与 PR 描述均已写明)。- 意图有效期内落库的同文案新错误会被补标(用户刚关掉的就是这种错误);该行的 live
横幅仍会显示,历史错误卡不受dismissed影响,可见影响有限。PR 描述「影响与回滚」
已如实写明。 - relay 重连窗口(session→device 映射暂空)内关闭错误,补标读写沿用现有
listMessagesFor/dismissErrorMessageFor易失映射路由,可能漏标但不会标错行;
与其余错误关闭路径口径一致,PR 已注明另开处理。
Rule coverage
按 rule-map 命中路径读取并逐项核对(只对照本次新增/修改代码,不追溯历史代码):
docs/dev-rules/development-workflow.md(P0/P1/P2 口径、PR 模板事实):Description 三大段
(这次改了什么 / 怎么验证的 / 风险)齐全、与 diff 一致;「变更类型=fix」「范围」列明包含与
明确不包含项(Worker 双错误行为已知问题另开);风险段写明额外 dismiss 写入与回滚方式。
验证命令与本次实测一致。严重度按 §3 口径判定,未发现 P0/P1。docs/dev-rules/engineering-conventions.mdReview 清单:- 无裸
console.log,日志走log.warn;2) 无新/改 IPC handler;3) 无 main 侧逻辑,
renderer 状态逻辑随 483 行回归用例覆盖主路径+失败路径(dismiss 落库失败回滚、认领读取失败
吞错告警);4) 新测试全部走 mock/FakeHost,无外网、无固定端口、无真实子进程;5) 无路径/
子进程/FS/快捷键改动,无平台分支,PR 已注明 Windows 未实测及理由;6) UI 文案无新增:
liveErrorBannerText只是把既有 reason→i18n 映射抽成函数(empty-response/turn-failed/
silent-stop-exhausted/codex-auto-review-unavailable四个既有 key,行为不变);
pnpm check:i18n、pnpm check:i18n-glossary通过(存量告警与本 PR 无关);7) 新增函数均带
职责注释;8) 无动画改动。
- 无裸
docs/dev-rules/electron-security-and-process-boundaries.md§8 清单:Renderer 未获得新特权
数据/能力(仅 store 内状态与既有 IPC 读写);无 preload/BrowserWindow/WebView/IPC/CSP/Fuses
改动;无新增安全边界。落库读写复用既有listMessagesFor、dismissErrorTailMessage→
dismissErrorMessageFor(远程走既有local-db:messages:*隧道 allowlist 通道),无新 wire
protocol。docs/dev-rules/remote-and-mobile-adaptation.mdReview 清单:会话数据读写经既有远程通道
(local-db:messages:list/local-db:messages:dismiss-error),SSH 远程不落本机fs;
无新 IPC/push、无 allowlist 变更;不触碰 device-link 重试/超时/断链恢复路径(重连窗口路由
为既有行为,PR 已说明并注明另开处理);移动端不消费makerChatStore,无需适配,理由已写在
描述与未执行验证中。docs/dev-rules/credentials-and-local-storage.md清单:无新增落盘/临时文件/fixture,仅复用
既有dismissed字段;测试无凭证;不涉及秘密外泄边界。DESIGN.md/docs/design-rules/cindy-design-system.md:无视觉、交互、布局或文案变化
(横幅文案函数抽取前后逐字符等价),无硬编码颜色/自造组件问题;uiEvidenceMissing(store
文件被标为 UI 路径但描述未附截图)按非阻断规则记入 warnings,不打回。- rule-map 固定问题:1) 单一目的(关闭错误提示后正确标记 dismissed),描述与 diff/测试一致;
2) 共享状态读方已核(disposedErrorPersistId三个消费方、errorDismissed回滚、尾部告警
查询不受非尾行标记影响);3) 无权限/凭证/跨平台边界变化;4) 未放松安全边界、无新依赖、无新
数据流向(远程写仍走既有 dismiss 通道);5) 测试覆盖本机/远程(FakeHost)、成功/失败回滚、
时序边界;6) 未把流程塞进 Core;7) 无 UI 证据需核对;8) 不涉及 mobile 原生配置;9) 无 P0/P1。
关键代码核验(逐处对照 diff 与调用方):
disposeLiveErrorPersist兜底:仅在「无绑定、无在途补写、state.error 存在」时按已加载历史
尾行认领(persistedTailRowIdForLiveError+isUndisposedErrorRowFor:role=error、未处置、
文案匹配才标),对不上只清界面,不会标到无关行;同时登记关闭意图供补标。markLiveErrorRowDisposed:dismiss 写入失败时把disposedErrorPersistId清回
null(dismissErrorTailMessage已回滚errorDismissed),尾部提示可再次关闭——三处调用方
(绑定 / 兜底 / 补标)一致受益。applyErrorPersistedDirtySignal:补标只走「persistId 不属于当前横幅」分支,当前横幅自己的
行不会被自动标掉;disposedIntentCoversLiveError(双向按行口径比文案)阻止关闭后重亮横幅
抢绑定,交给补标——对应已 Resolve 的 P1 thread(PRRT_kwDOTgdRUs6tgXs2)
的要求,最终 diff 已落实。- 意图作废点与描述一致:新一轮启动 / 队列新增真实项(
isPendingEnqueue !== true,本端乐观项
不算,对应 P1 thread PRRT_kwDOTgdRUs6tg7_9 的要求,16ef75ca 落实)/ 发送、插话被受理、UI
触发 / 投影带来文案不同的新错误 / /clear、删除、归档、LRU 驱逐(bumpRendererClearGeneration);
被拒的发送/插话不作废。 claimDisposedLiveErrorRow:按 persistId 读权威历史(本机messageService.list/ 远程隧道
local-db:messages:list),确认为未处置 error 行且文案一致才补标;读失败/读不到不写任何行。- 测试为真实断言(含「去掉修复时失败」的反证用例),304 条通过。
11 条历史 review thread(含 4 条 P1)全部 isResolved=true,P1 要求在最终 diff 中逐条可验
(保留绑定做法已撤回、关闭意图覆盖重亮横幅、乐观队列项不作废意图);两条评估后未采纳的 P2
(重试保留意图、粘滞归属路由)在 PR 描述中给了不采纳理由,按 P2 不阻断。
Verification
pnpm install --frozen-lockfile --prefer-offline:worktree 初始无 node_modules,按
docs/dev-rules/environment-setup.md安装(postinstall 补齐 Electron 二进制),退出 0。pnpm --filter desktop run --if-present typecheck:EXIT 0(tsc --noEmit)。pnpm test:unit:related:PASS apps/desktop unit(103.4s;vitest related 命中
deviceLinkControllerScenarios.test.ts、makerChatStoreTextDeltaBatching.test.ts、
makerChatStore.ts)。pnpm check:dco:通过,8 个 commit 全部 Signed-off-by(3110cfde..16ef75c)。pnpm check:i18n/pnpm check:i18n-glossary:通过(1317/18 处均为存量告警,无新增违规)。- 未执行:heavy 档恶意代码/数据外发专项与
security-scan.mjs(本 PR 为 standard 档,按分档
规则不跑;security门 scanned=true、hardHits/softHits 均为空);PR 描述中的实机手工验证
(假 Anthropic 接口造错、localDb.messages.list核对 dismissed)未由本审查复跑,作为作者
自证记录,不计为已验证项。
Intent alignment
- 描述来源:PR #6251 当前 body(读取时间 2026-10-17T16:32Z)+ 关联 issue #6247(协同面板关闭
Worker 错误提示后复现,声明无代码依赖、可独立合入)。原目标:任务错误提示被「关闭」后要把
对应错误行标记dismissed,切走切回 / 刷新不再复现(本机、Orca Worker 后台出错、device-link
远程任务同一口径)。 - 初始实现:
052f7c4d6e3d169e13e9f3328ef59f15269c47dc(2026-10-16,已实际读取该 revision 的
makerChatStore.ts:handOffPersistedLiveErrorToHistory在交给历史时保留errorPersistId
绑定,配合投影沿用绑定)。初始基线即本 PR base 的祖先,历史未改写,8 个 commit 时间线完整。 - 待合并 head:
16ef75ca40cc53ab3ffc899d3b7cf202b0fd02ef(diffHash
f7f97afcd8d105131ad901582c2ada34585789dd48560d63a1dfab0e924688ee)。
| 原目标/初始行为 | 最终行为与影响 | 代码/提交证据 | 变化依据 |
|---|---|---|---|
关闭后台落库的错误提示后标记 dismissed,不复现 |
保留:关闭/重试按绑定行或已加载历史尾行认领后写 dismissed,远程走隧道写被控端 |
disposeLiveErrorPersist / persistedTailRowIdForLiveError(makerChatStore.ts:15851-15922) |
同一目标,实现加强 |
初始:交接历史时保留 errorPersistId 绑定 |
撤回:绑定随横幅清掉,改为关闭时按真实尾行认领 | 18981b7→993de49f;persistedTailRowIdForLiveError 注释 |
两条已 Resolve 的 P1 thread(远程断线新错误顶替、scheduler 发送前失败换错)证明保留绑定会被错用到新错误、标掉旧行——缺陷证据充分,属目标内实现替换 |
| (修复过程中新增)关闭时行尚未落库的时序 | 关闭意图 + 落库信号补标,用一次即作废 | _disposedLiveErrorIntents / claimDisposedLiveErrorRow(makerChatStore.ts:15932-16001) |
人工 review P1 时序(A 已交历史→投影点亮同文案 B→B 落库前关闭);仍服务同一原目标 |
| (review 收紧)被拒发送/插话、重亮横幅不丢意图 | 16ef75c/2f90bc63/419e5e51 收紧作废与绑定条件 | invalidateDisposedLiveErrorIntentOnTransition、disposedIntentCoversLiveError |
已 Resolve 的 P1 thread 要求,最终 diff 已落实 |
- 结论:一致。三版实现(保留绑定 → 尾部兜底 → 补标意图)都围绕「关闭即处置、不复现」这一
原目标;撤回保留绑定有明确缺陷证据(会把新错误的行标成已处置 = 误标数据),不是无关扩范围;
新增机制全部收敛在 renderer store 内,无功能外扩、无协议/权限/持久化边界变化。多轮 Codex /
Greptile 意见与修复未改变用户原目标;两条评估后未采纳的 P2 建议有书面理由,属实现取舍,
不构成原意偏离。核心目标可核实(本机/远程回归用例 + 反证用例),无疑点需要用户裁定。
Overall — pass
没有 P0/P1;原意一致性复核结论为「一致」,可以进入 guarded Approve 与合并。
这次改了什么
摘要
现象:任务出错后,点输入框上方错误提示的「关闭」,切走再切回或刷新,错误提示又出现了;数据库里那条错误行没有被标记
dismissed。协同模式下的 Worker 最常碰到(Worker 出错时用户通常停在 Lead 视图),普通任务在后台出错同样会中招,device-link 远程任务也一样。根因(
apps/desktop/src/renderer/lib/makerChatStore.ts):applyErrorPersistedDirtySignal在任务不在视图时(或在视图时延到leaveView)把 live 横幅交给历史错误卡显示,并清空errorPersistId(这条横幅对应的错误行 id)。applyInputProjection把 live 横幅重新点亮——此时它没有对应的错误行 id。clearError → disposeLiveErrorPersist,既无errorPersistId也无在途补写,于是只清界面、不写 dismissed。刷新后尾部错误行仍未处置,尾部错误提示复现。修复:在
disposeLiveErrorPersist里补一个兜底(persistedTailRowIdForLiveError):没有绑定、也没有在途补写时,按已加载历史的最后一条认领——它是未处置的role='error'行,且文案与 live 横幅一致,才标记 dismissed;对不上(历史未加载、尾部不是 error、文案不同)就只清界面,退回修复前的行为,不会标到无关行。liveErrorBannerText(reducer 改为调用它,行为不变),比较时用行的 message / reason 重算横幅文案;事件附带的「(HTTP nnn)」后缀不落库,比较前去掉。投影点亮的横幅是 coordinator 记录的同一条 message 原文,直接等于行 message。clearError、retryLastError、continueAfterSilentStop,与原来「点重试或关闭即算已处置」同义。dismissErrorTailMessage → dismissErrorMessageFor,按来源设备走隧道写,一并修好。messageService.list/ 远程隧道local-db:messages:list)找到该行,未处置且文案一致就标 dismissed,用一次即作废。A 被顺带标记没有可见影响:dismissed只对尾部错误行生效(MessageStream尾行、CCAgentSessionView.errorTailMsg、sessionActiveTurn尾行告警查询)。disposedIntentCoversLiveError),交给补标处理,避免横幅随后被清掉而该行仍未处置。markLiveErrorRowDisposed在 dismiss 写入失败时把disposedErrorPersistId清回 null(errorDismissed原本已回滚),尾部错误提示重新出现、可再关一次;有绑定 / 兜底 / 补标三处调用一并受益。为什么不在交接时保留绑定(前两版的做法,已撤回):投影只有错误文案、没有错误代次。远程断线期间漏收的新一轮、scheduler 发送前失败直接把错误换掉等情况下,新错误可能不经过新一轮启动就顶替旧错误,保留的绑定会被错用,关闭标掉的是旧行(review 两条 P1)。改为关闭那一刻按数据库里真实的尾部行认领,不依赖长期保留的状态。交接逻辑恢复为修复前写法。
变更类型
feat新功能fix缺陷修复refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
makerChatStore.ts(liveErrorBannerText抽取、disposeLiveErrorPersist兜底与persistedTailRowIdForLiveError/markLiveErrorRowDisposed、关闭意图_disposedLiveErrorIntents与claimDisposedLiveErrorRow补标及作废);makerChatStoreTextDeltaBatching.test.ts、deviceLinkControllerScenarios.test.ts(回归用例)。UI 变化
不涉及:纯状态逻辑修复(错误提示关闭时的落库标记),无视觉、交互或文案变化。
怎么验证的
自动验证
手工验证
本 worktree 独立 dev app(macOS,企业 SSO 账号,热更新到本版代码)。用本机假 Anthropic 接口(列模型正常、发消息一律 401
authentication_error)作自定义供应商,稳定造出由 main 落库的终态错误;用window.electronAPI.localDb.messages.list(<sessionId>)核对错误行dismissed。dismissed→ 切走切回出现尾部错误提示,复现成功。dismissed: true,重载不复现。dismissed: true,切换与重载不复现。dismissed: true,切换与重载不复现。dismissed: true,原有路径不受影响。dismissed: true,切换与重载不复现。未执行的验证
sendMessage/steerMessage/sendUiTrigger的主动作废未单独写用例,由「队列出现新项」「新一轮启动」间接覆盖。listMessagesFor/dismissErrorMessageFor的易失映射路由(与现有所有错误关闭写入一致),可能漏标,关掉的错误重新打开后复现;读不到时不写任何行,不会标错。按粘滞归属统一路由所有错误关闭的读写另开处理(review 曾建议本 PR 内修,评估后未采纳:只改本路径会与其余关闭路径不一致、扩大改动面)。风险
风险分类
影响与回滚
提交前检查
git commit -s,见 DCO)