Skip to content

fix(desktop): 副窗口中会话被归档后关闭窗口,禁止继续对话 (#3175) - #3262

Open
yuaiccc wants to merge 23 commits into
makecindy:mainfrom
yuaiccc:fix/3175-detached-window-lifecycle
Open

fix(desktop): 副窗口中会话被归档后关闭窗口,禁止继续对话 (#3175)#3262
yuaiccc wants to merge 23 commits into
makecindy:mainfrom
yuaiccc:fix/3175-detached-window-lifecycle

Conversation

@yuaiccc

@yuaiccc yuaiccc commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

修复独立副窗口仍持有已归档任务时可以继续派发输入的问题。副窗口会在观察到任务归档后关闭;即使归档与“继续队列”或远程乐观发送发生竞态,Main 也会在真正恢复派发前按持久化任务状态再次拦截。

变更类型

  • fix 缺陷修复

范围

UI 变化

  • 引用的设计规范:不涉及新增视觉、文案或布局。改动复用既有 windowClose() 与分屏树收敛逻辑,属于独立辅助窗口的生命周期与故障隔离修复;对应 docs/design-rules/DESIGN.md 的多窗口一致性原则,以及 docs/dev-rules/electron-security-and-process-boundaries.md §3.1“独立辅助窗口统一生命周期基线”。

怎么验证的

自动验证

pnpm test:unit:related
结果:通过。

pnpm --filter desktop run --if-present typecheck
结果:通过。

Desktop 相关定向 Vitest(队列 coordinator、副窗口归档门禁、makerChatStore 远程恢复等 5 个文件)
结果:502 tests passed。

pnpm --filter @cindy/device-link exec vitest run src/__tests__/client.test.ts -t '多 peer 拓扑:一个 peer 停止 ACK 被限流,另一个 peer 的投递零感知'
结果:通过。

bash /Users/dash/Code/XD/dash/Skills/git/scripts/run-unit-gate.sh <worktree>
结果:Desktop 28,262 passed / 5 skipped;仅 ghostInstallReceipt.test.ts 两项失败。相同两项已在 clean origin/main 单独复现,判定为与本 PR 无关的主干基线故障。

手工验证

未执行;本轮以生命周期、IPC 边界与远程恢复回归测试覆盖。

未执行的验证

  • macOS / Windows 多窗口手工回归。
  • 全仓 unit gate 未达到全绿:被上述已在 clean main 复现的两项基线失败阻断。

风险

风险分类

  • 权限 / 安全 / 用户数据
  • 跨平台差异
  • 其他:独立窗口与远程派发生命周期竞态

影响与回滚

  • 影响范围:仅副窗口对已归档任务的输入派发、队列恢复,以及远程乐观发送恢复路径;主窗口既有归档恢复行为保持不变。
  • 回滚 / 降级方式:回滚本 PR 即恢复旧行为;未新增 migration、持久化 schema 或 wire 协议。
  • 故障半径三问:
    1. 触发层级是单条乐观发送请求或单个任务生命周期在归档边界发生竞态。
    2. 恢复动作保持同半径:只拒绝/回滚对应 outbox 请求,或让对应任务队列继续暂停;不会拆除 peer link、关闭 relay、重连或全量重放。
    3. 多 peer / 共享被控端:新增 Desktop 用例覆盖同一被控端上一个生命周期门禁拒绝不影响另一个在途请求;同时复跑 packages/device-link 既有“双 peer 中一个停止 ACK、另一个投递零感知”用例。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s
  • UI 改动已在“UI 变化”注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

@yuaiccc
yuaiccc requested a review from a team as a code owner August 22, 2026 20:57

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85356f3886

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 收紧了已归档会话在独立副窗口中的生命周期与派发边界,并补充持久化 active 状态门禁及请求级回滚。

  • 副窗口观察到会话归档后关闭,并阻止队列恢复、重试和远程乐观发送重新激活该会话
  • Goal、Learn、远程命令等派发路径在 Main 进程的会话 route lock 内复核持久化状态
  • Goal 更新链路传递既有 route lock 的所有权,避免首轮恢复派发重复获取非重入锁
  • 增加队列协调、窗口归档、远程恢复及事务隔离相关回归测试

Confidence Score: 5/5

当前实现已修复此前报告的 Goal 更新重复加锁问题,未发现仍需阻止合并的故障。

当前 HEAD 在 GOAL_UPDATE、updateGoal、resumeGoal、fireTurn 和 pending-agent-switch holder 之间完整传递已有 route lock 的所有权,因此此前会永久等待同一把非重入锁的路径已不再存在;没有其他阻塞性故障仍然成立。

Important Files Changed

Filename Overview
apps/desktop/src/main/maker-ipc/goal.ts 为副窗口及显式远程请求增加持久化 active 状态门禁,并向 GoalController 透传 route lock 所有权。
apps/desktop/src/main/goal-host/controller.ts updateGoal、resumeGoal 与 fireTurn 已完整传递 sessionRouteLockHeld,修复 Goal 更新路径的非重入锁自死锁。
apps/desktop/src/main/maker-ipc/register.ts pending-agent-switch holder 在调用方已持有 route lock 时跳过二次加锁,同时保留普通路径的串行语义。
apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx 收拢独立副窗口中的归档会话生命周期,并配合 Main 侧门禁阻止后续输入派发。
apps/desktop/src/renderer/lib/makerChatStore.ts 调整远程乐观发送的失败回滚和请求隔离,避免归档竞态影响无关请求。
apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts 在队列 Resume 与 Retry 的真正派发边界复核持久化 active 状态。

Sequence Diagram

sequenceDiagram
  participant W as 独立副窗口
  participant M as Main IPC
  participant L as Session route lock
  participant DB as 持久化会话状态
  participant G as GoalController
  W->>M: Goal 更新/恢复请求
  M->>L: 获取会话 route lock
  L-->>M: 已持锁
  M->>DB: 复核会话仍为 active
  alt 会话已归档
    DB-->>M: inactive
    M-->>W: 拒绝派发
  else 会话仍 active
    DB-->>M: active
    M->>G: "updateGoal(sessionRouteLockHeld=true)"
    G->>G: resumeGoal → fireTurn
    Note over G,L: 复用已有锁,不再重复获取
    G-->>M: 更新完成
    M-->>W: 成功
  end
Loading

Reviews (25): Last reviewed commit: "fix(desktop): gate compact, worker dispa..." | Re-trigger Greptile

@MagicLizi

Copy link
Copy Markdown
Contributor

这条改动会改变用户看得见的交互:副窗口里的会话被主窗口归档后,副窗会自动关闭,而不只是停在已归档会话上。这属于产品行为,需要维护者确认后再合。

请维护者在本 PR 上 Approve;如果希望改成「留窗但禁止发送/恢复」或其它收口,请 Request Changes。

讨论 issue:#3263

@MagicLizi MagicLizi added awaiting-discussion 等待维护者讨论(review-pr) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) labels Aug 22, 2026
@dashhuang
dashhuang force-pushed the fix/3175-detached-window-lifecycle branch from 85356f3 to d543d64 Compare August 22, 2026 22:21

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d543d64b04

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx Outdated
Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx Outdated
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d497cca98e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/OrcaSplitView.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 124fde79a8

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45be85fdd1

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx Outdated
Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 3 条 review conversation 没 resolve(apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 289f03d4df

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
Comment thread apps/desktop/src/main/maker-ipc/register.ts Outdated
@dashhuang

Copy link
Copy Markdown
Member

收敛检查点(HEAD 2defbf9c5

  • 不变量:副窗口一旦获知其路由任务已归档,普通发送、排队操作与恢复路径都不得再派发;脏文件预检取消时保留编辑器,但所有派发入口保持失效。
  • 对称路径:普通 / Workdir / Orca 关窗归属;普通 send / steer;附件物化后的发送;device-link 断线重连后的再次派发;错误、中断、silent-stop 与切换供应商后的 retry;队列 Resume / Steer。
  • 判据收拢:Renderer 用同步归档 ref 约束副窗口入口与每次远端实际派发;Main 仅在副窗口显式请求时,于 retry 入队边界复查持久化 active 状态,主窗口历史行为不变。
  • 可鉴别测试:覆盖重连后再次执行生命周期 fence、归档期间 retry 不入队、主窗口 archived retry 兼容、归档副窗移除 queue Resume / Steer dispatcher。
  • 故障半径:触发与动作都限定在单条乐观发送 / 单个任务生命周期;不拆 relay、不重建连接、不改变共享 peer 状态,因此不会把一个副窗的归档状态放大到其它控制端。

@dashhuang

Copy link
Copy Markdown
Member

收敛检查点:副窗口一旦得知其路由任务已归档,普通发送、排队操作与恢复入口都不得再派发工作;脏文件取消关窗时保留编辑器,但所有派发路径继续保持 inert。

已审计路径:普通 / Workdir / Orca 关窗所有权,send / steer,附件物化后的入队,device-link 断线重连,错误 / 中断 / silent-stop / provider-switch retry,以及队列 Resume / Steer。可鉴别回归覆盖重连后再次执行生命周期 fence、历史读取期间归档时拒绝副窗 retry、主窗归档任务 retry 保持既有恢复语义,以及归档副窗移除队列派发回调。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2defbf9c52

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx Outdated
Comment thread apps/desktop/src/renderer/lib/makerChatStore.ts
@MagicLizi MagicLizi added the touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) label Aug 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f950f29142

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx Outdated
Comment thread apps/desktop/src/renderer/lib/makerChatStore.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx / apps/desktop/src/renderer/lib/makerChatStore.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9cd208ff8b

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/maker-ipc/register.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/desktop/src/main/maker-ipc/register.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ed339149d

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/maker-ipc/register.ts Outdated
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/desktop/src/main/maker-ipc/register.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0bc01deb77

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6dd8088b62

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/maker-ipc/register.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e282539c05

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/maker-ipc/reviewStartHandler.ts Outdated
Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
@MagicLizi MagicLizi added the touches:large-diff 改动量较大(review-pr 自动维护,仅展示) label Aug 24, 2026
dashhuang and others added 14 commits August 25, 2026 10:15
Signed-off-by: Dash <dashhuang@gmail.com>
Signed-off-by: Dash <dashhuang@gmail.com>
Signed-off-by: Dash <dashhuang@gmail.com>
Signed-off-by: Dash <dashhuang@gmail.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Address Codex P2 finding on goal.ts: the lifecycle guard only fired for
device-link invokes with requireActiveSession, while a local secondary
window (which hosts a GoalIndicator on a full session) could call
resumeGoal/updateGoal/clearGoal/setGoal and bypass the active-session
fence — re-activating an archived task.

Derive secondary-window status from the real event.sender via
isSecondaryAppWindow(BrowserWindow.fromWebContents(event.sender)),
complementary to the device-link requireActiveSession marker (device-link
synthetic events have no sender). Either path now takes the route lock +
persistent active assertion. runWithLifecycleGuard reports whether it
fenced so GOAL_SET sets sessionRouteLockHeld consistently for both paths.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Windows (1/2) failed one unrelated test in packages/maker-core
(cindySubagentRunner 'honours a stop that shares a batch with an earlier
approval') with a 60s waitFor timeout, while Linux (1/2)(2/2) and Windows
(2/2) all passed. This PR only touches desktop main/renderer goal
lifecycle files (goal.ts, bootstrap-electron.ts, goalHandlers.test.ts)
and does not modify maker-core, so this is a Windows-only flake.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Address Codex P2 (goal.ts:128): GOAL_GET_STATUS looked like a read but its
resumeOnOpen() path has side effects — it rebuilds the Agent session and
may continue a dormant active goal. After a session was archived and its
auto-close cancelled over unsaved files, a secondary-window GoalIndicator
re-binding (renderer reload / session origin re-bind) could call
getGoalStatus and re-activate the archived task, because set/resume/update
/clear were fenced but this auto-recovery read was not.

- Wrap resumeOnOpen in runWithLifecycleGuard so local secondary windows
  (detected via the real event.sender) and device-link secondary windows
  (requireActiveSession marker, since their synthetic events have no
  sender) run it under the route lock + persistent active assertion.
- Primary windows / primary remote keep the historical resume-on-open
  semantics (opening a main-window session is allowed to recover).
- When the fence reports the session is no longer active, GET_STATUS
  degrades to returning the pre-recovery snapshot instead of resuming or
  throwing at the renderer.
- Thread requireActiveSession through makerTransport for the remote
  secondary-window getGoalStatus path (local main process auto-fences via
  sender, so no preload change is needed).
- Add regression tests for both remote and local secondary-window paths.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
@yuaiccc
yuaiccc force-pushed the fix/3175-detached-window-lifecycle branch from ef8c1a7 to 7e2f7d3 Compare August 25, 2026 02:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e2f7d3851

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/maker-ipc/goal.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/renderer/lib/makerTransport.ts / apps/desktop/src/main/maker-ipc/goal.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

…eadlock

Review P2: runWithLifecycleGuard holds the session route lock, then calls
controller.setGoal/resumeGoal/resumeOnOpen which re-enter the same
non-reentrant lock via acquirePendingAgentSwitchForDirectSend →
acquireSendToSessionLock, deadlocking the IPC.

The holder already supports a sessionRouteLockHeld option to skip the
second acquisition. Propagate the fenced flag through every side-effecting
Goal path:
- setGoal: input.sessionRouteLockHeld (already consumed by fireTurn)
- resumeGoal: new opt, forwarded to fireTurn
- resumeOnOpen: new opt, forwarded to acquirePendingAgentSwitch
- goal.ts fence: pass the flag when fenced, omit it otherwise

Also propagate requireActiveSession through the remote secondary-window
goal transport (setGoal/clearGoal/resumeGoal/updateGoal), not just
getGoalStatus (review P1): synthetic device-link events have no sender,
so without the marker the guard treats them as primary-window requests
and a secondary window can restart an archived task.

Tests: update goalHandlers assertions for the new flag, add a
send-to-session ordering contract for the holder fast-path, and fix the
SET_MODEL needle that drifted to `options` in this branch.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
Comment thread apps/desktop/src/main/maker-ipc/goal.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e87964aeb8

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/bootstrap-electron.ts Outdated
Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
@MagicLizi

Copy link
Copy Markdown
Contributor

@yuaiccc 👋 这个 PR 还有 5 条 review conversation 没 resolve(apps/desktop/src/renderer/lib/makerTransport.ts / apps/desktop/src/main/maker-ipc/goal.ts / apps/desktop/src/main/bootstrap-electron.ts / apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

…l IPC

Address remaining review threads on makecindy#3262:
- GOAL_UPDATE fenced path also re-enters the route lock: updateGoal
  resumes paused/blocked goals via resumeGoal→fireTurn when the objective
  changes, so pass sessionRouteLockHeld through updateGoal and its
  resumeGoal call. Previously only setGoal/resumeGoal/resumeOnOpen had
  the marker, leaving updateGoal to self-deadlock.
- isSecondaryWindowEvent must tolerate a missing sender. Device-link
  synthetic events set sender to undefined (invoke-registry); calling
  BrowserWindow.fromWebContents(undefined) threw before the request
  reached the controller. Return false for those calls — they are
  gated by the explicit requireActiveSession marker instead.
- Spread sessionRouteLockHeld only when fenced so non-fence callers
  keep the bare single/two-arg shape (goalHandlers tests updated).

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 63582a506e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
The remote secondary-window fence used [sid, remoteFenceOpts()] for
clearGoal/resumeGoal. When not in a secondary window remoteFenceOpts()
returned undefined, but the argument was still passed as a second
element, so spies/IPC saw (sid, undefined) instead of the bare (sid)
shape the transport-routing contract and its tests expect. Use a
conditional spread so non-secondary remote calls keep the single-arg
form (matching getGoalStatus), and only append {requireActiveSession}
for secondary windows.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f09c2a2a46

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/features/cc-agent/CCAgentSessionView.tsx
yuaiccc pushed a commit to yuaiccc/cindy that referenced this pull request Aug 25, 2026
…n active session

The secondary-window archive fence only blocked composer/queue input.
Three other entry points could still start an Agent turn on an archived
task when the auto-close was cancelled over dirty files (makecindy#3262 P2):

- Compact: both Pi (COMPACT_SESSION) and Claude (INPUT_COMPACT via the
  input coordinator) now run assertSessionActiveForManualDispatch when
  the caller is a secondary window (local by sender, or device-link with
  requireActiveSession). Renderer passes the marker through
  makerTransport.compactSession and makerChatStore.compactSession.
- Worker dispatch: WORKER_DISPATCH_UI_ASSIGNMENT re-checks the Lead's
  persisted active status inside the serialized claim, immediately before
  sendToWorker, instead of trusting the renderer's cached state.
- Interaction resolve: RESOLVE_INTERACTION looks up the pending
  interaction's owning session and asserts it is still active before
  resolving; approving a permission / answering ask_user / confirming a
  plan on an archived session is now rejected.

The existing assertSessionActiveForManualDispatch is reused (DB status
check + route lock semantics), so main is the single enforcement
boundary for all three paths.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c17557f8ec

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread node_modules Outdated
…n active session

The secondary-window archive fence only blocked composer/queue input.
Three other entry points could still start an Agent turn on an archived
task when the auto-close was cancelled over dirty files (makecindy#3262 P2):

- Compact: both Pi (COMPACT_SESSION) and Claude (INPUT_COMPACT via the
  input coordinator) now run assertSessionActiveForManualDispatch when
  the caller is a secondary window (local by sender, or device-link with
  requireActiveSession). Renderer passes the marker through
  makerTransport.compactSession and makerChatStore.compactSession.
- Worker dispatch: WORKER_DISPATCH_UI_ASSIGNMENT re-checks the Lead's
  persisted active status inside the serialized claim, immediately before
  sendToWorker, instead of trusting the renderer's cached state.
- Interaction resolve: RESOLVE_INTERACTION looks up the pending
  interaction's owning session and asserts it is still active before
  resolving; approving a permission / answering ask_user / confirming a
  plan on an archived session is now rejected.

The existing assertSessionActiveForManualDispatch is reused (DB status
check + route lock semantics), so main is the single enforcement
boundary for all three paths.

Signed-off-by: yuaiccc <yuaiccc@aliaun.com>
@yuaiccc
yuaiccc force-pushed the fix/3175-detached-window-lifecycle branch from c17557f to e9ec9fb Compare August 25, 2026 11:53

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e9ec9fb115

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return orcaUiAssignmentDispatchClaims.runOnce(
{ leadSessionId, workerSessionId, snapshotBeforeMs },
async () => {
await assertSessionActiveForManualDispatch(leadSessionId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 将 Lead 状态复核与 Worker 派单置于同一会话锁

当 UI assignment 与另一窗口归档 Lead 并发时,这个查询仍可能先读到 active,随后归档通过 session route lock 提交,最后 sendToWorker() 才启动 Worker;orcaUiAssignmentDispatchClaims 只按 assignment key 去重,并不与归档串行。相较先前评论,当前最终代码的新证据是新增的持久化复核仍是裸调用,没有包在 withSendToSessionLock(leadSessionId, ...) 中,因此请让复核与整个 Worker 派发共享 Lead 的 route lock。 docs/dev-rules/electron-security-and-process-boundaries.mdL38-L40

Useful? React with 👍 / 👎.

Comment on lines +13419 to +13420
if (requireActiveSession) {
await assertSessionActiveForManualDispatch(sid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 将压缩门禁保留到最终派发边界

当副窗口请求压缩时任务仍在运行,这里的状态检查通过后,inputCoordinator.compact() 会把一个不含 requireActiveSessionPendingCompactRequest 放入 pendingCompacts;若等待期间任务被归档,之后 dispatchCompact() 仍以无生命周期门禁的 send options 派发 /compact。相较先前手动压缩评论,当前最终代码的新证据是修复只增加了入队前检查,却没有把 fence 存入 compact 请求并传至最终 send 边界;请像普通队列项一样持久保留并最终复核该门禁。 docs/dev-rules/electron-security-and-process-boundaries.mdL38-L40

Useful? React with 👍 / 👎.

Comment on lines +14097 to +14100
const pendingEntry = pendingInteractionResolvers.get(requestId);
if (pendingEntry?.sessionId) {
await assertSessionActiveForManualDispatch(pendingEntry.sessionId);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 在会话锁内完成交互复核与解析

当用户提交 Permission、AskUser 或 Plan Review 的同时另一窗口归档任务时,这个异步复核可以先读到 active,归档随后在 route lock 内提交,而后面的 resolvePendingInteraction() 仍会批准交互并放行已归档任务的挂起 turn。相较先前交互确认评论,当前最终代码的新证据是新增检查虽然注释声称“在锁内”,实际没有调用 withSendToSessionLock;请将状态复核和 resolver 副作用置于同一 session route lock。 docs/dev-rules/electron-security-and-process-boundaries.mdL38-L40

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

在新窗口打开会话后,原会话删除或归档不会关闭新窗口,且仍可继续对话

3 participants