Skip to content

docs(verify-pr): key the turn-axes rule to the diff, not the central claim - #13819

Merged
yiliang114 merged 1 commit into
mainfrom
docs/verify-pr-turn-axes-diff-trigger
Oct 10, 2026
Merged

yiliang114 merged 1 commit into
mainfrom
docs/verify-pr-turn-axes-diff-trigger

Conversation

@wenshao

@wenshao wenshao commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

The scenario-axes rule in item 1 of the verify-pr skill's Scope selection is now triggered by the diff, not by the central claim. When the diff changes how a Turn is cancelled, parked, taken over, recovered, approved or retried, the agent names the scenario axes before choosing the A/B instrument, whether or not that code is the central claim. If it is not, that code gets its own A/B as a secondary claim. The rest of the rule is unchanged. The measured example gains one sentence about the arm that showed the gap, and the triage workflow test pins the new trigger inside its section.

Why it's needed

#13813 put the axes rule into the plan the agent follows, keyed to "when the claim is about a turn's lifecycle". Its own evidence run (arm C) showed that this trigger never matched. The agent named Harness generation adoption as the central claim, and its reasoning never mentions the rule or which Turn was parked. Yet it did mutate the cancellation-load branches of the recovery code, varying only the checkpoint phase. So the code the rule is about was in the diff, and the agent was working on it; the trigger was keyed to how the agent framed the claim. #13813 named a diff-keyed trigger as the untested option. This PR makes that change and runs it.

Reviewer Test Plan

How to verify

  1. Read item 1 of Scope selection.
  2. Run npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/qwen-triage-workflow.test.js scripts/tests/verify-capture.test.js. The case "carries the maintainer-round verification techniques" passes with the new pins.
  3. Non-vacuity: change any pinned phrase of the new trigger in the skill, or move the paragraph to another section unchanged. The same case fails on the assertion that names it.
  4. As with docs(verify-pr): add local-round publish, follow-up, mutation and rig rules #13756 and docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813, the CI verify lane restores .qwen from the base branch, so a /verify on this PR reads the old skill and these pins show red there. That is by design; the text takes effect after merge.

Evidence (Before & After)

Arm D, this text. It used the same rig, inputs and pre-registered criterion as arms A to C in #13732 and #13813. It ran alone on the same tree, like arm C. The skill was arm C's text plus this change, byte-identical to the commit's hunk. I captured the first model request offline; it holds the new trigger, and it equals arm C's request once the skill body is swapped.

Arm Target defect Verdict Assertions (pass/fail/total) Time Requests
A, before #13756 MISS findings 43/1/44 2840 s 78
B, after #13756 MISS blocked 23/4/27 2277 s 87
C, #13813 MISS blocked 37/0/37 3387 s 101
D, this PR CATCH inconclusive 11/4/15 2115 s 83
  • The trigger fired, and the target defect was caught.
    • The report's scenario-axes section opens with "This diff changes how a Turn is cancelled, parked, taken over and recovered, so the axes are named explicitly". It lists five axes, each with the settings the author's tests use.
    • On "which Turn parks", it copied the author's test and changed only the setup, so that Turn 1 completes before Turn 2 parks. At head this fails with expected 409 to be 200 and settledOnLoad=false, and the server logs Checkpoint names a different Turn. That is the round-9 defect.
    • Both criteria are met: the report says the cancellation takeover does not settle a park that is not the first Turn, and the failing run is in the artifact directory.
  • It filed the defect as pre-existing, not as a gap in the fix.
    • It ran the same probe on base, got a 409 there too, and recorded the gap as a correction to the description ("converts every previously unbounded 'parked forever' Turn state") rather than as a numbered finding.
    • The comparison is literally true, but base has no settle path at all. So it hides that the new path covers first Turns only.
    • On base the 409 also comes from a different refusal (takeover_unrecovered), which the report calls identical.
  • Other parts of the run were thinner than arm C's.
    • By the report's own account, the budget went to the A/B, the axis probe and two other findings, so no mutation matrix ran.
    • It also did not get Maven working in time, while arm C provisioned a JDK and Maven. So the Java central claim went unexecuted, and the verdict is inconclusive.
    • The merge-only red was still attributed correctly: 13/13 at HEAD^2, called a semantic merge conflict. This time the fix was not measured.

Pins. The mutation matrix from #13813 was rerun over all 14 pinned phrases of the two #13813 paragraphs, 4 of them new here. It also moved each paragraph, unchanged, into another section. It ran only the pinning case and required a failure whose message names the phrase: 16/16 killed. The unmutated case was green before and after, and the skill was restored from memory after each mutant.

Tested on

OS Status
🍏 macOS ⚠ïļ
🊟 Windows ⚠ïļ
🐧 Linux ✅

Environment (optional)

Linux x86_64, Node 22.22.2. The triage workflow and verify-capture test files: 199 passed and 1 skipped, the same counts as main (the pins were added to an existing case). Prettier and the pre-commit ESLint pass. npm run build and npm run typecheck were not run: the change touches only skill text and a JavaScript test under scripts/tests, which they do not compile.

Risk & Scope

  • Main risk or tradeoff: the trigger is wider. Any PR whose diff touches how a Turn is cancelled, parked, taken over, recovered, approved or retried now spends part of its budget on an A/B at a setting the author's tests do not use, even when its central claim is elsewhere. The always-loaded skill grows by 5 lines (19 added, 14 removed).
  • Not validated / out of scope:
    • The catch is in-sample, and each arm ran once. The rule and its example were written from this PR, and the example names the very setting the agent ran: parking Turn 2 after Turn 1 completed. The run shows that the diff-keyed trigger fires and that the agent follows it. It does not show that the rule finds defects it was not written from.
    • The cost is unclear. In the one run, the extra A/B came alongside no mutation matrix. Whether that is a cost of the rule or run-to-run variance is not measured.
    • The rig differs from the lane. It has the same differences as in docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813: GitHub hosts were blocked, Chromium was not installed, and no arm has the JDK provisioning text from ci(verify): provision a Java toolchain for sdk-java PRs #13763.
    • Other platforms. macOS and Windows were not tested; the change is text only.
  • Breaking changes / migration notes: none.

Linked Issues

Follow-up to #13813 and #13732. The re-run target is #13174 (round 9).

äļ­æ–‡čŊŽ

čŋ™äļŠ PR 做䚆äŧ€äđˆ

verify-pr æŠ€čƒ― Scope selection įŽŽ 1 éĄđé‡Œįš„åœšæ™ŊįŧīåšĶč§„åˆ™ïžŒįŽ°åœĻį”ą diff č§Ķå‘ïžŒč€Œäļæ˜Ŋį”ąäļ­åŋƒäļŧåž č§Ķ发。及č́ diff æ”đåŠĻ乆 Turn įš„å–æķˆã€åœä―ã€æŽĨįŪĄã€æĒåĪã€åŪĄæ‰đ或重čŊ•æ–đ垏agent å°ąč́åœĻ选åۚ A/B 手æŪĩäđ‹å‰åˆ—凚圚æ™ŊįŧīåšĶäļčŪščŋ™æŪĩäŧĢ᠁æ˜Ŋäļæ˜Ŋäļ­åŋƒäļŧ垠。åĶ‚æžœäļæ˜Ŋčŋ™æŪĩäŧĢį å°ąä―œäļšæŽĄč́äļŧåž ïžŒå•į‹Žåšäļ€æŽĄ A/Bã€‚č§„åˆ™å…ķä―™éƒĻ分äļå˜ã€‚åŪžæĩ‹äū‹å­é‡ŒčĄĨ乆äļ€åĨčŊŽæšīéœēčŋ™äļŠįžšåĢįš„é‚Ģäļ€č‡‚ïž›triage workflow æĩ‹čŊ•æŠŠæ–°įš„č§Ķå‘æĄäŧķ钉åœĻåŪƒæ‰€åœĻįš„å°čŠ‚é‡Œã€‚

äļšäŧ€äđˆéœ€č́

#13813 把įŧīåšĶč§„åˆ™æ”ūčŋ›äš† agent éĩåūŠįš„čŪĄåˆ’æļ…单č§Ķå‘æĄäŧķæ˜Ŋ"äļŧåž æķ‰åŠ turn įš„į”Ÿå‘―å‘Ļ期"。åŪƒč‡Šå·ąįš„čŊæŪčŋčĄŒïžˆC č‡‚ïž‰æ˜ūįĪščŋ™äļŠæĄäŧķäŧŽæēĄå‘―äļ­ã€‚agent 把äļ­åŋƒäļŧåž åۚäļš Harness äŧĢ际æŽĨįšģåŪƒįš„æŽĻį†é‡ŒäŧŽæēĄæåˆ°čŋ™æĄč§„则äđŸæēĄæåˆ°åœä―įš„æ˜Ŋ哊äļŠ Turnã€‚ä―†åۃįĄŪåŪžåŊđæĒåĪäŧĢį é‡ŒåĪ„į†å–æķˆåŠ č――įš„åˆ†æ”Ŋ做䚆变垂及æ˜Ŋæ”đįš„æ˜Ŋ checkpoint é˜ķæŪĩ。äđŸå°ąæ˜ŊčŊīïžŒč§„åˆ™é’ˆåŊđįš„äŧĢį å°ąåœĻ diff 里agent äđŸåœĻå΄ᐆåŪƒïž›é—ŪéĒ˜å‡šåœĻč§Ķå‘æĄäŧķ取å†ģ䚎 agent 怎äđˆčĄĻčŋ°äļŧ垠。#13813 把按 diff č§Ķ发列äļšå°šæœŠæĩ‹čŊ•įš„é€‰éĄđčŋ™äļŠ PR 把åۃæ”đčŋ‡æĨåđķåŪžé™…č·‘äš†äļ€æŽĄã€‚

