Skip to content

feat(cli): Add agent view PTY workers - #7800

Merged
yiliang114 merged 63 commits into
mainfrom
agent/agent-view-pty-workers
Aug 20, 2026
Merged

feat(cli): Add agent view PTY workers#7800
yiliang114 merged 63 commits into
mainfrom
agent/agent-view-pty-workers

Conversation

@ZijianZhang989

@ZijianZhang989 ZijianZhang989 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Stack position: 2/5. Parent: #7799. Next: #7801.

This stacked PR adds the PTY worker host layer used by managed Agent View sessions. It launches local terminal hosts for session workers, exposes authenticated host control, forwards attach streams, retains bounded recent output for logs, and preserves UTF-8 boundaries while trimming output.

Why it's needed

The supervisor needs a concrete worker runtime before it can manage lifecycle state. This layer provides the process and terminal bridge that later lifecycle code can start, reconnect, stop, hibernate, and attach without coupling the roster UI directly to worker process details.

Reviewer Test Plan

How to verify

  • Run npm run build; the repository should build successfully.
  • Run cd packages/cli && npx vitest run src/agent-view --coverage.enabled=false; all Agent View unit tests should pass.
  • Confirm PTY host sockets require the per-host auth token, enforce bounded request lines, and restrict Unix socket permissions where supported.
  • Confirm attach stream input and output bridge correctly, duplicate attach streams are rejected, logs are bounded, and unsupported kill signals are rejected.

Evidence (Before & After)

N/A — this is a non-UI worker runtime layer.

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

Environment (optional)

macOS, Node.js v26.2.0. Local verification required reinstalling current workspace dependencies and applying the existing Ink patch to local node_modules.

Risk & Scope

  • Main risk or tradeoff: This layer owns local PTY process control, so failures can affect attach, logs, and cleanup for managed background sessions.
  • Not validated / out of scope: Supervisor lifecycle policy and UI flows are in later PRs; fresh cross-platform manual validation was not run in this pass.
  • Breaking changes / migration notes: No existing CLI behavior changes; this adds private Agent View worker host plumbing.

Linked Issues

Refs #6383

中文说明

此 PR 的内容

堆栈位置:2/5。父 PR:#7799。下一个 PR:#7801

这个 stacked PR 增加托管 Agent View session 使用的 PTY worker host 层。它为 session worker 启动本地终端 host,暴露带认证的 host 控制,转发 attach stream,保留有界 recent output 供 logs 使用,并在裁剪输出时保留 UTF-8 边界。

为什么需要

supervisor 需要一个具体的 worker runtime,之后才能管理生命周期状态。这一层提供后续 lifecycle 代码可以启动、重连、停止、休眠和 attach 的进程与终端桥接能力,同时避免 roster UI 直接耦合 worker 进程细节。

评审者测试计划

如何验证

  • 运行 npm run build;仓库应成功构建。
  • 运行 cd packages/cli && npx vitest run src/agent-view --coverage.enabled=false;全部 Agent View 单元测试应通过。
  • 确认 PTY host socket 要求 per-host auth token,限制 request line 大小,并在支持的平台上限制 Unix socket 权限。
  • 确认 attach stream 输入输出桥接正确,重复 attach stream 会被拒绝,logs 有界,且不支持的 kill signal 会被拒绝。

证据(变更前后)

不适用——这是非 UI 的 worker runtime 层。

测试平台

操作系统 状态
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

环境(可选)

macOS,Node.js v26.2.0。本地验证前需要补齐当前 workspace 依赖,并把仓库已有 Ink patch 应用到本地 node_modules

风险与范围

  • 主要风险或权衡:这一层负责本地 PTY 进程控制,因此失败会影响托管后台 session 的 attach、logs 和 cleanup。
  • 未验证或范围外:supervisor 生命周期策略和 UI 流程位于后续 PR;本轮没有做新的跨平台手动验证。
  • 破坏性变更或迁移说明:没有现有 CLI 行为变化;这里只新增私有 Agent View worker host plumbing。

关联 Issue

关联 #6383

@ZijianZhang989
ZijianZhang989 force-pushed the agent/agent-view-supervisor-runtime branch from 05467fb to 44036f4 Compare July 27, 2026 05:32
@ZijianZhang989
ZijianZhang989 force-pushed the agent/agent-view-pty-workers branch from 2f54001 to 1b994c1 Compare July 27, 2026 05:32
@github-actions

Copy link
Copy Markdown
Contributor

Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration.

中文

请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration.

中文

请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。

