Skip to content

feat(core): add the output-style layer to the system prompt - #9565

Merged
wenshao merged 12 commits into
QwenLM:mainfrom
qqqys:feat/output-styles
Aug 24, 2026
Merged

feat(core): add the output-style layer to the system prompt#9565
wenshao merged 12 commits into
QwenLM:mainfrom
qqqys:feat/output-styles

Conversation

@qqqys

@qqqys qqqys commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

This adds output styles to Qwen Code: a named block of instructions that changes how the agent reports its work, chosen once and applied for the whole session. Four styles ship built in — Concise answers first and drops preamble and narration, Proactive starts working instead of proposing and prefers a stated assumption over a question, Explanatory teaches about the codebase while it changes it, and Learning hands the user small design decisions to implement by hand and then waits for them.

This is the core half of the feature. It introduces the style registry, the four built-in definitions, the accessors on Config, and the wiring that layers a style into the system prompt. It deliberately stops short of letting anyone pick one: there is no slash command, no settings key, and no CLI flag yet, so on this commit alone no session's prompt changes. Selection surfaces follow in separate PRs, which keeps the prompt-layering question — where the style goes and what it must not disturb — reviewable on its own.

A style is appended to the end of the stable base layer that assembleSystemPrompt already defines. That position matters twice over: it puts the style after the mandates it is meant to refine, and it keeps the style ahead of every context and volatile layer, so a session's prompt prefix stays cacheable for its whole life rather than being invalidated on each memory save.

Two precedence rules fall out of that, and both follow what prompts.ts already does for QWEN_SYSTEM_IDENTITY_MD. First, a QWEN_SYSTEM_MD override wins outright and the style is ignored — that file is a complete, user-owned prompt, and layering our section onto it would defeat the point of the override. Second, the QWEN_WRITE_SYSTEM_MD dump stays a pure base prompt with no style baked in, because a style is meant to sit on top of a base; writing it into the dump would apply it a second time as soon as that file is fed back through QWEN_SYSTEM_MD.

The keepCodingInstructions flag omits exactly one section of the base prompt — the software-engineering workflow guidance, split out here as getSoftwareEngineeringTasksSection() — for a style whose work is not coding. Nothing else is affected: identity, mandates, the # Executing actions with care safety rules, tool guidance, and tone stay in force under every style. A style adjusts how work is reported; it never switches off the rules for taking risky actions. All four built-ins keep the flag true regardless.

When a style is active the identity sentence points at it rather than claiming the agent specializes in software engineering, and the style section is headed # Output Style: <name> — the heading a custom style file will rely on once user- and project-level styles load, since such a file's body becomes the prompt verbatim. A QWEN_SYSTEM_IDENTITY_MD override is still inserted untouched, because that wording is distributor-owned.

Every active style carries a per-turn reminder; the optional turnReminder field replaces the generic wording rather than deciding whether a reminder exists at all. An Explanatory session drifts back to terse answers as readily as a Concise one does. getOutputStyleTurnReminder() renders the line; the injection site itself lands in a follow-up.

Why it's needed

The tone and shape of the agent's responses is currently fixed. A user who wants terser output, or who wants the agent to explain its reasoning as it goes, has only --append-system-prompt and QWEN_SYSTEM_MD — one is a per-invocation flag with no persistence and no discovery, and the other is an all-or-nothing replacement of the entire prompt that the user then has to maintain by hand against every upstream change. Neither is something a user can reasonably discover or switch between.

There is also an existing wire-protocol commitment with nothing behind it: the system/init message declares output_style?: string in both packages/cli/src/nonInteractive/types.ts and packages/sdk-typescript/src/types/protocol.ts, and no code anywhere populates it. Similarly, packages/core/src/extension/claude-converter.ts already parses an outputStyles field out of converted Claude plugins and merges it as metadata that nothing consumes. This PR builds the layer those two stubs were waiting for.

Finally, the interaction between a style and prompt caching is the part of this feature that is easiest to get wrong and hardest to notice: a style placed in the volatile tail would silently re-bill the entire prompt on every memory save. Landing the layering decision separately, with tests that pin the layer order, makes that reviewable before any UI depends on it.

Reviewer Test Plan

How to verify

The behaviour to confirm is that a style lands in the right place in the prompt and that the two overrides win where they should. Run npx vitest run src/core/output-styles.test.ts src/core/prompts.test.ts src/core/client.test.ts from packages/core — 479 tests pass, 24 of them new. The assertion most worth reading is that a keepCodingInstructions: false style drops ## Software Engineering Tasks while # Core Mandates, # Executing actions with care, ## Using Your Tools and ## Tone and Style all survive. The interesting ones are in the outputStyle parameter block of prompts.test.ts: they assert the style section appears after # Core Mandates and before both the context-files and append-prompt markers, that it disappears entirely when QWEN_SYSTEM_MD is set, and that it never reaches the file written by QWEN_WRITE_SYSTEM_MD.

For the plumbing, client.test.ts gains a case asserting that Config.getOutputStyle() reaches getCoreSystemPrompt as its fifth argument, and packages/cli's contextCommand.test.ts (16 passing) covers the /context estimator, which has to build the same string that is actually sent or its token accounting drifts.

Reviewers should also confirm the negative: with nothing selecting a style, the default prompt is byte-identical to before. The existing prompts.test.ts snapshot is unchanged in this diff, which is the evidence for that.

Two known pre-existing failures show up when running the full suites as root, in skill-curator.test.ts and session-writer-lease.test.ts for core, plus seven in cli. All were confirmed to fail identically on a clean upstream/main checkout with this branch's changes stashed; they are chmod-based tests that cannot fail as uid 0 and are unrelated to this change.

Evidence (Before & After)

N/A — no user-visible surface in this PR. Nothing selects a style yet, so the rendered prompt is unchanged for every existing session; the UI that makes this visible lands in the follow-up.

Tested on

OS Status
🍏 macOS ⚠️ not tested
🪟 Windows ⚠️ not tested
🐧 Linux ✅ tested

Environment

Linux, Node 22.23.0, npm 10.9.8. Unit tests only, plus npm run typecheck for @qwen-code/qwen-code-core and @qwen-code/qwen-code, and eslint and prettier --check over every changed file. Note that typechecking the cli package requires npm run build --workspace @qwen-code/qwen-code-core first, since the cli resolves core through its built dist declarations.

Risk & Scope

  • Main risk or tradeoff: the style occupies the tail of the stable base layer, which is also where setStaticSystemPrefix draws the cache boundary for the Anthropic converter. Placing it there is what keeps the prefix stable across a session, but it does mean that switching styles mid-session invalidates the cached prefix once — the cost is paid on the switch, not on every turn. Config.setOutputStyle documents that callers must follow a mid-session change with GeminiClient.refreshSystemInstruction(), since the style lives in an already-bound system instruction.
  • Not validated / out of scope: no selection surface exists yet, so the styles are unreachable in a real session and the prompt text has not been evaluated against a live model. Custom user- and project-level styles, the output_style field on system/init, and the outputStyles field that claude-converter.ts already parses all remain unwired. The per-turn reminder is rendered but not yet injected anywhere — that arrives with the reminder-injection PR.
  • Breaking changes / migration notes: none. getCoreSystemPrompt gains an optional fifth parameter and Config gains two accessors; every existing call site and every default-path prompt is unchanged. Hand-written Config mocks in tests do need the new getOutputStyle accessor added, which is why client.test.ts and contextCommand.test.ts appear in this diff.

Linked Issues

None.

中文说明

这个 PR 做了什么

本 PR 为 Qwen Code 引入 output styles(输出风格):一段具名的指令块,用来改变 agent 汇报工作的方式,选定一次后在整个会话中生效。内置四种风格 —— Concise 先给结论、去掉铺垫与过程叙述;Proactive 直接动手而不是先提方案,并且倾向于给出一个明确的假设而非发问;Explanatory 在改动代码的同时讲解这个代码库;Learning 把小的设计决策交给用户亲手实现,然后停下来等待。

这是该功能的 core 部分。它引入了风格注册表、四个内置风格定义、Config 上的读写方法,以及把风格叠进系统提示词的接线。它刻意没有提供任何选择入口:目前没有斜杠命令、没有 settings 键、也没有 CLI 参数,所以仅凭这个 commit,任何会话的提示词都不会发生变化。选择入口会在后续 PR 中加入,这样「风格放在哪一层、不能扰动什么」这个提示词分层问题就可以被单独评审。

风格被追加到 assembleSystemPrompt 已经定义好的稳定 base 层的末尾。这个位置有双重意义:它让风格排在它所要修饰的 mandates 之后,同时又让风格排在所有 context 层和 volatile 层之前,因此一个会话的提示词前缀在整个生命周期内都保持可缓存,而不会在每次保存记忆时被作废。

由此引出两条优先级规则,两条都沿用 prompts.tsQWEN_SYSTEM_IDENTITY_MD 已有的处理方式。第一,QWEN_SYSTEM_MD 覆盖优先级最高,此时风格被忽略 —— 那个文件是一份完整的、由用户拥有的提示词,把我们的段落叠上去会违背覆盖本身的意图。第二,QWEN_WRITE_SYSTEM_MD 导出的文件保持为纯粹的 base 提示词,不烘焙进风格,因为风格本就是叠在 base 之上的;一旦写进导出文件,这份文件再被 QWEN_SYSTEM_MD 读回时风格就会被应用两次。

keepCodingInstructions 标志只会省略 base 提示词中的一节 —— 软件工程工作流指引,本 PR 中被拆分为 getSoftwareEngineeringTasksSection() —— 供那些工作内容并非编码的风格使用。其余部分一律不受影响:identity、mandates、# Executing actions with care 安全条款、工具指引和语气段落在任何风格下都完整生效。风格调整的是工作如何被汇报,它绝不关闭执行高风险操作的规则。四个内置风格无论如何都保持该标志为 true

当有风格生效时,identity 句子会指向该风格,而不再声称 agent 专精于软件工程;风格段落的标题为 # Output Style: <name> —— 这正是将来用户级/项目级自定义风格文件所依赖的标题,因为这类文件的正文会原样成为 prompt。QWEN_SYSTEM_IDENTITY_MD 覆盖仍然原封不动地插入,因为那是发行方拥有的措辞。

每一个生效的风格都带有每轮提醒;可选的 turnReminder 字段替换的是通用文案,而不是决定提醒是否存在。Explanatory 会话漂移回简短回答的速度,和 Concise 会话一样快。getOutputStyleTurnReminder() 负责渲染这一行;注入点本身在后续 PR 中落地。

为什么需要它

目前 agent 回复的语气和形态是固定的。想要更简短的输出,或者想让 agent 边做边解释思路的用户,只有 --append-system-promptQWEN_SYSTEM_MD 两条路 —— 前者是每次调用都要带的参数,既不持久也无从发现;后者是对整个提示词的全有或全无式替换,之后用户还得自己手工跟进上游的每一次改动。两者都不是用户能合理发现或在其间切换的东西。

另外还存在一处已经承诺、但背后空无一物的线协议:system/init 消息在 packages/cli/src/nonInteractive/types.tspackages/sdk-typescript/src/types/protocol.ts 中都声明了 output_style?: string,而全仓库没有任何代码写入它。同样地,packages/core/src/extension/claude-converter.ts 已经会从转换后的 Claude 插件里解析出 outputStyles 字段并作为元数据合并,但没有任何消费方。本 PR 补上了这两处存根一直在等的那一层。

最后,风格与提示词缓存之间的相互作用,是这个功能里最容易做错、也最难被察觉的部分:一个被放进易变尾部的风格,会在每次保存记忆时悄悄地把整个提示词重新计费。把分层决策单独落地,并用测试钉死层序,可以让这一点在任何 UI 依赖它之前就得到评审。

评审者测试计划

如何验证

需要确认的行为是:风格落在提示词的正确位置,并且两个覆盖机制在该赢的地方赢。在 packages/core 下运行 npx vitest run src/core/output-styles.test.ts src/core/prompts.test.ts src/core/client.test.ts —— 479 个测试通过,其中 24 个是新增的。最值得一读的断言是:keepCodingInstructions: false 的风格会丢掉 ## Software Engineering Tasks,而 # Core Mandates# Executing actions with care## Using Your Tools## Tone and Style 全部保留。值得关注的是 prompts.test.ts 里的 outputStyle parameter 块:它断言风格段落出现在 # Core Mandates 之后、且在 context-files 与 append-prompt 两个标记之前,断言设置 QWEN_SYSTEM_MD 时风格完全消失,以及断言风格绝不会进入 QWEN_WRITE_SYSTEM_MD 写出的文件。

关于接线部分,client.test.ts 新增了一个用例,断言 Config.getOutputStyle() 会作为第五个参数抵达 getCoreSystemPromptpackages/clicontextCommand.test.ts(16 个通过)覆盖 /context 估算器 —— 它必须构造出与实际发送完全相同的字符串,否则 token 统计会漂移。

评审者还应确认反面情况:在没有任何东西选中风格时,默认提示词与之前逐字节一致。本 diff 中 prompts.test.ts 的快照文件没有变化,这就是该结论的证据。

以 root 身份运行完整测试套件时会出现若干已存在的失败:core 侧在 skill-curator.test.tssession-writer-lease.test.ts 各一个,cli 侧七个。已通过把本分支改动 stash 后在干净的 upstream/main 检出上复跑确认,它们以完全相同的方式失败;这些是基于 chmod 的测试,在 uid 0 下不可能失败,与本次改动无关。

证据(Before & After)

N/A —— 本 PR 没有任何用户可见界面。目前没有东西会选中风格,因此对所有既有会话而言渲染出的提示词没有变化;让它变得可见的 UI 会在后续 PR 中落地。

测试环境

操作系统 状态
🍏 macOS ⚠️ 未测试
🪟 Windows ⚠️ 未测试
🐧 Linux ✅ 已测试

环境(可选)

Linux,Node 22.23.0,npm 10.9.8。仅单元测试,外加对 @qwen-code/qwen-code-core@qwen-code/qwen-codenpm run typecheck,以及对所有改动文件的 eslintprettier --check。注意:对 cli 包做类型检查前需要先执行 npm run build --workspace @qwen-code/qwen-code-core,因为 cli 是通过 core 构建出的 dist 声明来解析类型的。

风险与影响范围

  • 主要风险或权衡:风格占据稳定 base 层的尾部,而这里也正是 setStaticSystemPrefix 为 Anthropic 转换器划定缓存边界的位置。放在这里正是保证前缀在会话内稳定的原因,但这也意味着会话中途切换风格会使缓存前缀失效一次 —— 代价付在切换那一刻,而不是每一轮。Config.setOutputStyle 已在文档中说明:会话中途修改的调用方必须随后调用 GeminiClient.refreshSystemInstruction(),因为风格存在于一个已经绑定的 system instruction 之中。
  • 未验证 / 不在范围内:目前不存在任何选择入口,因此这些风格在真实会话中无法触达,提示词文案也尚未在真实模型上评估过。用户级与项目级的自定义风格、system/init 上的 output_style 字段,以及 claude-converter.ts 已经在解析的 outputStyles 字段,都仍未接线。每轮提醒(turn reminder)已可渲染,但尚未注入到任何地方 —— 那部分会随提醒注入的 PR 一起到来。
  • 破坏性改动 / 迁移说明:无。getCoreSystemPrompt 新增一个可选的第五参数,Config 新增两个方法;所有既有调用点和所有走默认路径的提示词都不受影响。测试中手写的 Config mock 确实需要补上新的 getOutputStyle 方法,这就是 client.test.tscontextCommand.test.ts 出现在本 diff 中的原因。

关联 Issue

无。

qqqys added 2 commits August 20, 2026 15:55
Introduces output styles: a named prompt section that changes how the
agent reports its work, selected per session. This is the core half —
the registry, the four built-in styles, and the prompt wiring. Nothing
selects a style yet; the picker, the settings key, and the per-turn
reminder follow separately.