čŊ„åŪĄæĩ‹čŊ•čŪĄåˆ’

åĶ‚ä―•éŠŒčŊ

  1. 阅čŊŧ Scope selection įš„įŽŽ 1 éĄđ。
  2. čŋčĄŒ npx vitest run --config ./scripts/tests/vitest.config.ts scripts/tests/qwen-triage-workflow.test.js scripts/tests/verify-capture.test.js。į”Ļäū‹ "carries the maintainer-round verification techniques" åļĶį€æ–°é’‰å­é€ščŋ‡ã€‚
  3. 非įĐšæ€§ïžšæ”đåŠĻæŠ€čƒ―é‡Œæ–°č§Ķå‘æĄäŧķäļ­äŧŧäļ€čĒŦé’‰ä―įš„įŸ­čŊ­ïžŒæˆ–把čŋ™äŪĩ原样挊到åˆŦįš„å°čŠ‚ïžŒåŒäļ€į”Ļäū‹äžšåœĻį‚đ名čŊĨ៭čŊ­įš„æ–­čĻ€äļŠåĪąčīĨ。
  4. äļŽ docs(verify-pr): add local-round publish, follow-up, mutation and rig rules #13756、docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813 ä ·ïžŒCI verify lane 侚äŧŽ base 分æ”ŊæĒåĪ .qwen所äŧĨåŊđæœŽ PR č·‘ /verify čŊŧåˆ°įš„æ˜Ŋæ—§æŠ€čƒ―ïžŒčŋ™äš›é’‰å­åœĻé‚Ģ里侚æ˜ūįĪšäļšįšĒ。čŋ™æ˜ŊčŪūčŪĄåĶ‚æ­Ī文朎åœĻ合å…ĨåŽæ‰į”Ÿæ•ˆã€‚

čŊæŪ前后åŊđæŊ”

D č‡‚ïžŒåģ朎 PR įš„æ–‡æœŽã€‚ æēŋį”Ļ #13732 和 #13813 äļ­ A 到 C č‡‚įš„įŽŊåĒƒã€čū“å…Ĩ和䚋先į™ŧčŪ°įš„åˆĪåŪšæ ‡å‡†ïžŒäļŽ C 臂ä ·åœĻ同äĢĩ树äļŠå•į‹ŽčŋčĄŒã€‚æŠ€čƒ―文朎æ˜Ŋ C č‡‚įš„æ–‡æœŽåŠ äœŽ PR įš„æ”đåŠĻäļŽæäšĪé‡Œįš„æ”đåŠĻé€å­—čŠ‚äļ€č‡ī。我įĶŧįšŋ抓取䚆éĶ–äļŠæĻĄåž‹čŊ·æą‚ïžšå…ķäļ­åŒ…åŦæ–°įš„č§Ķå‘æĄäŧķïž›æŠŠæŠ€čƒ―æ­Ģ文æĒ回 C įš„į‰ˆæœŽåŽïžŒäļŽ C č‡‚įš„čŊ·æą‚åیå…Ļį›ļ同。

臂 į›Ūæ ‡įžšé™· įŧ“čŪš 断čĻ€ïžˆé€ščŋ‡/åĪąčīĨ/æ€ŧ数 į”Ļæ—ķ čŊ·æą‚æ•°
A#13756 äđ‹å‰ MISS findings 43/1/44 2840 s 78
B#13756 äđ‹åŽ MISS blocked 23/4/27 2277 s 87
C#13813 MISS blocked 37/0/37 3387 s 101
D朎 PR CATCH inconclusive 11/4/15 2115 s 83
  • č§Ķå‘æĄäŧķį”Ÿæ•ˆäš†ïžŒį›Ūæ ‡įžšé™·äđŸčĒŦ抓到。
    • æŠĨå‘Šįš„åœšæ™ŊįŧīåšĶäļ€čŠ‚åž€åĪīå†™į€ "This diff changes how a Turn is cancelled, parked, taken over and recovered, so the axes are named explicitly"åđķ列凚䚔äļŠįŧīåšĶæŊäļŠéƒ―æģĻæ˜Žä―œč€…æĩ‹čŊ•į”Ļįš„čŪūį―Ū。
    • åœĻ"åœä―įš„æ˜Ŋ哊äļŠ Turn"čŋ™äļŠįŧīåšĶäļŠïžŒåۃåĪåˆķäš†ä―œč€…įš„æĩ‹čŊ•及æ”đ准å·æ­ĨéŠĪïžšå…ˆčŪĐ Turn 1 åŪŒæˆïžŒå†åœä― Turn 2。čŋ™äļŠį”Ļäū‹åœĻ head äļŠåĪąčīĨæŠĨ expected 409 to be 200settledOnLoad=falseïžŒæœåŠĄįŦŊæ—Ĩåŋ—æ˜Ŋ Checkpoint names a different Turn。čŋ™æ­Ģæ˜ŊįŽŽ 9 č―Ūįš„įžšé™·ã€‚
    • äļĪæĄæ ‡å‡†éƒ―æŧĄčķģïžšæŠĨ告写明取æķˆæŽĨįŪĄæ— æģ•æ”ķå°ū非éĶ–äļŠ Turn įš„åœä―ïžŒåĪąčīĨįš„čŋčĄŒčŪ°å―•äđŸåœĻčŊæŪį›Ūå―•é‡Œã€‚
  • åŪƒæŠŠįžšé™·åŪšæ€§äļšæ—Ē有é—ŪéĒ˜ïžŒč€Œäļæ˜ŊäŋŪåĪæœŽčšŦįš„įžšåĢ。
    • åۃåœĻ base äļŠč·‘同äļ€äļŠæŽĒ针同样åū—到 409䚎æ˜Ŋ把čŋ™äļŠįžšåĢčŪ°æˆåŊđ PR 描čŋ°įš„æ›īæ­Ģ描čŋ°é‡Œå†™įš„æ˜Ŋ "converts every previously unbounded 'parked forever' Turn state"æēĄæœ‰åˆ—äļšįž–å·įš„ finding。
    • čŋ™äļŠåŊđæŊ”å­—éĒäˆįŦ‹ïžŒä―† base æ đ朎æēĄæœ‰æ”ķå°ūč·Ŋåū„所äŧĨæŽĐį›–äš†"新č·Ŋåū„及č͆ᛖéĶ–äļŠ Turn"čŋ™äļ€į‚đ。
    • base äļŠįš„ 409 äđŸæĨ臩åĶäĄæ‹’įŧč·Ŋåū„takeover_unrecoveredæŠĨ告åīčŊīäļĪ者åیå…Ļį›ļ同。
  • čŋ™æŽĄčŋčĄŒįš„å…ķäŧ–éƒĻ分æŊ” C č‡‚å•č–„ã€‚
    • 按æŠĨå‘Šč‡Šå·ąįš„čŊīæģ•éĒ„įŪ—čŠąåœĻ乆 A/B、įŧīåšĶæŽĒ针和åĶåĪ–äļĪäļŠå‘įŽ°äļŠïžŒæ‰€äŧĨæēĄč·‘变垂įŸĐé˜ĩ。
    • åۃäđŸæēĄčƒ―及æ—ķčĢ…åĨ― MavenïžŒč€Œ C 臂čĢ…åĨ―乆 JDK 和 Maven。所äŧĨ Java äū§įš„äļ­åŋƒäļŧåž æēĄæœ‰æ‰§čĄŒïžŒįŧ“čŪšæ˜Ŋ inconclusive。
    • 及åœĻ merge äļŠå‡šįŽ°įš„įšĒäŧį„ķå―’å› æ­ĢįĄŪïžšHEAD^2 äļŠ 13/13 通čŋ‡ïžŒåˆĪäļščŊ­äđ‰åˆå…Ĩå†ēįŠïž›ä―†čŋ™æŽĄæēĄæœ‰åŪžæĩ‹äŋŪåĪã€‚

钉子。 é‡č·‘äš† #13813 įš„å˜åž‚įŸĐé˜ĩč͆ᛖ #13813 äļĪæŪĩ里å…ĻéƒĻ 14 äļŠčĒŦé’‰ä―įš„įŸ­čŊ­ïžˆå…ķäļ­ 4 äļŠæ˜Ŋ朎 PR 新åĒžįš„ïž‰ïžŒåđķæŠŠæŊäŪĩ原样挊到åˆŦįš„å°čŠ‚ã€‚åŠč·‘é’‰ä―åۃäŧŽįš„į”Ļäū‹ïžŒčĶæą‚åĪąčīĨäŋĄæŊį‚đ名čŊĨ៭čŊ­ïžš16/16 å…ĻéƒĻčĒŦæ€ã€‚æœŠå˜åž‚įš„į”Ļäū‹å‰åŽéƒ―æ˜ŊįŧŋæŊäļŠå˜åž‚äđ‹åŽæŠ€čƒ―æ–‡æœŽéƒ―äŧŽå†…å­˜æĒåĪã€‚

æĩ‹čŊ•åđģ台

OS įŠķ态
🍏 macOS ⚠ïļ
🊟 Windows ⚠ïļ
🐧 Linux ✅

įŽŊåĒƒïžˆåŊ选

Linux x86_64Node 22.22.2。triage workflow 和 verify-capture äļĪäļŠæĩ‹čŊ•æ–‡äŧķïžš199 通čŋ‡ã€1 č·ģčŋ‡ïžŒäļŽ main į›ļ同钉子加åœĻå·ē有į”Ļäū‹é‡Œïž‰ã€‚Prettier 和 pre-commit įš„ ESLint 均通čŋ‡ã€‚æēĄæœ‰čŋčĄŒ npm run build 和 npm run typecheckïžšæ”đåŠĻ及æķ‰åŠæŠ€čƒ―文朎和 scripts/tests äļ‹įš„äļ€äļŠ JavaScript æĩ‹čŊ•čŋ™äļĪæĄå‘―äŧĪéƒ―äļįž–čŊ‘åۃäŧŽã€‚

éĢŽé™ĐäļŽčŒƒå›ī

  • äļŧč́éĢŽé™Đæˆ–å–čˆïžšč§Ķå‘čŒƒå›ī变åŪ―äš†ã€‚åŠč́ diff æ”đåŠĻ乆 Turn įš„å–æķˆã€åœä―ã€æŽĨįŪĄã€æĒåĪã€åŪĄæ‰đ或重čŊ•æ–đ垏åģä―ŋäļ­åŋƒäļŧåž åœĻåˆŦåĪ„ïžŒPR äđŸč́æ‹ŋ凚äļ€éƒĻ分éĒ„įŪ—ïžŒåœĻä―œč€…æĩ‹čŊ•æēĄį”Ļåˆ°įš„čŪūį―ŪäļŠåšäļ€æŽĄ A/B。åļļéĐŧåŠ č――įš„æŠ€čƒ―å‡€åĒž 5 čĄŒïžˆæ–°åĒž 19 čĄŒïžŒåˆ é™Ī 14 čĄŒïž‰ã€‚
  • 朊銌čŊ / äļåœĻ范å›ī内
    • čŋ™æŽĄæŠ“åˆ°åąžäšŽæ ·æœŽå†…ïžŒč€ŒäŊč‡‚åŠč·‘äš†äļ€æŽĄã€‚ č§„åˆ™å’Œäū‹å­éƒ―æšč‡Ščŋ™äļŠ PRäū‹å­į‚đå‡šįš„æ­Ģæ˜Ŋ agent č·‘įš„é‚ĢäļŠčŪūį―ŪïžščŪĐ Turn 1 先åŪŒæˆå†åœä― Turn 2。čŋ™æŽĄčŋčĄŒčŊŽæŒ‰ diff č§Ķå‘įš„æĄäŧķäžšį”Ÿæ•ˆïžŒagent äđŸäžšį…§åšïž›ä―†äļčƒ―čŊŽčŋ™æĄč§„åˆ™čƒ―æ‰ū凚åŪƒæ‰€æĨ暐äđ‹åĪ–įš„įžšé™·ã€‚
    • äŧĢäŧ·å°šäļæļ…æĨšã€‚ åœĻčŋ™äļ€æŽĄčŋčĄŒé‡ŒïžŒåĪšå‡šæĨįš„ A/B äļŽæēĄč·‘变垂įŸĐé˜ĩ同æ—ķå‡šįŽ°ã€‚čŋ™æ˜Ŋč§„åˆ™įš„äŧĢäŧ·čŋ˜æ˜ŊčŋčĄŒé—īįš„éšæœšå·Ū垂æēĄæœ‰æĩ‹é‡ã€‚
    • čŋ™åĨ—įŽŊåǃäļŽ lane 有å·Ū垂。 å·Ūåž‚äļŽ docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813 į›ļåŒïžšåąč”―äš† GitHub äļŧ朚æēĄæœ‰čĢ… ChromiumïžŒæ‰€æœ‰č‡‚éƒ―æēĄæœ‰ ci(verify): provision a Java toolchain for sdk-java PRs #13763 įš„ JDK 准åĪ‡æ–‡æœŽã€‚
    • å…ķäŧ–åđģ台。 macOS 和 Windows 朊æĩ‹čŊ•ïž›æ”đåŠĻ及æ˜Ŋ文朎。
  • į ī坏性变æ›ī / čŋį§ŧčŊŽïžšæ— ã€‚

å…ģ联 Issue

#13813 和 #13732 įš„åŽįŧ­ã€‚é‡č·‘åŊđ蹥æ˜Ŋ #13174ïžˆįŽŽ 9 č―Ū。

â€Ķclaim

The scenario-axes requirement in Scope selection fired only when the
central claim was about a turn's lifecycle. In a third re-run arm on
#13174 R9 the agent named Harness generation adoption as the claim, so the
rule never applied, although it mutated the cancellation-load branches.
Trigger the rule on any diff that changes how a Turn is cancelled,
parked, taken over, recovered, approved or retried, and give that code
its own A/B as a secondary claim when it is not the central one.
@wenshao
wenshao requested a balanced review from Copilot October 10, 2026 05:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@qwen-code-review-bot

qwen-code-review-bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Qwen Triage finished — CI landed green on 0e59ea1 and the deferred approval was posted. finalize run

✅ Qwen Triage å·ēåŪŒæˆ —— 0e59ea1 įš„ CI å…ĻįŧŋåŧķčŋŸåŪĄæ‰đå·ē提äšĪ。æŸĨįœ‹ finalize čŋčĄŒ

@qwen-code-review-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: observed, not theoretical. #13813 shipped the axes rule keyed to the central claim, and the arm C re-run on #13174 R9 shows that trigger never matched — the agent named Harness generation adoption as its claim while still mutating the cancellation-load branches. The failure sits in a run record, so there is a real defect here rather than a hypothesis. One caveat I cannot close from this seat: the arm evidence is your own run log. This is an unattended CI pass, so I executed no PR-derived code, and by your own note the CI verify lane restores .qwen from base — nothing on this side re-derives arm C independently.

Direction: aligned. This is the repo's own verification tooling, the third step in a line a maintainer has already landed twice (#13756, #13813), and diff-keying is the option #13813 itself named as untested. The upstream CHANGELOG is not a useful signal for internal skill text, so I did not weigh it.

Size: not applicable — no core paths. Both files sit outside packages/*: 19 added / 14 removed in the skill markdown, 15 added / 1 removed in the workflow test. 34 additions and 15 deletions total, far under every threshold.

Approach: the scope feels right, and it matches what I would have written from the problem statement alone — re-key the one trigger sentence in place instead of adding a parallel rule or a new section. Net +5 lines of skill text. No drive-by churn; the only adjacent edit is the test comment explaining why the trigger moved, which belongs with it.

One question worth thinking about, not a blocker: the new sentence sends non-central turn-lifecycle code to "its own A/B as a secondary claim", but the budget list has no numbered slot for a secondary A/B. Item 1 is scoped to the central claim at "~half the budget", and the section closes with "Never let breadth eat the A/B". Your arm D run is where that pressure shows up — no mutation matrix, the Java claim unexecuted, verdict inconclusive. You list the cost as unmeasured in Risk & Scope, which is the honest framing; I would just note that the mandate now exists without a budget line attached, and this file's own test documents that class of gap three times over. Picking it up in the code review.

Risk: no elevated risk signals — nothing under Stage 1e's revert-correlated paths.

Moving on to code review. 🔍

äļ­æ–‡čŊŽ

感č°ĒčīĄįŒŪ

æĻĄæŋåیæ•ī ✓

é—ŪéĒ˜ïžš æ˜ŊåŪžé™…č§‚æĩ‹åˆ°įš„äļæ˜ŊᐆčŪšåŠ å›šã€‚#13813 把įŧīåšĶč§„åˆ™įš„č§Ķå‘æĄäŧķæŒ‚åœĻ"äļ­åŋƒäļŧåž "äļŠïžŒč€ŒåœĻ #13174 R9 äļŠįš„ C č‡‚é‡č·‘æ˜ūįĪščŋ™äļŠæĄäŧķäŧŽæœŠå‘―äļ­â€”—agent 把äļ­åŋƒäļŧåž åۚäļš Harness äŧĢ际æŽĨįšģåīäŧį„ķ变垂䚆åĪ„į†å–æķˆåŠ č――įš„åˆ†æ”Ŋ。åĪąčīĨčŪ°å―•åœĻčŋčĄŒæ—Ĩåŋ—里所äŧĨčŋ™é‡Œæœ‰įœŸåŪžįžšé™·č́äŋŪïžŒč€Œäļæ˜Ŋ假čŪū。有äļ€į‚đ我无æģ•åœĻčŋ™äļŠä―į―ŪčĄĨäļŠïžšå„臂čŊæŪæĨč‡Šä― č‡Šå·ąįš„čŋčĄŒčŪ°å―•ã€‚čŋ™æ˜Ŋ无䚚倞åŪˆįš„ CI æĩįĻ‹ïžŒæˆ‘æēĄæœ‰æ‰§čĄŒäŧŧä―• PR åļĶæĨįš„äŧĢį ïž›č€ŒäŒ‰ä― č‡Šå·ąįš„čŊŽïžŒCI verify lane 侚äŧŽ base æĒåĪ .qwen所äŧĨčŋ™äļ€äū§æ— æģ•į‹ŽįŦ‹åĪįŽ° C č‡‚ã€‚

æ–đ向 åŊđé―ã€‚čŋ™æ˜Ŋäŧ“åš“č‡ŠčšŦįš„éŠŒčŊå·Ĩ具æ˜ŊįŧĪ者å·ēįŧäļĪæŽĄåˆå…Ĩįš„įģŧ列#13756、#13813ïž‰įš„įŽŽä­ĨïžŒč€ŒæŒ‰ diff č§Ķ发æ­Ģæ˜Ŋ #13813 č‡Šå·ąåˆ—äļš"尚朊æĩ‹čŊ•"įš„é‚ĢäļŠé€‰éĄđ。äļļ CHANGELOG åŊđ内éƒĻæŠ€čƒ―æ–‡æœŽæēĄæœ‰å‚č€ƒäŧ·å€žïžŒå› æ­Ī我æēĄæœ‰é‡‡įšģčŋ™äļŠäŋĄå·ã€‚

规æĻĄïžš äļé€‚į”Ļ——朊č§Ķ及æ ļåŋƒč·Ŋåū„。äļĪäļŠæ–‡äŧķéƒ―åœĻ packages/* äđ‹åĪ–ïžšæŠ€čƒ― markdown 新åĒž 19、删é™Ī 14workflow æĩ‹čŊ•æ–°åĒž 15、删é™Ī 1。合čŪĄæ–°åĒž 34、删é™Ī 15čŋœä―ŽäšŽæ‰€æœ‰é˜ˆå€žã€‚

æ–đæĄˆïžš 范å›īåˆį†ïžŒäđŸå’Œæˆ‘åŠįœ‹é—ŪéĒ˜æčŋ°æ—ķäžšå†™å‡šįš„æ–đæĄˆäļ€č‡īâ€”â€”å°ąåœ°æ”đ写é‚Ģäļ€åĨč§Ķå‘æĄäŧķïžŒč€Œäļæ˜Ŋ新åĒžäĄåđģčĄŒč§„åˆ™æˆ–æ–°åž€äļ€čŠ‚ã€‚æŠ€čƒ―文朎净åĒž 5 čĄŒïžŒæēĄæœ‰éĄšæ‰‹åĪđåļĶįš„æ”đåŠĻïž›å”Ŋäļ€įš„į›ļé‚ŧäŋŪæ”đæ˜Ŋč§Ģ释č§Ķå‘æĄäŧķäļšä―•į§ŧåŠĻįš„é‚ĢæŪĩæĩ‹čŊ•æģĻ释åŪƒæœŽå°ąčŊĨ跟åœĻäļ€čĩ·ã€‚

有äļ€äļŠå€žåū—æ€č€ƒįš„é—ŪéĒ˜ïžŒäļæ˜Ŋé˜ŧåĄžéĄđïžšæ–°åĨ子把"非äļ­åŋƒäļŧåž "įš„ turn į”Ÿå‘―å‘Ļ期äŧĢ᠁äšĪįŧ™"ä―œäļšæŽĄč́äļŧåž å•į‹Žåšäļ€æŽĄ A/B"ïžŒä―†éĒ„įŪ—æļ…单里æēĄæœ‰įŧ™æŽĄč́ A/B įš„įž–å·æ§―ä―ã€‚įŽŽ 1 éĄđ限åۚäļšäļ­åŋƒäļŧ垠、占"įšĶäļ€åŠéĒ„įŪ—"ïžŒč€ŒæœŽčŠ‚įŧ“å°ūå†™į€"Never let breadth eat the A/B"ã€‚ä― įš„ D 臂čŋčĄŒæ­Ģæ˜Ŋčŋ™äļŠåŽ‹åŠ›æ˜ūįŽ°įš„åœ°æ–đ——æēĄč·‘变垂įŸĐé˜ĩ、Java äļŧåž æœŠæ‰§čĄŒã€įŧ“čŪš inconclusiveã€‚ä― åœĻ Risk & Scope 里把äŧĢäŧ·åˆ—äļšæœŠæĩ‹é‡ïžŒčŋ™äļŠčĄĻčŋ°æ˜ŊčŊšåŪžįš„ïž›æˆ‘åŠæ˜ŊæƒģæŒ‡å‡šïžŒįŽ°åœĻčŋ™æĄåžšåˆķčĶæą‚å­˜åœĻåīæēĄæœ‰é…åĨ—įš„éĒ„įŪ—čĄŒïžŒč€Œčŋ™äļŠæ–‡äŧķč‡Šå·ąįš„æĩ‹čŊ•å·ēįŧæŠŠčŋ™äļ€įąŧįžšåĢčŪ°å―•čŋ‡äļ‰æŽĄã€‚čŊĶ见äŧĢ᠁åŪĄæŸĨ。

éĢŽé™Đïžš æ— å‡įš§éĢŽé™ĐäŋĄå·â€”—Stage 1e įš„ revert į›ļå…ģč·Ŋåū„äļ€äļŠéƒ―æēĄå‘―äļ­ã€‚

čŋ›å…ĨäŧĢ᠁åŪĄæŸĨ 🔍

— Qwen Code · qwen3.8-max-2026-09-02

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

@qwen-code-review-bot

qwen-code-review-bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Code review

Before reading the diff I wrote down what I would do from the title and the motivation alone: the trigger was keyed to how the agent frames its claim, which is unobservable from outside, so re-key it to something observable — the diff — and make sure turn-lifecycle code still gets an A/B when it is not the central claim, then pin the wording so the trigger cannot silently regress. That is what this PR does, and I did not find a simpler path. It edits one rule in place instead of adding a parallel section, and the only other edit is a test comment explaining why the trigger moved.

What I checked statically, since I executed nothing:

  • The four new pins really bite. flat is verifySkill.replace(/\s+/g, ' ') (line 4545) — a normalized string, so scopeSelection is a substring and toContain does substring matching across the markdown's line wraps. All four phrases land inside the ## Scope selection â€Ķ ## Method slice after the rewrite: When the diff changes how a Turn is cancelled, parked, taken over, whether or not that code is the central claim, it gets its own A/B as a secondary claim, The trigger is therefore the diff, not the claim.
  • The five pre-existing docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813 pins in that slice all survive — the rewrite keeps name the scenario axes before choosing the A/B instrument, even when the instrument is the PR's own test files, parking Turn 2 after Turn 1 completed, The report lists each axis with the settings that ran and `expected 409 to be 200`.
  • No orphaned pins anywhere. I grepped scripts/ and .github/ for the wording this PR deletes: turn's lifecycle and take them from return zero hits, so nothing else asserts on the removed phrasing. The other Parameterise scenarios pin (line 4929) targets the Method-section heading at SKILL.md:918, which is untouched.
  • The second slice of the same section is safe. A different case, budgets evidence capture in scope selection (line 6318), slices the raw skill and asserts /^4\. \*\*Capture/m plus four item-4 phrases. The PR renumbers nothing and leaves items 2–4 byte-identical.
  • verify-capture.test.js, the other file in your verify command, has no pin on Scope selection, the scenario axes, Turn 2, central claim or Parameterise. Including it is harmless, but it is not load-bearing for this change.
  • The cross-reference still resolves. _Parameterise scenarios_ under wire-oracle harnesses is SKILL.md:918, and the axes it lists — "which turn is parked or cancelled (the first, or a later one after a completed turn)" — are the ones the measured example turns on.
  • Formatting matches Prettier. Every new markdown line is â‰Ī 80 columns, and each new expect breaks exactly where Prettier would break it (the single-line forms run 81–90 chars).

One reservation, non-blocking — the secondary A/B has no budget slot. The new sentence mandates an extra A/B, but it lives inside item 1, whose heading is "A/B load-bearing proof of the central claim (always, ~half the budget)". No numbered item budgets a secondary A/B, and the section closes with "Everything else is explicitly out of scope" and "Never let breadth eat the A/B: one proven load-bearing claim beats ten unverified observations" — which reads against a mandated extra one. Your arm D is where that pressure surfaces: the budget went to the A/B, the axis probe and two findings, so no mutation matrix ran, Maven never came up, the Java central claim went unexecuted and the verdict was inconclusive. That is breadth eating the A/B, in the one run that has the data.

The instruction being inside the list is the real improvement and arm D demonstrates it, so I would not hold the PR for this. But it is worth a follow-up that either gives the secondary A/B its own numbered budget line or states what it displaces — especially since this file's own test documents that exact failure class three times over at line 6313 ("Third instance of one structural bug: an instruction placed outside the flow the agent actually follows"). To be fair to the diff: secondary claims never had a budget slot, the section intro only says "plus up to two secondary claims". What is new is mandating one.

No critical blockers, no AGENTS.md violations.

Test evidence

This is an unattended CI pass, so per the gate rules I built nothing, ran no test and executed no PR-derived code. Everything below is the PR's own CI, read through the API on the reviewed commit. Zero checks are red so far; the two that decide this PR are still running and I am not polling them.

The load-bearing detail: the test job runs test:ci:workspaces and then, only if that exits 0, test:scripts (ci.yml:787-790) — and test:scripts is vitest run --config ./scripts/tests/vitest.config.ts, the lane that executes qwen-triage-workflow.test.js and therefore these four pins. It is in_progress, so the pin result is not in yet. Test (macos-latest) and Test (windows-latest) are both skipped, so the pins are exercised on ubuntu only — consistent with your Tested-on table (Linux ✅, macOS/Windows ⚠ïļ) and fine for a text-only change.

Your local figures — 199 passed / 1 skipped, Prettier and pre-commit ESLint green — are your claim, not evidence I reproduced. Lint & Static is still in flight, so I have not independently confirmed formatting either.

Not verified, with reasons: (1) that the new pins pass — the job that runs them has not finished; (2) Prettier/ESLint on the changed files — Lint & Static still running; (3) the 16/16 mutation-kill claim — a mutation matrix is not something I can re-run here, and it is not a CI lane.

Final CI results for 0e59ea1 (auto-updated by the triage finalize job after CI completed):

Check Conclusion
Classify PR ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Integration Tests (no-AK, No Sandbox) ✅ success
Lint & Static (ubuntu-latest, Node 22.x) ✅ success
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success

One row per check name (latest run); skipped checks omitted; failures sort first. / æŊäļŠæĢ€æŸĨ名äļ€čĄŒïžˆå–最新äļ€æŽĄčŋčĄŒïž‰ïžŒįœį•Ĩ skippedåĪąčīĨéĄđ排åœĻ最前。

Sandboxed verification

The central claim here is behavioural — that a diff-keyed trigger actually fires and drives the agent to name the axes — and neither the static review above nor CI substantiates it. A green test:scripts proves the pins match the text; it says nothing about whether an agent reading that text behaves differently.

Naming the usual lane would be noise in this specific case, so let me be precise instead: @qwen-code /verify cannot settle it pre-merge, for the reason you already documented — the CI verify lane restores .qwen from the base branch, so a run against this PR reads the old skill and the new pins show red by design. You have write access, so the lane is available to you without sponsorship; it is just the wrong instrument here.

What would actually settle it is post-merge: re-run an arm on a target the rule was not written from. Your own Risk & Scope says the catch is in-sample and each arm ran once — the rule and its measured example both come from #13174 R9, and the example names the exact setting arm D happened to probe (park Turn 2 after Turn 1 completed). Arm D shows the trigger fires and the agent follows it. It does not show the rule finds defects it was not authored from, and that is the claim carrying the merge decision. Worth stating plainly in the follow-up rather than leaving it implied.

Real-scenario testing

N/A — unattended CI run. tmux real-scenario driving is local-invocation only, and the change has no user-visible TUI surface: it is agent-skill prose plus a workflow test.

äļ­æ–‡čŊŽ

äŧĢ᠁åŪĄæŸĨ

åœĻįœ‹ diff äđ‹å‰ïžŒæˆ‘及æ đæŪ标éĒ˜å’ŒåŠĻ朚写äļ‹äš†č‡Šå·ąįš„æ–đæĄˆïžšč§Ķå‘æĄäŧķæŒ‚åœĻ agent åĶ‚ä―•čĄĻčŋ°äļŧåž äļŠïžŒč€Œčŋ™äŧŽåĪ–éƒĻäļåŊ观æĩ‹ïžŒæ‰€äŧĨåš”čŊĨæ”đ挂到åŊ观æĩ‹įš„äļœčĨŋ——diff——äļŠïž›åŒæ—ķäŋčŊ turn į”Ÿå‘―å‘Ļ期äŧĢ᠁åœĻäļæ˜Ŋäļ­åŋƒäļŧåž æ—ķäŧį„ķæ‹ŋ到äļ€æŽĄ A/B再把掊čūžé’‰ä―ïžŒé˜ēæ­Ēč§Ķå‘æĄäŧķæ‚„悄退化。čŋ™äļŠ PR åšįš„æ­Ģæ˜Ŋčŋ™äš›ïžŒæˆ‘æēĄæœ‰æ‰ū到æ›īįŪ€å•įš„č·Ŋåū„。åŪƒå°ąåœ°æŠŠäĄč§„则æ”đæŽ‰ïžŒč€Œäļæ˜Ŋ新åĒžäļ€čŠ‚åđģčĄŒå†…åŪđïž›å”Ŋäļ€įš„åĶäļ€åĪ„æ”đåŠĻæ˜Ŋč§Ģ释č§Ķå‘æĄäŧķäļšä―•į§ŧåŠĻįš„æĩ‹čŊ•æģĻ释。

äŧĨä˜Ŋ我静态æ ļåŊđįš„å†…åŪđæēĄæœ‰æ‰§čĄŒäŧŧä―•äļœčĨŋ

  • 四äļŠæ–°é’‰å­įĄŪåŪžæœ‰æ•ˆã€‚ flat æ˜Ŋ verifySkill.replace(/\s+/g, ' ')4545 čĄŒïž‰â€”â€”äļ€äļŠå―’äļ€åŒ–åŽįš„å­—įŽĶäļē所äŧĨ scopeSelection æ˜Ŋ子äļētoContain åšįš„æ˜Ŋč·Ļ markdown æĒčĄŒįš„å­äļēåŒđ配。æ”đ写äđ‹åŽïžŒå››äļŠįŸ­čŊ­éƒ―č―åœĻ ## Scope selection 到 ## Method čŋ™äŪĩ里。
  • docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813 åŽŸæœ‰įš„äš”äļŠé’‰å­å…ĻéƒĻäŋį•™ïžŒæ”đ写æēĄæœ‰åŠĻ到åۃäŧŽäūčĩ–įš„æŽŠčūžã€‚
  • æēĄæœ‰äŧŧä―•å­ĪįŦ‹įš„钉子。 我åœĻ scripts/ 和 .github/ 里搜䚆朎 PR åˆ æŽ‰įš„æŽŠčūžïžšturn's lifecycle 和 take them from å‘―äļ­æ•°äļšé›ķčŊŽæēĄæœ‰åˆŦåĪ„æ–­čĻ€äūčĩ–čĒŦåˆ įš„æ–‡æœŽã€‚åĶäļ€åĪ„ Parameterise scenarios 钉子4929 čĄŒïž‰æŒ‡å‘ SKILL.md:918 įš„ Method å°čŠ‚æ ‡éĒ˜ïžŒæœŽ PR 朊æ”đåŠĻ。
  • 同äļ€å°čŠ‚įš„įŽŽäšŒåĪ„åˆ‡į‰‡æ˜ŊåŪ‰å…Ļįš„ã€‚ åĶäļ€äļŠį”Ļäū‹ budgets evidence capture in scope selection6318 čĄŒïž‰åˆ‡įš„æ˜ŊæœŠå―’äļ€åŒ–įš„æŠ€čƒ―文朎断čĻ€ /^4\. \*\*Capture/m å’Œå››æĄįŽŽ 4 éĄđ៭čŊ­ã€‚朎 PR æēĄæœ‰æ”đįž–å·ïžŒįŽŽ 2 åˆ°įŽŽ 4 éĄđé€å­—čŠ‚æœŠå˜ã€‚
  • ä― éŠŒčŊå‘―äŧĪé‡Œįš„åĶäļ€äļŠæ–‡äŧķ verify-capture.test.jsåŊđ Scope selection、圚æ™ŊįŧīåšĶ、Turn 2、central claim、Parameterise éƒ―æēĄæœ‰é’‰å­ã€‚åļĶäļŠåŪƒæ— åŪģïžŒä―†åŊđæœŽæŽĄæ”đåŠĻäļčĩ·ä―œį”Ļ。
  • äšĪ叉垕į”Ļäŧį„ķ有效。 _Parameterise scenarios_ under wire-oracle harnesses åœĻ SKILL.md:918åŪƒåˆ—å‡šįš„įŧīåšĶ"åœä―æˆ–å–æķˆįš„æ˜Ŋ哊äļŠ turnïžšéĶ–äļŠïžŒčŋ˜æ˜ŊåŪŒæˆäļ€äļŠäđ‹åŽįš„后įŧ­é‚ĢäļŠ"æ­Ģæ˜ŊåŪžæĩ‹äū‹å­æ‰€äūčĩ–įš„ã€‚
  • 栞垏įŽĶ合 Prettier。 新åĒž markdown æŊčĄŒéƒ―äļčķ…čŋ‡ 80 列æŊäļŠæ–° expect įš„æĒčĄŒä―į―ŪäđŸå’Œ Prettier įš„æ–­čĄŒäļ€č‡īïžˆå•čĄŒå―Ē垏æ˜Ŋ 81 到 90 字įŽĶ。

äļ€äļŠäŋį•™æ„č§ïžŒéžé˜ŧåĄžâ€”â€”æŽĄč́ A/B æēĄæœ‰éĒ„įŪ—æ§―ä―ã€‚ 新åĨ子垚åˆķčĶæą‚åΚ做äļ€æŽĄ A/BïžŒä―†åŪƒä―äšŽįŽŽ 1 éĄđäđ‹å†…ïžŒč€ŒįŽŽ 1 éĄđįš„æ ‡éǘæ˜Ŋ"äļ­åŋƒäļŧåž įš„ A/B æ‰ŋč――æ€§čŊæ˜Žïžˆåŋ…做įšĶ占äļ€åŠéĒ„įŪ—ïž‰"。æēĄæœ‰äŧŧä―•įž–å·éĄđäļšæŽĄč́ A/B 列éĒ„įŪ—ïžŒč€ŒæœŽčŠ‚įŧ“å°ūå†™į€"å…ķä―™äļ€åˆ‡éƒ―明įĄŪäļåœĻ范å›ī内"äŧĨ及"Never let breadth eat the A/Bïžšäļ€äļŠčĒŦčŊæ˜Žįš„æ‰ŋč――æ€§äļŧåž čƒœčŋ‡åæĄæœŠéЌčŊįš„č§‚åŊŸ"——čŋ™äļŽåžšåˆķåΚ做äļ€æŽĄæ˜Ŋį›ļäš’įŸ›į›ūįš„ã€‚ä― įš„ D 臂æ­Ģæ˜Ŋčŋ™äļŠåŽ‹åŠ›æ˜ūįŽ°įš„åœ°æ–đïžšéĒ„įŪ—čŠąåœĻ乆 A/B、įŧīåšĶæŽĒ针和åĶåĪ–äļĪäļŠå‘įŽ°äļŠïžŒäšŽæ˜ŊæēĄč·‘变垂įŸĐé˜ĩ、Maven æēĄčĢ…čĩ·æĨ、Java äļ­åŋƒäļŧåž æœŠæ‰§čĄŒã€įŧ“čŪš inconclusive。åœĻå”Ŋäœ‰æ•°æŪįš„é‚ĢæŽĄčŋčĄŒé‡ŒïžŒčŋ™å°ąæ˜Ŋ"åđŋåšĶ吃掉䚆 A/B"。

指äŧĪä―äšŽæļ…单äđ‹å†…才æ˜Ŋᜟæ­Ģįš„æ”đčŋ›ïžŒč€Œ D 臂čŊæ˜Žäš†čŋ™äļ€į‚đ所äŧĨ我äļäžšå› æ­Īæ‹Ķä―čŋ™äļŠ PRã€‚ä―†å€žåū—äļ€äļŠåŽįŧ­ïžšč́äđˆįŧ™æŽĄč́ A/B äĄč‡Šå·ąįš„įž–å·éĒ„įŪ—čĄŒïžŒč́äđˆå†™æ˜ŽåۃæŒĪå įš„æ˜Ŋäŧ€äđˆâ€”—å°Īå…ķ因äļščŋ™äļŠæ–‡äŧķč‡Šå·ąįš„æĩ‹čŊ•åœĻ 6313 行å·ēįŧæŠŠčŋ™äļ€įąŧåĪąčīĨčŪ°å―•čŋ‡äļ‰æŽĄïžˆ"同äļ€įŧ“构性 bug įš„įŽŽäļ‰æŽĄå‡šįŽ°ïžšæŒ‡äŧĪčĒŦæ”ūåœĻ agent åŪžé™…éĩåūŠįš„æĩįĻ‹äđ‹åĪ–"ïž‰ã€‚å°ą diff 朎čšŦå…Žåđģ地čŊīïžšæŽĄč́äļŧåž äŧŽæĨå°ąæēĄæœ‰éĒ„įŪ—æ§―ä―ïžŒæœŽčŠ‚åž€åĪī及写䚆"åĪ–åŠ æœ€åΚäļĪäļŠæŽĄč́äļŧåž "ã€‚æ–°å‡šįŽ°įš„äļœčĨŋæ˜ŊåžšåˆķčĶæą‚äļ€äļŠã€‚

无å…ģé”Ūé˜ŧåĄžéĄđ无 AGENTS.md čŋč§„。

æĩ‹čŊ•čŊæŪ

čŋ™æ˜Ŋ无䚚倞åŪˆįš„ CI æĩįĻ‹ïžŒå› æ­Ī按é—ĻįĶč§„åˆ™æˆ‘æēĄæœ‰æž„åŧšã€æēĄæœ‰č·‘æĩ‹čŊ•、æēĄæœ‰æ‰§čĄŒäŧŧä―• PR åļĶæĨįš„äŧĢį ã€‚äļ‹éĒå…ĻéƒĻæ˜Ŋ通čŋ‡ API čŊŧåˆ°įš„ã€čŊĨ PR 臩čšŦåœĻčĒŦåŪĄæäšĪäļŠįš„ CI įŧ“果。į›Ū前æēĄæœ‰įšĒįš„æĢ€æŸĨïž›å†ģåۚčŋ™äļŠ PR įš„äļĪäļŠäŧåœĻčŋčĄŒïžŒæˆ‘äļäžšåŽŧč―ŪčŊĒåۃäŧŽã€‚

å…ģé”Ūįŧ†čŠ‚ïžštest ä―œäļšå…ˆč·‘ test:ci:workspacesį„ķ后äŧ…åœĻå…ķé€€å‡šį äļš 0 æ—ķč·‘ test:scriptsci.yml:787-790ïž‰â€”â€”č€Œ test:scripts å°ąæ˜Ŋ vitest run --config ./scripts/tests/vitest.config.tsåģæ‰§čĄŒ qwen-triage-workflow.test.js、čŋ›č€Œæ‰§čĄŒčŋ™å››äļŠé’‰å­įš„é‚ĢæĄ lane。åۃį›Ū前æ˜Ŋ in_progress所äŧĨ钉子įŧ“æžœčŋ˜æēĄå‡šæĨ。Test (macos-latest) 和 Test (windows-latest) éƒ―æ˜Ŋ skipped因æ­Ī钉子及åœĻ ubuntu äļŠčĒŦæ‰§čĄŒâ€”â€”čŋ™äļŽä― įš„æĩ‹čŊ•åđģ台čĄĻLinux ✅、macOS/Windows ⚠ïļïž‰äļ€č‡īåŊđįšŊ文朎æ”đåŠĻäđŸæēĄé—ŪéĒ˜ã€‚

ä― æœŽåœ°įš„æ•°å­—â€”â€”199 通čŋ‡ / 1 č·ģčŋ‡ã€Prettier 和 pre-commit ESLint įŧŋ——æ˜Ŋä― įš„åĢ°æ˜ŽïžŒäļæ˜Ŋ我åĪįŽ°įš„čŊæŪ。Lint & Static äŧåœĻčŋčĄŒïžŒæ‰€äŧĨ栞垏我äđŸčŋ˜æēĄæœ‰į‹ŽįŦ‹įĄŪčŪĪ。

朊銌čŊéĄđ及原因1新钉子æ˜ŊåĶ通čŋ‡â€”—跑åۃäŧŽįš„ä―œäļščŋ˜æēĄįŧ“束2æ”đåŠĻ文äŧķäļŠįš„ Prettier/ESLint——Lint & Static äŧåœĻčŋčĄŒïž›ïžˆ316/16 变垂å…Ļæ€įš„åĢ°æ˜Žâ€”â€”å˜åž‚įŸĐé˜ĩäļæ˜Ŋ我åœĻčŋ™é‡Œčƒ―é‡č·‘įš„äļœčĨŋäđŸäļæ˜ŊäĄ CI lane。

CI čĄĻæ žč§ä–đč‹ąæ–‡éƒĻåˆ†įš„æ ‡čŪ°åŒšåŸŸïžŒæ­ĪåĪ„äļé‡åĪã€‚ïž‰

æē™įŪąéŠŒčŊ

čŋ™é‡Œįš„äļ­åŋƒäļŧåž æ˜Ŋ行äļšæ€§įš„——按 diff č§Ķå‘įš„æĄäŧķæ˜ŊåĶįœŸįš„į”Ÿæ•ˆã€åđķéĐąåŠĻ agent 列凚圚æ™ŊįŧīåšĶ——äļŠéĒįš„é™æ€åŪĄæŸĨ和 CI éƒ―æ— æģ•čŊåŪžåŪƒã€‚test:scripts 变įŧŋåŠčƒ―čŊæ˜Žé’‰å­äļŽæ–‡æœŽåŒđ配åیå…Ļäļčƒ―čŊŽčŊŧ到čŋ™æŪĩæ–‡æœŽįš„ agent 行äļšæœ‰æ‰€äļåŒã€‚

åœĻčŋ™į§æƒ…å†ĩäļ‹åĨ—į”Ļåļļ规 lane 及䞚æ˜Ŋ噊éŸģ所äŧĨ我čŊīåū—æ›īå…·ä―“äš›ïžš@qwen-code /verify 无æģ•åœĻ合å…Ĩ前č§Ģå†ģčŋ™äļ€į‚đïžŒåŽŸå› ä― å·ēįŧå†™æ˜Žâ€”—CI verify lane 侚äŧŽ base 分æ”ŊæĒåĪ .qwen所äŧĨåŊđæœŽ PR č·‘äļ€æŽĄčŊŧåˆ°įš„æ˜Ŋæ—§æŠ€čƒ―ïžŒæ–°é’‰å­æŒ‰čŪūčŪĄæ˜ūįĪšäļšįšĒã€‚ä― æœ‰å†™æƒé™ïžŒå› æ­Īčŋ™æĄ lane åŊđä― åŊį”Ļ、äļéœ€čĶæ‹…äŋïž›åŠæ˜ŊåœĻčŋ™é‡Œåۃæ˜Ŋé”™įš„å·Ĩ具。

ᜟæ­Ģčƒ―č§Ģå†ģåŪƒįš„æ˜Ŋ合å…Ĩäđ‹åŽïžšåœĻäļ€äļŠäļæ˜Ŋčŋ™æĄč§„则æĨæšįš„į›Ū标äļŠé‡č·‘äļ€č‡‚ã€‚ä― č‡Šå·ąåœĻ Risk & Scope 里写䚆čŋ™æŽĄæŠ“åˆ°åąžäšŽæ ·æœŽå†…ã€æŊč‡‚åŠč·‘äļ€æŽĄâ€”â€”č§„åˆ™å’ŒåŪžæĩ‹äū‹å­éƒ―æšč‡Š #13174 R9ïžŒč€Œäū‹å­į‚đå‡šįš„æ­Ģæ˜Ŋ D č‡‚æ°åĨ―æŽĒæĩ‹įš„é‚ĢäļŠčŪūį―ŪčŪĐ Turn 1 先åŪŒæˆå†åœä― Turn 2。D 臂čŊŽč§Ķå‘æĄäŧķäžšį”Ÿæ•ˆã€agent äžšį…§åšïž›åۃäļčƒ―čŊŽčŋ™æĄč§„åˆ™čƒ―æ‰ū凚åŪƒæ‰€æĨ暐äđ‹åĪ–įš„įžšé™·ïžŒč€Œčŋ™æ­Ģæ˜Ŋæ‰ŋč――åˆå…Ĩå†ģåŪšįš„é‚ĢäļŠäļŧ垠。čŋ™äļ€į‚đ倞åū—åœĻ后įŧ­é‡Œå†™æ˜ŽïžŒč€Œäļæ˜Ŋį•™į€čŪĐäššč‡Šå·ąæŽĻ断。

ᜟåŪžåœšæ™Ŋæĩ‹čŊ•

N/A——无䚚倞åۈ CI čŋčĄŒã€‚tmux ᜟåŪžåœšæ™ŊéĐąåŠĻäŧ…适į”ĻäšŽæœŽåœ°č°ƒį”ĻïžŒč€ŒäœŽæŽĄæ”đåŠĻæēĄæœ‰į”Ļ户åŊč§įš„ TUI į•ŒéĒïžšåۃæ˜Ŋ agent æŠ€čƒ―æ–‡æœŽåŠ äļ€äļŠ workflow æĩ‹čŊ•。

— Qwen Code · qwen3.8-max-2026-09-02

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

@qwen-code-review-bot

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — the trigger re-key is minimal, demonstrably needed and pinned; the one reservation is a budget ambiguity the author already half-disclosed, not a defect.

Stepping back. My independent proposal and this PR are the same shape: the trigger was keyed to how the agent frames its claim, which nothing outside the agent can observe, so keying it to the diff is the obvious correction — and it is the option #13813 itself left on the table as untested. I did not find a simpler path, and I do not think one exists. Five net lines of skill text, four assertions, no machinery added.

Does it solve something anyone cares about? The consumer is the verify lane, not an end user, but a rule that never fires is dead weight in an always-read skill — #13813 shipped it, arm C proved it inert, and leaving it would mean every future run pays the reading cost for an instruction that never applies. So yes, this earns its place.

The honest split in what I am approving. I am approving the trigger re-key, which is demonstrated: the diff shows the rule now keys off an observable property, the four pins bite (verified statically against the whitespace-normalized slice), no other test in scripts/ or .github/ asserts on the deleted wording, and the second slice of the same section is untouched. I am not certifying the generalization — that this rule finds defects it was not authored from. Arm D is in-sample, ran once, and the measured example names the exact setting it probed. The PR says so itself, which is why this is a 4 and not a 5 rather than a reason to block: the unproven part is disclosed, and the proven part is what is merging.

Six months from now I would thank the author, not curse them. A trigger keyed to the diff is checkable by anyone reading the report; one keyed to the claim required reading the agent's mind. The residual maintenance cost is the budget question from Stage 2, and it is small enough to defer.

Two things I want on the record rather than buried:

  1. Give the secondary A/B a budget line, or say what it displaces. Item 1 is titled "A/B load-bearing proof of the central claim (always, ~half the budget)", the section closes with "Never let breadth eat the A/B", and now a non-central turn-lifecycle change mandates an extra A/B with no numbered slot. Arm D is the evidence: no mutation matrix, Java claim unexecuted, inconclusive. Follow-up material, not a blocker.
  2. Pattern check, since this is the third in a series (docs(verify-pr): add local-round publish, follow-up, mutation and rig rules #13756, docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813, now this). I asked myself whether I am being worn down by volume. I do not think so — each of the three landed one discrete, evidence-backed rule and this one is five net lines, not an accretion. But the series is steadily growing a skill that is read on every verify run, and the budget list is exactly where that pressure will surface next. Worth a maintainer's eye on the aggregate at some point, not on this PR.

Am I being a pushover? I do not think so. I have a real reservation, I stated it in both stages, and I am not approving to avoid friction — I am approving because the load-bearing change is correct, minimal, and pinned, and because the gap I found is a disclosed scope limitation rather than a defect in the diff.

Approval deferred until CI lands green on 0e59ea1924d931462f80db2f3b02b7da2240be49. The test job — the one that runs test:scripts, and therefore these pins — was still in flight at review time, along with Lint & Static. Approving now would attest to a result that does not exist yet, so this comment carries the deferred-approval instruction and the finalize workflow will post the commit-pinned approval once every check on that SHA completes green. If anything lands red, or the head moves, it withholds and flags instead.

äļ­æ–‡čŊŽ

äŋĄåŋƒïžš4/5 —— č§Ķå‘æĄäŧķįš„é‡æŒ‚æ˜Ŋ最小æ”đåŠĻ、įĄŪ有åŪžčŊéœ€čĶã€åđķäļ”å·ēčĒŦé’‰ä―ïž›å”Ŋäļ€įš„äŋį•™æ„č§æ˜Ŋä―œč€…å·ēéƒĻ分æŠŦéœēįš„éĒ„įŪ—åŦįģŠïžŒäļæ˜Ŋįžšé™·ã€‚

退ä­Ĩįœ‹ã€‚æˆ‘įš„į‹ŽįŦ‹æ–đæĄˆå’Œčŋ™äļŠ PR å―ĒįŠķäļ€č‡īïžšč§Ķå‘æĄäŧķ原朎挂åœĻ agent åĶ‚ä―•čĄĻčŋ°äļŧåž äļŠïžŒč€Œčŋ™åœĻ agent äđ‹åĪ–æ— æģ•č§‚æĩ‹ïžŒæ‰€äŧĨæ”đ挂到 diff ä˜Ŋæ˜ūč€Œæ˜“č§įš„äŋŪæ­Ģ——而äļ”čŋ™æ­Ģæ˜Ŋ #13813 č‡Šå·ąåˆ—äļš"尚朊æĩ‹čŊ•"č€Œį•™äļ‹įš„é‚ĢäļŠé€‰éĄđ。我æēĄæœ‰æ‰ū到æ›īįŪ€å•įš„č·Ŋåū„äđŸäļčŪĪäļšå­˜åœĻã€‚æŠ€čƒ―æ–‡æœŽå‡€åĒž 5 čĄŒã€å››æĄæ–­čĻ€ïžŒæēĄæœ‰æ–°åĒžæœšåˆķ。

åۃč§Ģå†ģįš„æ˜Ŋ有䚚åœĻæ„įš„äļœčĨŋ吗æķˆčīđ者æ˜Ŋ verify laneäļæ˜ŊįŧˆįŦŊį”Ļæˆ·ïž›ä―†äĄæ°ļäļč§Ķå‘įš„č§„åˆ™ïžŒåœĻäļ€äļŠæŊæŽĄéƒ―侚čĒŦčŊŧå–įš„æŠ€čƒ―é‡Œå°ąæ˜ŊįšŊįēđįš„é‡é‡â€”â€”#13813 把åŪƒåˆäš†čŋ›æĨC 臂čŊæ˜Žåۃæ˜Ŋæ­ŧįš„ïžŒį•™į€åŪƒæ„å‘ģį€äŧŠåŽæŊäļ€æŽĄčŋčĄŒéƒ―č́äļšäĄæ°ļäļé€‚į”Ļįš„æŒ‡äŧĪäŧ˜å‡šé˜…čŊŧ成朎。所äŧĨåۃįŦ™åū—ä―ã€‚

我č́čŊšåŪžåŒšåˆ†æˆ‘åœĻæ‰đ准äŧ€äđˆã€‚我æ‰đå‡†įš„æ˜Ŋč§Ķå‘æĄäŧķįš„é‡æŒ‚ïžŒčŋ™äļ€į‚đ有åŪžčŊïžšdiff æ˜ūįĪšč§„åˆ™įŽ°åœĻäūčĩ–äļ€äļŠåŊ观æĩ‹åąžæ€§ïž›å››äļŠé’‰å­æœ‰æ•ˆïžˆæˆ‘é’ˆåŊđå―’äļ€åŒ–åŽįš„åˆ‡į‰‡åšäš†é™æ€æ ļåŊđscripts/ 和 .github/ 里æēĄæœ‰åˆŦįš„æĩ‹čŊ•æ–­čĻ€äūčĩ–čĒŦ删é™Īįš„æŽŠčūžïž›åŒäļ€å°čŠ‚įš„įŽŽäšŒåĪ„åˆ‡į‰‡æœŠčĒŦæ”đåŠĻ。我æēĄæœ‰äļšæ™Ūé€‚æ€§čƒŒäđĶ——åģčŋ™æĄč§„åˆ™čƒ―æ‰ū凚åŪƒæ‰€æĨ暐äđ‹åĪ–įš„įžšé™·ã€‚D č‡‚åąžäšŽæ ·æœŽå†…ã€åŠč·‘äš†äļ€æŽĄïžŒč€ŒåŪžæĩ‹äū‹å­į‚đå‡šįš„æ­Ģæ˜ŊåۃæŽĒæĩ‹įš„é‚ĢäļŠčŪūį―Ū。PR č‡Šå·ąäđŸčŋ™äđˆå†™äš†ïžŒčŋ™æ­Ģæ˜Ŋåۃæ‹ŋ 4 åˆ†č€Œäļæ˜Ŋ 5 åˆ†įš„åŽŸå› ïžŒč€Œäļæ˜Ŋæ‹Ķ戊åŪƒįš„į†į”ąïžšæœŠčĒŦčŊæ˜Žįš„é‚ĢéƒĻ分å·ēįŧæŠŦéœēïžŒč€ŒčĒŦčŊæ˜Žįš„é‚ĢéƒĻ分才æ˜Ŋčŋ™æŽĄč́合å…Ĩįš„ã€‚

半åđīäđ‹åŽæˆ‘䞚感č°Ēä―œč€…ïžŒč€Œäļæ˜Ŋ埋æ€Ļ。挂åœĻ diff äļŠįš„č§Ķå‘æĄäŧķäŧŧä―•äšščŊŧæŠĨå‘Šéƒ―čƒ―æ ļåŊđ挂åœĻäļŧåž äļŠįš„č§Ķå‘æĄäŧķ需č́åŽŧጜ agent åœĻæƒģäŧ€äđˆã€‚å‰Đäļ‹įš„įŧοˆæœŽå°ąæ˜Ŋ Stage 2 é‡Œįš„éĒ„įŪ—é—ŪéĒ˜ïžŒå°åˆ°åŊäŧĨåŧķ后。

有äļĪäŧķ䚋我č́写åœĻ明åĪ„ïžŒč€Œäļæ˜Ŋ埋čĩ·æĨïžš

  1. įŧ™æŽĄč́ A/B äĄéĒ„įŪ—čĄŒïžŒæˆ–č€…å†™æ˜ŽåۃæŒĪ占äŧ€äđˆã€‚ įŽŽ 1 éĄđįš„æ ‡éǘæ˜Ŋ"äļ­åŋƒäļŧåž įš„ A/B æ‰ŋč――æ€§čŊæ˜Žïžˆåŋ…做įšĶ占äļ€åŠéĒ„įŪ—ïž‰"ïžŒæœŽčŠ‚įŧ“å°ūå†™į€"Never let breadth eat the A/B"ïžŒč€ŒįŽ°åœĻäļ€æŽĄéžäļ­åŋƒįš„ turn į”Ÿå‘―å‘Ļ期æ”đåŠĻčĒŦåžšåˆķčĶæą‚åΚ做äļ€æŽĄ A/BåīæēĄæœ‰įž–å·æ§―ä―ã€‚D č‡‚å°ąæ˜ŊčŊæŪïžšæēĄč·‘变垂įŸĐé˜ĩ、Java äļŧåž æœŠæ‰§čĄŒã€įŧ“čŪš inconclusive。čŋ™æ˜Ŋ后įŧ­ææ–™ïžŒäļæ˜Ŋé˜ŧåĄžéĄđ。
  2. æĻĄåžæĢ€æŸĨ因äļščŋ™æ˜Ŋįģŧåˆ—é‡Œįš„įŽŽäļ‰äļŠïžˆdocs(verify-pr): add local-round publish, follow-up, mutation and rig rules #13756、docs(verify-pr): name scenario axes in scope selection and attribute merge-only reds #13813、äŧĨåŠæœŽæŽĄïž‰ã€‚æˆ‘é—Ūčŋ‡č‡Šå·ąæ˜Ŋäļæ˜ŊčĒŦ数量įĢĻč―Ŋ䚆。我čŪĪäļšæēĄæœ‰â€”—äļ‰æŽĄå„č‡Šč―åœ°äš†äĄįĶŧæ•Ģįš„ã€æœ‰åŪžčŊæ”Ŋæ’‘įš„č§„åˆ™ïžŒč€Œčŋ™äļ€æŽĄæ˜Ŋ净åĒž 5 čĄŒïžŒäļæ˜Ŋ堆į§Ŋã€‚ä―†čŋ™äļŠįģŧ列įĄŪåŪžåœĻčŪĐäļ€äļŠæŊæŽĄ verify čŋčĄŒéƒ―侚čŊŧå–įš„æŠ€čƒ―æŒįŧ­åĒžé•ŋïžŒč€ŒéĒ„įŪ—æļ…单æ­Ģæ˜Ŋčŋ™į§åŽ‹åŠ›äļ‹æŽĄäžšæ˜ūįŽ°įš„åœ°æ–đ。某äļŠæ—ķį‚đ倞åū—įŧĪč€…įœ‹äļ€įœžæ€ŧé‡ïžŒä―†äļåŋ…č―åœĻčŋ™äļŠ PR äļŠã€‚

我æ˜Ŋäļæ˜ŊåœĻå―“č€åĨ―䚚我äļčŪĪäļšã€‚我有äļ€äļŠįœŸåŪžįš„äŋį•™æ„č§ïžŒåœĻäļĪäļŠé˜ķæŪĩéƒ―å†™æ˜Žäš†ïž›æˆ‘æ‰đ准äļæ˜Ŋäļšäš†éŋ免æ‘Đæ“ĶïžŒč€Œæ˜Ŋ因äļšæ‰ŋč――æ€§įš„æ”đåŠĻæ˜Ŋæ­ĢįĄŪ、最小äļ”čĒŦé’‰ä―įš„ïžŒč€Œæˆ‘å‘įŽ°įš„įžšåĢæ˜Ŋäļ€äļŠå·ēæŠŦéœēįš„čŒƒå›ī限åˆķäļæ˜Ŋ diff é‡Œįš„įžšé™·ã€‚

æ‰đ准æŽĻčŋŸåˆ° CI åœĻ 0e59ea1924d931462f80db2f3b02b7da2240be49 äļŠå…Ļįŧŋäđ‹åŽã€‚ test ä―œäļšâ€”—äđŸå°ąæ˜ŊčŋčĄŒ test:scripts、čŋ›č€ŒčŋčĄŒčŋ™äš›é’‰å­įš„é‚ĢäļŠâ€”—åœĻåŪĄæŸĨæ—ķäŧåœĻæ‰§čĄŒïžŒLint & Static äđŸæ˜Ŋã€‚įŽ°åœĻæ‰đå‡†į­‰äšŽäļšäļ€äļŠčŋ˜äļå­˜åœĻįš„įŧ“æžœčƒŒäđĶ所äŧĨæœŽæĄį•™čĻ€åļĶäļŠäš†æŽĻčŋŸæ‰đå‡†įš„æŒ‡äŧĪfinalize å·Ĩä―œæĩäžšåœĻčŊĨ SHA ä‰€æœ‰æĢ€æŸĨįŧŋ乆äđ‹åŽïžŒæäšĪįŧ‘åۚ到čŊĨ提äšĪįš„æ‰đ准。åĶ‚æžœæœ‰æĢ€æŸĨ变įšĒïžŒæˆ–č€… head å‘į”Ÿį§ŧåŠĻåŪƒäžšæ”đäļšäļäšˆæ‰đ准åđķæ ‡å‡šįŠķ态。

— Qwen Code · qwen3.8-max-2026-09-02

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

@qwen-code-review-bot qwen-code-review-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 — CI landed green after the review. ✅

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM — docs-only change keying the verify-pr turn-axes rule to the diff. CI green on the required checks; approving per maintainer request.

@yiliang114
yiliang114 added this pull request to the merge queue Oct 10, 2026
Merged via the queue into main with commit 2d4c5be Oct 10, 2026
73 of 74 checks passed
@wenshao
wenshao deleted the docs/verify-pr-turn-axes-diff-trigger branch October 10, 2026 15:53
@qwen-code-review-bot

Copy link
Copy Markdown
Collaborator

Released in v0.25.1.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants