fix(integration): configure Docker sandbox networking for submitted-prompt provenance test (#7879) - #7881
Conversation
…rompt provenance test (#7879)
Release failure diagnosis (issue #7879)The nightly release failed in the Root cause
In Docker mode the CLI runs inside a container while the fake OpenAI server runs on the host. By default This is the same class of failure previously fixed for FixMirrored the existing Verification
中文说明发布失败诊断(issue #7879)夜间发布在 根因
在 Docker 模式下,CLI 运行在容器内,而 fake OpenAI 服务器运行在宿主机上。默认情况下 这与之前 修复在 验证
🧠 Handled by Qwen Code · model/模型 |
|
✅ Qwen Triage finished — CI landed green on ✅ Qwen Triage 已完成 —— |
|
Thanks for the PR! Template looks good ✓ Problem: observed CI failure — the nightly release ( Direction: test-infrastructure fix for Docker sandbox networking, squarely within scope. The submitted-prompt provenance test (#7762) was the only interactive test missing the container networking handling the suite already requires. Size: not applicable — single file in Approach: minimal and focused. Reuses the exact pattern already proven in Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ 问题:已观测到的 CI 故障——夜间发布在 方向:Docker 沙箱网络配置的测试基础设施修复,完全在范围内。submitted-prompt provenance 测试(#7762)是唯一缺少容器网络处理的 interactive 测试。 规模:不适用——仅改动 方案:最小且聚焦。复用了 进入代码审查 🔍 — Qwen Code · qwen3.8-max-preview Reviewed at |
Code ReviewIndependent proposal: given a fake server unreachable from inside a Docker container, I would detect the container sandbox via Findings: no critical blockers, no convention violations. The diff is the minimal change: one file, one established pattern reused faithfully from Nothing to flag. TestingThis is a test-infrastructure fix with no user-visible or TUI surface — real-scenario testing is N/A. CI evidence from the PR's own check runs on Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 The main unit test suite ( Not verified: the Docker-mode path cannot be confirmed until the next nightly run or a manual 中文说明代码审查独立方案: 面对容器内无法访问 fake 服务器的问题,我会通过 发现: 无关键阻塞项,无规范违反。改动是最小集:单文件,忠实复用 无需标记的问题。 测试这是测试基础设施修复,没有用户可见或 TUI 层面的变化——真实场景测试不适用。 CI 证据来自 PR 自身在 未验证:Docker 模式路径需等待下一次夜间运行或手动 — Qwen Code · qwen3.8-max-preview Reviewed at |
|
Confidence: 5/5 — textbook minimal fix: one file, one established pattern, zero production code touched. This is exactly the right change. The submitted-prompt provenance test was the last interactive test missing Docker sandbox networking — the nightly failure is direct evidence, and the fix reuses the same Approval deferred until CI lands green on 中文说明置信度:5/5 —— 教科书式的最小修复:单文件、单模式复用、零生产代码改动。 这正是正确的改动。submitted-prompt provenance 测试是最后一个缺少 Docker 沙箱网络处理的 interactive 测试——夜间发布失败是直接证据,修复复用了 审批推迟至 CI 在 — Qwen Code · qwen3.8-max-preview Reviewed at |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship — CI landed green after the review. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline.
中文说明
已审查——无阻断问题。 建议见行内评论。
— qwen3.7-max via Qwen Code /review
|
@qwen-code /verify |
|
Sandboxed verification: 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. 沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 Scripted assertions: 17 passed · 0 failed · 17 total Verification report (report.md)Harness scripts and raw logs are in the workflow run artifacts (7-day retention). — Qwen Code · sandboxed verification |
|
🤖 Addressed the latest review feedback (round 1/10). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/10 轮)。改动内容与我反驳保留之处如下: Review round summary — PR #7881 (issue #7879)Feedback point
Decision: ImplementedThis is an early-round suggestion that is valuable, codebase-consistent ( Changes
Net: 4 files changed, 93 insertions(+), 101 deletions(-). No production code touched; the change is behavior-preserving (identical constant values and restore semantics). Conflict notes
Verification
Note: the container-sandbox (Docker/Podman) path that #7879 originally fixed cannot run on this runner; the refactor is value-identical to the prior inline code, and the workflow's Docker/Podman CI remains the final gate for that path. 中文说明审查轮次总结 — PR #7881(issue #7879)反馈点
决定:已实现这是一条早期轮次的建议,有价值、与代码库风格一致( 变更内容
净变更:4 个文件改动,93 行新增,101 行删除。未触及任何生产代码;改动保持行为一致(常量取值与恢复语义完全相同)。 冲突说明
验证
说明:#7879 最初修复的容器沙箱(Docker/Podman)路径无法在本运行环境中执行;本次重构与原先的内联代码取值完全一致,该路径最终以工作流的 Docker/Podman CI 为门禁。 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 10 this bot stops and leaves the PR for a human. · 有空请复审;第 10 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
中文说明
未发现问题。LGTM!✅
— qwen3.7-max via Qwen Code /review
doudouOUC
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
中文说明
未发现问题。LGTM!✅
— qwen3.7-max via Qwen Code /review
Main merged #7881, which fixes the same docker-sandbox networking issue and extracts the container-sandbox detection, NO_PROXY save/restore, and fake-server host options into integration-tests/test-helper.ts. Resolve the provenance-test conflict to main's helper-based version, dropping the inline duplication this branch originally added. This is exactly the de-duplication the PR review requested.
Measured on 2026-07-28 across 22 open PRs: of the 16 whose AUTHOR had write access and that already carried a triage comment, exactly 1 mentioned `/verify`. The lane it recommends has produced real evidence on four PRs (QwenLM#7829 2565 assertions, QwenLM#7821 1347, QwenLM#7830 27, QwenLM#7881 17), so the gap is not that the lane is useless — it is that almost nobody is told it exists. The instruction was there the whole time. It was a conditional clause inside a section headed "2c. Real-Scenario Testing — local invocation ONLY" whose first words are "Never in unattended CI." An agent running in CI reasonably skips that section, and the assembly order at the end of Stage 2 only allotted 2c a slot "when one was driven locally" — so on the CI path there was no place for the recommendation to go even if it had been read. Split the CI-path half out into its own section, 2b-bis, sited immediately after the CI-evidence step it follows from: 2b tells you the suite is green, and cannot tell you the suite pins the change. It is a required element of the Stage 2 comment when the central claim is behavioural, with two explicit skip conditions — nothing behavioural to settle, or the author lacks write (both lanes execute the author's code, so recommending them on an external contributor's PR is a guaranteed denial). It must name the specific unsubstantiated claim, because a bare "you could run /verify" is noise and noise is why the line got skipped. Stage 1e carried the same dead pointer, and worse: on the high-risk paths — the strongest triage-time signal in the skill, 10 of 31 reverted PRs against 5 of 60 controls, p = 0.006 — it recommended tmux alone and never named /verify. The PRs most likely to be reverted were the ones never offered the lane that proves a change is load-bearing. 1e now points at 2b-bis and names both lanes. The fix is positional, so the tests are positional: asserting that the file mentions `/verify` would have passed throughout the entire period the recommendation was dead. Mutation-verified 4/4 — moving 2b-bis back below the local-only heading, dropping it from the assembly order, dropping the author-write carve-out, and reverting 1e to the tmux-only pointer each turn a test red. Prose assertions are whitespace-normalised and shown to survive a maximal re-wrap, since prettier reflows this file. Co-authored-by: wenshao <wenshao@example.com>
|
Released in v0.21.1. |
What this PR does
This PR makes the submitted-prompt provenance interactive integration test work when the suite runs inside the Docker (or Podman) sandbox. The test drives the CLI against a local fake OpenAI server, but in a container sandbox the CLI runs inside the container while the fake server runs on the host. The test now detects a container sandbox and, only in that mode, binds the fake server to all interfaces, advertises the host-gateway address (
host.docker.internal) to the sandboxed CLI, and setsNO_PROXY/no_proxyso no proxy intercepts that traffic. Outside a container sandbox the test behaves exactly as before.Why it's needed
The nightly release (
v0.21.0-nightly.20260728.923e5ab42) failed in theintegration_dockerjob at the "Run Interactive Docker Integration Tests" step, while the same interactive suite passed without a sandbox (integration_none) and the Docker image build also passed. The submitted-prompt provenance test was added recently (#7762) and was the only interactive test using the fake server without the Docker networking handling the suite already requires. By default the fake server listens on127.0.0.1and advertises a127.0.0.1base URL; inside the container that address points at the container itself, so the sandboxed CLI cannot reach the host's fake server, the model turn never completes, and the test times out. This mirrors a failure previously fixed for the protocol-tags interactive test (commitb2601c861), and the sandbox already maps the host gateway into the container (--add-host host.docker.internal:host-gateway), so this PR reuses that established, proven pattern.Reviewer Test Plan
How to verify
Run the interactive integration suite in the Docker sandbox and confirm the submitted-prompt provenance test now completes instead of timing out: build the bundle and sandbox, then
QWEN_SANDBOX=docker npx vitest run --root ./integration-tests interactive. Theintegration_dockerrelease/CI job exercises exactly this path. To confirm there is no regression outside a container, runQWEN_SANDBOX=false npx vitest run --root ./integration-tests interactive/submitted-prompt-provenance.test.ts— it passes locally (1 passed). The change is gated behindQWEN_SANDBOX=docker|podman, so non-container runs take the unchanged code path (the server option resolves toundefined).Evidence (Before & After)
N/A — this is a test-infrastructure fix with no user-visible/TUI surface. Before: the interactive Docker job timed out on the submitted-prompt provenance test because the sandboxed CLI could not reach the host's fake OpenAI server. After: the fake server is reachable from inside the container via
host.docker.internal, matching the existing protocol-tags interactive test.Tested on
Environment (optional)
Local verification used
QWEN_SANDBOX=false(no container) plusnpm run typecheckand ESLint. The Docker-mode path could not be executed locally because no Docker daemon is available on the runner; it is validated by the workflow'sintegration_dockerCI job.Risk & Scope
protocol-tags-interactive.test.ts; non-container behavior is unchanged.integration_dockerCI job. No production code is touched.Linked Issues
Fixes #7879
中文说明
本 PR 做了什么
本 PR 让 submitted-prompt provenance 这个 interactive 集成测试能够在 Docker(或 Podman)沙箱内运行时正常工作。该测试会驱动 CLI 对接一个本地的 fake OpenAI 服务器,但在容器沙箱中,CLI 运行在容器内,而 fake 服务器运行在宿主机上。本 PR 现在会检测容器沙箱,并且仅在该模式下,将 fake 服务器绑定到所有网卡、向沙箱内的 CLI 暴露宿主机网关地址(
host.docker.internal),并设置NO_PROXY/no_proxy,以免代理拦截这部分流量。在非容器沙箱环境下,该测试的行为与之前完全一致。为什么需要它
夜间发布(
v0.21.0-nightly.20260728.923e5ab42)在integration_docker任务的 “Run Interactive Docker Integration Tests” 步骤失败,而同一个 interactive 套件在无沙箱时(integration_none)通过了,Docker 镜像构建也通过了。submitted-prompt provenance 测试是最近新增的(#7762),它是唯一一个使用 fake 服务器却没有做该套件本就需要的 Docker 网络处理的 interactive 测试。默认情况下 fake 服务器监听127.0.0.1并暴露127.0.0.1的 base URL;在容器内部该地址指向容器自身,因此沙箱内的 CLI 无法访问宿主机的 fake 服务器,模型回合永远无法完成,测试随之超时。这与之前 protocol-tags interactive 测试修复过的故障一致(commitb2601c861),并且沙箱已经把宿主机网关映射进容器(--add-host host.docker.internal:host-gateway),所以本 PR 复用了那个既有且经过验证的模式。评审者测试计划
如何验证
在 Docker 沙箱中运行 interactive 集成套件,确认 submitted-prompt provenance 测试现在能够完成而不是超时:先构建 bundle 与沙箱,然后执行
QWEN_SANDBOX=docker npx vitest run --root ./integration-tests interactive。integration_docker发布/CI 任务正是走的这条路径。如需确认非容器环境无回归,可运行QWEN_SANDBOX=false npx vitest run --root ./integration-tests interactive/submitted-prompt-provenance.test.ts——本地已通过(1 个通过)。该改动被限定在QWEN_SANDBOX=docker|podman之后,因此非容器运行走的是未改动的代码路径(服务器选项解析为undefined)。证据(前后对比)
N/A——这是一个测试基础设施修复,没有用户可见/TUI 层面的变化。修复前:interactive Docker 任务在 submitted-prompt provenance 测试上超时,因为沙箱内的 CLI 无法访问宿主机的 fake OpenAI 服务器。修复后:fake 服务器可从容器内通过
host.docker.internal访问,与现有的 protocol-tags interactive 测试一致。测试环境
环境(可选)
本地验证使用了
QWEN_SANDBOX=false(无容器),并辅以npm run typecheck和 ESLint。Docker 模式路径无法在本地执行,因为运行环境没有可用的 Docker 守护进程;它由工作流的integration_dockerCI 任务来验证。风险与范围
protocol-tags-interactive.test.ts中验证过的模式;非容器行为保持不变。integration_dockerCI 任务。未触及任何生产代码。关联 Issue
Fixes #7879