The style lands at the end of the stable `base` layer: after the mandates
it refines, and still ahead of every context/volatile layer, so the
prompt prefix stays cacheable for the whole session.

Two precedence rules, both following what the file already does for
QWEN_SYSTEM_IDENTITY_MD:

- A QWEN_SYSTEM_MD override wins. That file is a full, user-owned prompt;
  layering our section onto it would defeat the override.
- The QWEN_WRITE_SYSTEM_MD dump stays a pure base prompt. A style sits on
  top of a base, so baking it into the dump would apply it twice once
  that file is fed back through QWEN_SYSTEM_MD.

`keepCodingInstructions: false` lets a style replace the base outright,
for styles that are not about software engineering at all. All four
built-ins keep it true — Proactive in particular changes how much you
plan and ask, not what you are allowed to do, and says so in its prompt
so it does not read as a second permission knob next to ApprovalMode.

Subagents and arena runs deliberately do not inherit the main session's
style: it would multiply Explanatory's insight blocks across every child,
and skew an arena comparison that is supposed to isolate the model.
@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 20, 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

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

Copy link
Copy Markdown
Collaborator

Re-run on head c99e3ace — the gate was re-checked against the current diff. Since the last pass (90e4784e) the maintainer takeover merged main four times and landed one +2/−2 cosmetic commit; the scope is unchanged.

  • Template: looks good ✓
  • Problem: still a real, verifiable gap rather than a speculative one. Re-verified on current main: output_style?: string in packages/cli/src/nonInteractive/types.ts and packages/sdk-typescript/src/types/protocol.ts still has nothing populating it, and claude-converter.ts still parses outputStyles from Claude plugins into metadata nothing consumes. The only user knobs remain --append-system-prompt (per-invocation) and QWEN_SYSTEM_MD (all-or-nothing replacement).
  • Direction: aligned. Claude Code's CHANGELOG still shows output styles shipping with the same family — a built-in "Concise" style that "leads with results and skips preamble", a keep-coding-instructions option, and the "Output style is now fixed at session start for better prompt caching" decision. This PR mirrors those choices and fills the two dead stubs rather than inventing a new concept.
  • Size: touches core paths — 451 production lines (prompts.ts 201, output-styles.ts 186, client.ts 35, config.ts 17, contextCommand.ts 10, ArenaManager.ts 1, index.ts 1) vs 439 test lines, 0 generated/schema. Under the 500-production-line awareness threshold, so no escalation.
  • Approach: scope still feels right for a staged landing — the prompt-layering question is reviewed without any selection UI attached. Everything added since the last pass is either main merges (none of which touched the PR's files beyond two unrelated main-side changes) or a 2-line cosmetic fix aligning a doc comment with the real heading and finishing a truncated style description.
  • Risk: no elevated risk signals — none of the changed files match the repo's revert-correlated high-risk paths.

Moving on to code review. 🔍

中文说明

在 head c99e3ace 上重跑——门槛检查已针对当前 diff 重新执行。自上次通过(90e4784e)以来,维护者接管后合并了四次 main,并落地了一个 +2/−2 的外观修复 commit;范围未变。

  • 模板:完整 ✓
  • 问题:仍是真实、可验证的缺口而非推测。已在当前 main 上重新核实:packages/cli/src/nonInteractive/types.tspackages/sdk-typescript/src/types/protocol.ts 中的 output_style?: string 仍无任何代码填充;claude-converter.ts 解析 Claude 插件的 outputStyles 后仍无人消费。目前用户的调节手段仍然只有 --append-system-prompt(单次调用)和 QWEN_SYSTEM_MD(整体替换)。
  • 方向:对齐。Claude Code 的 CHANGELOG 仍显示输出风格以同一家族发布——内置 "Concise" 风格("先给结果、去掉开场白")、keep-coding-instructions 选项、以及 "Output style is now fixed at session start for better prompt caching" 的决策。本 PR 复刻这些选择并填补上述两个死桩,而非发明新概念。
  • 规模:触及核心路径——生产代码 451 行(prompts.ts 201、output-styles.ts 186、client.ts 35、config.ts 17、contextCommand.ts 10、ArenaManager.ts 1、index.ts 1),测试 439 行,生成/schema 0 行。低于 500 生产行的维护者关注阈值,无需升级。
  • 方案:作为分阶段落地,范围仍然合理——提示词分层问题在没有任何选择 UI 的情况下单独评审。上次通过之后的全部新增,要么是与 main 的合并(除两处无关的 main 侧改动外未触碰 PR 文件),要么是一个 2 行的外观修复(让文档注释与真实标题一致、补全被截断的风格描述)。
  • 风险:无升级风险信号——改动文件均未命中本仓库与 revert 相关的高风险路径。

进入代码审查。🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review (head c99e3ace)

This is the fourth pass on this PR and the delta since the last deep review is deliberately small, so this is a re-confirmation rather than a first read. What changed since 90e4784e:

  • Four main merges by the takeover bot. Three touch none of the PR's 12 files. One (5b7a5977) brings main-side changes into two of them — an added versionNegotiation parameter on MCPServerConfig in config.ts and a VERTEX_ADC_HINT export in index.ts — neither of which interacts with the output-style wiring.
  • One code commit, ee29373d (+2/−2). It aligns the prompt field's doc comment with the heading the renderer actually emits (# Output Style: <name>), and finishes a truncated sentence in the Concise description ("…the work stays as thorough as ever"). Cosmetic only: description is picker text and no picker exists yet, and no test asserts either string verbatim.

The substantive findings from the prior round therefore stand, and I re-verified each load-bearing property against this head:

  1. Default path stays byte-identical. The prompts.ts hunks are unchanged since the last review, and the extraction in getSoftwareEngineeringTasksSection() is pinned by snapshot files this diff does not touch — a drift would fail CI, which is green here.
  2. Layering, precedence, dump purity. The style lands last inside the stable base layer — after # Core Mandates, ahead of the context/append layers, inside the cached prefix; QWEN_SYSTEM_MD wins outright; QWEN_WRITE_SYSTEM_MD dumps the unstyled base so feeding it back cannot double-apply a style. All pinned by dedicated tests.
  3. Shared selector. /context and the live client both go through getMainSessionBaseSystemPrompt in client.ts; the structural Pick covers exactly what resolveInteractionMode reads (signature re-checked), so token accounting cannot drift from the live prompt.
  4. Call-site audit. Every non-test consumer of getCoreSystemPromptclient.ts, ArenaManager.ts, contextCommand.ts — is on the style-aware path.

No critical blockers. The two non-blocking observations from the prior round stand: the staged-but-unwired surface (setOutputStyle, ConfigParameters.outputStyle, turnReminder, the non-built-in source variants) should actually be consumed by its follow-up PRs, and the headless-Learning drop matching on style.name === 'Learning' wants to become a property of the definition once user-defined styles exist. One hygiene note carried over from the takeover rounds: the Reviewer Test Plan in the PR body cites test paths without the packages/core/ prefix and carries stale counts — worth correcting whenever the body is next touched, not merge-blocking.

Files changed (12 of 12 shown)
File What changed
packages/core/src/core/output-styles.ts New module: four built-in style definitions, section renderer, per-turn reminder, and the apply helper
packages/core/src/core/prompts.ts New fifth outputStyle parameter; workflow section extracted; styled identity sentence; headless-Learning drop; unstyled write-dump
packages/core/src/core/client.ts Shared getMainSessionBaseSystemPrompt selector used by the live system instruction and the /context estimator
packages/core/src/config/config.ts outputStyle field, get/set accessors, ConfigParameters slot
packages/core/src/agents/arena/ArenaManager.ts In-process worker prompts now inherit the active style
packages/cli/src/ui/commands/contextCommand.ts Token estimate now built through the shared selector
packages/core/src/index.ts Exports the new output-styles module
packages/core/src/core/output-styles.test.ts New suite: registry shape, lookup, section rendering, reminder wording, apply identity
packages/core/src/core/prompts.test.ts Layer order, override precedence, identity wording, keepCodingInstructions scope, headless/interactive/acp Learning, identity override, dump purity
packages/core/src/core/client.test.ts Asserts the active style reaches getCoreSystemPrompt as its fifth argument
packages/core/src/agents/arena/ArenaManager.test.ts Worker prompt carries the headless marker and the active style together
packages/cli/src/ui/commands/contextCommand.test.ts Style billed into the estimate; custom-prompt estimate matches the live client

Test evidence (the PR's own CI — per repo policy I do not run PR code)

All 39 check-runs on the reviewed commit have resolved: the Linux unit suite is green and nothing failed anywhere on this head. The skipped entries are the macOS/Windows matrix and integration jobs that gate on the Linux result — this repo's normal shape.

CI checks at the reviewed commit (Qwen Code CI run: success, Security Checks run: success):

Check Conclusion
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success
precheck-pr / precheck ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Dependency CVE audit ✅ success
Secret scan (TruffleHog) ✅ success
Test (macos-latest, Node 22.x) ⏭️ skipped (gated on Linux)
Test (windows-latest, Node 22.x) ⏭️ skipped (gated on Linux)
Integration Tests (CLI, No Sandbox) ⏭️ skipped (gated on Linux)

Sandboxed verification: the previous trigger's run (run 32640968248) passed on head 90e4784e — verdict merge-ready, 52/52 scripted assertions, clean flakiness gate. The only code delta since is the two cosmetic lines above plus main merges that never touch the PR's files, so that A/B evidence still carries. The verify job launched by this trigger (inside run 32683160241) is still in progress and will post its own report here when it completes.

Real-scenario testing: N/A — this run is on the CI path, and there is nothing user-visible to drive on this commit regardless: no surface selects a style yet, so every real session renders exactly the prompt it did before. Not verified: prompt-text quality against a live model (no selection surface exists yet — explicitly out of scope per the PR body).

中文说明

代码审查(head c99e3ace

这是本 PR 的第四轮评审,距上次深度评审的增量刻意很小,因此本轮是再确认而非首读。90e4784e 之后的变化:

  • 接管机器人的四次 main 合并。 其中三次完全未触碰 PR 的 12 个文件;一次(5b7a5977)带入了两处 main 侧改动——config.tsMCPServerConfig 新增的 versionNegotiation 参数与 index.ts 中的 VERTEX_ADC_HINT 导出——两者均不与输出风格接线发生交互。
  • 一个代码 commit:ee29373d(+2/−2)。 它把 prompt 字段的文档注释与渲染器实际输出的标题(# Output Style: <name>)对齐,并补全了 Concise 描述中被截断的句子("…the work stays as thorough as ever")。纯外观:description 是选择器文案而目前尚无选择器,也没有任何测试逐字断言这两个字符串。

因此上一轮的实质性结论全部成立,且我在当前 head 上重新核实了每一条关键性质:

  1. 默认路径保持逐字节不变。 prompts.ts 的相关 hunk 自上次评审以来未变;getSoftwareEngineeringTasksSection() 的抽取由本 diff 未触碰的快照文件钉住——任何漂移都会使 CI 失败,而此处 CI 为绿。
  2. 分层、优先级、导出纯净。 风格落在稳定 base 层末尾——位于 # Core Mandates 之后、context/append 各层之前、被缓存前缀之内;QWEN_SYSTEM_MD 完全优先;QWEN_WRITE_SYSTEM_MD 导出无风格 base,喂回时不会二次应用风格。均有专门测试钉住。
  3. 共享选择器。 /context 与真实客户端都经由 client.tsgetMainSessionBaseSystemPrompt;结构化 Pick 恰好覆盖 resolveInteractionMode 所读取的内容(已重新核对签名),因此 token 统计不会与真实提示词漂移。
  4. 调用点审计。 getCoreSystemPrompt 的全部非测试消费者——client.tsArenaManager.tscontextCommand.ts——都在带风格的路径上。

无关键阻塞项。上一轮的两条非阻塞观察仍然成立:预留但未接通的表面(setOutputStyleConfigParameters.outputStyleturnReminder、非 built-in 的 source 变体)应真正被后续 PR 消费;headless 下按 style.name === 'Learning' 丢弃的匹配方式,在用户自定义风格出现后应改为定义上的属性。另有一条接管轮次留下的卫生提示:PR 正文的评审测试计划引用测试路径时缺少 packages/core/ 前缀且计数已过时——下次编辑正文时顺手更正即可,不阻塞合入。

(改动文件一览表见上方英文部分。)

测试证据(PR 自己的 CI——按仓库规则我不运行 PR 代码)

受审 commit 上的全部 39 个 check-run 均已落定:Linux 单测套件为绿,该 head 上没有任何失败项。被跳过的条目是等待 Linux 结果的 macOS/Windows 矩阵与集成测试,这是本仓库的正常形态。(检查明细表见上方英文部分的标记区域。)

沙箱验证:上一次触发的运行(run 32640968248)已在 head 90e4784e 上通过——判定可合入,脚本断言 52/52,抖动门干净。其后的代码增量仅为上述两行外观修复与未触碰 PR 文件的 main 合并,因此该 A/B 证据仍然有效。本次触发的验证作业(位于 run 32683160241 内)仍在运行,完成后会在此单独发布报告。

真机测试:N/A——本次运行在 CI 路径上,且该 commit 上本就没有任何用户可见面可驱动:尚无入口选择风格,每个真实会话渲染的提示词与之前完全一致。未验证:提示词文本相对真实模型的质量(尚不存在选择入口——PR 正文已明确列为范围外)。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean across every stage on the current head; the point off is the same as last time: the staged wiring stays dead until the follow-up PRs land, and the headless-Learning drop still matches on the style name.

Stepping back: this re-run had little new to judge — since the last deep pass the branch merged main four times (none of the merges touched the PR's files beyond two unrelated main-side changes) and added exactly one +2/−2 cosmetic commit. That is the shape you want to see from a takeover: no silent re-scoping, no drive-by edits. The independent baseline I wrote before first reading the diff — registry in core, Config as carrier, style at the tail of the stable base layer, QWEN_SYSTEM_MD winning outright, the dump staying pure, /context forced through the client's selector — still matches the implementation, and the three earlier Criticals remain fixed with tests that would fail on the exact regressions they describe.

On the evidence: the doubts that would block a merge are absent. There is still no reachable behavior change — nothing selects a style on this commit, so no existing session can regress. The default prompt is pinned byte-identical by untouched snapshots plus green CI, both overrides demonstrably win, and the prior trigger's sandboxed A/B verification passed on a head whose only delta from this one is two cosmetic lines (52/52 scripted assertions, clean flakiness gate). CI on the current head is fully settled — Linux unit suite green, zero failures, no pending PR runs — so the approval below is posted now, pinned to the exact commit reviewed. The verify job launched by this trigger is still in flight and will post its own report separately; it is additional assurance, not a precondition.

The small items I am leaving named for the follow-ups, none blocking: consume the staged dead surface (setOutputStyle, turnReminder injection, the output_style protocol field), turn the Learning name-match into a property of the definition once user styles exist, and correct the test-plan paths/counts in the PR body next time it is edited.

中文说明

置信度:4/5 —— 当前 head 上各阶段均干净;扣分原因与上次相同:预留接线在后续 PR 落地前仍是死的,headless 下丢弃 Learning 仍按风格名字匹配。

退一步看:这次重跑几乎没有新的判断对象——自上次深度评审以来,分支合并了四次 main(除两处无关的 main 侧改动外,合并均未触碰 PR 文件),并恰好只加了一个 +2/−2 的外观修复 commit。这正是接管后乐于见到的形态:没有悄悄扩大范围,没有顺手改动。我在首读 diff 前写下的基线方案——core 中的注册模块、Config 作为载体、风格落在稳定 base 层末尾、QWEN_SYSTEM_MD 完全优先、导出保持纯净、/context 强制走客户端的选择器——与实现仍然一致;早先三条 Critical 保持已修复状态,且测试会在它们所描述的确切回归上失败。

就证据而言:阻塞合入的疑虑都不存在。仍然没有可达的行为变化——该 commit 上尚无入口选择风格,因此不可能回归任何现有会话。默认提示词由未触碰的快照与绿色 CI 共同钉为逐字节一致,两条完整覆盖路径都明确优先,上一次触发的沙箱 A/B 验证在一个与当前仅差两行外观代码的 head 上通过(脚本断言 52/52,抖动门干净)。当前 head 的 CI 已完全落定——Linux 单测为绿、零失败、无待定的 PR 运行——因此下方的批准现已发布,并钉死在所评审的确切 commit 上。本次触发的验证作业仍在运行,将单独发布报告;它是额外保障,而非前置条件。

留给后续的非阻塞小项:真正消费预留的死代码(setOutputStyleturnReminder 注入、output_style 协议字段);用户自定义风格出现后把 Learning 的名字匹配改为定义上的属性;下次编辑 PR 正文时更正测试计划中的路径与计数。

Qwen Code · qwen3.8-max

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

`keepCodingInstructions: false` replaced the whole base prompt, which
took the safety rules down with the workflow guidance: a non-coding
style lost `# Executing actions with care`, the mandates, the tool
guidance and the tone section along with the part it meant to drop.

It now omits exactly one section — the software-engineering workflow
guidance, split out as `getSoftwareEngineeringTasksSection()`. Every
other section stays under every style. A style adjusts how work is
reported; it never switches off the rules for taking risky actions.

Two smaller corrections in the same area:

The identity sentence now points at the style when one is active
("responding according to your Output Style below") instead of claiming
the agent specializes in software engineering under a style that says
otherwise. A `QWEN_SYSTEM_IDENTITY_MD` override is still inserted
verbatim — that wording is distributor-owned and not ours to rewrite.

The style section is headed `# Output Style: <name>` rather than
`# <name> Style Active`. The heading is the contract a custom style file
will rely on once user and project styles load: the file body becomes
the prompt verbatim and the heading is what names it.

The per-turn reminder is now every style's, not just the two that spell
one out. `turnReminder` overrides the generic wording rather than
deciding whether a reminder exists at all — an Explanatory session
drifts back to terse answers as readily as a Concise one does.
`getOutputStyleTurnReminder()` renders the line the injection site will
use.

Because the style now feeds the base prompt rather than only being
appended to it, the QWEN_WRITE_SYSTEM_MD dump builds its own unstyled
copy, preserving the invariant that the dump is a reusable base.

The prompts.test.ts snapshots are unchanged, which is the evidence that
a session with no style selected still gets a byte-identical prompt.

@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. Suggestions are inline.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 22432, 20732, 1638, 1616, 494, 3849, 553 passed; 16 passing — this review observed 22432, 20732, 1638, 1616, 494, 3849, 553 passed.

中文说明

仅完成部分审查,审查缺口已披露。 建议见行内评论。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 22432, 20732, 1638, 1616, 494, 3849, 553 passed; 16 passing — this review observed 22432, 20732, 1638, 1616, 494, 3849, 553 passed

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

Comment thread packages/core/src/core/prompts.ts
Comment thread packages/cli/src/ui/commands/contextCommand.ts Outdated
…unpinned

Two coverage gaps from the r1 review, both confirmed by mutation probes:

R1-1 (prompts.test.ts): the `QWEN_SYSTEM_IDENTITY_MD` override combined with
an active output style was pinned by nothing — the identity-override tests
pass no style and the `outputStyle parameter` tests never stub the override.
Skipping the style append under an override kept all 105 tests green while
silently dropping the user's style for every deployment shipping an identity
override. The new case asserts the override text wins verbatim, the styled
identity sentence is skipped, and `# Output Style: Concise` still lands.

R1-2 (contextCommand.test.ts): the `config.getOutputStyle()` forwarding into
`getCoreSystemPrompt` was never exercised with a style active — every config
mock returned `undefined`. Deleting the argument kept the suite at 16/16
while `/context` undercounted system-prompt tokens by the style section. The
new case bills a `Concise` style and asserts the estimate grows by that
section.

Mutation verification: skipping the style append under an identity override
fails only the new prompts case (1 failed | 105 passed); deleting the
`config.getOutputStyle()` argument fails only the new contextCommand case
(1 failed | 16 passed).

@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 — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not reviewed: reverse audit — an auditor ran and opened its brief, but no agent was launched with the prompt the CLI built — the launch was written by hand, and what the agent was actually asked is not what this skill certifies.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory.

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

  • packages/core/src/config/config.ts:5499 — [review] No round-trip test for the real Config output-style holder
  • packages/core/src/core/output-styles.ts:27 — [review] Stale heading contract in prompt field doc
  • packages/core/src/core/prompts.test.ts:600 — [probe] Tail-placement test never asserts the style lands last in the base layer
  • packages/core/src/core/prompts.test.ts:675 — [probe] keepCodingInstructions:false drop test leaves its borders unguarded
  • packages/core/src/core/output-styles.ts:44 — [review] Concise style description truncated mid-sentence
中文说明

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

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未审查:反向审计——有审计 agent 运行并打开了自己的 brief,但没有 agent 是用 CLI 构建的 prompt 启动的——启动 prompt 是手写的,agent 实际被要求做的并不是本 skill 所认证的内容。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory

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

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

@wenshao wenshao 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 — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory.

中文说明

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

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory

— glm-5.3 via Qwen Code /review (v0.21.14)

Comment thread packages/cli/src/ui/commands/contextCommand.ts Outdated
Comment thread packages/core/src/core/output-styles.ts
Comment thread packages/core/src/core/prompts.ts
@qqqys
qqqys dismissed wenshao’s stale review August 22, 2026 21:26

Superseded by subsequent commit cfdbdc5; the current head requires re-review.

@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. Suggestions are inline.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 22434, 1638, 1616, 494, 3849, 553 passed; 16 passing — this review observed 22434, 1638, 1616, 494, 3849, 553 passed.

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

  • packages/core/src/core/output-styles.ts:27 — [review] Stale heading contract in OutputStyleDefinition.prompt doc comment
  • packages/core/src/config/config.ts:2203 — [probe] No round-trip test for the real Config output-style holder
  • packages/core/src/core/prompts.ts:517 — [probe] Unstyled-dump comment justifies itself with an unreachable double-application hazard
  • packages/core/src/core/prompts.test.ts:602 — [probe] Tail-placement test pins only the lower bound; 'last in the stable layer' is unpinned
  • packages/core/src/core/prompts.test.ts:670 — [probe] keepCodingInstructions:false drop test asserts only 4 of the surviving sections

Convergence: round 4 posted 2 inline comment(s), 2 of them reported for the first time. Findings keep coming back to the same files: packages/core/src/core/prompts.ts (findings in round 3; 1 more now). (Evidence: the previous round was recovered from a marker this account did not post, so those rounds may not be this account's own.) A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. (Observation only — nothing was withheld from this review because of this observation.)

中文说明

仅完成部分审查,审查缺口已披露。 建议见行内评论。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 22434, 1638, 1616, 494, 3849, 553 passed; 16 passing — this review observed 22434, 1638, 1616, 494, 3849, 553 passed

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

收敛情况:第 4 轮发布了 2 条行内评论,其中 2 条是首次提出。发现反复回到同一批文件:packages/core/src/core/prompts.ts(第 3 轮已出过发现,本轮又有 1 条)。(证据说明:上一轮的数据来自并非本账号发布的标记,上述轮次可能不属于本账号。)一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。(仅为观察——本轮评审未因此扣留任何内容。)

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

Comment thread packages/core/src/core/prompts.test.ts
Comment thread packages/core/src/core/prompts.ts

@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. Suggestions are inline.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 20735, 1638, 22434, 1616, 494, 3849, 553 passed; 16 passing — this review observed 20735, 1638, 22434, 1616, 494, 3849, 553 passed.

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

  • packages/core/src/core/prompts.test.ts:584 — [probe] Describe-scoped ! assertions can silently disarm the headless-Learning negative test

Convergence: round 5 posted 1 inline comment(s), 1 of them reported for the first time; the previous round posted 2 (2 new). Findings keep coming back to the same files: packages/core/src/core/prompts.test.ts (findings in round 4; 1 more now). A cluster that keeps producing siblings usually means the fixes are treating instances of a shared root cause — triaging that cause before the next round, or splitting an independent cluster into its own pull request, tends to end the loop faster than fixing them one at a time. No Critical finding is open on this round, so merging and moving the remaining Suggestion threads to a follow-up issue is available as an ending — a merged pull request cannot diverge further. (Observation only — nothing was withheld from this review because of this observation.)

中文说明

仅完成部分审查,审查缺口已披露。 建议见行内评论。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 20735, 1638, 22434, 1616, 494, 3849, 553 passed; 16 passing — this review observed 20735, 1638, 22434, 1616, 494, 3849, 553 passed

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

收敛情况:第 5 轮发布了 1 条行内评论,其中 1 条是首次提出;上一轮发布了 2 条(其中 2 条首次提出)。发现反复回到同一批文件:packages/core/src/core/prompts.test.ts(第 4 轮已出过发现,本轮又有 1 条)。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。本轮没有未决的 Critical,因此"合入后把剩余 Suggestion 线程转到后续 issue"是一个可选的结束方式——已合入的 PR 不会继续发散。(仅为观察——本轮评审未因此扣留任何内容。)

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

Comment thread packages/core/src/core/prompts.test.ts

@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 — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory.

中文说明

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

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory

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

@wenshao

wenshao commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /takeover

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

Copy link
Copy Markdown
Collaborator

🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. This is a fork PR, so the first round comes from the next scheduled scan (usually within minutes). Remove the autofix/takeover label (or comment @qwen-code /takeover stop) to release.

中文说明

🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。本 PR 来自 fork,首轮处理将由下一次定时扫描执行(通常几分钟内)。移除 autofix/takeover 标签(或评论 @qwen-code /takeover stop)即可释放。

@qwen-code-dev-bot

qwen-code-dev-bot commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

AutoFix round 5 finishedview run. See this round's report below.

中文说明

AutoFix 第 5 轮已完成 —— 查看运行。本轮报告见下方。

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix round: no action needed on PR #9565

This round found no actionable feedback, and every previously raised finding was re-verified as already fixed in the current head (90e4784e4a). No code changes were made; the working tree is unchanged and clean.

Why no action

  • The newest automated review (round 6, run on this exact head commit) reported zero findings.
  • All eight inline findings listed in this round's feedback — three Critical from the maintainer-driven review and five Suggestions from the automated reviewer — already have fixes committed on this branch, and each was re-verified against the code and its tests this round (details below). Nothing new was requested.
  • No failed checks, no still-red checks, no base conflict (--conflict false). PR CI aggregate: 16 checks SUCCESS, 49 SKIPPED, 0 failures.
  • The Deferred under the convergence posture items quoted in earlier review bodies were explicitly recorded by the reviewer as "not requested in this round" and were not addressed here.

Re-verification of the eight findings (all resolved in code)

Finding Fix verified at head
rc:3836919558 [Critical] /context estimated the styled default prompt while the live client sends a custom prompt when getSystemPrompt() is set getMainSessionBaseSystemPrompt() in client.ts is now the single shared custom/default selector, used by both GeminiClient.getMainSessionSystemInstruction() and /context (contextCommand.ts). Regression test estimates the custom system prompt used by the live client asserts the CUSTOM + Concise estimate is 2 tokens, not ~6344.
rc:3836919560 [Critical] Learning style combined with headless mode told the agent to stop and wait for a reply that can never arrive getCoreSystemPrompt() drops Learning only under interactionMode === 'headless'; test omits Learning from headless prompts that cannot receive a reply pins the headless marker, the plain-identity fallback, and the absence of the style section, TODO(human), and the wait wording.
rc:3836919563 [Critical] ArenaManager.buildAgentSpawnConfig() built in-process worker prompts without the active output style Arena worker prompt construction now passes this.config.getOutputStyle(); test builds the in-process worker prompt with headless mode and the active style asserts both the headless marker and # Output Style: Concise on every spawned worker.
rc:3820289326 (S) identity override + active style untested keeps the style section under a QWEN_SYSTEM_IDENTITY_MD override pins the override leading verbatim, the styled identity sentence absent, and # Output Style: Concise still present.
rc:3820289334 (S) /context style forwarding unexercised bills the active output style into the system-prompt estimate pins the token delta to the real styled/unstyled character delta (±5 tokens).
rc:3837242882 (S, R4-1) headless-Learning test pinned only absence The same test now also pins the plain identity sentence and the absence of the styled identity, so the move-down mutation the reviewer described cannot ship.
rc:3837242890 (S, R4-2) Learning in interactive mode unpinned keeps Learning in interactive prompts pins the section and its TODO(human) handoff marker.
rc:3837441052 (S, R5-1) Learning in acp mode unpinned keeps Learning in acp prompts pins the section for the third sibling mode.

Environment repair (no code or lockfile change)

The first local npm run build failed with type errors in packages/core/src/telemetry/* — files this PR does not touch. Evidence showed the checkout's installed node_modules matched origin/main's newer lockfile (@opentelemetry/sdk-logs@0.221.0, core@2.10.0) instead of this branch's lockfile (sdk-logs@0.203.0, core@2.0.1); main's newer OpenTelemetry interfaces (LogRecordExporter.forceFlush, Logger.enabled) are what the stale telemetry code on this branch does not implement, and main's own code was updated alongside its bump while this branch predates it. The runner precondition (a clean npm ci from the branch lockfile) was violated by the checkout state. Repair: removed the corrupted tree and ran npm ci from this branch's committed lockfile (with a writable npm cache). No lockfile, code, or generated artifact was modified — git status is clean and HEAD is unchanged. With the branch-locked tree restored, every required check passes, consistent with this PR's green CI.

Verification

  • npm ci --no-audit --no-fund (branch lockfile, restored the documented runner precondition) — exit 0
  • npm run build — passed (exit 0)
  • npm run typecheck — passed (exit 0)
  • npm run lint — passed (exit 0)
  • cd packages/core && npx vitest run src/core/prompts.test.ts — 109 passed (109)
  • cd packages/core && npx vitest run src/core/prompts.test.ts src/core/output-styles.test.ts src/agents/arena/ArenaManager.test.ts — 152 passed (3 files)
  • cd packages/core && npx vitest run src/core/client.test.ts — 359 passed (359)
  • cd packages/cli && npx vitest run src/ui/commands/contextCommand.test.ts — 18 passed (18)
中文说明

Autofix 轮次:PR #9565 无需操作

本轮没有可执行的反馈,此前提出的全部发现均已重新验证为已在当前 head(90e4784e4a)修复。本轮未做任何代码改动,工作区保持不变且干净。

为什么无需操作

  • 最新一轮自动审查(第 6 轮,正是在该 head 提交上运行)报告零发现
  • 本轮反馈列出的全部 8 条行内发现——来自维护者触发审查的 3 条 Critical 与来自自动审查器的 5 条 Suggestion——在本分支上均已有提交的修复,且本轮逐条对照代码与测试重新验证(详见下表)。没有任何新的修改请求。
  • 无失败检查、无持续红灯检查、无与 base 分支的冲突(--conflict false)。PR CI 汇总:16 项 SUCCESS、49 项 SKIPPED、0 项失败。
  • 早前审查正文中引用的 Deferred under the convergence posture(收敛姿态下延后)条目已被审查者明确标注为"本轮不要求修改",本轮未处理。

八条发现的重新验证(均已在代码中解决)

发现 在 head 上验证的修复
rc:3836919558 [Critical]getSystemPrompt() 已设置时,/context 估算的是带风格的默认 prompt,而真实客户端发送的是自定义 prompt client.ts 中的 getMainSessionBaseSystemPrompt() 现在是唯一的共享 custom/default 选择器,同时被 GeminiClient.getMainSessionSystemInstruction()/contextcontextCommand.ts)使用。回归测试 estimates the custom system prompt used by the live client 断言 CUSTOM + Concise 的估算为 2 tokens,而非约 6344。
rc:3836919560 [Critical] Learning 风格与 headless 模式组合时会要求 agent 停下等待一个永远不会到来的回复 getCoreSystemPrompt() 仅在 interactionMode === 'headless' 时丢弃 Learning;测试 omits Learning from headless prompts that cannot receive a reply 钉住了 headless 标记、plain identity 回退,以及风格段落、TODO(human)、等待措辞的缺失。
rc:3836919563 [Critical] ArenaManager.buildAgentSpawnConfig() 构建 in-process worker prompt 时未传入激活的 output style Arena worker prompt 构建现在传入 this.config.getOutputStyle();测试 builds the in-process worker prompt with headless mode and the active style 对每个派发的 worker 断言 headless 标记与 # Output Style: Concise 同时存在。
rc:3820289326 (S) identity 覆盖 + 激活风格的组合无测试 keeps the style section under a QWEN_SYSTEM_IDENTITY_MD override 钉住覆盖文本原样置首、带风格的 identity 句子缺失、且 # Output Style: Concise 仍存在。
rc:3820289334 (S) /context 的风格转发从未被验证 bills the active output style into the system-prompt estimate 将 token 增量钉死在真实带风格/不带风格字符增量(±5 tokens)范围内。
rc:3837242882 (S, R4-1) headless-Learning 测试只钉住了"缺失" 同一测试现在同时钉住 plain identity 句子与带风格 identity 的缺失,使审查者描述的"下移"变异无法溜过。
rc:3837242890 (S, R4-2) interactive 模式下 Learning 的去向未被钉住 keeps Learning in interactive prompts 钉住风格段落及其 TODO(human) 交接标记。
rc:3837441052 (S, R5-1) acp 模式下 Learning 的去向未被钉住 keeps Learning in acp prompts 为第三个同族模式钉住该段落。

环境修复(未改动任何代码或 lockfile)

首次本地 npm run buildpackages/core/src/telemetry/* 报类型错误——这些文件本 PR 完全未触碰。证据显示:该检出中已安装的 node_modules 匹配的是 origin/main 较新的 lockfile(@opentelemetry/sdk-logs@0.221.0core@2.10.0),而不是本分支的 lockfile(sdk-logs@0.203.0core@2.0.1);main 上较新的 OpenTelemetry 接口(LogRecordExporter.forceFlushLogger.enabled)正是本分支上旧版遥测代码未实现的内容——main 在升级依赖的同时更新了自己的代码,而本分支早于该变更。检出状态违反了运行器前提条件(从分支 lockfile 执行干净的 npm ci)。修复方式:删除损坏的依赖树,并从本分支已提交的 lockfile 重新执行 npm ci(使用可写的 npm 缓存)。未修改任何 lockfile、代码或生成产物——git status 干净,HEAD 未变。恢复分支锁定的依赖树后,所有必需检查全部通过,与本 PR 的 CI 绿灯一致。

验证

  • npm ci --no-audit --no-fund(分支 lockfile,恢复文档约定的运行器前提条件)— exit 0
  • npm run build — 通过(exit 0)
  • npm run typecheck — 通过(exit 0)
  • npm run lint — 通过(exit 0)
  • cd packages/core && npx vitest run src/core/prompts.test.ts — 109 通过(109)
  • cd packages/core && npx vitest run src/core/prompts.test.ts src/core/output-styles.test.ts src/agents/arena/ArenaManager.test.ts — 152 通过(3 个文件)
  • cd packages/core && npx vitest run src/core/client.test.ts — 359 通过(359)
  • cd packages/cli && npx vitest run src/ui/commands/contextCommand.test.ts — 18 通过(18)

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@wenshao

wenshao commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

@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.

⚠️ Downgraded from Approve to Comment: CI failing: Test (ubuntu-latest, Node 22.x). Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 1685, 1653, 495, 4164, 599 passed; 16 passing — this review observed 1685, 1653, 495, 4164, 599 passed.

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

  • packages/core/src/core/output-styles.ts:27 — [review] Stale heading contract in OutputStyleDefinition.prompt doc comment
  • packages/core/src/config/config.ts:5516 — [review] No round-trip test for the real Config output-style holder
中文说明

⚠️ 已从批准降级为评论:CI failing: Test (ubuntu-latest, Node 22.x)。 仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 1685, 1653, 495, 4164, 599 passed; 16 passing — this review observed 1685, 1653, 495, 4164, 599 passed

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

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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下:

Round summary — PR #9565 (address-review)

One commit this round: ee29373d61 fix(core): align output-style doc comment and Concise description (+2/−2, one file). The round's main work was an evidence-based diagnosis of the red Test (ubuntu-latest, Node 22.x) check that both automated reviews cited as the downgrade reason.

Diagnosis of the failing Test check

Two independent facts, each evidenced:

1. The recorded failure for the current head is a 19-second early-job failure, not a test failure. The check run for head 2fed45bc16 (run 32651399331, job 97223498866, from the workflow-supplied checks data) started 2026-08-23T16:21:33Z and completed FAILURE at 16:21:52Z — 19 seconds, before npm ci could finish, let alone lint or the unit suite (which takes ~15–25 minutes). The only steps that execute that early are workspace cleanup, checkout, the Verify checkout includes expected head commit guard, CI-profile classification, and the workflow-file-size check. The workflow's own comments document this failure class: the checkout can be served a stale ref by a caching egress proxy right after a push, and the verify-checkout-head guard fails the job fast when that happens. The head 2fed45bc16 is itself a merge commit pushed seconds earlier by the autofix merge-main step, which is exactly the race the guard exists for. This is not reproducible locally and not attributable to any code in this PR; the normal remedy is a CI re-run.

2. If the job runs to completion on current main, it will fail the workflow-size ratchet — a defect inherited from main. A full local reproduction of the Test job's substance (details in Verification) shows every workspace suite green (cli 875/875, core 604 passed + 1 skipped, vscode-ide-companion 54/54, web-shell 197/197, desktop 35/35, all smaller packages green). The one deterministic red is:

FAIL scripts/tests/workflow-size.test.js > workflow size growth ratchet >
     .github/workflows/cd-cua-driver.yml is within its baseline allowance
AssertionError: expected 42519 to be less than or equal to 33811
  • Main commit b5fbdb22d3 ("feat(cua-driver): add versioned Computer Use SDK and release pipeline (feat(cua-driver): add versioned Computer Use SDK and release pipeline #9587)", merged 2026-08-23) grew .github/workflows/cd-cua-driver.yml from 29,715 → 42,519 bytes without updating .github/workflows/.size-baseline (records 29,715; allowance 4,096 → cap 33,811). The ratchet test predates the growth commit (a5d77eb817, 2026-08-22), so the growth slipped through a CI-timing gap.
  • The failing files (.size-baseline, cd-cua-driver.yml, workflow-size.test.js) are byte-identical between this branch and the latest origin/main (fetched during this round: fd4b7c008a), and the test still fails at that main tip — main's own Test check is red on this test right now, and every PR merged with current main inherits it.
  • This PR's diff touches none of those files; the PR's own tests are all green (see Verification).

The one-line fix (record 42519 in .size-baseline) lives under .github/, an area this round is not allowed to touch, and it properly belongs on main so all PRs clear at once. Recorded in deferred-findings.json; a maintainer needs to land that baseline update on main, after which this branch should re-merge main. Nothing this PR can change will clear the ratchet until then.

Feedback dispositions

  • [rv:5002823450], [rv:5002938898] (downgrade from Approve to Comment, reason: CI failing) — addressed as far as this PR can: the recorded 19-second failure is an early-job/infrastructure failure needing a re-run (see above), and the full local reproduction shows the PR's own surface is green; the only substantive red remaining anywhere in the job is the main-inherited ratchet (deferred, needs a main-side fix). Their disclosed gaps (integration suite not run locally, reverse audit not converged) and Test Plan mismatches (PR-body paths like src/core/output-styles.test.ts should read packages/core/src/...; stale counts "479/16" vs observed) are PR-description inaccuracies that require editing the PR body — not possible from this runner (no GitHub writes). Flagging for maintainers: the body should be corrected to the real paths and counts.
  • Deferred item: stale heading contract in OutputStyleDefinition.prompt doc comment (output-styles.ts:27)Fixed: comment said `# <Name> Style Active` while renderOutputStyleSection() emits # Output Style: <name> (the contract pinned by ~15 tests and stated by that function's own doc comment). Same nit as the sandboxed-verification report's Finding.
  • Deferred item: Concise style description truncated mid-sentence (output-styles.ts:45)Fixed: completed the sentence ("…the work stays as thorough as ever"); no test or code pinned the truncated string (verified by grep before editing).
  • Deferred item: no round-trip test for the real Config output-style holder (config.ts:5516) — left as recorded by the reviewer ("not requested in this round"); no change.
  • [ic:5386122771] (sandboxed verification: ✅ passed, 52/52 assertions; flakiness gate green) — advisory, no action needed beyond its Finding, which is fixed by this round's commit. Its two Corrections (PR body says arena runs don't inherit the style while the final code deliberately does; stale test counts) are PR-body edits and are flagged above for maintainers.
  • Failed checks: Test (ubuntu-latest Node 22.x) — root-caused above: 19-second early-job failure on the merge commit's run (re-run needed) plus the main-inherited workflow-size ratchet that any full run on current main will hit. Two other local-only failures in npm run test:scripts are runner tooling gaps, not code defects: install-script.test.js throws because this self-hosted runner lacks zip (CI's own "Install tmux and zip tooling" step installs it before tests), and verify-capture.test.js's 256-colour test fails because this runner has zero fonts installed (fc-list = 0; the helper renders SVG text with DejaVu Sans Mono, which GitHub-hosted runners ship).
  • Incidental observation (not feedback, not blocking CI): packages/cli/src/ui/auth/AuthDialog.test.tsx "drives API key provider steps from endpoint options metadata" is genuinely broken on main for local (non-CI) runs — it hardcodes one down-arrow from DeepSeek to MiniMax, but the Grok (xAI) provider inserted between them by feat(providers): add xAI Grok provider preset #6805 (2026-07-14) makes the stop land on Grok. It never fails CI because itWhenTuiInputReliable skips these tests when CI=true. Pre-existing, out of this PR's footprint; mentioned here so it isn't lost.

Changes

  • packages/core/src/core/output-styles.ts — doc-comment heading contract corrected; Concise picker description completed. No guards/branches/behavior added (comment + string literal only), so no mutation probe applies — no suite can witness prose, and the verification report independently confirmed the suite is green either way.

No conflicts this round (--conflict false); no merge performed.

Verification

Commands actually run this round (after the committed change unless noted):

  • npm run build — passed
  • npm run typecheck — passed (0 TS errors)
  • npm run lint — passed
  • node scripts/lint.js --eslint — passed (an earlier run failed with ENOENT only because my own concurrently running test suite was writing packages/cli/coverage/ mid-scan; re-run sequentially after the suite → exit 0)
  • node scripts/lint.js --prettier — exited 0. Note: this wrapper runs prettier --write . and checks nothing afterwards, so it cannot red the Test job; on this machine it rewrote 41 committed files because the local node_modules prettier deviates from the lockfile — those rewrites were discarded (restored to HEAD) and are unrelated to the PR.
  • node scripts/lint.js --sensitive-keywords — passed
  • npx prettier --check on the changed file — passed
  • npm run check-i18n — passed
  • npm run generate:settings-schema + git status on the schema — schema up-to-date (no drift)
  • npm run check:lockfile — passed
  • npm run check:desktop-isolation — passed
  • npm run check:voice-guard-sync — passed
  • npm run check:serve-fast-path-bundle — passed
  • node --test <all 18 HELPER_TESTS files> — 383 passed / 0 failed
  • npx tsc -p integration-tests/tsconfig.json — passed
  • Focused Vitest (core): output-styles.test.ts + prompts.test.ts + client.test.ts + ArenaManager.test.ts514/514 passed (re-run at the committed state with CI=true)
  • Focused Vitest (cli): contextCommand.test.ts18/18 passed
  • Full npm run test:ci with CI-faithful env (CI=true, fresh HOME, SANDBOX/QWEN_HOME/API keys unset) — all workspace packages green: cli 875/875, core 604 passed + 1 skipped, acp-bridge 32 files, vscode-ide-companion 54/54, web-shell 197/197, desktop 35/35, remaining packages green. test:scripts leg: 1588 passed, 3 failures — one real and inherited from main (workflow-size ratchet, root-caused above, deferred), two self-hosted-runner tooling gaps (missing zip, zero installed fonts) that GitHub-hosted CI does not have.
  • Checks data (workflow-supplied checks.json): the failing Test (ubuntu-latest, Node 22.x) run completed in 19 s (16:21:33Z → 16:21:52Z) — early-job failure, see diagnosis.
  • Note: two earlier local full-suite runs produced extra failures that were all traced to my own harness (harness-set QWEN_HOME/SANDBOX env leaking into tests, and a concurrent check:serve-fast-path-bundle rebuild racing vite resolution); each was re-verified green once the contamination was removed, so none of them is attributed to the PR.

Not run: the no-AK integration gate's vitest leg and the Chrome-extension packaging step (both only run after the unit leg in CI; the gate's tsc leg is verified above, and the unit leg is where any substantive red would surface). The PR's behavioral A/B evidence remains the sandboxed verification report (52/52 assertions, mutation matrix 8/8).

中文说明

本轮摘要 — PR #9565(address-review)

本轮提交一个 commit:ee29373d61 fix(core): align output-style doc comment and Concise description(+2/−2,单个文件)。本轮的主要工作是对两次自动评审都引用的降级原因——Test (ubuntu-latest, Node 22.x) 检查变红——做基于证据的根因诊断。

Test 检查失败的诊断

两个各自有证据支撑的事实:

1. 当前 head 上记录的这次失败是 19 秒的早期 job 失败,不是测试失败。 head 2fed45bc16 对应的 check run(run 32651399331、job 97223498866,来自工作流提供的 checks 数据)于 2026-08-23T16:21:33Z 开始,16:21:52Z 以 FAILURE 结束——仅 19 秒,npm ci 都跑不完,更别说 lint 和单元测试(约需 15–25 分钟)。这么早只会执行到:工作区清理、checkout、Verify checkout includes expected head commit 守卫、CI profile 分类、workflow 文件大小检查。工作流自身的注释记录了这类失败:push 之后缓存出口代理可能提供过期的 ref,verify-checkout-head 守卫在这种情况下快速失败。head 2fed45bc16 本身是 autofix 的 merge-main 步骤几秒前刚 push 的 merge commit,正是该守卫要防的竞态。此问题无法本地复现,也不能归因于本 PR 的任何代码;正常补救是重跑 CI。

2. 若 job 在当前 main 上完整跑完,会挂在 workflow 大小 ratchet 上——这是继承自 main 的缺陷。 对 Test job 实质内容的完整本地复现(细节见 Verification)显示所有 workspace 套件全绿(cli 875/875、core 604 通过 + 1 跳过、vscode-ide-companion 54/54、web-shell 197/197、desktop 35/35,其余小包全绿)。唯一确定性红色是:

FAIL scripts/tests/workflow-size.test.js > workflow size growth ratchet >
     .github/workflows/cd-cua-driver.yml is within its baseline allowance
AssertionError: expected 42519 to be less than or equal to 33811
  • main 提交 b5fbdb22d3("feat(cua-driver): add versioned Computer Use SDK and release pipeline (feat(cua-driver): add versioned Computer Use SDK and release pipeline #9587)",2026-08-23 合入)把 .github/workflows/cd-cua-driver.yml29,715 → 42,519 字节,却没有更新 .github/workflows/.size-baseline(记录值 29,715;允许增量 4,096 → 上限 33,811)。ratchet 测试早于该增长提交(a5d77eb817,2026-08-22),因此这次增长是借 CI 时序间隙溜过去的。
  • 失败相关文件(.size-baselinecd-cua-driver.ymlworkflow-size.test.js)在本分支与最新 origin/main(本轮现取:fd4b7c008a)之间逐字节一致,且在该 main 顶端该测试仍然失败——也就是说 main 自己的 Test 检查此刻就红在这个测试上,任何合入了当前 main 的 PR 都会继承它。
  • 本 PR 的 diff 完全没有触碰这些文件;PR 自身的测试全绿(见 Verification)。

一行修复(把 .size-baseline 记为 42519)位于 .github/ 之下——本轮不允许触碰该区域,而且它理应落在 main 上以便所有 PR 一次性解除。已记入 deferred-findings.json;需要维护者先在 main 上落地该基线更新,之后本分支重新合并 main。在此之前,本 PR 无论改什么都无法解除该 ratchet。

反馈处置

  • [rv:5002823450]、[rv:5002938898](从 Approve 降级为 Comment,原因:CI failing)——已在本 PR 能力范围内处理:记录的 19 秒失败属早期 job/基础设施失败,需要重跑(见上);完整本地复现表明 PR 自身层面全绿;整个 job 中剩余的唯一实质红色是继承自 main 的 ratchet(已延迟登记,需 main 侧修复)。其披露的缺口(集成套件未在本地运行、反向审计未收敛)与 Test Plan 不符(PR 正文里 src/core/output-styles.test.ts 这类路径应为 packages/core/src/...;"479/16" 等过期计数)属于 PR 描述不准确,需要编辑 PR 正文——本运行器无 GitHub 写权限,无法代改。提请维护者注意:正文应更正为真实路径与计数。
  • 延迟项:OutputStyleDefinition.prompt 文档注释中的过期标题契约(output-styles.ts:27——已修复:注释原写 `# <Name> Style Active`,而 renderOutputStyleSection() 实际输出 # Output Style: <name>(该契约由约 15 个测试钉住,且同函数的文档注释也如此声明)。与沙箱验证报告的 Finding 为同一条。
  • 延迟项:Concise 风格描述句中截断(output-styles.ts:45——已修复:补全句子("…the work stays as thorough as ever");编辑前已用 grep 确认没有任何测试或代码钉住截断前的字符串。
  • 延迟项:真实 Config output-style 持有者缺少 round-trip 测试(config.ts:5516——按评审者的收敛姿态保持记录状态("本轮不要求修改"),不做改动。
  • [ic:5386122771](沙箱验证:✅ 通过,52/52 断言;抖动门绿)——咨询性证据,除其 Finding 外无需行动,而该 Finding 已由本轮提交修复。其两条更正(PR 正文称 arena 运行不继承风格,而最终代码是刻意继承的;过期测试计数)属于 PR 正文编辑,已在上文提请维护者处理。
  • Failed checks: Test (ubuntu-latest Node 22.x)——根因见上:merge commit 那次运行是 19 秒早期 job 失败(需重跑),外加当前 main 上任何完整运行都会命中的、继承自 main 的 workflow 大小 ratchet。本地 npm run test:scripts 另有 2 个仅本地失败,属运行器工具缺口而非代码缺陷:install-script.test.js 因本自托管运行器缺 zip 而抛错(CI 自己的 "Install tmux and zip tooling" 步骤会在测试前安装它);verify-capture.test.js 的 256 色测试因本运行器一种字体都没装(fc-list = 0;helper 用 DejaVu Sans Mono 渲染 SVG 文本,GitHub 托管运行器自带该字体)。
  • 附带观察(非反馈、不阻塞 CI)packages/cli/src/ui/auth/AuthDialog.test.tsx 的 "drives API key provider steps from endpoint options metadata" 在 main 上对本地(非 CI)运行确实已坏——它硬编码从 DeepSeek 按一次下键到 MiniMax,但 feat(providers): add xAI Grok provider preset #6805(2026-07-14)在两者之间插入了 Grok (xAI) 提供者,导致落点变成 Grok。它从不曾在 CI 上失败,因为 itWhenTuiInputReliableCI=true 时跳过这些测试。属 main 既有问题、本 PR 足迹之外;在此记录以免遗失。

变更内容

  • packages/core/src/core/output-styles.ts——修正文档注释的标题契约;补全 Concise 选择器描述。未新增任何守卫/分支/行为(纯注释 + 字符串字面量),因此不适用变异探针——散文无法被套件见证,且验证报告已独立确认该注释两种写法下套件均为绿。

本轮无冲突(--conflict false);未执行合并。

Verification(验证)

本轮实际执行的命令(除特别注明外均在提交之后运行):

  • npm run build — 通过
  • npm run typecheck — 通过(0 个 TS 错误)
  • npm run lint — 通过
  • node scripts/lint.js --eslint — 通过(早先一次失败出现 ENOENT,仅因我自己并发运行的测试套件正在向 packages/cli/coverage/ 写文件;套件结束后顺序重跑 → exit 0)
  • node scripts/lint.js --prettier — exit 0。注意:该包装器执行 prettier --write . 且事后不做任何检查,因此不可能把 Test job 染红;在本机上它因本地 node_modules 的 prettier 与 lockfile 有偏差而重写了 41 个已提交文件——这些重写已被丢弃(恢复至 HEAD),与本 PR 无关。
  • node scripts/lint.js --sensitive-keywords — 通过
  • 对变更文件执行 npx prettier --check — 通过
  • npm run check-i18n — 通过
  • npm run generate:settings-schema + 对 schema 文件 git status — schema 为最新(无漂移)
  • npm run check:lockfile — 通过
  • npm run check:desktop-isolation — 通过
  • npm run check:voice-guard-sync — 通过
  • npm run check:serve-fast-path-bundle — 通过
  • node --test <全部 18 个 HELPER_TESTS 文件> — 383 通过 / 0 失败
  • npx tsc -p integration-tests/tsconfig.json — 通过
  • 定向 Vitest(core):output-styles.test.ts + prompts.test.ts + client.test.ts + ArenaManager.test.ts514/514 通过(在提交后的状态下以 CI=true 重跑)
  • 定向 Vitest(cli):contextCommand.test.ts18/18 通过
  • 完整 npm run test:ci,CI 等价环境(CI=true、全新 HOME、未设 SANDBOX/QWEN_HOME/API key)——所有 workspace 包全绿:cli 875/875、core 604 通过 + 1 跳过、acp-bridge 32 个文件、vscode-ide-companion 54/54、web-shell 197/197、desktop 35/35,其余包全绿。test:scripts 段:1588 通过、3 个失败——1 个真实且继承自 main(workflow-size ratchet,根因见上,已延迟登记),2 个为自托管运行器工具缺口(缺 zip、零安装字体),GitHub 托管 CI 不存在这两个问题。
  • Checks 数据(工作流提供的 checks.json):失败的 Test (ubuntu-latest, Node 22.x) 运行 19 秒即结束(16:21:33Z → 16:21:52Z)——早期 job 失败,见诊断。
  • 说明:更早的两次本地全套运行产生的额外失败,全部追溯为我自己的 harness 污染(harness 设置的 QWEN_HOME/SANDBOX 环境变量泄漏进测试;以及并发的 check:serve-fast-path-bundle 重建与 vite 解析竞态);去除污染后逐一复验为绿,因此均不归于本 PR。

未运行:no-AK 集成门的 vitest 段与 Chrome 扩展打包步骤(两者在 CI 中都排在单元测试段之后;该门的 tsc 段已在上方验证,且任何实质红色都会出现在单元测试段)。PR 的行为级 A/B 证据仍以沙箱验证报告为准(52/52 断言、变异矩阵 8/8)。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@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.

⚠️ Downgraded from Approve to Comment: CI failing: Test (ubuntu-latest, Node 22.x). Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 1685, 23496, 1653, 495, 4164, 599 passed; 16 passing — this review observed 1685, 23496, 1653, 495, 4164, 599 passed.

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

  • packages/core/src/config/config.ts:981 — [review] Output-style layer has no producer; present-tense doc comments overstate live behavior
中文说明

⚠️ 已从批准降级为评论:CI failing: Test (ubuntu-latest, Node 22.x)。 仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 1685, 23496, 1653, 495, 4164, 599 passed; 16 passing — this review observed 1685, 23496, 1653, 495, 4164, 599 passed

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

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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run.

中文说明

🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。

@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.

⚠️ Downgraded from Approve to Comment: CI failing: Test (ubuntu-latest, Node 22.x). Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 23526, 21070, 1685, 1654, 495, 4190, 610 passed; 16 passing — this review observed 23526, 21070, 1685, 1654, 495, 4190, 610 passed.

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

  • packages/core/src/config/config.ts:5517 — [probe] No round-trip test for the real Config output-style holder
  • packages/core/src/core/prompts.test.ts:603 — [probe] Tail-placement test pins only a band, not "last in the base layer"
  • packages/core/src/core/prompts.test.ts:669 — [probe] keepCodingInstructions:false drop test leaves splice-adjacent base content unguarded
  • packages/core/src/core/prompts.test.ts:776 — [probe] QWEN_WRITE_SYSTEM_MD dump test discards the returned prompt; styled-return invariant unpinned
中文说明

⚠️ 已从批准降级为评论:CI failing: Test (ubuntu-latest, Node 22.x)。 仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 23526, 21070, 1685, 1654, 495, 4190, 610 passed; 16 passing — this review observed 23526, 21070, 1685, 1654, 495, 4190, 610 passed

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

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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Could not produce a passing fix for this feedback (round 4/100). This item now needs a human; the loop stays engaged and still picks up new feedback and base conflicts, but will not retry this item on its own.

What I found before stopping:

Autofix stopped: the red Test check is caused by a broken workflow-size baseline on main, not by this PR

Blocker

The Test (ubuntu-latest, Node 22.x) check on PR #9565 fails in the Check workflow file size step, before any test runs. The gate script reports:

::error file=.github/workflows/cd-cua-driver.yml::.github/workflows/cd-cua-driver.yml grew to 42519 bytes, 12804 over its recorded 29715 (allowance 4096). Move prose into a sibling .md and long steps into .github/scripts/ — or, if the growth is real, update .github/workflows/.size-baseline in this PR and say why.

The fix is a one-line update of .github/workflows/.size-baseline (2971542519 for cd-cua-driver.yml). That file is CI machinery under .github/, an area this PR never touched. This round's rules prohibit expanding into .github/ outside the PR's own footprint — the deterministic gate rejects such a round outright — and feedback requiring such a change is escalated to a maintainer rather than implemented. So this round commits nothing and hands the fix over.

Evidence

  1. Check-run data for the latest CI run (workflow run 32664807875): Test (ubuntu-latest, Node 22.x) failed after ~19 seconds (started 2026-08-23T20:34:24Z, completed 2026-08-23T20:34:43Z) — far too fast to have reached any test step.
  2. In the same run, the downstream web-shell E2E Smoke job ran and passed, and its if requires needs.test.outputs.ci_profile == 'full'. That output is set by
中文说明

🤖 未能为该反馈产生可通过验证的修复(第 4/100 轮)。此项现在需要人工处理;循环保持在线,仍会拾取新反馈与 base 冲突,但不会自行重试此项。

停止前我了解到的情况:

Autofix 已停止:Test 检查变红是 main 上的 workflow 体积基线损坏导致的,与本 PR 无关

阻塞点

PR #9565Test (ubuntu-latest, Node 22.x) 检查在 Check workflow file size 这一步失败,此时还没有运行任何测试。门禁脚本报错如下:

::error file=.github/workflows/cd-cua-driver.yml::.github/workflows/cd-cua-driver.yml grew to 42519 bytes, 12804 over its recorded 29715 (allowance 4096). Move prose into a sibling .md and long steps into .github/scripts/ — or, if the growth is real, update .github/workflows/.size-baseline in this PR and say why.

修复方法是对 .github/workflows/.size-baseline 做一行更新(把 cd-cua-driver.yml29715 改为 42519)。该文件是 .github/ 下的 CI 机制,而本 PR 完全没有触碰过这个目录。本轮的规则禁止把改动扩展到 PR 自身足迹之外的 .github/ 区域——确定性门禁会直接拒绝这样的轮次——并且要求此类变更的反馈应升级给维护者处理,而不是由本轮实现。因此本轮不提交任何内容,把修复移交出去。

证据

  1. 最新一次 CI 运行(workflow run 32664807875)的 check-run 数据显示:Test (ubuntu-latest, Node 22.x) 在约 19 秒后失败(开始于 2026-08-23T20:34:24Z,结束于 2026-08-23T20:34:43Z)——远快于到达任何测试步骤所需的时间。
  2. 在同一次运行中,下游的 web-shell E2E Smoke 作业运行并通过了,而它的 if 条件要求 needs.test.outputs.ci_profile == 'full'。该输出来自 Test 作业的 "Classify CI profile" 步骤,说明 Test 作业完成了分类、并在紧接着的下一步——"Check workflow file size"——失败。
  3. 在 PR 头部直接运行同一个门禁脚本可以确定性地复现失败:.github/scripts/check-workflow-size.sh 以退出码 1 结束,报错即上文所引用的内容。
  4. 变异探针:临时把基线条目改为 42519 cd-cua-driver.yml 后,脚本以退出码 0 结束("every workflow file is under the 470000-byte gate and within 4096 bytes of its recorded baseline");随后工作区已恢复到 HEAD。
  5. git diff origin/main HEAD -- .github/workflows/cd-cua-driver.yml .github/workflows/.size-baseline 为空:该违规在 origin/main 本身就存在。它由 feat(cua-driver): add versioned Computer Use SDK and release pipeline #9587feat(cua-driver): add versioned Computer Use SDK and release pipeline,提交 b5fbdb22d3,于 2026-08-23 14:20 UTC 合入)引入——该 PR 把 cd-cua-driver.yml 从 29715 字节增大到 42519 字节,却没有按门禁要求在同一个 PR 里更新基线。自那次合入之后,所有 PR 的 full-profile Test 检查都在这一步失败。本 PR 的第 9、10 两轮评审都仅因这个失败的检查而降级,且没有其他可执行的发现。

本 PR 自身验证为绿色

以下所有检查都在 HEAD 5b7a59777f 上实际运行过:

  • npm run build —— 通过
  • npm run typecheck —— 通过
  • `npm run lin

Run log: https://github.com/QwenLM/qwen-code/actions/runs/32670233705


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run.

中文说明

🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。

@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 — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Test Plan (not a blocker): src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 21070, 1685, 1654, 495, 4190, 610 passed; 16 passing — this review observed 21070, 1685, 1654, 495, 4190, 610 passed.

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

  • packages/core/src/config/config.ts:5526 — [review] Output-style layer has no producer — the entire surface added by this PR is staged and unwired
  • packages/core/src/core/output-styles.ts:161 — [review] Turn-reminder mechanism exported, tested and documented as live, but no production consumer
  • packages/core/src/core/output-styles.ts:12 — [review] OutputStyleSource ships three never-populated variants; docs advertise contracts to nonexistent consumers
  • packages/core/src/core/output-styles.test.ts:50 (+2 locations) — [review] Test text states the inverse of keepCodingInstructions semantics
  • packages/core/src/core/prompts.ts:517 (+2 locations) — [probe] Dump-rationale comments teach a nonexistent double-application
  • packages/core/src/core/prompts.test.ts:769 — [probe] Styled dump test discards the returned prompt; styled-return invariant unpinned
  • packages/core/src/core/prompts.ts:520 — [probe] Dump bakes interaction-mode wording into a file declared reusable across modes
中文说明

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

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

Test Plan(非阻断):src/core/output-styles.test.tsno such file or directory; src/core/prompts.test.tsno such file or directory; src/core/client.test.tsno such file or directory; 479 tests pass — this review observed 21070, 1685, 1654, 495, 4190, 610 passed; 16 passing — this review observed 21070, 1685, 1654, 495, 4190, 610 passed

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

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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix round: no action required on PR #9565

No commit was made this round. HEAD (c99e3aced6) is clean and matches the commit the review covered; there is no base conflict.

Why no change

No actionable feedback arrived since the last evaluation (2026-08-23T22:07:50Z):

  • The only new review (rv:5003932771, automated reviewer) is COMMENTED, and its ledger reports 0 new findings (round 11, floor c, 0 posted). It is a review-coverage disclosure, not a request for changes.
  • No failed checks. Every check on the head commit is green or skipped by workflow design. The previously red Test (ubuntu-latest, Node 22.x) now passes: that failure was caused by a broken workflow-size baseline on main (unrelated to this PR), fixed upstream in fix(ci): record cd-cua-driver.yml's shipped size in the workflow size baseline #9822, and brought into this branch by the base update (merge commit c99e3aced6).
  • No new inline review comments and no maintainer comments. The two issue-level comments in this window are status notices from the workflow's own dev-bot (a stop/handoff notice and the base-update notice) — not feedback.

Points checked that needed no code change

  • Disclosed gap — "Integration Tests (CLI, No Sandbox)" was not covered. The check is SKIPPED by workflow design on this run (confirmed in the check-run data), not failing. Enabling it is CI machinery outside this PR's footprint, an area this round must not touch. All runnable checks of the Test job passed on the head commit.
  • Test Plan notes (explicitly "not a blocker"). The reviewer reported src/core/output-styles.test.ts, src/core/prompts.test.ts, and src/core/client.test.ts as "no such file or directory". Verified: all three files exist at packages/core/src/core/...; the test-plan paths are package-relative, matching this repository's convention of running individual tests from within the package directory (cd packages/core && npx vitest run src/core/...). The pass-count discrepancy is a PR-description artifact, which this workflow cannot edit. Neither note implies a working-tree change.
  • Seven deferred findings (convergence posture, round 11). The automated reviewer explicitly recorded them as "recorded, not requested in this round" — the whole-surface wiring questions among them are product/scope decisions. They stay in the review ledger for future rounds and maintainer direction; this round deliberately does not touch them.

Verification

No verification commands were run because no code change was made; the head commit is the exact one CI already validated (all runnable checks green).

中文说明

Autofix 本轮:PR #9565 无需处理

本轮未产生任何提交。HEAD(c99e3aced6)工作区干净,与本次审查所覆盖的提交完全一致;与 base 分支无冲突。

为什么没有改动

自上次评估(2026-08-23T22:07:50Z)以来,没有收到任何需要处理的反馈:

  • 唯一的新审查(rv:5003932771,自动审查器)状态为 COMMENTED,其台账报告显示 0 条新发现(第 11 轮,下限 c,发布 0 条)。它只是审查覆盖面的披露,并非改动要求。
  • 没有失败的检查。 头提交上的所有检查要么为绿色,要么因工作流设计而跳过。此前变红的 Test (ubuntu-latest, Node 22.x) 现已通过:那次失败是 main 上损坏的 workflow 体积基线所致(与本 PR 无关),已在上游 fix(ci): record cd-cua-driver.yml's shipped size in the workflow size baseline #9822 中修复,并通过 base 更新(合并提交 c99e3aced6)带入本分支。
  • 没有新的行内审查评论,也没有维护者评论。 本窗口内的两条 issue 级评论均来自工作流自身的 dev-bot(一条停止/交接通知和一条 base 更新通知)——不属于反馈。

已核查但无需改代码的要点

  • 已披露的缺口 —— "Integration Tests (CLI, No Sandbox)" 未被覆盖。 该检查在本次运行中因工作流设计而 SKIPPED(已在 check-run 数据中确认),并非失败。启用它属于本 PR 足迹之外的 CI 机制,是本轮不允许触碰的区域。Test 任务中所有可运行的检查在头提交上均已通过。
  • Test Plan 备注(明确标注"非阻断")。 审查器报告 src/core/output-styles.test.tssrc/core/prompts.test.tssrc/core/client.test.ts "no such file or directory"。已核实:三个文件均存在于 packages/core/src/core/...;测试计划中的路径是相对包目录的,与本仓库"在包目录内运行单个测试"的约定一致(cd packages/core && npx vitest run src/core/...)。通过数量的出入是 PR 描述文本层面的问题,而本工作流无法编辑 PR 描述。两条备注均不意味着需要改动工作区代码。
  • 七条延后发现(收敛姿态,第 11 轮)。 自动审查器已明确将其记录为"已记录,本轮不要求修改"——其中关于整个功能面尚未接线的问题属于产品/范围决策。它们保留在审查台账中,留待后续轮次与维护者决定;本轮刻意不去触碰。

验证

由于没有做任何代码改动,本轮未运行任何验证命令;头提交正是 CI 已验证过的那个提交(所有可运行的检查均为绿色)。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@wenshao

wenshao commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 24, 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: 114 passed · 0 failed · 114 total

Flakiness gate: ✅ 5 changed test file(s) x 5 identical rounds, no divergence

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

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

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

抖动门:✅ 5 changed test file(s) x 5 identical rounds, no divergence

Verification report

PR 9565 Deep Verification (follow-up round) — feat(core): add the output-style layer to the system prompt

Verdict: merge-ready — 114 scripted assertions executed, 114 pass / 0 fail.
Verified head: c99e3aced6f20b7bdd352462256d833404372a23 (merge commit
c2c349e533, base tip 3a1f86d8056cb1bec689ea71ba6590c1d9e43041).
Follow-up round over the previous report (verified head there: 90e4784e…,
base tip 7f2c4416…, verdict merge-ready, 52/52). Every carried-forward
measurement was re-run at the new head; nothing was diffed from the old
report.

中文摘要
  • 结论:merge-ready。114 个脚本化断言全部通过,0 失败。这是跟进轮:上一轮在旧 head(90e4784e)上判定可合入;本轮在新 head(c99e3ace,base 更新至 3a1f86d8)上全部重新测量,未沿用任何旧数字。
  • 上轮发现的状态(详见状态表):① 文档注释过时(nit)→ 已修复ee29373d,注释已改为 # Output Style: <name>);② 描述称 arena 不继承风格、代码实际继承 → 仍成立(描述未更新,代码未变,变异 M7 重新钉住);③ 描述中的测试计数过时 → 仍成立(重测:受影响的 5 个测试文件 532 通过,PR 新增 30 个测试块)。
  • A/B 结论:48 个默认路径单元格(3 交互模式 × 4 模型 × 有无 memory × 有无 append)base 与 head 编译产物逐字节一致(sha 前 16 位 2812d89d98cb7514,长度 24114,与上轮一致);42 个风格单元格(分层位置、identity 句式、两条覆盖优先级、导出文件纯净性、keepCodingInstructions 收窄、headless 排除 Learning、registry 语义)全部通过。变异周期后重跑仍 90/90。
  • 变异矩阵:8/8。逐一还原每个守卫(identity 覆盖下丢风格、参数删除/取值置空、覆盖上叠风格、风格烘焙进导出、整段 base 被丢、headless-Learning 排除移除、arena 不再接收风格),每一次都恰好使钉住它的测试失败;阳性对照触发 16 个失败,管线有效。
  • 门禁:串行(逐文件)门禁 5/5 绿(514 core + 18 cli),变异周期后重跑仍绿;tsc --build(core+cli)0 错误并做了活性验证。注意:并行门禁首轮出现一次 15s 超时(未改动的 arena 生命周期测试),经归属测量判定为负载诱导(base 侧同跑通过、单独运行通过、后续两轮通过、冷转换缓存+超额订阅所致),不计入断言,详见门禁节与未覆盖节。
  • findings:一条轻微项 —— getBuiltInOutputStyle 对非字符串入参在 name.trim() 抛 TypeError;当前无生产调用点(选择入口在后续 PR),供接线时注意。
  • 未覆盖:风格文案未经真实模型评估(无选择入口,真实会话不可达,PR 自述);逐 commit 归因不可达(shallow depth 2,12 个 commit 仅 1 个本地可达,验证的是聚合 diff);base 侧完整套件未跑(由 A/B 与 base 并行门禁覆盖);turn-reminder 注入、system/init.output_style、claude-converter outputStyles 均未接线(diff 未触及,PR 自述)。

Previous-finding status (follow-up round)

# Finding at previous head 90e4784e Severity Status at new head c99e3aced6
1 Stale doc comment on OutputStyleDefinition.prompt (output-styles.ts:27 still said `# <Name> Style Active`) nit fixed — commit ee29373d; the comment now reads rendered under the `# Output Style: <name>` heading. Re-measured: grep -rn "Style Active" packages/ finds zero matches in output-styles.ts; the only remaining hit is a prose comment in prompts.ts ("With a style active the identity points at it"), not a heading reference
2 Correction: PR body says arena runs "deliberately do not inherit" the style, but the code passes it through correction stands — the PR body is unchanged and so is the code: ArenaManager.ts still passes this.config.getOutputStyle() into the worker prompt ('headless' mode, so Learning is excluded there), and the renamed test builds the in-process worker prompt with headless mode and the active style still pins it (mutation M7 re-proves the test load-bearing)
3 Correction: stale test counts in the body ("479 tests pass, 24 of them new"; contextCommand "16 passing") correction stands — re-measured at the new head: the five affected suites pass 532 tests (prompts 109, output-styles 15, client 362, ArenaManager 28, contextCommand 18); the PR adds 30 new test blocks (12+15+1+2 per file vs base) and renames/extends one arena test. Body numbers unchanged since round 1

Round-1's Not covered note on this container's node_modules drift
(missing packages/core/node_modules/ajv@8, forcing the base build to carry
two pre-existing type errors) no longer applies: this container ships the
lockfile-correct per-package deps (ajv@8.20.0, ignore@7.0.5 under
packages/core/node_modules), the base arm now builds with tsc --build
exit 0, and the head typecheck gate runs clean below.

Central claim and A/B proof

Central claim: when a style is selected it lands at the tail of the
stable base layer (after the mandates, ahead of every context/volatile
layer), the two overrides win where the PR says they do, and with nothing
selecting a style the prompt is byte-identical to before.

The A/B drives the compiled dist/ output of both builds (no mocks):
BASE = tmp/base-tree worktree at HEAD^1 rebuilt with the same
tsc --build the head build uses, HEAD = the CI-built packages/core/dist.
Cells use real env vars and real temp files; executed twice (before and
after the mutation cycle), 90/90 both times. Witness:
01-ab-byte-identity-and-style-cells.png (full 93-line run); raw logs
logs/ab-run1.log, logs/ab-run2-post-mutation.log.

# Cell Oracle base head
P1 48 default cells: {interactive, headless, acp} × {∅, qwen3-coder-7b, qwen-vl-max, gpt-4} × {∅, memory} × {∅, append} byte equality 48/48 identical (sha 2812d89d98cb7514, len 24114)
S1 Concise, interactive, memory+append markers # Core Mandates < style < memory < append n/a (feature absent) pass (5 checks)
S2 identity sentence plain keeps SE wording; styled points at "Output Style" and drops the SE wording n/a pass (3)
S3 QWEN_SYSTEM_MD override + style override verbatim, style absent, base arm byte-identical to head arm (sha 16de9ace…) override semantics unchanged pass (4)
S4 QWEN_WRITE_SYSTEM_MD dump + style dump unstyled; returned prompt styled; dump ≡ default prompt (sha 2812d89d…); base dump == head dump pass (4)
S5 QWEN_SYSTEM_IDENTITY_MD + style override verbatim at start, styled sentence skipped, style section lands; base==head no-style symmetry (sha 0f49a619…) n/a pass (4)
S6 keepCodingInstructions:false SE section heading + Key-Principle text gone; Core Mandates / Executing actions with care / Using Your Tools / Tone and Style all survive n/a pass (7)
S7 Learning × {headless, interactive, acp}; Concise × headless headless drops Learning only n/a pass (4)
S8 absence controls no # Output Style: <name> heading in any default head prompt (all 4 names) pass (via P1 byte equality) pass (4)
S9 registry exactly the 4 documented styles; case-insensitive + trimmed lookup; unknown → undefined; generic vs custom turn reminder; heading contract n/a pass (7)

Harness: ab-harness.mjs (90 scripted checks, exit 0).

Closure audit (required before trusting a base control in a monorepo):
closure-audit.mjs walked the base prompts.js import closure — 11 modules,
all under tmp/base-tree, and exactly one external package
(@opentelemetry/api) plus node builtins; zero @qwen-code/* workspace
imports
, so no base cell can silently load changed head code through the
shared node_modules. The realpath cross-check shows why the audit matters:
readlink -f tmp/base-tree/node_modules/@qwen-code/qwen-code-core
/__w/qwen-code/qwen-code/packages/core (the head tree).

Delta since the previous round

  • ee29373d "fix(core): align output-style doc comment and Concise
    description": fixes nit pre-release: fix ci #1 above; the Concise description now reads
    "Answers first, with no preamble, narration, or closing recap — the work
    stays as thorough as ever" (matches the PR body's wording). Description
    strings are picker UI text — the suite pins them non-empty, not verbatim,
    so no behavioral cell applies. (The commit itself is unreachable at
    depth 2; both facts measured against the current tree.)
  • Four bot merges of main into the branch. git diff HEAD^2..HEAD is
    empty — the merge-ref merge added nothing, because the branch's last
    merge of main (committed 23:35:40Z) postdates the main tip 3a1f86d8
    (23:33:12Z) by ~2.5 minutes. The verified tree is exactly main tip + the
    12-file PR diff: git diff HEAD^1..HEAD lists precisely the 12 PR files,
    so no conflict resolution could have silently dropped main-side content
    anywhere else. One extra test arrived via main into client.test.ts
    (361 → 362 vs the previous round); the PR's own test delta is unchanged
    (30 new blocks).

Mutation matrix (vacuity of the new tests)

Each row reverts one guard of the PR in the head tree, runs the four
affected core files serially (M2/M2b also the cli file through a rebuilt
dist), and compares the failing-test set against the expected set —
scripted in mutation-runner.mjs + postprocess-matrix.mjs (vitest emits
full describe breadcrumbs; verdicts are suffix-matched). Tree restored and
verified clean after every row (git status --porcelain empty). Witness:
02-mutation-matrix-adjudicated.png; per-mutation logs logs/mut-M*.log.

Mut Guard reverted Failing test(s) Result
M1 style append skipped under QWEN_SYSTEM_IDENTITY_MD override keeps the style section under a QWEN_SYSTEM_IDENTITY_MD override exact (1 failed | 513 passed across the 4 files)
M2 drop config.getOutputStyle() in getMainSessionBaseSystemPrompt (argument removed) 6 tests: the new client plumbing test, the 4 pre-existing mode/append call-shape expectations the PR updated to the 5-arg form, and cli bills the active output style… fully accounted (5 client + 1 cli)
M2b same site, shape preserved (config.getOutputStyle()undefined) passes the active output style to the core system prompt + bills the active output style into the system-prompt estimate exact (2) — isolates the value flow through both consumers
M3 style layered onto QWEN_SYSTEM_MD override is ignored when QWEN_SYSTEM_MD replaces the base prompt exact
M4 style baked into QWEN_WRITE_SYSTEM_MD dump does not bake the style into the QWEN_WRITE_SYSTEM_MD dump exact
M5 keepCodingInstructions:false drops the whole base (commit-1 behavior: safety rules lost) drops only the software-engineering section for keepCodingInstructions: false exact
M6 headless-Learning exclusion removed omits Learning from headless prompts that cannot receive a reply exact
M7 arena worker prompt no longer receives the style builds the in-process worker prompt with headless mode and the active style exact
M8 positive control: mutate the default identity string 16 tests incl. the base-prompt snapshot pins (should return the base prompt when no userMemory is provided, …) and model-specific format tests CONTROL-CAUGHT

M1, M3–M7 each fail exactly the test that pins the reverted guard; M2's
two variants together prove both the argument's existence (6 call-shape
assertions react) and its value flow (exactly the 2 style-value tests react
when the shape is preserved). M8 (landed in the same file as the mutants)
proves the vitest command collects failures at all. Failure messages quote
expected-vs-actual values, so the reds are behavioral, not import/compile
breakage. Baseline (unmutated head) was green before the matrix: 514 core +
18 cli.

Targeted gates

Gate Result Witness
Serial gate @​ head: prompts + output-styles + client + ArenaManager (core) + contextCommand (cli), executed twice (matrix baseline + post dist-rebuild rerun) 109+15+362+28 = 514/514, 18/18 — green both executions 03-gate-head-serial.png, logs/gate-core-head.log, logs/gate-cli-head.log, logs/gate-rerun-stderr.log (exit 0)
Typecheck @​ head: tsc --build core + cli exit 0, no errors; liveness proven — a planted const x: number = "not a number" in output-styles.ts produced error TS2322 at the planted line, then restored to clean command output quoted here
Base-arm parallel gate (attribution control): prompts + client + ArenaManager at HEAD^1 486/486 pass (ran twice, green both times) logs/gate-base-parallel.log; base dist built tsc --build exit 0 (logs/base-build.log)
Parallel 4-file regime @​ head, 3 rounds round 1: 1 failureArenaManager > active session lifecycle > collects diff summaries and fallback approach summaries, Error: Test timed out in 15000ms; rounds 2–3: 4 passed (4); arena file alone: 28/28 logs/gate-core-parallel-r1.log, 04-parallel-round1-arena-timeout.png

The round-1 parallel timeout is attributed to container load, not to this
PR.
Evidence: the test is byte-identical at base and untouched by the diff
(the PR's only arena-test change is the renamed style test); the identical
3-file parallel run at base passes with the test at 1004 ms; the same head
invocation passes in rounds 2–3 and standalone; and round 1 was also the
cold transform-cache run (arena file 19 s vs 5 s standalone). The repo's own
vitest.config.ts documents the regime — testTimeout: 15000 exists because
"the self-hosted CI runners are heavily oversubscribed" — and even that
raised ceiling was exceeded once under 4-file contention. One PR-adjacent
note for completeness: this PR adds the fourth file to that parallel pool
(output-styles.test.ts), which marginally increases contention; the root
cause is the test's margin under contention, not the new file. Because the
failure is proven environmental (base-arm and warm-state controls above)
rather than PR-caused, it is reported here and not counted in
assertions.json; the mutation matrix deliberately uses serial runs so its
failing-set attribution is load-independent.

Findings

Nit (informational, for the follow-up wiring PR): getBuiltInOutputStyle throws on non-string input

getBuiltInOutputStyle(name) calls name.trim() unconditionally;
undefined/null/number/object inputs throw TypeError (probed against
the built dist). All string shapes behave: exact/case-insensitive/trimmed
lookup, '' and NUL-padded strings return undefined cleanly. Today there
are zero production call sites (measured: only tests and the definition
reference it; no code populates the outputStyle ConfigParameters slot or
calls Config.setOutputStyle — the setOutputStyle in packages/sdk-java
is the Java SDK's own unwired protocol-message field, a separate surface),
so this cannot fire in a session — but the follow-up PRs that wire the
settings key / CLI flag parse untrusted text into this function and should
guard at that boundary. Not a merge blocker; no suite can pin it either way
at this commit.

Not covered

  • Live-model behavior of the style texts. Nothing selects a style yet
    (confirmed at the new head: no production caller of setOutputStyle, no
    source of the outputStyle ConfigParameters slot), so the prompts were
    never evaluated against a model. The harnesses reproduce wiring and
    layering, not model-side effects. Declared out of scope by the PR.
  • Per-commit attribution. Depth-2 checkout: git rev-list HEAD^1..HEAD^2
    reaches 1 commit, the metadata lists 12. Verified the aggregate
    HEAD^1..HEAD diff; per-commit claims (e.g. exactly what ee29373d
    changed beyond the two measured facts) were not exercised.
  • Base-side full test suite. Base behavior is covered by the A/B cells
    and the 486-test base-arm parallel gate; running the entire base suite in
    the worktree was not budgeted.
  • Repo-wide gates. Only the two affected workspaces (packages/core,
    packages/cli) were gated — tests, typecheck, build. No repo-wide lint
    run in this round (PR's own CI covers it; round 1 ran eslint/prettier per
    the author).
  • Parallel-pool flake fully characterized across many rounds — 3 head
    rounds + 1 base round + 1 standalone run; a full flake-gate sweep (5×5)
    is the workflow's own lane.
  • Turn-reminder injectiongetOutputStyleTurnReminder() verified at
    render level only (S9-5/S9-6 and the suite); the injection site lands in a
    follow-up PR (declared). Re-measured at the new head: still no injection
    call site.
  • system/init.output_style wire field and claude-converter
    outputStyles
    — remain unwired exactly as declared (the diff touches
    neither file; both files confirmed absent from git diff HEAD^1..HEAD).

Methodology

Environment: CI verify container (node:22-bookworm, Node v22.23.2, npm
10.9.8), merge-ref checkout at depth 2 (HEAD merge commit c2c349e5,
HEAD^1 base tip 3a1f86d8, HEAD^2 verified head c99e3aced6;
$QWEN_VERIFY_CONTEXT metadata + previous report treated as untrusted
input). npm ci + npm run build pre-ran at head. Base arm:
git worktree add tmp/base-tree HEAD^1, core rebuilt with the root
workspace's tsc --build (exit 0) after symlinking the root and
per-package node_modules into the worktree so dependency resolution is
byte-identical to the head build — the PR changes no lockfile (0-line diff
on all package.json/package-lock.json), making that a clean control.
The emitted base dist was closure-audited (script above; only external
import @opentelemetry/api; zero workspace links in the loaded path). The
A/B harness drives compiled dist/ modules by absolute-path import with
real env vars (QWEN_SYSTEM_MD, QWEN_WRITE_SYSTEM_MD,
QWEN_SYSTEM_IDENTITY_MD) and real temp files — no stubs of code under
test. Mutations were applied by exact string replacement with a uniqueness
guard (mutate.mjs, all 8 anchors pre-verified count==1), run against the
source through vitest (as the suites themselves run), with M2/M2b's cli arm
crossing into a freshly rebuilt dist exactly the way packages/cli consumes
core in production; every row restored via git checkout -- plus a scripted
clean-tree check, and the A/B harness re-executed after the final rebuild
(90/90) to prove dist integrity. Evidence images produced with
scripts/verify-capture.mjs. Raw per-cell, per-mutation and per-gate logs
live in logs/; harness scripts (ab-harness.mjs, closure-audit.mjs,
mutations.mjs, mutate.mjs, mutation-runner.mjs,
postprocess-matrix.mjs, m2b-run.mjs, gate-run.mjs) are in this
directory and rerunnable.

Flakiness gate log

rounds=5 files=5 skipped=0
file packages/cli/src/ui/commands/contextCommand.test.ts: (cd packages/cli) npx --no-install vitest run ./src/ui/commands/contextCommand.test.ts
file packages/core/src/agents/arena/ArenaManager.test.ts: (cd packages/core) npx --no-install vitest run ./src/agents/arena/ArenaManager.test.ts
file packages/core/src/core/client.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/client.test.ts
file packages/core/src/core/output-styles.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/output-styles.test.ts
file packages/core/src/core/prompts.test.ts: (cd packages/core) npx --no-install vitest run ./src/core/prompts.test.ts


per-file results (P=pass F=fail I=infra-exit, one letter per run):
  packages/cli/src/ui/commands/contextCommand.test.ts: PPPPP
  packages/core/src/agents/arena/ArenaManager.test.ts: PPPPP
  packages/core/src/core/client.test.ts: PPPPP
  packages/core/src/core/output-styles.test.ts: PPPPP
  packages/core/src/core/prompts.test.ts: PPPPP

verdict: pass
summary: 5 changed test file(s) x 5 identical rounds, no divergence

--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/ui/commands/contextCommand.test.ts: P (exit 0)
round 1 · packages/core/src/agents/arena/ArenaManager.test.ts: P (exit 0)
round 1 · packages/core/src/core/client.test.ts: P (exit 0)
round 1 · packages/core/src/core/output-styles.test.ts: P (exit 0)
round 1 · packages/core/src/core/prompts.test.ts: P (exit 0)
round 2 · packages/cli/src/ui/commands/contextCommand.test.ts: P (exit 0)
round 2 · packages/core/src/agents/arena/ArenaManager.test.ts: P (exit 0)
round 2 · packages/core/src/core/client.test.ts: P (exit 0)
round 2 · packages/core/src/core/output-styles.test.ts: P (exit 0)
round 2 · packages/core/src/core/prompts.test.ts: P (exit 0)
round 3 · packages/cli/src/ui/commands/contextCommand.test.ts: P (exit 0)
round 3 · packages/core/src/agents/arena/ArenaManager.test.ts: P (exit 0)
round 3 · packages/core/src/core/client.test.ts: P (exit 0)
round 3 · packages/core/src/core/output-styles.test.ts: P (exit 0)
round 3 · packages/core/src/core/prompts.test.ts: P (exit 0)
round 4 · packages/cli/src/ui/commands/contextCommand.test.ts: P (exit 0)
round 4 · packages/core/src/agents/arena/ArenaManager.test.ts: P (exit 0)
round 4 · packages/core/src/core/client.test.ts: P (exit 0)
round 4 · packages/core/src/core/output-styles.test.ts: P (exit 0)
round 4 · packages/core/src/core/prompts.test.ts: P (exit 0)
round 5 · packages/cli/src/ui/commands/contextCommand.test.ts: P (exit 0)
round 5 · packages/core/src/agents/arena/ArenaManager.test.ts: P (exit 0)
round 5 · packages/core/src/core/client.test.ts: P (exit 0)
round 5 · packages/core/src/core/output-styles.test.ts: P (exit 0)
round 5 · packages/core/src/core/prompts.test.ts: P (exit 0)

Evidence images

01-ab-byte-identity-and-style-cells

02-mutation-matrix-adjudicated

03-gate-head-serial

04-parallel-round1-arena-timeout

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

Qwen Code · sandboxed 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.

LGTM, looks ready to ship. ✅

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix round: no action required on PR #9565

No commit was made this round. HEAD (c99e3aced6) is clean, matches origin/feat/output-styles, and there is no base conflict (--conflict false).

Why no change

Point by point, against the feedback prepared for this round:

  • Reviews: none newer than the last evaluation. Nothing to address.
  • Inline comments: none newer than the last evaluation. Nothing to address.
  • Issue-level comments: the single new item (ic:5390027295) is the CI bot's status notification that sandboxed verification is running. It is an informational marker for the verification workflow itself — it contains no findings, requests no changes, and will be followed by the verification report when the run completes. There is nothing for a code change to respond to.
  • Failed checks: none. All completed checks on the PR are green (SUCCESS); the rest are SKIPPED by design. The previously red Test (ubuntu-latest, Node 22.x) check passes on current main after the base update.
  • Deferred non-Critical feedback / growth audit: no such sections present this round; nothing is gated.

The loop remains engaged and will pick up the verification report, any new maintainer or automated-reviewer feedback, and any future base conflict in later rounds.

中文说明

Autofix 本轮:PR #9565 无需改动

本轮没有产生提交。HEAD(c99e3aced6)处于干净状态,与 origin/feat/output-styles 一致,且不存在 base 冲突(--conflict false)。

为什么无需改动

针对本轮准备的反馈,逐点说明:

  • Reviews(评审):上次评估之后没有新的评审。无需处理。
  • Inline comments(行内评论):上次评估之后没有新的行内评论。无需处理。
  • Issue-level comments(Issue 级评论):唯一的新条目(ic:5390027295)是 CI 机器人发布的通知,说明沙箱验证正在运行。它是验证流程自身的信息性标记——不包含任何发现、不请求任何改动,且运行完成后会跟进发布验证报告。没有任何需要代码改动来响应的内容。
  • Failed checks(失败的检查):无。PR 上所有已完成的检查均为绿色(SUCCESS);其余检查按设计为 SKIPPED。此前红色的 Test (ubuntu-latest, Node 22.x) 检查在 base 更新后已在当前 main 上通过。
  • Deferred non-Critical feedback(延迟处理的非 Critical 反馈)/ growth audit(增长审计):本轮没有这些部分;没有任何事项被门控。

循环保持启用状态,后续轮次会处理验证报告、任何新的维护者或自动评审反馈,以及任何未来出现的 base 冲突。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@wenshao

wenshao commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Maintainer-local verification: ✅ passed — merge-ready (agent verdict, independent round)

Ran an independent local verification round on the same head the latest CI sandbox round verified (c99e3ace, 114/114 earlier today): macOS + Node v24 arm, an independently written A/B harness whose numbers agree with the CI round's, a 4-mutation vacuity re-check, and — new since that round — merge-forward verification against current main, which advanced twice during this round and has already touched 4 of this PR's 12 files. The merge is conflict-free and the merged tree passes everything.

72 scripted assertions: 72 pass · 0 fail. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

中文 — 判定:✅ 通过 · 可合入(维护者本地独立验证轮)

在与最新一轮 CI 沙箱验证相同的 head(c99e3ace)上执行的维护者本地独立验证:macOS + Node v24 臂、独立实现的 A/B harness(49/49,默认提示词 sha 与 CI 轮 Linux 容器逐字节一致)、变异矩阵 4/4 击杀、门禁全绿(head core 514/514、cli 18/18、typecheck 0 错),并新增 对当前 main 的前向合并验证(main 本轮内两次前进且已动过本 PR 12 个文件中的 4 个;合并无冲突,合并树 518/518 + 18/18,默认提示词仍逐字节不变)。三项遗留发现:文档注释已修复,两条描述类 correction 仍成立。仅作评审证据,不构成评审、批准或 CI 检查。

Verification report

PR 9565 Local Deep Verification (maintainer round, macOS) — feat(core): add the output-style layer to the system prompt

Verdict: merge-ready — 72 scripted assertions executed, 72 pass / 0 fail.
Verified head: c99e3aced6f20b7bdd352462256d833404372a23 (recorded base 3a1f86d8056cb1bec689ea71ba6590c1d9e43041).

This is an independent maintainer-local round at the same head the latest CI
sandbox round verified (2026-08-24 02:30 UTC, 114/114, merge-ready). It was
not required by a head move; its added value is (a) a second OS/compiler arm —
macOS + Node v24.18.1 vs the CI container's Linux + Node v22 — (b) an
independently written A/B harness whose numbers agree with the CI round's,
(c) a 4-mutation re-run of the vacuity checks, and (d) merge-forward
verification against current main, which moved twice during this round

(3a1f86d4d3f9ff501416830c9): main has touched 4 of this PR's
12 files since the recorded base, so the conflict-free merge below is
information the CI round could not have.

中文摘要
  • 结论:merge-ready。72 个脚本化断言全部通过,0 失败。这是与最新一轮 CI 沙箱验证(同 head c99e3ace,114/114)相互独立的维护者本地验证:macOS + Node v24 臂、独立编写的 A/B harness、4 项变异复跑,以及 对当前 main 的前向合并验证(本轮期间 main 从 3a1f86d 两次前进到 01416830,且 main 已动过本 PR 12 个文件中的 4 个)。
  • A/B 结论:默认(无风格)提示词在 head/base/合并树三方逐字节一致(sha 前 16 位 2812d89d98cb7514,长度 24114),且与 CI 轮 Linux 容器测得的数值完全相同——跨机器交叉印证。风格生效时:段落落在 # Core Mandates 之后、context/append 层之前,且位于缓存静态前缀内(记忆保存不再使前缀失效);QWEN_SYSTEM_MD 覆盖时风格被忽略;QWEN_WRITE_SYSTEM_MD 导出保持纯净;keepCodingInstructions:false 只删 SE 一节,安全条款全部保留;headless 仅丢弃 Learning;base 臂第 5 参数被忽略(对照成立)。
  • 变异矩阵:4/4 全部击杀 + 对照绿。M1(不再叠加风格)恰好击杀 6 个测试;M2/M3/M4 各恰好击杀 1 个对应测试。
  • 门禁:head core 514/514、cli 18/18、typecheck 0 错(含活性验证);base 归因门禁 486/486;合并树(main@0141683 + PR)core 518/518、cli 18/18,合并无冲突,合并增量恰好等于 PR 的 12 文件,合并后默认提示词仍逐字节不变。
  • 遗留发现状态:① Style Active 注释过时(nit)→ 已修复;② 「arena 不继承风格」的提交说明与代码不符 → 仍成立(correction);③ PR 正文测试计数过时(自述 479/24,实测 532/30)→ 仍成立(correction)。getBuiltInOutputStyle 非字符串入参抛 TypeError 的轻微项依旧存在(信息性,当前无生产调用点)。
  • 未覆盖:风格文案未经真实模型评估(无选择入口,结构性不可达——setOutputStyle 非测试调用方为零已复核);逐 commit 归因(验证聚合 diff);repo 级 lint;Windows 臂;完整 base 套件。

Previous-finding status (carried from the CI round at the same head)

# Finding Severity Status in this round
1 Stale doc comment (# <Name> Style Active) on OutputStyleDefinition.prompt nit fixed — re-measured: grep -rn "Style Active" packages/core/src → 0 matches (scripted, check F1)
2 Commit-message claim "subagents and arena runs deliberately do not inherit" vs code passing the style to arena workers correction standsArenaManager.ts:1092 still passes this.config.getOutputStyle(); the renamed arena test still pins it (scripted, check F2). Description-level only; subagents indeed do not inherit (agent-core builds prompts from per-agent promptConfig.systemPrompt)
3 Stale test counts in the PR body ("479 tests pass, 24 of them new"; contextCommand "16 passing") correction stands — measured 514 (4 core files) + 18 (cli) = 532, with 30 new tests vs base (28 across the core files — 486→514 including the new 15-test file — plus 2 in cli, 16→18); body numbers unchanged (scripted, check F3)
getBuiltInOutputStyle throws TypeError on non-string input (round-2 nit) nit persists — re-probed against dist: undefined/null/42 all throw; '' returns undefined cleanly (harness cell T). Zero production call sites today (census re-run: no non-test caller of setOutputStyle, no writer of the outputStyle config slot, output_style appears only as type declarations). Informational; the follow-up wiring PR should guard at its parse boundary

Central claim and A/B proof

Central claim: a selected style lands at the tail of the stable base
layer (after the mandates it refines, ahead of every context/volatile layer,
inside the cacheable static prefix), both override mechanisms win where the
PR says they do, and with nothing selecting a style the prompt is
byte-identical to before.

Independent harness (harnesses/ab-prompt.mjs + adjudicate-ab.mjs): drives
the compiled dist/ of both trees by absolute-path import, uses the real
built-in style objects on head (a literal definition on base, where the
concept does not exist), and sets QWEN_SYSTEM_MD / QWEN_SYSTEM_IDENTITY_MD
/ QWEN_WRITE_SYSTEM_MD through real environment variables and real temp
files. 49/49 scripted assertions pass. Witness:
01-ab-adjudication-macos.png (full 49-line adjudication).

Cell group Oracle base head
A default (interactive / headless / model variant) sha256 equality 2812d89d98cb7514 ×3 identical ×3 (len 24114; headless 7ea4e2b698f461b7 on both)
B style via 5th param section lands; identity switches arg ignored, sha == default (control) section + styled identity present, SE wording gone
C layer order # Core Mandates < style < contextFiles < append n/a pass (3/3)
D QWEN_SYSTEM_MD + style override verbatim, style absent override verbatim (no regression) pass (2/2)
E QWEN_WRITE_SYSTEM_MD + style returned styled, dump pure dump == default base pass (4/4, dump sha == default sha == base-arm dump sha)
F keepCodingInstructions:false SE section gone; Mandates / Executing actions with care / Using Your Tools / Tone and Style / reminder bullet survive SE kept (control) pass (8/8)
G Learning × modes headless drops Learning only n/a pass (3/3)
H turn reminders well-formed; Concise custom; Explanatory generic n/a pass (3/3)
I identity override + style override verbatim, styled sentence skipped, style survives override verbatim pass (4/4)
J cache boundary (mirror of client.ts stableLayers) style inside static prefix; prefix stable across a memory save; volatile tail outside prefix has no style (control); startsWith intact pass (5/5)
K combo (SE-dropping style × identity override) — not covered by the PR's tests all three behaviors hold simultaneously n/a pass (4/4)

The base arm's control cells (B3/B4, F1b, J1b) are what make the head cells
load-bearing: the same harness passing a real style value into the base build
changes nothing (2812d89d…), while the head build layers it.

Cross-machine corroboration: the default-prompt sha (2812d89d98cb7514,
24114 bytes) is byte-for-byte what the CI Linux round measured at the same
head — two independently built artifacts on two OS/toolchain arms agree.

Mutation matrix (vacuity re-check, macOS)

Each row reverts one guard in packages/core/src/core/prompts.ts (head
worktree) with a unique-anchor replacement, runs the two central test files,
restores, and verifies. Control (unmutated) green before the matrix. Witness:
02-mutation-matrix-macos.png.

Mut Guard reverted Result
M1 style never appended to the returned prompt killed — exactly 6 failures, precisely the style-landing tests (appends the style section, keeps the style ahead of the context and volatile layers, drops only the software-engineering section, keeps Learning in interactive/acp prompts, keeps the style section under a QWEN_SYSTEM_IDENTITY_MD override); the no-style/override/headless-omission tests correctly stay green
M2 style baked into the QWEN_WRITE_SYSTEM_MD dump killed — exactly 1 failure (does not bake the style into the QWEN_WRITE_SYSTEM_MD dump)
M3 Learning no longer dropped in headless killed — exactly 1 failure (omits Learning from headless prompts that cannot receive a reply)
M4 keepCodingInstructions:false no longer drops the SE section killed — exactly 1 failure (drops only the software-engineering section for keepCodingInstructions: false)

M1–M4 re-prove on this arm the same guards the CI round's matrix covered (its
style-append, dump-purity, headless-Learning and SE-section rows), with the
same exact-attribution property: each revert fails only the tests that
pin it.

Gates

Witness: 03-gates-summary-from-junit.png (parsed from the junit.xml the
runs emitted) and 04-merge-forward-gate.png (live re-run on the merged
tree).

Gate Result
head core affected suites (output-styles + prompts + client + ArenaManager, serial) 514/514
head cli contextCommand.test.ts 18/18
base-arm attribution gate (prompts + client + ArenaManager at 3a1f86d) 486/486 — head delta is exactly the PR's new tests
merged-tree core gate (main@01416830 + PR head) 518/518 (the +4 over head are tests main added to client.test.ts since the recorded base)
merged-tree cli gate 18/18
typecheck @Head (core, cli via built dist) exit 0 / exit 0; liveness proven — planted const x: number = "not a number" reported as TS2322 at output-styles.ts(188,7), restored to exit 0
workspace-link pins all @qwen-code/* links in each of the 3 trees resolve into that tree (scripted, per-tree realpath audit)

Merge-forward verification (new in this round)

main advanced 3a1f86d01416830c9 during the round and had touched 4
of the PR's 12 files
(config.ts 61 lines, client.ts 24, client.test.ts 169,
index.ts 2 — 231 insertions since the recorded base). Trial merge of the PR
head into main@01416830:

  • conflict-free; merged delta is exactly the 12 PR files (803 insertions /
    87 deletions — identical to the PR's own diff stat);
  • merged-tree default prompt still byte-identical (2812d89d98cb7514);
    style layering, SE-drop and Learning/headless cells unchanged;
  • affected suites on the merged tree: 518/518 core, 18/18 cli.

main is a fast-moving target (it moved again mid-round); the merge trial is
valid against 01416830c9 specifically.

Findings

None new. All 72 assertions passed; no regression reproduced; the three
carried-forward items are description/commit-message corrections (table
above), not code defects, and the round-2 TypeError nit remains informational
with zero production call sites (census re-verified at this head:
setOutputStyle has no non-test caller; output_style exists only as type
declarations in nonInteractive/types.ts and sdk-typescript protocol).

Not covered

  • Live-model behavior of the style texts — no selection surface exists
    (structural, re-verified by census), so no real session can carry a style;
    harnesses prove wiring/layering, not model-side effect. Declared out of
    scope by the PR.
  • Per-commit attribution — 13 commits; the verified unit is the aggregate
    base..head diff (plus the merge-forward tree).
  • Windows arm; author tested Linux, CI verified Linux, this round macOS.
  • Repo-wide lint / full suite — only the two affected workspaces gated;
    the PR's own CI covers the rest.
  • Full base-side suite — base covered by the A/B cells + 486-test
    attribution gate.
  • Environment note: per-tree npm ci emitted allow-scripts pending-approval
    warnings (some dependency postinstalls skipped by npm policy); all builds,
    tests and typechecks completed green regardless, and nothing on the
    verified paths depends on the skipped scripts.

Methodology

Maintainer laptop, macOS (darwin), Node v24.18.1, npm 11.16.0, machine load
average ≈ 120 from concurrent verification sessions — all suites run
serially for that reason (the CI round's load-attribution lesson,
applied). Three detached git worktrees under tmp/: head c99e3ace, base
3a1f86d, merge-forward main@01416830 + head; each installed with its own
npm ci from the shared lockfile (the PR changes no lockfile — its 12 files
contain none), and every @qwen-code/* workspace link asserted to resolve
inside its own tree (assert-pins.sh) so no arm can load another tree's
code. The A/B harness imports compiled dist/ modules by absolute path with
real env vars and temp files — no stubs of code under test; adjudication is a
separate script so expectations live in exactly one place. Mutations applied
by unique-anchor string replacement with restore + tree-clean verification.
Gates read from the junit.xml the runs emitted. Evidence rasterised with
scripts/verify-capture.mjs. All harnesses, logs and JSONs are rerunnable
from this artifact directory (harnesses/, logs/).

Qwen Code · maintainer-local verification round

Evidence images

01-ab-adjudication-macos

02-mutation-matrix-macos

03-gates-summary-from-junit

04-merge-forward-gate

Qwen Code · maintainer-local verification round

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

🤖 AutoFix review round: no code changes needed

Feedback triaged this round: a single issue-level comment — a maintainer-local deep-verification report on head c99e3ace (verdict ✅ pass / merge-ready, 72/72 scripted assertions, mutation matrix 4/4 killed, merge-forward against current main conflict-free). No reviews, no inline comments, no failed or still-red CI checks (all check runs on the head are SUCCESS or legitimately SKIPPED). The report is advisory evidence for human reviewers and requests no change.

The carried-over items it re-lists were each probed against the code before disposition (authorship adds no credibility — only execution evidence does):

# Item Disposition Evidence
1 Stale # <Name> Style Active doc comment on OutputStyleDefinition.prompt already fixed (prior round) case-sensitive search for Style Active across packages/core/src → 0 matches; the only remaining hit is the lowercase phrase "style active" in an explanatory comment in prompts.ts, which accurately describes the identity-sentence switch
2 Commit-message claim "subagents and arena runs deliberately do not inherit" while the code passes the style to arena workers declined — description-level correction with no fix available in this mode confirmed: ArenaManager.ts passes config.getOutputStyle() to arena workers and the renamed arena test pins it (the behavior is intentional). The inaccuracy lives in a historical commit message, and this workflow allows additive commits only — no amend/rebase/history rewriting — so there is no in-scope fix; subagents indeed do not inherit
3 Stale test counts in the PR body ("479 tests pass, 24 of them new"; contextCommand "16 passing") declined — description-level correction with no mechanism in this mode the report measured 532 tests across the touched suites with 30 new vs base; address-review mode publishes comments only — the PR body is owned by the PR-creation flow and is not an output this mode can update, and the agent holds no GitHub write access. The corrected counts are recorded here so the thread carries them
4 getBuiltInOutputStyle throws TypeError on non-string input (round-2 nit) deferred to the follow-up queue — real, but the fix lives in the future wiring PR, not this one confirmed at the source: name.trim() throws for non-strings. Caller census re-verified: every call site in the repo is a test file; setOutputStyle has no non-test caller, so no production path can reach it with a non-string today — guarding it now would be error handling for a condition that cannot occur. The verification report itself assigns the guard to the follow-up wiring PR's parse boundary, so the finding is recorded in the deferred-findings queue to survive merge

No code was changed and nothing was committed. The PR stays at c99e3ace with all CI checks green, awaiting human review/merge.

中文说明

🤖 AutoFix 评审轮:无需代码改动

本轮处理的反馈: 仅一条 issue 级评论 —— 维护者在 head c99e3ace 上执行的本地深度验证报告(结论 ✅ 通过 / 可合入:72/72 脚本化断言全部通过、4/4 变异全部击杀、对当前 main 的前向合并无冲突)。没有评审、没有行内评论、没有失败或持续飘红的 CI 检查(head 上所有 check run 均为 SUCCESS 或合理 SKIPPED)。该报告是供人类评审参考的佐证,未提出任何改动请求。

报告重新列出的各项遗留发现均已先探针核实、再定处置(来源不增减可信度,只有执行证据才算数):

# 事项 处置 证据
1 OutputStyleDefinition.prompt# <Name> Style Active 过时文档注释 已在先前轮次修复 packages/core/src 全量大小写敏感搜索 Style Active → 0 处匹配;唯一残留是 prompts.ts 一条解释性注释中的小写短语 "style active",其内容准确描述了身份句切换
2 提交说明称「子代理与 arena 运行刻意不继承风格」,而代码实际向 arena worker 传入风格 拒绝 —— 描述层面的更正,本模式无可用修复手段 已确认:ArenaManager.ts 向 arena worker 传入 config.getOutputStyle(),且改名后的 arena 测试将其钉住(行为是有意为之)。不准确之处位于历史提交说明中,而本工作流只允许增量提交 —— 禁止 amend / rebase / 重写历史 —— 因此不存在范围内的修复手段;子代理确实不继承
3 PR 正文测试计数过时(「479 tests pass, 24 of them new」;contextCommand「16 passing」) 拒绝 —— 描述层面的更正,本模式无相应机制 报告实测触及套件共 532 个测试、较 base 新增 30 个;address-review 模式只能发布评论 —— PR 正文由建 PR 的流程持有,不是本模式可更新的输出,且 agent 无任何 GitHub 写权限。已在本轮评论中记录正确计数,使线程留有凭据
4 getBuiltInOutputStyle 对非字符串入参抛 TypeError(第 2 轮 nit) 移交后续队列 —— 发现属实,但修复属于未来接线 PR,不属于本 PR 源码已确认:name.trim() 对非字符串会抛错。调用点普查复核:全仓所有调用点均为测试文件;setOutputStyle 无任何非测试调用方,因此当前不存在任何生产路径能以非字符串触达该函数 —— 现在加守卫将是为不可能发生的条件编写错误处理。验证报告本身也将该守卫归于后续接线 PR 的解析边界,故已将该发现记入 deferred-findings 队列,以免合并时丢失

本轮未改动任何代码、未产生任何提交。PR 保持在 c99e3ace,全部 CI 检查为绿,等待人类评审 / 合入。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max

@wenshao
wenshao added this pull request to the merge queue Aug 24, 2026
Merged via the queue into QwenLM:main with commit c7c4dc8 Aug 24, 2026
75 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.22.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants