后台子代理权限请求被静默 cancel(无 UI/无日志)+ 取消风暴导致父 turn 僵尸化(allow 内命令也秒拒)

Abierto
#687 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
electron, typescript

Línea de trabajo

Start by tracing permission handling for background subagent requests and the permission-registry timeout mentioned in the report; compare that path with allow-rule handling in the parent turn. Then inspect POST /api/chat/interrupt and its no-active-turn behavior. Reproduce each reported failure and add focused tests; done means unauthorized requests are surfaced accurately, allowed tools remain usable, and interrupting with no active turn does not cancel unrelated work.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug P0-crash-or-interrupt
CodePilot 版本 / Version

0.67.15 (0.67.15)

操作系统与架构 / OS & arch

macOS 26.6.2,Apple Silicon (arm64, M5 Pro)

Runtime

Claude Code (SDK)

Provider / Model

qwen3.8max

是否可复现 / Reproducible?

每次都能复现 / always

复现步骤 / Steps to reproduce

Bug 1:后台子代理权限请求被静默 cancel(不上 UI、不入队、无日志)

  1. 在 CodePilot 会话中用 Agent 工具启动一个后台子代理(转录 meta:requestShape:"background"、requestNonInteractive:true)
  2. 子代理调用一个不在 allow 规则内的工具(如 WebSearch / WebFetch / Bash(curl:*))
  3. 观察:子代理侧立即收到拒绝,文案为 The user doesn't want to take this action right now. STOP...;CodePilot UI 无任何审批弹框;服务端日志(codepilot-main.log)无 [permission-review] 记录

Bug 2:子代理取消风暴后,父 turn 工具管道僵尸化(allow 内命令也秒拒)

  1. 在同一会话中让该子代理连续撞墙多次(实例中为 12 次 cancelled),子代理最终失败返回
  2. 回到主会话执行任意工具调用——包括精确匹配 allow 规则的命令(实例:单行 python3 -c "print(...)",匹配 Bash(python3:*),该规则 15 分钟前还反复生效)
  3. 观察:全部秒级 cancelled(USE 与 ERR 时间戳同秒),转录记录 "toolDenialKind": "cancelled";服务端无任何 error/abort/interrupt 日志;只能重启进程恢复

实例时间线(2026-09-10,同一 SDK turn 内,19:52:38Z 启动,用户全程未操作/在睡觉)

UTC 事件
19:56–20:07 主会话 20+ 次 Bash/Edit/Write/git 全部正常(含刚加入 allow 的新规则,热加载生效)
20:07:40 启动后台侦察子代理
20:07:57 主会话最后一次成功工具调用(git commit)
~20:08–20:13 子代理 12 次工具调用被静默 cancel(Bug 1),失败返回
20:15:12 起 主会话所有工具调用秒级 cancelled(Bug 2),含 allow 匹配的单行 python3 探针

一夜之间同一会话共 29 次被拒(主会话 11 + 子代理 A 6 + 子代理 B 12),29/29 全部 toolDenialKind:"cancelled",无一条 user-denied。

期望 vs 实际 / Expected vs actual

Bug 1:后台子代理权限请求

  • 实际:请求在 CLI 进程内被静默取消,子代理只看到 "The user doesn't want…"(误导性文案——并没有 user 参与);CodePilot 审批 UI 和服务端日志对此零记录
  • 期望:权限请求应转发到 CodePilot 审批 UI(原生 Claude Code 终端会把后台子代理的权限请求浮出给用户),或至少在服务端日志留痕、给子代理返回准确的"无审批通道"错误,而非伪装成用户拒绝

Bug 2:父 turn 僵尸化

  • 实际:子代理批量取消后,父 turn 内所有工具调用(含本应直接放行的 allow 匹配项)立即 cancelled,无任何报错日志,不可恢复
  • 期望:① allow 规则匹配的工具调用不应经过任何审批通道,僵尸态不应存在;② 若控制通道损坏,应显式报错并结束 turn,而非让模型在 2 分钟内反复撞墙收到误导性"user denied"文案

证据文件(可按需提供,已确认不含密钥)

  • 会话转录 + 子代理转录(含 29 条 toolDenialKind:"cancelled" 原始记录):~/.claude/projects/<project-slug>/<session-id>/subagents/agent-a89b70d5304eccf13.jsonl 等
  • codepilot-main.log 事发窗口摘录(该会话仅 1 条 permission-review,为 17:41Z 的 AskUserQuestion,正常)
  • 会话内部 ID:chat_sessions 5bcb38d7…,sdk_session b6ddc5a7…

关联发现(同轮排查确认,可分拆处理)

  1. interrupt 扇出连坐:POST /api/chat/interrupt 在 no active turn 时仍执行完整扇出(abort 整个 SDK 进程 + cancelSubagentRunsForParentSession),一次调用杀死原生后台 agent、CodePilot 子代理和父会话进程。建议 no active turn 时 no-op,或提供"保留后台任务"选项。(日志 11 次实例,2026-09-03 至 09-11)
  2. 权限请求 300s 硬编码超时(permission-registry setTimeout(..., 3e5)):超时自动 deny 不可配置;超时后用户再点批准,服务端仍记一条 approved 日志但实际已 deny,纯误导。
  3. 子代理审批 fail-open:codepilot_spawn_subagent 启动的子代理执行 Bash/写文件零审批、零日志(对照组:父会话每条 Bash 都走人工审批);required_capabilities 不强制——声明 read_workspace 的子代理成功执行 touch 写文件,与文档 "fail closed" 承诺矛盾;提示词注入场景下子代理通道是零闸门。
  4. 子代理路由认证失败表现为"莫名中断":spawn 到未登录/不匹配的 provider 路由时直接 RUNTIME_ERROR: Not logged in,用户侧只看到任务自动中断,无明确归因。
日志 / 截图 / session id

No response

影响面 / Impact
  • 涉及文件写入或可能误改/丢失数据 / involves file write or possible data loss
  • 导致崩溃、闪退或对话被自动中断 / causes crash / quit / auto-interrupt
Lenguaje dominante
TypeScript
Estrellas
6.5k
Forks
697
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

  • Sin Dockerfile ni archivo de Docker Compose
  • Tiene una plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de op7418/CodePilot

Todos los issues de op7418/CodePilot

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.