Skip to content

fix: 权限/死循环 continuation 泄漏及状态持久化问题 #1

@terryso

Description

@terryso

问题来源

Checkpoint review 中发现,权限内联审批迁移引入的 4 个 Patch 级问题。非阻塞发布,但应在后续 Story 中修复。

问题列表

1. clearEvents() 泄漏 CheckedContinuation

AgentBridge.swift:401-426

clearEvents() 未 resume permissionContinuationsdoomLoopContinuations。当在有 pending 权限卡片时切换会话或清空事件,CheckedContinuation 永远不被 resume,违反 Swift continuation 契约,SDK 回调挂起。

修复:在 clearEvents 中遍历并 resume 所有 pending continuations(权限返回 deny,死循环返回 stop)。

2. trimOldEvents() 可泄漏 permission continuations

AgentBridge.swift:449-464

若内存事件窗口满 500 条限制,trimOldEvents 移除 pending 权限/死循环事件时,关联的 continuation 不会被 resume。

修复:在 trimOldEvents 中检查被移除事件是否有 pending continuation 并 resume。

3. allowOncealwaysAllow 行为完全一致

AgentBridge.swift:536-548

两个 case 都调用 addSessionOverride(toolName, decision: .approved)。语义上 allowOnce 应只批准本次不留记录,alwaysAllow 应做 session override。

修复allowOnce 跳过 addSessionOverride 调用(直接返回 .allow()),alwaysAllow 保持当前 session override 行为。若需持久化则应使用 addPersistentRule

4. 权限/死循环解决状态未持久化到 event metadata

AgentBridge.swift:558-566

resolvePermissionresolveDoomLoop 只 resume continuation,不更新 event 的 metadata。markStalePermissionEvents 在重新加载时将所有无 resolved 标记的事件标为 "expired",导致已批准卡片显示"已过期"。

修复:在 resolve 时更新 event metadata 的 resolved 字段(如 "approved"/"denied"/"stopped"/"allowed")。

影响评估

  • 日常使用中 clearEventstrimOldEvents 在有 pending 权限时被触发的概率低
  • allowOnce/alwaysAllow 语义差异对用户体验有影响但不影响正确性
  • 解决状态不持久化仅影响重新加载后的 UI 显示
  • 不影响 Story 5-1 Skill 管线

Labels: bug, tech-debt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions