Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[ZCode 主仓 bug] 后台智能体运行期间编辑消息重发会永久丢失完成通知(stale-branch fencing 误伤),任务 UI 永久运行中——已定位到源码丢弃点

Aperta
#64 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
52/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
backend, cli

Direzione di ricerca

Start with core/src/runtime-task/registry.ts and trace branchGeneration updates in core/src/runtime/methods/rewind-message.ts. Then inspect core/src/runtime/methods/background-notifications.ts and core/src/runtime/methods/subagent.ts, using the described edit-and-retry scenario to follow notification and terminal-event fencing. Done means a still-running task remains deliverable after an edit, stale abandoned-branch events remain fenced, and the UI reaches a terminal state.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

借道说明同 #60:ZCode 主仓 issues 关闭、外部账号 PR 被权限拦截,只能在本仓反馈。本 issue 已完成日志证据与开源源码(main@29628c9)双侧定位,丢弃点、日志级别、设计意图注释均可直接对应到行。

[Bug] 后台智能体运行期间"编辑消息重发"会永久丢失该智能体的完成通知,任务在 UI 永久显示运行中

一句话

用户在后台子智能体运行期间编辑一条已发送消息并重发(editUserQuery → conversation rewind → 会话分支代数 branchGeneration 推进),该智能体完成后其通知被"迟到围栏"(stale-branch fencing)以 debug 级日志静默丢弃——生产日志不可见、无报错、无补偿;UI 因终态事件被同一围栏拦截而永久显示"运行中",取消时报 background_task_not_running,形成死循环。

复现步骤

  1. 在会话中派一个后台子智能体(Agent 工具 run_in_background=true),任务需运行数分钟;
  2. 智能体运行期间,编辑一条已发送的消息并重发(触发 editUserQuery → rewind);
  3. 等智能体完成。

结果:~/.zcode/cli/agents/<会话>/<智能体id>/metadata.json 为 status: completed(执行侧干净结束),但父会话永远收不到完成通知;UI 任务永久"运行中";尝试取消报 background work <id> was not cancelled: background_task_not_running。

实测证据链(2026-10-04,zcode-2026-10-04.jsonl + model-io 转录,时间为本地)

时间 事件 证据
10:38:22 round2 评审智能体后台启动 tracking.started,taskId=agent_0003c234
10:45:07 / 10:45:29 / 10:45:40 用户三次编辑重发消息(根因窗口) 3 次 conversation.command.edit_user_query;伴随 2 次 stopActiveForegroundExecution + 1 次 sendQueuedNow preempts active turn;回合计数 165→32(回卷重建痕迹)
11:03:53.281 智能体完成,通知"封存" runtime.background_task_notifications.sealed, reason: subagent_terminal
11:03:53.313 通知"入队"但随即被丢弃 subagent.background.notification.enqueued(info)之后全天无该智能体的 background_task.notification.runtime_enqueued——实际在 background-notifications.ts:33 被 debug 级 stale_branch_dropped 丢弃(见下方源码;当天日志级别分布 info 9332 / warn 65 / error 14 / debug 0,故不可见)
— 通知从未注入模型 父会话转录中 <task-id>agent_d2419519(对照组 round1)通知块 23 个;<task-id>agent_0003c234 0 个(会话全天共 265 个通知块)
11:21-11:44 桥本身正常 回卷之后启动的任务分别获得 runtime_command_52/55/57 并正常送达——坏的只有"回卷前注册"的那一个
11:44:32-11:47:31 取消失败 ×5 background_task_not_running;UI 仍显示运行中(终态事件 emit 被同一围栏拦截,状态永不更新)

对照:round1(agent_d2419519)10:20:34 完成瞬间为完整链 runtime_enqueued(runtime_command_36) → enqueued → batch_started → 注入;全天仅有的 3 次 edit_user_query 恰好全部落在 round2 运行窗口内。

源码因果链(四步闭合,apps/zcode-cli)

  1. 注册打戳:core/src/runtime-task/registry.ts:119-122——任务注册时盖 branchGeneration 戳,接口注释明说意图:"task 注册时所属 active conversation branch;用于迟到 completion fencing"。

  2. 编辑→回卷→代数推进:bootstrap/src/zcode-protocol-v4/commands/handlers/fork-edit-retry.ts:4("editUserQuery = 换文本的 retryTurn:rewind 截断该 turn");core/src/runtime/methods/rewind-message.ts:580-581——this.branchGeneration = branchGeneration; this.runtimeTaskRegistry.setActiveBranchGeneration(...),只推进新注册指针,存量运行中任务的旧代数戳原样保留。

  3. 丢弃点:core/src/runtime/methods/background-notifications.ts:31-43——通知到达时查注册表,task.branchGeneration !== this.branchGeneration → logger.debug("Dropped stale-branch background task notification") + return。debug 级 + 生产日志无 debug = 静默。

  4. 误导性"成功"痕迹:core/src/subagent/runner.ts:1860-1896——enqueueParentTaskNotification 为 void 调用、不检查结果,之后无条件打 info 级 subagent.background.notification.enqueued。日志里"已入队"不代表进了投递队列(真正的入队日志在 runtime-command-queue.ts:23-35 的 runtime_enqueued)。

补充:终态事件路径 core/src/runtime/methods/subagent.ts:76(isStaleBranchRuntimeTaskEvent)被同一围栏拦截,导致 UI 永久"运行中";回卷后新任务通知正常(其代数戳为新代数),且不在注册表的 taskId 会走 ?? this.branchGeneration 回退而恰好放行——两个现象都与源码一致。

设计缺陷本质

围栏无法区分两种情形:任务属于被放弃的旧分支(该拦:防止迟到通知污染回卷后的新对话)vs 任务仍在运行、用户只是编辑了一条消息(不该拦:智能体还在为新分支工作,其完成通知对新分支完全有效)。后者的通知被拦后,任务在 UI 悬死且无任何可见痕迹。

修复建议(按侵入性排序)

  1. 语义修复:回卷时(或通知到达时)对注册表中非终态的运行中任务重刷 branchGeneration 为新代数——仍存活的任务,其通知对新分支有效;只有终态/已通知条目保留旧代数参与围栏。
  2. 可观测性修复:stale_branch_dropped 从 debug 提升到 warn,并在 runner 侧检查投递结果,消除误导性的 info 级 "enqueued" 痕迹。
  3. 状态收口:终态事件(emitParentEvent 路径)的 fencing 应与通知 fencing 区分处理,至少保证 UI 侧任务状态能收口,避免"永久运行中 + 取消报 not_running"的死循环。

规避(用户侧,已验证)

后台智能体运行期间不要"编辑消息重发",需补充内容新发一条;若已触发,以磁盘产物为准:读 ~/.zcode/cli/agents/<会话>/<智能体id>/metadata.json 的 status,最终回复在同目录 task.output。

Lingua principale
Python
Stelle
86
Fork
51
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di zai-org/zcode-plugins

Tutte le issue di zai-org/zcode-plugins

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.