docs: record where a background agent shows up, and who owns it - #10951
docs: record where a background agent shows up, and who owns it#10951yiliang114 wants to merge 2 commits into
Conversation
Three separate things already answer "what is running": the live-process registry, the Agent View roster, and the daemon's own session model — and the daemon reads neither of the other two (`rg 'listLiveSessions|session-registry' packages/cli/src/serve` is empty across 94,136 lines). A Web Shell panel built on the daemon's model would make that split permanent. Records the decision the CLI half already implements — the roster is the authority on background agents, every other surface reads it — with the argument for it: only the roster carries `needs_input`, because only the supervisor is told. The registry knows a process is alive; the daemon knows a conversation exists; neither can answer "is it stuck waiting for me", which is the only question the surface exists for. Also records the consequence that decides what the Web Shell should not build: a `--bg` session registers and binds a peer inbox like any interactive session, so it is already addressable by `send_message`. The panel needs to show a background agent, not invent a second way to talk to one. Leaves one question to a maintainer rather than answering it: whether daemon-owned sessions (scheduled tasks, channel workers) should adopt into the roster too.
|
Thanks for the PR! Template looks good ✓ — every required heading is there, with the N/A substitutions the template asks for on a docs-only change. Problem: observed, not theoretical. The doc rests on a measurement rather than an argument, so I re-ran it: Direction: aligned. AGENTS.md asks for a design doc on non-trivial work and puts implementation plans in Size: not applicable — one new markdown file, +57/−0, no core paths. Approach: the scope feels right and I'd cut nothing. The most useful line in the doc is the §3 rule about labelling by task state rather than display group, and I checked it: One non-blocking thing to fix: §3 cites Risk: no elevated risk signals — no source paths touched. Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ —— 所有必需小标题都在,纯文档改动该填 N/A 的地方也填了。 问题: 是已观测的事实,不是理论性加固。这份文档的依据是一个实测结果而不是论证,所以我重跑了一遍: 方向: 对齐。AGENTS.md 要求非平凡工作写设计文档,并把实现计划放在 规模: 不适用 —— 新增一个 markdown 文件,+57/−0,未触及核心路径。 方案: 范围合理,我不会砍任何内容。文档里最有用的一句是 §3 关于「按任务状态而不是按显示分组来标注」的规则,我核对过: 一个非阻塞的小问题:§3 两次引用 风险: 无升级风险信号 —— 未触及任何源码路径。 进入代码审查 🔍 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
Code reviewThis is a docs-only PR, so the review is a fact-check: a decision record is worth exactly as much as the measurements it cites. I checked every code claim in it against
So the §0 decision is not resting on assertion. The §1 table is accurate as scoped — note the rg is scoped to The §3 labelling rule is the part I'd single out. One finding, non-blocking. §3 cites Nothing else. No critical blockers, no AGENTS.md violations — the file is where the repo's own conventions put it, it's short, and it adds no code. Not verified: the "94,136 lines" figure for Test evidenceThis is an unattended CI run, so I did not build or execute anything from this PR. The evidence below is the PR's own CI on the reviewed commit, read through the API. Nothing is red, and there is nothing left running that belongs to the PR: both Formatting is covered by CI rather than taken on faith: the
No sandboxed lane is named here on purpose: the PR makes no behavioural claim, so there is nothing for 中文说明代码审查这是纯文档 PR,所以审查就是一次事实核查:一份决策记录的价值,完全等于它所引用的那些实测数据。我把文档里每一条代码层面的结论都在 上表十项全部核实通过: 所以 §0 的决定不是靠断言撑起来的。§1 的表格在其限定范围内准确 —— 注意那条 rg 限定在 §3 关于标注的规则是我要特别点出的一处。 一处发现,非阻塞。 §3 两次引用 其余没有问题。无阻塞性缺陷,也无 AGENTS.md 违规 —— 文件放在仓库约定指定的位置,篇幅克制,且不引入任何代码。 未核实: 测试证据本次为无人值守 CI 运行,因此我没有构建或执行本 PR 的任何代码。下面的证据来自 API 读取的、该 PR 自身在被审提交上的 CI 结果。没有红灯,也没有属于本 PR 的任务仍在运行:两个 格式检查由 CI 覆盖,而非采信作者自述: 此处刻意不点名任何沙箱验证通道:本 PR 没有提出行为性主张, — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
|
Confidence: 4/5 — solid and unusually well-evidenced for a design doc; one non-blocking citation nit, named below. Stepping back: before reading the diff I asked what I'd write in this situation, and the answer was the same shape — pick one authority, show the measurement that forces the choice rather than arguing for it, name the next concrete piece of code, and explicitly leave the bigger question to a human. So this isn't a case where I found a simpler path the PR missed. §4 declining to propose daemon adoption is the part that most matches what I'd have done; the temptation in a doc like this is to answer everything, and a doc that answers everything is the one that gets closed unmerged. I fact-checked rather than skimmed, because a decision record is worth exactly what its measurements are worth. Ten of the eleven code claims resolved exactly, including both line numbers, against a The reservation I'd voice honestly, without letting it block anything: this doc's usefulness is coupled to #10942, #10943 and #10949 actually landing. If those three go the way of #8719 and #9399, this becomes a record of a decision about code that never shipped. The header does disclose the coupling, and the same author owns all four PRs, so it's visible rather than hidden — but a maintainer merging this is implicitly betting on the CLI half too. That's a reasonable bet and it's a human's to make, not mine to refuse. On the "am I being worn down by volume" question: the author has 35 open PRs, and I checked this one on its own merits. It's 57 lines, it adds no code, and I could independently confirm nearly every factual claim in it. That's the opposite of volume-as-filler. Six months from now I'd thank whoever wrote §3's labelling rule. Approving. The 中文说明Confidence: 4/5 —— 对一份设计文档而言,论证扎实、证据异常充分;有一处非阻塞的引用小问题,见下。 退一步看:在读 diff 之前我先问了自己「这种情况下我会写什么」,答案与本文形状一致 —— 选定一个权威来源、用实测数据而不是论证来逼出这个选择、点名下一块具体的代码,并明确把更大的问题留给人判断。所以这不是「我找到了一条 PR 漏掉的更简路径」的情形。§4 拒绝提出 daemon 收养方案,正是最贴合我会做的处理:这类文档的诱惑在于把所有问题都回答掉,而把所有问题都回答掉的文档,恰恰是会被关闭且不合并的那种。 我做的是事实核查而不是略读,因为一份决策记录的价值就等于它那些实测数据的价值。十一条代码结论中有十条精确对上,包括两处行号,而且核对用的 我要诚实说出、但不让它阻塞任何事情的顾虑是:这份文档的价值与 #10942、#10943、#10949 真正落地是绑在一起的。如果这三个 PR 走上 #8719 和 #9399 的老路,那这份文档就变成了一份关于从未交付的代码的决策记录。文档头部确实披露了这层耦合,而且四个 PR 都是同一位作者,所以这是可见的而非隐藏的 —— 但合并这份文档的维护者,实际上也在对 CLI 那一半下注。这是个合理的赌注,而且该由人来下,不该由我来否决。 关于「我是否被数量磨软了」这个问题:作者有 35 个 open PR,而我是单独按本 PR 自身的价值来审的。它 57 行、不引入任何代码,而且其中几乎每一条事实性结论我都能独立确认。这与「以数量充数」正好相反。 六个月后,我会感谢写下 §3 那条标注规则的人。 予以批准。 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
Two ways to put an agent on a terminal now exist — Arena's opt-in TmuxBackend and the Agent View supervisor's PTY host — and the risk is not that both exist, it is that a third gets built when attach lands. Records that they have different owners and different session lifetimes, that attach should drive the supervisor's PTY host rather than reach into the Arena backend, and that ITermBackend is the counter-example already in the tree: present, never wired, and now reported as unsupported rather than handed to someone as an untested path.
|
📄 Docs-only change — the automatic review ran at
Reviewed head: 中文说明📄 纯文档变更 —— 自动评审以 |
What this PR does
Adds one design doc,
docs/plans/2026-09-04-background-agent-surfaces.md. No code.It records a decision the CLI half of this work already implements — the Agent View roster is the authority on background agents, and every other surface reads it — together with the measurement that forced the decision, and the one question it deliberately leaves open.
Why it's needed
Three separate things already answer "what is running": the live-process registry (
~/.qwen/sessions/<pid>.json), the Agent View roster (~/.qwen/daemon/roster.json), and the daemon's own in-memory session model. The daemon reads neither of the other two —rg 'listLiveSessions|session-registry' packages/cli/src/servereturns nothing across 94,136 lines.That matters right now because the obvious next step is a Web Shell panel showing background agents, and the obvious way to build it — on the daemon's existing session model — would make the split permanent and give the product a fourth idea of what a session is.
The argument for the roster is not preference. Only the roster carries a background agent's semantic state (
needs_input,working,failed), because only the supervisor is told by the worker. The registry knows a process is alive; the daemon knows a conversation exists. Neither can answer "is it stuck waiting for me", which is the only question a background-agent surface exists to answer.The doc also records a consequence that decides what the Web Shell should not build: a
--bgsession is launched as a full interactive session (supervisor-dispatch.ts:196), so it registers in the live-process registry and binds a peer inbox when cross-session messaging is on. It is already addressable withsend_messagefrom another session, with no code that makes it so. The panel needs to show a background agent, not invent a second way to talk to one.It is short on purpose. Two previous designs in this area (#8719, #9399) were closed unmerged, and neither failed on its reasoning; a third grand plan is not what is missing. This one records a decision and names the next concrete piece of code.
Reviewer Test Plan
How to verify
Documentation only. The three measurements it rests on are each one command:
rg 'listLiveSessions|session-registry' packages/cli/src/serve→ no matches.startInteractiveUI.tsx:421—registerSessionis called unconditionally, so every interactive session (a background worker included) registers.supervisor-dispatch.ts:196— the worker argv is--session-id <id> --prompt-interactive=<prompt>.prettier --checkis clean on the file.Evidence (Before & After)
N/A — documentation.
Tested on
Environment (optional)
N/A.
Risk & Scope
Linked Issues
Records the decision behind #10942, #10943 and #10949. Supersedes nothing; #8719 and #9399 stay closed.
中文说明
这个 PR 做了什么
新增一份设计文档
docs/plans/2026-09-04-background-agent-surfaces.md。无代码。它记录了本工作 CLI 一侧已经在实现的一个决定 —— Agent View roster 是后台 agent 的权威,其他所有界面都读它 —— 以及促成该决定的实测数据,和它有意留下未答的那个问题。
为什么需要
现在已经有三样东西在回答「什么在运行」:live-process registry(
~/.qwen/sessions/<pid>.json)、Agent View roster(~/.qwen/daemon/roster.json),以及 daemon 自己的进程内 session 模型。而 daemon 既不读前者也不读中者 ——rg 'listLiveSessions|session-registry' packages/cli/src/serve在 94,136 行中零命中。这件事此刻重要,是因为下一步显而易见是做一个展示后台 agent 的 Web Shell 面板,而显而易见的做法 —— 基于 daemon 已有的 session 模型 —— 会把这个割裂固化下来,并让产品拥有第四种「session 是什么」的理解。
选择 roster 并非偏好。只有 roster 承载后台 agent 的语义状态(
needs_input、working、failed),因为只有 supervisor 会被 worker 告知。registry 知道某个进程活着;daemon 知道某个会话存在。两者都无法回答「它是不是卡住在等我」—— 而这正是一个后台 agent 界面存在的唯一理由。文档还记录了一个决定「Web Shell 不该建什么」的结论:
--bgsession 是以完整交互式 session 启动的(supervisor-dispatch.ts:196),因此它会注册进 live-process registry,并在跨 session 通信打开时绑定 peer inbox。它已经可以被另一个 session 用send_message寻址,无需任何专门代码。面板需要的是把后台 agent 显示出来,而不是再发明第二种与之对话的方式。文档刻意写得短。这个方向上此前的两份设计(#8719、#9399)都被关闭且未合并,而它们都不是败在论证上;缺的不是第三份宏大计划。这一份只记录一个决定,并点名下一块具体的代码。
评审者测试计划
如何验证
纯文档。它依据的三处测量各是一条命令:
rg 'listLiveSessions|session-registry' packages/cli/src/serve→ 无匹配。startInteractiveUI.tsx:421——registerSession是无条件调用,因此每个交互式 session(包括后台 worker)都会注册。supervisor-dispatch.ts:196—— worker 的 argv 是--session-id <id> --prompt-interactive=<prompt>。该文件的
prettier --check干净。证据(前后对比)
N/A —— 纯文档。
测试环境
运行环境(可选)
N/A。
风险与范围
关联 Issue
记录 #10942、#10943、#10949 背后的决定。不取代任何文档;#8719 与 #9399 保持关闭。