@ZijianZhang989
ZijianZhang989 marked this pull request as ready for review July 28, 2026 02:30
@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: this is a feature addition (stacked PR 2/5 for Agent View, refs #6383), not a bug fix — no reproduction needed. The need for a PTY worker runtime layer is clear from the stack design: the supervisor (PR 1/5) needs a concrete process and terminal bridge before lifecycle code can manage sessions.

Direction: aligned. Background session management and agent view are active areas — Claude Code's CHANGELOG has extensive work on background sessions, worker heartbeats, agent view attach/detach, and managed session lifecycle. This layer provides the PTY process plumbing that later lifecycle PRs in the stack will build on.

Size: not core paths (all files in packages/cli/src/agent-view/). 1702 production lines + 1157 test lines across 10 files. Above the 1000-line advisory threshold, but this is a deliberately stacked PR (2/5) — the scope is bounded by design.

Approach: the five modules are cohesive — PTY host process server/client over Unix sockets with per-host auth tokens, attach lease management with TTL expiry, bounded output ring with UTF-8-safe trimming, worker sideband env communication, and managed detach for session adoption. Each module has a clear responsibility and the test coverage is thorough. The socket protocol is simple (newline-delimited JSON) and the security posture looks solid (timing-safe token comparison, 0o700/0o600 socket permissions, bounded request lines, allowlisted kill signals). No unrelated changes or scope creep — everything serves the stated goal.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

问题:这是功能新增(Agent View 堆栈 PR 2/5,关联 #6383),不是 bug 修复——无需复现。PTY worker runtime 层的需求来自堆栈设计:supervisor(PR 1/5)需要具体的进程和终端桥接,后续 lifecycle 代码才能管理 session。

方向:对齐。后台 session 管理和 agent view 是活跃方向——Claude Code 的 CHANGELOG 有大量后台 session、worker 心跳、agent view attach/detach 和托管 session 生命周期相关工作。这一层提供后续 lifecycle PR 将构建其上的 PTY 进程管道。

规模:非核心路径(全部文件在 packages/cli/src/agent-view/)。1702 行生产代码 + 1157 行测试代码,共 10 个文件。超过 1000 行建议阈值,但这是刻意拆分的堆栈 PR(2/5)——范围由设计决定。

方案:五个模块职责清晰——通过 Unix socket 的 PTY host 进程服务端/客户端(带 per-host auth token)、带 TTL 过期的 attach 租约管理、UTF-8 安全裁剪的有界输出环、worker sideband 环境通信、以及 session 接管的 managed detach。测试覆盖充分。Socket 协议简洁(换行分隔 JSON),安全姿态扎实(timing-safe token 比较、0o700/0o600 socket 权限、有界请求行、白名单 kill 信号)。无无关改动或范围蔓延。

进入代码审查 🔍

Qwen Code · qwen3.8-max-preview

Reviewed at 1b994c18cdf23982a1e76384b34c00ffb7b2a979 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

Independent proposal: given "add a PTY worker host layer for managed Agent View sessions", I would have built: (1) a PTY host module wrapping node-pty with bounded output capture, (2) a Unix socket server exposing host control (status, logs, resize, kill, shutdown, attach) with per-host auth, (3) an attach lease mechanism to prevent duplicate attaches, (4) a worker sideband for env-based worker ↔ supervisor communication, and (5) a managed detach entry point for session adoption. The PR's five modules map almost exactly to this decomposition.

Comparison: the PR matches the independent proposal. The implementation is well-structured — each module has a single responsibility, the socket protocol is minimal (newline-delimited JSON, one request per connection for control ops, persistent connection for attach streams), and the test suite covers the important paths: auth enforcement, duplicate attach rejection, bounded output with UTF-8 safety, lease expiry, signal allowlisting, and socket permission restrictions.

No critical blockers found. A few observations, none blocking:

  • The BoundedOutputRing UTF-8 trimming is correctly implemented — trimUtf8Start skips continuation bytes (0x80–0xBF) after truncation, and the tests verify no replacement characters appear. The ring retains the newest bytes, which is the right policy for log tailing.
  • Auth token validation uses timingSafeEqual with a length pre-check, consistent with existing patterns in packages/cli/src/serve/auth.ts and elsewhere.
  • The createRemoteExitTracker polls the host socket every 5 seconds to detect remote host death — a pragmatic approach for the connect (non-spawn) path. The interval is unref'd so it won't keep the process alive.
  • The lastStateReportKey module-level mutable in worker-sideband.ts is a minor code smell, but it's test-resettable and the deduplication logic is sound for the heartbeat use case.
  • All imports from sibling modules (protocol.js, supervisor-runner.js, supervisor-client.js, supervisor-store.js, terminal-bridge.js, current-cli-argv.js) are expected dependencies from the parent PR (feat(cli): Add agent view supervisor runtime #7799) in the stack.

No AGENTS.md violations: ESM throughout, no any types, kebab-case file names, tests collocated with source, no relative cross-package imports.

Testing

This is an unattended CI run. No CI workflow runs exist for this commit — the PR targets the feature branch agent/agent-view-supervisor-runtime, not main, so the standard CI suite does not trigger.

Check Conclusion
(no PR CI runs — feature branch target)

The PR author reports macOS verification with npm run build and npx vitest run src/agent-view (author's claim, not independently verified here). Windows and Linux were not tested by the author.

Real-scenario testing: N/A — non-UI worker runtime layer, and this is an unattended CI run. A maintainer can trigger the isolated @qwen-code /tmux job if behavioral verification is needed, though the TUI surface is not touched by this PR.

Not verified: build and unit test execution (no CI ran on this feature branch PR; PR code is never executed during triage).

中文说明

代码审查

独立方案: 给定"为托管 Agent View session 添加 PTY worker host 层",我会构建:(1) 包装 node-pty 的 PTY host 模块(带有界输出捕获),(2) 通过 Unix socket 暴露 host 控制的服务器(status、logs、resize、kill、shutdown、attach,带 per-host auth),(3) 防止重复 attach 的租约机制,(4) 基于环境变量的 worker ↔ supervisor 通信 sideband,(5) session 接管的 managed detach 入口。PR 的五个模块几乎完全对应这一分解。

对比: PR 与独立方案一致。实现结构良好——每个模块职责单一,socket 协议精简(换行分隔 JSON,控制操作每连接一请求,attach 流使用持久连接),测试覆盖重要路径:auth 强制、重复 attach 拒绝、UTF-8 安全的有界输出、租约过期、信号白名单、socket 权限限制。

未发现关键阻塞问题。几个观察,均非阻塞:

  • BoundedOutputRing 的 UTF-8 裁剪实现正确——trimUtf8Start 在截断后跳过延续字节(0x80–0xBF),测试验证无替换字符出现。
  • Auth token 验证使用 timingSafeEqual 加长度预检,与 packages/cli/src/serve/auth.ts 等现有模式一致。
  • createRemoteExitTracker 每 5 秒轮询 host socket 检测远程 host 死亡——对 connect(非 spawn)路径是务实方案。
  • worker-sideband.ts 中的 lastStateReportKey 模块级可变状态是小瑕疵,但可测试重置,去重逻辑对心跳场景合理。
  • 所有兄弟模块导入(protocol.jssupervisor-runner.js 等)是堆栈中父 PR(feat(cli): Add agent view supervisor runtime #7799)的预期依赖。

无 AGENTS.md 违规。

测试

这是无人值守 CI 运行。此提交无 CI 工作流运行——PR 目标是功能分支 agent/agent-view-supervisor-runtime,非 main,标准 CI 套件不触发。

PR 作者报告 macOS 验证(作者声明,非独立验证)。Windows 和 Linux 未经作者测试。

真实场景测试:不适用——非 UI worker runtime 层,且为无人值守 CI 运行。

未验证:构建和单元测试执行(功能分支 PR 无 CI 运行;triage 期间不执行 PR 代码)。

Qwen Code · qwen3.8-max-preview

Reviewed at 1b994c18cdf23982a1e76384b34c00ffb7b2a979 · re-run with @qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean, well-structured infrastructure PR; the only gap is the structural absence of CI on this feature branch target.

This is solid plumbing work. The five-module decomposition maps cleanly to the problem: PTY host lifecycle, socket-based control with auth, attach leasing, worker sideband communication, and managed detach. The code reads well — the socket protocol is minimal, the BoundedOutputRing handles the UTF-8 edge cases correctly, and the security posture (timing-safe tokens, restricted socket permissions, signal allowlisting, bounded request lines) is thoughtful without being over-engineered.

The test suite is thorough for a runtime layer: 1157 lines covering auth enforcement, duplicate attach rejection, lease expiry with corrupted timestamps, UTF-8 trimming with multi-byte characters, oversized request handling, and socket permission verification. The tests use real Unix sockets where it matters (the pty-host-process tests) and clean fakes where it doesn't (the pty-host tests with injected PTY).

My independent proposal for this problem was essentially the same decomposition — I didn't find a simpler path the PR missed. The 821-line pty-host-process.ts is the heaviest module, but it earns its size: socket server, client, request/response protocol, attach stream bridging, process spawning, and exit tracking are all tightly coupled concerns that would be harder to review split across files.

The one reservation is structural: no CI ran because the PR targets the feature branch agent/agent-view-supervisor-runtime. The code will get its full CI pass when the stack merges toward main, but right now the build and test claims rest on the author's local verification alone. That's a gap in evidence, not a concern about the code.

中文说明

置信度:4/5 ——干净、结构良好的基础设施 PR;唯一缺口是功能分支目标导致 CI 结构性缺失。

这是扎实的管道工作。五模块分解清晰对应问题:PTY host 生命周期、基于 socket 的带 auth 控制、attach 租约、worker sideband 通信、managed detach。代码可读性好——socket 协议精简,BoundedOutputRing 正确处理 UTF-8 边界,安全姿态(timing-safe token、受限 socket 权限、信号白名单、有界请求行)考虑周到且不过度工程化。

测试套件对 runtime 层来说很充分:1157 行覆盖 auth 强制、重复 attach 拒绝、带损坏时间戳的租约过期、多字节字符 UTF-8 裁剪、超大请求处理、socket 权限验证。测试在关键处使用真实 Unix socket(pty-host-process 测试),在非关键处使用干净的 fake(注入 PTY 的 pty-host 测试)。

我的独立方案基本是相同的分解——没有找到 PR 遗漏的更简路径。821 行的 pty-host-process.ts 是最重的模块,但其大小合理:socket 服务器、客户端、请求/响应协议、attach 流桥接、进程 spawn、退出跟踪都是紧耦合关注点,拆分反而增加审查难度。

唯一保留是结构性的:因 PR 目标是功能分支 agent/agent-view-supervisor-runtime,无 CI 运行。代码在堆栈向 main 合并时会获得完整 CI 通过,但目前构建和测试声明仅基于作者本地验证。这是证据缺口,非代码质量问题。

Qwen Code · qwen3.8-max-preview

Reviewed at 1b994c18cdf23982a1e76384b34c00ffb7b2a979 · re-run with @qwen-code /triage

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/worker-sideband.ts
Comment thread packages/cli/src/agent-view/worker-sideband.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host-process.ts Outdated
Comment thread packages/cli/src/agent-view/pty-host.ts
@qwen-code-dev-bot qwen-code-dev-bot added the autofix/needs-human The autofix loop stopped on this PR — a human must re-arm, split, merge, or close it label Aug 15, 2026
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔓 Takeover auto-released: the autofix loop paused on this PR 7 day(s) ago (🤖 AutoFix stopped: this counting window now contains 3 time-budget exhaustions (pushed rounds in between included; this ) and no re-arm followed, so the autofix/takeover label is removed to keep the managed pool honest. autofix/needs-human stays as the reminder that this PR needs a human decision: merge it, close it, or split/reduce it and comment @qwen-code /takeover to re-engage with a fresh round window.

中文说明

🔓 已自动释放接管:autofix 循环在 7 天前暂停于此 PR(🤖 AutoFix stopped: this counting window now contains 3 time-budget exhaustions (pushed rounds in between included; this ),此后无人重新武装,现移除 autofix/takeover 标签以保持托管池真实可用。保留 autofix/needs-human 作为待办提醒 —— 本 PR 需要人工决策:合并、关闭,或拆分/缩小后评论 @qwen-code /takeover 以全新轮次窗口重新接管。

@qwen-code-dev-bot qwen-code-dev-bot removed the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Aug 15, 2026

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally — win32 branches (pipe paths, skipIf guards, signal-less kill) verified by reading only.

Not reviewed: build-and-test — Test (macos-latest, Node 22.x) was skipped in CI and its suite did not run locally.

Not explored to full depth (tool budget reached): "agent reverse-audit (round 1)": isolate which ingredient of the real bridgeAgentViewTerminal path suppresses the connection idle timer under Node v22.23.0 (bisected receive/pause/resume, wri….

Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

Deferred under the convergence posture (round 18, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/agent-view/attach-lease.test.ts:142 (+1 locations) — [probe] negative ttlMs never rejected in tests
  • packages/cli/src/agent-view/attach-lease.test.ts:149 (+1 locations) — [probe] 'exactly MAX accepted' TTL boundary unpinned
  • packages/cli/src/agent-view/attach-lease.test.ts:189 (+1 locations) — [probe] expire() full-sweep contract unpinned
  • packages/cli/src/agent-view/attach-lease.test.ts:232 (+1 locations) — [probe] heartbeat() !lease guard unpinned
  • packages/cli/src/agent-view/attach-lease.ts:58 (+3 locations) — [probe] Pattern: production default constants unverified (3…
  • packages/cli/src/agent-view/attach-lease.ts:68 (+1 locations) — [probe] Lazy expire() in acquire() untested
  • packages/cli/src/agent-view/managed-detach.test.ts:20 (+1 locations) — [probe] path.resolve() contract unpinned by absolute-only fixtures
  • packages/cli/src/agent-view/managed-detach.ts:39 (+1 locations) — [probe] globalDir forwarding via storeOptions unpinned
  • packages/cli/src/agent-view/managed-detach.ts:50 (+1 locations) — [probe] stdout fallback terminal geometry never asserted
  • packages/cli/src/agent-view/pty-host-process.test.ts:48 (+1 locations) — [probe] detach→re-attach cycle has zero coverage; resetInput never…
  • packages/cli/src/agent-view/pty-host-process.test.ts:97 (+1 locations) — [probe] second-attach rejection test doesn't pin active stream…
  • packages/cli/src/agent-view/pty-host-process.test.ts:734 (+1 locations) — [probe] exit-poller two-strike rule unpinned
  • packages/cli/src/agent-view/pty-host-process.test.ts:805 (+1 locations) — [probe] coalesced leftover delivery after attach ack untested
  • packages/cli/src/agent-view/pty-host-process.test.ts:1299 (+1 locations) — [probe] launch-path auth-token presentation unpinned
  • packages/cli/src/agent-view/pty-host-process.test.ts:1305 (+1 locations) — [probe] RPC-failure fallback child kills never exercised
  • packages/cli/src/agent-view/pty-host-process.ts:265 (+1 locations) — [probe] Attach-handshake failures swallowed by no-op error listener
  • packages/cli/src/agent-view/pty-host-process.ts:316 (+1 locations) — [probe] remote dispose() settles exited early; lost RPC leaves…
  • packages/cli/src/agent-view/pty-host-process.ts:400 (+1 locations) — [probe] listen-failure dispose branch untested; orphaned worker…
  • packages/cli/src/agent-view/pty-host-process.ts:428 (+1 locations) — [review] Predictable fallback socket dir enables permanent DoS squat
  • packages/cli/src/agent-view/pty-host-process.ts:730 (+1 locations) — [probe] socket.setTimeout(0) attach exemption untested
  • …and 11 more (see the run report)
中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally — win32 branches (pipe paths, skipIf guards, signal-less kill) verified by reading only。

未审查:build-and-test — Test (macos-latest, Node 22.x) was skipped in CI and its suite did not run locally。

未探索到全部深度(达到工具调用预算):"agent reverse-audit (round 1)"isolate which ingredient of the real bridgeAgentViewTerminal path suppresses the connection idle timer under Node v22.23.0 (bisected receive/pause/resume, wri…

未审查:反向审计——在 5 轮的反审轮数上限内未收敛。

收敛姿态下延后(第 18 轮,非阻断)——已记录,本轮不要求修改:共 31 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.13)

@ZijianZhang989

Copy link
Copy Markdown
Collaborator Author

@qwen-code /verify

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 493 passed · 0 failed · 493 total

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:493 通过 · 0 失败 · 493 总计

Verification report

PR 7800 Deep Verification — PTY worker host layer (Agent View stack 2/5)

Verdict: merge-ready — 493 scripted assertions executed, 493 passed, 0 unexpected failures.
Verified head: 8572f3681832c44e4e49c8ead75c629ff96576e9 (git rev-parse HEAD^2, matches metadata headRefOid); base tip f16975ee561fb99351983ecab401944d75a7d614.
Artifact dir: tmp/pr7800-verify-20260818-035246/.

中文摘要
  • 结论merge-ready。493 条脚本化断言全部通过,0 条非预期失败。
  • A/B 结论:核心主张(PTY host 提供「带 per-host token 认证的 Unix socket 控制面 + 字节透明 attach 流」)经真实进程/真实 PTY/真实 socket 的端到端 harness 验证,head 构建 27/27 通过;分别删除认证守卫、重复 attach 守卫、UTF-8 边界修复三个关键 hunk 后,对应行为全部翻转(未认证请求被接受、第二个 attach 被接受、裁剪窗口出现 U+FFFD 损坏),其余单元格不变 —— 三个守卫均为 load-bearing(见 01/02/03/04 截图与下表)。
  • 测试有效性:4 个突变体全部被 PR 自己的具名测试杀死(4/82、1/50、3/32、1/12),无存活突变;未突变控制组 216/216 绿。
  • Findings:无阻塞项。两条信息性观察(内部 host 参数尚未被 CLI 入口消费——stack 后续 PR 接线;attach 快速重连存在理论竞态窗口但本机 0/10 复现)。
  • 未覆盖:Windows 路径、supervisor 生命周期、per-commit 归因(shallow 仅 3 个提交可达)等,详见 Not covered

Scope selection

PR diff is purely additive: 11 new files under packages/cli/src/agent-view/ (5,284 lines; no existing file modified, package.json/lockfile untouched).

  • Central claim: runAgentViewPtyHostProcess + createAgentViewPtyHostServer provide an auth-gated Unix-socket control plane (status/logs/resize/kill/shutdown) and a byte-transparent attach stream over a real PTY, with socket-path locking and permission hardening.
  • Secondary claim 1: BoundedOutputRing bounds retained output at the configured cap while keeping the retained window valid UTF-8 at every trim boundary.
  • Secondary claim 2: exclusivity and allowlist guards — duplicate attach streams rejected, kill signals restricted to SIGINT/SIGTERM/SIGKILL, request lines bounded at 1 MiB, attach-lease TTL capped at 1 h.

A/B load-bearing proof

Environment per cell: real node subprocess running the PR's runAgentViewPtyHostProcess (compiled dist/ for head; tsx on scratch-mutated src/ for controls), real @lydell/node-pty PTY running a bash worker, real Unix-domain socket, raw line-protocol client written from the wire format. The three controls each revert exactly one hunk (marker VERIFY-MUTATION-Mx), restored afterwards (git status clean at exit).

# cell head control (hunk reverted) oracle
A1/A2 no-token / wrong-token status unauthorized error, 2/2 rejected M1: both accepted, return {pid, workerPid} JSON error code on the wire
A9 second concurrent attach already_attached error M2: second attach accepted JSON error code on the wire
A7 attach request + keystroke coalesced in one packet keystroke reaches worker verbatim (hello echoed) — (head only) PTY echo round-trip
A8a/A8b UTF-8 out; multi-byte input split across writes intact 中文→𝄞; split reassembled exact strings
A12 3 MiB worker output, then logs op retained = 1,048,576 B (exactly cap) byte count of logs result
A13 kill with SIGSTOP rejected: "signal is not allowed" error message
A14 1 MiB+1 request line, no newline connection destroyed, no response socket close with zero bytes
A15 TERM-resistant worker (trap '' TERM) + shutdown host exits code 0 after 2012–2026 ms (2 s grace → SIGKILL); worker pid gone exit code + kill(pid,0)
A16 socket + lock files after exit both removed existsSync
A17 second host launch on live socket exits 1, EADDRINUSE + "already in use" exit code + stderr
A4/A5 socket file / dir modes 0600 / 0700 stat
B3–B6 ring trim across 2/3/4-byte chars + oversize chunk retained ≤ cap, zero U+FFFD, window starts on a full char M3 (trimUtf8Start→identity): U+FFFD appears in B3/B4/B6 and in the per-append fuzz decoded window content

Head: 27/27 (Harness A) + 9/9 (Harness B). Controls flip exactly the probed behavior and nothing else (25/27 and 26/27 sibling cells unchanged in the respective mutants). Witnesses: 01-harness-a-head-all-green.png, 02-harness-a-control-auth-guard-removed.png, 03-ring-control-utf8-corruption.png, 04-ring-head-utf8-clean.png.

One probe nuance: in the M3 control, the 4-byte-astral cell (B5) stayed clean by coincidental width alignment (cap 1000 is a multiple of 4), while 2-byte (odd cap) and 3-byte cells corrupted — the width matrix, not any single case, is what pins the repair.

Mutation matrix (vacuity check on the PR's own tests)

Unmutated control green: 216/216 (cd packages/cli && npx vitest run src/agent-view --coverage.enabled=false, exactly the PR's Reviewer Test Plan command). Positive control: M1 red proves the harness can fail this suite.

mutant change PR tests going red harness A/B flip verdict
M1 auth guard removed 4/82: "requires auth when the host server has a token", "wires the env host token into the entrypoint server", "requires auth for attach streams", "fails fast when connecting with the wrong host token" A1/A2 → accepted killed
M2 duplicate-attach guard removed 1/50: "rejects a second attach stream while one is active" A9 → accepted killed
M3 trimUtf8Start disabled 3/32: "does not retain partial UTF-8 characters from oversized chunks / across chunks / when sub-capacity chunks overflow" B3/B4/B6/B8 → U+FFFD killed
M4 attach-lease max-TTL enforcement removed 1/12: "rejects non-positive, oversized, and non-finite ttls" n/a (pure logic) killed

No survivors → no coverage-gap or dead-code classification needed. Witness: 05-mutation-matrix-summary.png. Raw per-test JSON runs in logs/.

Findings

None blocking. All executed assertions passed; no regression reproduced.

Observations (non-blocking, informational):

  1. The internal host entry is not wired to the CLI yet (stack context, not a defect of this PR). INTERNAL_AGENT_VIEW_PTY_HOST_ARG has zero consumers outside the new files (grep over packages/), so defaultSpawnPtyHostbuildCurrentQwenCliArgv cannot produce a working host until a later stack PR (3/5+) wires the arg. This matches the PR's stated scope ("adds private Agent View worker host plumbing", stack 2/5). The verification therefore drove runAgentViewPtyHostProcess directly — the same function the wired entry will call.
  2. Attach handover race is structural but did not materialize. Client-side onData destroys the previous attach socket before opening the new one; the server rejects while the old socket is not yet observed closed. Measured: 10/10 zero-delay destroy→re-attach cycles accepted on a local Unix socket (race-reattach.mjs), 0 rejects. The window exists in principle (would matter on slow transports); current local behavior is clean.
  3. Auth is fail-open when a host is configured with no token (if (authToken && …)). The only production launcher (launchAgentViewPtyHostProcess) always generates a randomUUID token and the socket is 0600, so no path serves unauthenticated today; a future direct caller of runAgentViewPtyHostProcess omitting the token would.

Not covered

  • Windows paths (\\.\pipe\…, windowsHide, argument-less kill): this container is Linux; the PR marks Windows ⚠️ unvalidated too.
  • Per-commit attribution: shallow (depth 2, grafted) checkout — git rev-list HEAD^1..HEAD^2 sees 1 of the 62 metadata commits. Verified the aggregate HEAD^1..HEAD diff only.
  • Supervisor lifecycle / roster integration: explicitly deferred to later stack PRs; worker-sideband verified only via the suite (22 tests) and code read, no live supervisor peer exercised.
  • launchAgentViewPtyHostProcess spawner path end-to-end: unreachable until the CLI entry consumes the internal arg (observation 1); its error path (host stderr tail surfacing) is covered by PR tests, not re-driven here.
  • Repo-wide gates: only the affected workspace suite + the CI-prebuilt npm run build (compile+typecheck) at HEAD; no repo-wide lint/typecheck re-run.
  • First Harness-A and first ring-control runs were superseded by corrected harness expectations (attach stream intentionally carries only post-attach output; fuzz invariant must be checked after every append). Their logs remain in logs/ (head-run-1.log, ring-control.log); canonical counts use the final runs only.

Methodology

Ran in the CI verify container (node v22.23.2, Linux), tree at merge commit 7479213258, npm ci + npm run build pre-done. Harness A spawns the PR code as a real subprocess (host-entry.mjs importing compiled dist/src/agent-view/pty-host-process.js for the head arm; tsx over scratch-mutated src/ for control arms), launches a real PTY via @lydell/node-pty (bash workers, incl. a trap '' TERM variant for SIGKILL-escalation), and speaks the newline-delimited JSON protocol over the real Unix socket with a hand-written client. Harness B imports the compiled BoundedOutputRing and probes trim boundaries with 2/3/4-byte char streams, the oversize-chunk path, and a 500-iteration seeded fuzz checking the bound and UTF-8 validity after every append. Mutations were applied in place (single-hunk edits), exercised, and restored (git status verified clean after each). Raw per-cell logs in logs/; harness scripts in this directory are rerunnable (node harness-a.mjs --mode head --host-base packages/cli/dist/src/agent-view, etc.). Assertion accounting: 27 (A head) + 9 (B head) + 216 (gate) + 82+50+32+12 (mutant vitest runs, intended reds encoded as expected) + 27+27 (control harnesses, flipped expectations) + 9 (ring control, 3 expected reds) + 2 (race probe) = 493.

Evidence images

01-harness-a-head-all-green

02-harness-a-control-auth-guard-removed

03-ring-control-utf8-corruption

04-ring-head-utf8-clean

05-mutation-matrix-summary

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

yiliang114 pushed a commit that referenced this pull request Aug 18, 2026
packages/cli/src/agent-view/ has no references elsewhere in main, and the
first revision concluded from that it was abandoned and should be deleted.
It is the base of #7799, whose remaining four PRs (#7800-#7803) are open,
non-draft, and touch the directory directly. Static reachability in main
cannot see consumers that live in pending PRs.

This surfaces a real conflict the document was papering over: that series
builds natively the terminal and supervisor layer section 4 argues to leave
to herdr. Recorded as open question 7.6 rather than resolved, because it is
a product decision.
yiliang114 pushed a commit that referenced this pull request Aug 18, 2026
The row read as settled fact by citing herdr alone. #7800 is building PTY
workers natively, so §4 states one side of an open disagreement rather than
a decision. Label it as a position and point at §7.6, which owns it.
yiliang114 pushed a commit that referenced this pull request Aug 18, 2026
There is no conflict. #7800, #7801 and #7803 touch no file under
packages/core; #7802 touches three unrelated utilities; none of the four
touches agents/team/, send-message.ts, tasks.ts or mailbox.ts — the entire
surface this design changes.

The conflict was an artifact of how 4 was written. Phrased as "not
building X" it read as a project-wide ruling rather than this design's
scope, so a PR building X looked like a contradiction. It is not one:
whether Qwen hosts terminals natively is orthogonal to whether two sessions
can ask each other a question.

Removes open question 6, restores the two non-goal rows, and scopes 4
explicitly to this design.
yiliang114
yiliang114 previously approved these changes Aug 19, 2026

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed — 0 unresolved threads. Note: a number of resolved Criticals were silently resolved; the bot's re-scan did not re-flag, so treat as addressed. Approve.

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with @qwen-code /review. See workflow logs.

@yiliang114
yiliang114 dismissed qwen-code-ci-bot’s stale review August 19, 2026 17:06

Superseded by 3c63475: all review threads are resolved and the current head passed the targeted local verification.

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Partially reviewed — gaps disclosed.

9 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:

  • X19-1 attach-handshake failures swallowed by no-op error listener — already reported (comment 3735552361)
  • X19-2 predictable fallback socket dir enables permanent DoS squat — already reported (comments 3750798749, 3744227498)
  • X19-3 RPC-failure child-kill fallbacks untested — already reported (round-18 deferred list)
  • X19-4 listen-failure dispose branch untested — already reported (round-18 deferred list)
  • X19-5 server malformed-request path untested — already reported (comment 3735552377)
  • X19-6 managed-detach terminal fallback / globalDir forwarding unasserted — already reported (round-18 deferred list)
  • X19-7 stateReportChains.delete mutant survived — already reported (comments 3750798471, 3748472882)
  • X19-8 stateReportChains.clear mutant survived — already reported (comment 3750798481)
  • X19-9 defaultSpawnPtyHost/withHostStderrTail untested — already reported (comment 3735552443)

Not reviewed: reverse audit — reached the 5-round cap without two consecutive dry rounds; rounds 3, 4, and 5 each surfaced new verified findings.

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) failed in CI at the reviewed commit; attribution could not be measured from this Linux review (win32 branches verified by reading only).

Not reviewed: build-and-test — Test (macos-latest, Node 22.x) failed in CI at the reviewed commit; attribution could not be measured from this Linux review.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) failed in CI at the reviewed commit; attribution could not be measured from this Linux review.

Deferred under the convergence posture (round 19, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/agent-view/pty-host-process.ts:719 — [probe] shape rejections misreported as invalid_json
  • packages/cli/src/agent-view/pty-host.ts:209 — [probe] appendChunk retains caller Buffers by reference
  • packages/cli/src/agent-view/pty-host.ts:276 — [probe] schemaVersion rejection branch untested
  • packages/cli/src/agent-view/pty-host-process.test.ts:1360 — [probe] readLine/readChunk never settle on close without newline
  • packages/cli/src/agent-view/pty-host.test.ts:23 — [probe] BoundedOutputRing constructor guard untested
  • packages/cli/src/agent-view/worker-sideband.test.ts:232 — [probe] control-event validator rejection branches ungated
  • packages/cli/src/agent-view/pty-host-process.ts:664 (+3 locations) — [probe] Pattern: lock-contention guards mutation-ungated
  • packages/cli/src/agent-view/worker-sideband.test.ts:233 — [probe] control-read transport-error contract unpinned
  • packages/cli/src/agent-view/worker-sideband.test.ts:170 — [probe] partial-answer acceptance ungated
  • packages/cli/src/agent-view/worker-sideband.test.ts:429 — [probe] process.env default parameter never exercised
  • packages/cli/src/agent-view/pty-host-process.test.ts:517 — [probe] socket-dir hardening chmod ungated
  • packages/cli/src/agent-view/pty-host.ts:390 — [review] signal-less kill SIGHUP divergence between handles
中文说明

仅完成部分审查,审查缺口已披露。

本轮确认的 9 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。

未审查:reverse audit — reached the 5-round cap without two consecutive dry rounds; rounds 3, 4, and 5 each surfaced new verified findings。

未审查:build-and-test — Test (windows-latest, Node 22.x) failed in CI at the reviewed commit; attribution could not be measured from this Linux review (win32 branches verified by reading only)。

未审查:build-and-test — Test (macos-latest, Node 22.x) failed in CI at the reviewed commit; attribution could not be measured from this Linux review。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) failed in CI at the reviewed commit; attribution could not be measured from this Linux review。

收敛姿态下延后(第 19 轮,非阻断)——已记录,本轮不要求修改:共 12 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.14)

@yiliang114

Copy link
Copy Markdown
Collaborator

Cross-platform verification conclusion for the current head (3c63475d): I did not find a blocking platform defect, but native Windows runtime behavior has not been verified yet.

Evidence:

  • On macOS with Node 22.22.0, the five PR-scoped suites passed: 5 files / 121 tests.
  • A real @lydell/node-pty smoke passed end to end: spawn → output ready → write input → echo output → exit 0.
  • The Windows-specific unit contracts pass for the \\.\pipe\... endpoint shape and signal-less ConPTY kill/shutdown behavior.
  • The PR page's macOS, Windows, and CLI Integration checks are intentionally skipped: those jobs are configured for merge_group only. The earlier duplicate workflow was cancelled at startup, not a test failure.

The remaining evidence gap is a native Windows run covering named-pipe bind/connect/close, real ConPTY spawn/process-tree cleanup, and detached PTY-host shutdown. I would not block #7800 on that gap because this PR adds dormant infrastructure and no public activation path. Before #7802 exposes Agent View, though, we should require one current-stack native Windows run (at minimum these five suites, ideally with a small real ConPTY smoke). If #7800 goes through the merge queue, the platform jobs will run there; a direct squash merge is not guaranteed to run them under the current branch rules.

@yiliang114
yiliang114 enabled auto-merge August 20, 2026 03:07

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM — the current head has no unresolved blocking findings, and the PR-scoped tests plus the native macOS PTY smoke pass. Native Windows verification remains a non-blocking follow-up before #7802 exposes the feature.

@yiliang114
yiliang114 added this pull request to the merge queue Aug 20, 2026
Merged via the queue into main with commit bba2e1a Aug 20, 2026
57 of 73 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.15.

yiliang114 added a commit that referenced this pull request Aug 22, 2026
* feat(cli): manage agent view session lifecycle

* fix(cli): preserve agent view lifecycle state

* fix(cli): harden agent view lifecycle persistence

* fix(cli): harden agent view lifecycle

* fix(cli): harden agent view lifecycle recovery

* fix(cli): close agent view lifecycle review gaps

* fix(cli): address lifecycle review suggestions

* fix(cli): Address round-4 agent-view lifecycle review feedback

- Respawn decisions now use refreshed state under the host-setup lock:
  refreshed updatedAt for stop observation (C1), re-read host after
  refresh, unconditional attach block reason, identity-checked registry
  deletion, stored worker pid kill when no in-memory host (C5/C6/C9/C12)
- Stored stop fallback captures pids at scheduling time and only marks
  stopped when the worker record still matches (C2)
- Failed re-adoption of a stale adopting record falls back to a terminal
  adoption_failed state (C3); auto-exit blocks while adopting (C4)
- Attach prep clears stale persisted attach flags without bumping
  updatedAt (C7); unplanned exits keep the queued prompts (C8)
- Repeated stops always rewrite state to stay observable (C11);
  hibernating transitions are guarded and re-validated (C10/S20)
- Suggestions: S1/S2/S5/S6/S8/S10/S11/S13/S14/S15/S16/S17/S18

* fix(cli): Address round-5 agent-view lifecycle review feedback

- Queued user input now survives worker replacement: unplanned exits,
  send-triggered revives, and the stored stop fallback keep pending
  prompt/answer controls and drop only stop/redraw (R5-1/R5-2/R5-11)
- The queue marker is persisted before the in-memory control so a
  failed write rejects cleanly (R5-4); orphaned markers left by dead
  daemons are cleared on send (R5-9); superseded-host exits, buffered
  worker events, and pre-queue events can no longer resurrect or clear
  a settled session (R5-3/R5-12/R5-13)
- Activity/state writes use field-level patches instead of whole-file
  read-modify-write off stale snapshots (R5-8); list() isolates
  per-session heal failures (R5-5); stale adopting records reconcile
  to a terminal state instead of blocking auto-exit (R5-7); dispatch's
  ready-wait catch honors deliberate stops (R5-10)
- Suggestions: shared inputKind/sessionState validators (R5-14/R5-15),
  AgentViewSessionStoppedError for stop classification (R5-18),
  shared worker-token digest (R5-20), roster self-heal on read
  (R5-22), truncated queued-prompt preview (R5-23), CI keys stripped
  from the worker pty env (R5-24), live-control-aware stale clear
  (R5-25), and test coverage for R5-16/R5-17/R5-19/R5-21/R5-26/R5-27

* fix(cli): address R6 review findings and slim test suite

R6 Critical fixes:
- Replace whole-snapshot writes with patchAgentViewSessionState
- Add bootGeneration guard for killStoredWorkerPids and ready-wait
- Add preserveQueuedInputControls to failure paths
- Add isStoppedError branch in adopt() catch
- Move hibernation mark transitions inside withHostSetupLock
- Add resolveSessionCwd for symlink-safe cwd comparison
- Stamp event.at at emit time for dequeue ordering guard
- Re-validate lastQueuedPromptAt in clearStalePendingPromptIfNeeded
- Absolutize getCurrentQwenCliEntrypoint via path.resolve
- Restore ensureSessionStillLaunchable transient read check
- Remove dead hibernation policy enabled field
- Use injectable now clock in snapshot cache

Test slimming:
- Remove 26 redundant/vacuous tests across supervisor-process,
  presentation, supervisor-store, and worker-sideband test files
- Simplify SessionSnapshotCache (remove dirty/version counters)

* Merge agent/agent-view-pty-workers into agent/agent-view-lifecycle

* fix(cli): address R7 review findings

Fix 14 issues from round-7 review:
- R6-1: patchAgentViewSessionState replaces writeAgentViewSessionState in respawn
- R6-10: adopt catch mirrors dispatch - rejectPendingWorkerReady + terminateSession moved into non-stopped branch
- R6-12: adopt() wrapped in withHostSetupLock for per-session serialization
- R7-2: hibernateIdleSessionsWithPolicy calls refreshMissingWorkerState in !host branch
- R7-5: scheduleStopFallback ordered before markStoppedSession in host branch
- R7-6: writeAttachState wrapped in try/catch in attach finally
- R7-14: markFailedSession preserves completed terminal verdict, uses patch
- R7-15: shortHash reverted to 12-hex for endpoint stability
- R7-24: updateExitedSession checks sessionState !== starting before completed
- R7-27: healing catch restores both state and activity on partial failure
- R7-28: in-lock re-validation excludes sessionState === working
- R7-29: applyWorkerEvent returns boolean, caller resolves only when applied
- R7-30: shutdownAll uses Promise.allSettled instead of Promise.all
- R7-34: patchAgentViewSessionState serialized via stateMutationQueues

Also fixes 3 pty-host.test.ts failures from merge with #7800:
- Add NO_COLOR/FORCE_COLOR/CI to INTERNAL_ONLY_WORKER_ENV_KEYS
- Add initialPrompt validation to validateAgentViewLaunchConfig
- Use launch.env TERM instead of hardcoded xterm-256color

* fix(cli): don't optimistically resolve exit tracker on SIGINT

* fix(cli): sync non-agent-view files to latest pty-workers base

* fix(cli): address R8 review findings

* fix(cli): address remaining R8 critical findings

- guard queued-prompt marker until the pending input control is consumed
- release host cleanup on the no-host killSession branch
- rotate the worker sideband token on respawn and persist its digest
- decide the stale-worker heal inside the queued mutation so concurrent
  terminal verdicts are preserved

* fix(cli): close agent-view respawn, worker-event and prompt-marker races

- respawn: persist the 'starting' state patch and rotated tokenDigest
  before launch so a fast replacement ready authenticates and passes
  the dead-worker guard
- applyWorkerEvent: decide the state patch inside the queued mutation
  so an exit verdict enqueued after the guard read is not clobbered
- store: route activity.json read-merge-writes through a per-session
  mutation queue and add patchAgentViewActivityIf
- clearPersistedPromptQueue: re-validate lastQueuedPromptAt inside the
  queued mutation before clearing
- clearStalePendingPromptIfNeeded: take the orphan branch only when no
  live host is registered, so a drained control is not mistaken for a
  lost one
- correct the queued-answer comment (answers are intentionally
  ephemeral)

* fix(cli): close agent-view stale-attach, stop-fallback and hibernate races

* fix(cli): close R11 stop-clobber, restart marker wedge and ready-waiter hang

- respawn pre-launch patch and updateExitedSession now re-validate inside
  the queued state mutation so a concurrent stop verdict is never clobbered
- pending-prompt markers queued before daemon start are orphaned, un-wedging
  restarted needs_input sessions
- dropped ready events reject the pending waiter instead of hanging 15s
- bootGeneration entries are released on session kill/terminate
- pre-bridge attach failures keep the socket open for the error envelope

* fix(cli): close R12 stop-launch orphan, marker clobber and pid-signaling races

- terminate orphan worker when dispatch/adopt stop errors bypass queueStop
- drain queued stop control before hibernate; re-validate pin under roster lock
- serialize worker file writes through the shared per-path mutation queue
- make dequeue/state heals marker-guarded and skip terminal sessions
- sanitize adopted session ids once; guard stale pid signaling

* fix(cli): close R13 verdict races, resume casing and stop/respawn lifecycle gaps

* fix(cli): close R14 respawn EADDRINUSE, dispatch pid timing and stale verdict races

* fix(cli): Harden Agent View lifecycle verdicts, ghost cleanup, and resume argv

* fix(cli): Confirm worker death before terminal verdicts and close roster fail-open paths

Round-16 review fixes for the Agent View lifecycle:

- Roster strict reader now rejects a declared-but-non-boolean pinned
  field; roster mutations read through the same fail-closed path so a
  corrupt-but-present roster.json can no longer be overwritten with an
  emptied roster (pins exist nowhere else).
- The dead-worker event guards also drop events against 'hibernating'
  records, so a straggler event after the sweep's point of no return
  cannot flip the record back to alive and fail the hibernated mark.
- respawn releases the predecessor's registry entry before launching,
  keeping the graceful-stop fallback timer from matching the retired
  host mid-launch.
- Worker events normalize waitingFor case at ingest so the queued-
  prompt dequeue gates and presentation agree.
- shouldAdvanceActivityTime stops advancing lastActivityAt while an
  input control suppresses the marker dequeue, keeping the stale-marker
  wall-clock evidence honest.
- Hibernation sweep, stop fallback, remove, and shutdownAll confirm the
  actual exit (shutdown RPC with SIGKILL escalation, then host.exited)
  before writing terminal verdicts: a still-draining worker must not
  keep the session socket with no signalling path able to reach it.

* fix(cli): harden agent view lifecycle races

* fix(cli): serialize agent view lifecycle transitions

* fix(cli): close agent view prompt recovery races

* fix(cli): close agent view lifecycle races

* fix(cli): make agent view lifecycle recoverable

* fix(cli): close agent view lifecycle races

* fix(cli): serialize stopped session healing

* fix(cli): harden agent view lifecycle recovery

---------

Co-authored-by: 俊良 <zzj542558@alibaba-inc.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix/needs-human The autofix loop stopped on this PR — a human must re-arm, split, merge, or close it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants