feat(review): carry the fix's premises beside its claim — add fixConstraint - #10168
Conversation
…traint `fixWitness` (#9596) pins what a suggested fix claims: the test that reds when the fix is removed. Nothing pinned what a fix assumes — the premises it newly introduces — and those are a different defect class that passes a witnessed test cleanly. Two Criticals on the merged nested-approval fix (#9793) were both of this class and both had a fixWitness-grade test: a hand-picked `hops < 16` lineage cap below the user-configurable `MAX_SUBAGENT_DEPTH_LIMIT = 100` reintroduced the very hang the fix was for, and parking several runtimes' approvals on one registry entry broke a `callId` uniqueness dedup and resolve relied on elsewhere, routing a user's answer to the wrong agent. The agent that found each defect had already run the greps that name the fact, so the marginal cost of carrying it is close to zero. The finding gains one optional field beside `fixWitness`, carried the same way: `fixConstraint` — an existing fact the fix must not violate, with its source. It reaches the finder brief (`FINDING_FORMAT`), the skill's Step 6 list and Step 4 aggregate slot, the artifact field list, and Step 7's posting rule, so the human fixer reading the comment — the loop with no other brake — sees it. Two properties differ from the sibling field, and both are deliberate. It is omitted when nothing was observed, never `N/A`: an absent constraint carries no information and would lengthen every posted comment (#9177). `validateFindings` normalises a literal `N/A`/`none` to absence so the poster keys on presence alone, and a finder that copies the fixWitness habit cannot hand it a placeholder to post. And its evidence bar is the `witness` bar, not the `fixWitness` bar — quote the constant or give the `file:line`, or omit — because the costs are asymmetric: a wrong fixWitness is one test not written; a wrong constraint is confidently-stated misdirection the fixer will follow. "Be careful about concurrency" is forbidden in the field the way "this looks risky" is forbidden in the failure scenario. Like fixWitness, the field never gates reporting. Pinned at every site: the validator (round-trip, snake_case, placeholder drop, and the drop's narrowness), the built finder brief (format line, omission clause, evidence bar, forbidden prose, claim/premise split), and the skill corpus (Step 6 item, aggregate slot, field list, posting rule, and the no-`N/A` silence clause). DESIGN.md records the incident. Closes #10153
|
Thanks for the PR! Template looks good ✓ — all sections present, bilingual, and the Reviewer Test Plan names the exact suites and what each pin proves. Problem: observed, not theoretical. The linked issue #10153 documents two concrete Criticals on the merged nested-approval fix (#9793) — a hand-picked Direction: aligned. This extends the review loop's existing machinery the way Size: core paths touched ( Approach: scope feels right, and the post-review commits prove the point. Since the first pass, four commits landed closing real loss paths the review rounds found: dedup merges kept the most detailed description and silently dropped a constraint only the other copy recorded; a Critical relocated to Risk: no elevated risk signals — none of the changed files matches the revert-correlated paths. Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ —— 各节齐全,中英双语,评审者测试方案写明了具体套件和每个钉子证明什么。 问题:已观测到,非理论性问题。关联 issue #10153 记录了已合入的嵌套审批修复(#9793)中的两个具体 Critical——手写的 方向:对齐。这是对评审循环既有机制的延伸,方式与 规模:触及核心路径( 方案:范围合理,且评审后的提交恰好证明了这一点。首轮之后落地的四个提交关闭了评审轮发现的真实丢失路径:dedup 合并保留最详细描述、悄悄丢掉只有另一份副本记录的约束;被移入 风险:无升级风险信号——改动文件均不命中与 revert 相关的高风险路径。 进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewReviewed against the full current diff (8 files, +294/−7), including the four commits landed since the first triage pass. The implementation mirrors the shipped Findings: none blocking.
No sequence diagram or files table — a small, focused change whose shape the paragraphs above cover. Test evidence — the PR's own CI (unattended run; PR code is never executed here)CI on the reviewed commit
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 The author's claimed suite numbers (103 files / 5101 passed in No sandboxed-lane line: there is no behavioural claim for 中文说明代码审查对照当前完整 diff 审查(8 个文件,+294/−7),包括首轮分诊之后落地的四个提交。实现与已上线的 无阻塞性发现。
无时序图与文件表——小而聚焦的改动,上面几段已覆盖其形状。 测试证据 —— PR 自身 CI(无人值守运行;此处从不执行 PR 代码)评审提交 作者的套件数字( 无沙箱验证行:没有需要 — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 5/5 — clean across every stage: a documented defect class, a sibling-faithful implementation, every survival site pinned by a test, and four review rounds' loss paths closed and pinned rather than argued away. Stepping back: the independent proposal I wrote before reading the diff — an optional premise field beside The diff remains minimal — 50 production lines and 22 corpus lines, every file a site the field must survive — and backward compatibility is pinned, not asserted: an absent field validates exactly as before, and the round-trip test holds it there. If I'm maintaining this in six months, the incident-cited comments and the DESIGN.md entry tell me why every clause exists. CI is fully settled on the reviewed commit: unit suite green, desktop-shell and web-shell smokes green, security checks green; the skipped matrix legs are the classifier baseline, same shape as the first commit's finalized table. One bookkeeping note: the outstanding changes-requested review on this PR is this same bot account's, from a Approving, pinned to the reviewed commit. ✅ 中文说明置信度:5/5 —— 各阶段全部干净:有记录的缺陷类别、与兄弟字段同构的实现、每处存活位置都有测试钉住、四个评审轮发现的丢失路径全部关闭并被钉住,而不是被辩解掉。 退一步看:我在读 diff 之前写下的独立方案—— diff 仍然最小——50 行生产代码、22 行语料,每个文件都是字段必须存活的一处——向后兼容是被钉住的而非声称的:缺省字段的校验行为与之前完全一致,往返测试把它钉在那里。六个月后维护它时,引事件的注释与 DESIGN.md 条目会告诉我每条子句为何存在。评审提交上的 CI 已全部落定:单测套件绿,desktop-shell 与 web-shell 冒烟绿,安全检查绿;被跳过的矩阵分支是分类器基线,与首个提交的最终表格同形。 一条簿记说明:本 PR 上未解决的 changes-requested 评审来自本 bot 账号自己,是 批准,钉在所评审的提交上。✅ — Qwen Code · qwen3.8-max Reviewed at |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship — CI landed green after the review. ✅
|
@qwen-code /takeover |
|
🤝 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. Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
Not explored to full depth (tool budget reached): "agent 3b": none — no check was cut short..
Test Plan (not a blocker): 5101 passed — this review observed 1735, 1662, 605, 4290, 638 passed.
中文说明
已审查。 建议见行内评论。
未探索到全部深度(达到工具调用预算):"agent 3b":none — no check was cut short.。
Test Plan(非阻断):5101 passed — this review observed 1735, 1662, 605, 4290, 638 passed。
— qwen3.8-max via Qwen Code /review (v0.22.2)
…straint (#10168) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Address-review summary — PR #10168 (round after review 2026-08-26T14:05:34Z)Feedback points and dispositions[rc:3864179794] R1-2 — [Suggestion]
|
wenshao
left a comment
There was a problem hiding this comment.
Test Plan (not a blocker): 5101 passed — this review observed 24965, 21906, 1735, 1662, 610, 4290, 638 passed.
中文说明
Test Plan(非阻断):5101 passed — this review observed 24965, 21906, 1735, 1662, 610, 4290, 638 passed。
— gpt-5.6-sol via Qwen Code /review (v0.22.0)
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not explored to full depth (tool budget reached): "agent 1a": running findings.test.ts / agent-prompt.test.ts / SKILL.test.ts under vitest (no node_modules in worktree; npm ci not attempted).
Test Plan (not a blocker): 5101 passed — this review observed 24978, 21909, 1735, 1662, 605, 4290, 638 passed.
Deferred under the convergence posture (round 2, not a blocker) — recorded, not requested in this round:
packages/core/src/skills/bundled/review/SKILL.md:1112 — [review] Guidelines summary lacks the sibling fix-constraint bulletpackages/core/src/skills/bundled/review/SKILL.md:688 — [review] pattern-aggregate fix-constraint slot has no multi-constraint merge rule
中文说明
未探索到全部深度(达到工具调用预算):"agent 1a":running findings.test.ts / agent-prompt.test.ts / SKILL.test.ts under vitest (no node_modules in worktree; npm ci not attempted)。
Test Plan(非阻断):5101 passed — this review observed 24978, 21909, 1735, 1662, 605, 4290, 638 passed。
收敛姿态下延后(第 2 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.2)
…l relocation (#10168) Both round-1 Criticals name sites where the new field can be dropped on its way to the fixer. Step 4's deduplication and the two pair-loop dedup bullets kept the most detailed description, the highest severity, and the source tags — never a fix-side field — so two agents reporting one root cause lost the constraint only the less detailed copy recorded, before canonicalization ever saw the record. The merge rule now keeps every sourced constraint: consistent ones combined, conflicting ones adjudicated explicitly instead of silently discarded. The posting rule also scoped the constraint sentence to inline comment bodies, but a Critical whose locations all fail anchor resolution moves to bodyCriticals — the finding's sole published copy. The posting rule and the compose-state field now both require that entry to append the constraint sentence, copied from the artifact. Each requirement is pinned by a static SKILL.test.ts assertion that reds when its clause is removed (mutation-probed), and both new tests red against the pre-fix prose. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Autofix round summary — PR #10168 (review round 3)One batch addressed both Critical findings, each filed in round 1 and re-filed R1-2 — Pre-verification deduplication can discard the only
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline.
Test Plan (not a blocker): 5101 passed — this review observed 21911, 1735, 24978, 1662, 605, 4290, 638 passed.
Deferred under the convergence posture (round 3, not a blocker) — recorded, not requested in this round:
packages/core/src/skills/bundled/review/SKILL.md:688 — [review] pattern-aggregate fix-constraint slot has no multi-constraint merge rule (deferred under the convergence posture — code unchanged since round 2, already deferred there)
Convergence: round 3 posted 2 inline comment(s), 2 of them reported for the first time; the previous round posted 2 (0 new). Findings keep coming back to the same files: packages/core/src/skills/bundled/review/SKILL.md (findings in round 1; 1 more now); packages/core/src/skills/bundled/review/references/posting.md (findings in round 1; 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.)
中文说明
已审查——无阻断问题。 建议见行内评论。
Test Plan(非阻断):5101 passed — this review observed 21911, 1735, 24978, 1662, 605, 4290, 638 passed。
收敛姿态下延后(第 3 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
收敛情况:第 3 轮发布了 2 条行内评论,其中 2 条是首次提出;上一轮发布了 2 条(其中 0 条首次提出)。发现反复回到同一批文件:packages/core/src/skills/bundled/review/SKILL.md(第 1 轮已出过发现,本轮又有 1 条);packages/core/src/skills/bundled/review/references/posting.md(第 1 轮已出过发现,本轮又有 1 条)。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。本轮没有未决的 Critical,因此"合入后把剩余 Suggestion 线程转到后续 issue"是一个可选的结束方式——已合入的 PR 不会继续发散。(仅为观察——本轮评审未因此扣留任何内容。)
— qwen3.8-max via Qwen Code /review (v0.22.2)
…itical relocation (#10168)
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Autofix round summary — PR #10168 (address-review)Round 4 addressing round-3 feedback: two inline Suggestion findings from the automated reviewer, no Criticals, no failed checks, no conflict ( Feedback points and dispositions1. R3-1 —
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed. Suggestions are inline.
Not reviewed: reverse audit — stopped before round 8 by the review time budget.
Test Plan (not a blocker): 5101 passed — this review observed 21911, 1735, 24981, 1662, 605, 4290, 638 passed.
Deferred under the convergence posture (round 4, not a blocker) — recorded, not requested in this round:
packages/core/src/skills/bundled/review/SKILL.test.ts:882 — [probe] Dedup pin guards adjudication's opening, not its resolution rulepackages/core/src/skills/bundled/review/SKILL.test.ts:855 — [probe] Constraint sentence's severity-invariance clause unpinned
Convergence: round 4 posted 3 inline comment(s), 3 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/skills/bundled/review/references/posting.md (findings in round 3; 3 more now). The rate of new findings is not falling. 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. Batching the remaining fixes and verifying them before the next push, or dropping this PR's reviews to --severity-floor critical, keeps the loop from re-deriving the same set. 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.)
中文说明
仅完成部分审查,审查缺口已披露。 建议见行内评论。
未审查:反向审计——评审时间预算不足,未能开始第 8 轮。
Test Plan(非阻断):5101 passed — this review observed 21911, 1735, 24981, 1662, 605, 4290, 638 passed。
收敛姿态下延后(第 4 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。
收敛情况:第 4 轮发布了 3 条行内评论,其中 3 条是首次提出;上一轮发布了 2 条(其中 2 条首次提出)。发现反复回到同一批文件:packages/core/src/skills/bundled/review/references/posting.md(第 3 轮已出过发现,本轮又有 3 条)。新发现的产出速度没有下降。一个不断再生兄弟发现的簇,通常意味着逐条修复只在处理同一根因的实例——先定位并处理该根因,或把独立的簇拆成单独的 PR,通常比逐条修复更快结束循环。把剩余修复攒成一批、验证后再推送,或将本 PR 的评审降到 --severity-floor critical,可以避免循环反复推导同一组发现。本轮没有未决的 Critical,因此"合入后把剩余 Suggestion 线程转到后续 issue"是一个可选的结束方式——已合入的 PR 不会继续发散。(仅为观察——本轮评审未因此扣留任何内容。)
— qwen3.8-max via Qwen Code /review (v0.22.2)
…hannels (#10168) Three suggestions on the fixConstraint posting paragraph, one cluster. The carry-mandate clause — the operative half of the rule — had no assertion: the heading was pinned but the sentence was not, so an edit weakening "the posted body carries it" shipped green. The placement instruction, "beside the fix-witness sentence", underdetermined the position: the fix-witness rule closes the body with the witness, so immediately before it is the only consistent place, and a finding whose `fixWitness` is `N/A` had no referent to stand beside at all. The paragraph now fixes the order, names the N/A fallback (the constraint sentence takes the witness's place after the suggestion block), and states the same order for a `bodyCriticals` entry that carries both sentences. The paragraph also scoped the accepted loss to the Aone submit-time relocation, leaving two structurally identical channels unnamed: the deferral rendering (a `DeferredEntry` holds no fix-side field and the line caps at 240 characters) and the duplicate-drop account (name and location only, never the finding's own text). Both are now named beside the Aone residue; the loss stays a named acceptance, not a silent one. Each new clause is pinned by a toContain assertion in SKILL.test.ts; six mutation probes (weaken the mandate, delete the placement, the fallback, the order clause, or either channel naming) all red the tests, and the restored suite is green. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 4/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 4/100 轮)。改动内容与我反驳保留之处如下: Address review summary — PR #10168Three inline Suggestions, all on the same fixConstraint paragraph in Feedback points and decisions[rc:3867942213] R3-2 (fix-induced): two loss channels left unnamed — RESOLVEDClaim verified against the code before editing: Change: the fixConstraint paragraph now names both exits beside the Aone [rc:3867942216] Placement clause underdetermines placement — RESOLVEDClaim verified against the corpus: "beside the fix-witness sentence" was the Change: the paragraph fixes the order and names the fallback in the same [rc:3867942219] Carry-mandate clause pinned by no assertion — RESOLVEDClaim verified: "the posted body carries it" appeared only in posting.md; no Change: added the exact proposed assertion to Review-level items — nothing requested
Files changed
Conflict notesNone ( Verification
Note: no Critical or Request-changes finding was open this round, so the 中文说明处理评审总结 — PR #10168三条行内 Suggestion,全部集中在 反馈点与决定[rc:3867942213] R3-2(修复引发):两个丢失通道未点名 — 已解决编辑前已对照代码核实: 修改:fixConstraint 段落现在在 Aone 残留旁点名这两个出口——"另有两次移动存在且均不 [rc:3867942216] 放置子句无法确定位置 — 已解决对照语料核实:原放置指令只有"紧挨修复见证句(beside)";而修复见证规则要求正文以见证 修改:段落在同一句中固定顺序并点名兜底——"紧挨修复见证句之前,见证句仍为正文收尾—— [rc:3867942219] 携带义务子句无任何断言钉住 — 已解决核实:全库搜索显示 "the posted body carries it" 只出现在 posting.md 中,没有任何断言 修改:在 评审级条目 — 无待办
变更文件
冲突说明无( 验证
说明:本轮没有未决的 Critical 或 Request-changes 发现,因此变更的测试属于覆盖新增; 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/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
2 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- Constraint sentence's severity/report-invariance clause unpinned (posting.md:43) — already disclosed in the round-4 deferred list (review 5036380101)
- Dedup adjudication resolution clause unpinned (SKILL.test.ts:897) — already disclosed in the round-4 deferred list (review 5036380101)
Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 10.
Test Plan (not a blocker): 5101 passed — this review observed 1735, 24978, 1662, 605, 4290, 638 passed.
7 Suggestion(s) were drafted inline past the resolved critical posting floor — the floor engaged early: the first-time-finding rate has not fallen for 2 consecutive round(s); the CLI moved them into the deferral list below (floor enforcement).
Deferred under the convergence posture (round 5, not a blocker) — the floor engaged early: the first-time-finding rate has not fallen for 2 consecutive round(s) — recorded, not requested in this round:
packages/core/src/skills/bundled/review/SKILL.test.ts:829 — [review] R5-1: This test's comment defines half 3's witness-grade evidence property as holding "at both sites", but the format-site evidence-grade clause — SKILL.md:805's parenthet…packages/core/src/skills/bundled/review/SKILL.test.ts:937 — [review] R5-2: This compose-site pin stops at appends the corresponding sentence , leaving SKILL.md:970's provenance-and-ban tail — , copied from the artifact — the only publishe…packages/core/src/skills/bundled/review/references/posting.md:43 — [review] R4-1: (fix-induced) The fix for R4-1 replaced the ambiguous "beside the fix-witness sentence" placement with this explicit two-branch placement — and the new fallba…packages/core/src/skills/bundled/review/references/posting.md:43 — [review] R5-3: The artifact-provenance mandate copied from the artifact, not re-derived is pinned by no test, while the bodyCriticals-move sibling later in this same parag…packages/core/src/skills/bundled/review/references/posting.md:43 — [review] R5-4: The enumeration naming WHICH two moves carry the fix side — unmappable, or relocated by the 422 recovery — rides in no assertion: the carry test's pin captu…packages/core/src/skills/bundled/review/references/posting.md:43 — [review] R5-5: The positive content instruction — state the fact the fix must not violate and its source — the quoted constant, the \ file:line\ — is pinned by no test: t…packages/core/src/skills/bundled/review/references/posting.md:43 — [review] R5-6: The residue enumeration omits one loss channel: a mis-routed **Critical** carried into deferredSuggestions is relocated by compose-review into bodyCritical…
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 2 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:反向审计——在 10 轮的反审轮数上限内未收敛。
Test Plan(非阻断):5101 passed — this review observed 1735, 24978, 1662, 605, 4290, 638 passed。
7 条 Suggestion 在已解析的 critical 发布下限之外被起草为行内评论——发布下限因首次发现速率连续 2 轮未下降而提前生效;CLI 已将其移入下方延后清单(下限强制执行)。
收敛姿态下延后(第 5 轮,非阻断)——发布下限因首次发现速率连续 2 轮未下降而提前生效——已记录,本轮不要求修改:共 7 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.2)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round: no action taken (PR #10168)Triage of this round's feedbackThe only feedback this round is the automated reviewer's round-5 review
There are no inline comments, issue-level comments, failed checks, or Why no code change is warranted
This round therefore makes no commits and leaves the branch at 中文说明Autofix 本轮:未采取任何操作(PR #10168)本轮反馈分类本轮唯一的反馈是自动审查器的第 5 轮审查(rv:5037957696,
本轮没有行内评论、issue 级评论、失败检查或持续失败的检查。 为何无需改代码
因此本轮不产生任何提交,分支保持在 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
|
@qwen-code /triage |
|
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: 100 passed · 0 failed · 100 total Flakiness gate: ✅ 3 changed test file(s) x 5 identical rounds, no divergence 中文 — 判定:✅ 通过 · 可合入(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:100 通过 · 0 失败 · 100 总计 抖动门:✅ 3 changed test file(s) x 5 identical rounds, no divergence Verification reportPR #10168 Deep Verification —
|
| Cell | Input | Base (control) | Head | Result |
|---|---|---|---|---|
| V1 | real constraint (camelCase) | field absent (predicted) | carried verbatim | flip ✓ |
| V2 | fix_constraint (snake_case) |
absent | carried verbatim | flip ✓ |
| V3 | 10 placeholders: N/A n/a NA none None. ␣N/A␣ none observed None observed None observed. no constraints observed |
absent (field unknown) | normalised to absence, 10/10 | head-only behaviour ✓ |
| V4 | none of the callers pass 0 (src/a.ts:12) |
absent | kept — drop is narrow ✓ | ✓ |
| V5 | fixWitness: 'N/A' + real constraint |
only fixWitness kept |
both kept, distinct | ✓ |
| V6 | finding without the field (A/A) | — | output byte-identical to base | backward compat ✓ |
| V7 | 123, null, {a:1}, true, '', '␣␣' |
— | absent, no throw, 6/6 | ✓ |
| V8 | {findings:[…]} wrapper |
— | constraint carried | ✓ |
| V9 | dist(tsc) vs esbuild head, 12 inputs | — | identical | ✓ |
| B1–B2 | 6 brief clauses (format line, OMIT-never-N/A, witness-grade bar, forbidden prose, never-gates, claim/premise split) | 0/6 present (predicted) | 6/6 present | flip ✓ |
| B3 | sibling Fix-witness block | present | present, paragraph intact | no regression ✓ |
| B4–B5 | esbuild head brief vs dist; length | — | byte-identical; head strictly longer | ✓ |
Base-cell behaviour (field dropped entirely, clauses absent) is exactly the predicted control — those reds are encoded as assertions and count as passes.
Corrections
None (first round; no earlier report or bot comment to correct).
Findings
No blocking findings. Two informational items, in severity order:
1. (Observation — accepted tradeoff, not a defect) The placeholder drop is narrow by design; 12 near-miss placeholders pass through
isNotApplicable drops exactly the four anchored literals (± one trailing dot, case-insensitive, trimmed). The sibling sweep (evidence/03-sibling-sweep-regex-boundaries.png, 33/33 probes behaved as designed) measured the escapees: "None..", "None .", "none observed!", "none observed extra", "no constraints observed..", "no constraints", "no constraints.", "N.A.", "TBD", "nothing observed", "null", "-". Each would survive into the artifact and, presence-keyed, into a posted comment.
Why this is not a finding against the PR: (a) the primary bar is instruction-level and forbids any caution without a quoted constant/file:line in the field; (b) the drop exists as a backstop for the exact omission literals the pipeline itself names — all covered (the two long ones are what the finder is told to write when it ignores "omit the line"); (c) the PR and the code comment both state the narrowness is deliberate and name the follow-up ("a validator check that the string names a constant or a file:line"). Reproduce: node tmp/pr10168-verify-20260827-103317/harness/sibling-sweep.mjs.
2. (Nit) PR-body test counts are stale relative to the verified head
SKILL.test.ts: body says 42 tests; the verified head has 44 (the later commits of this PR added pin tests after the body was written). All 44 pass.- Whole directory
src/commands/review: body claims "103 files, 5101 passed, 2 skipped"; this container measures 103 files, 5098 passed, 5 skipped — the total is identical (5103). The split moves three tests from passed toskipIf-skipped for environment reasons, none related to this PR: 3×script-linttests need theshellcheckbinary (not installed here), 1×save-artifacttest needs a case-insensitive filesystem (Linux ext4 is not; macOS default is), 1×sandboxed-exectest is Windows-only (skipped on both). All five skipped names are enumerated inlogs/07-skipped-tests.txt(parsed fromjunit.xml).
Mutation matrix and vacuity (tests are load-bearing)
Witness: evidence/02-mutation-matrix-all-killed.png. Green control (unmutated, mutant tree): 121/121. Every mutation reverted afterwards; mutant tree confirmed clean.
| Row | Mutation (findings.ts) | Result | Count | First red (intended assertion) |
|---|---|---|---|---|
| M1 | remove the !isNotApplicable normalisation (raw passthrough) |
KILLED | 1F/120P | expected 'N/A' to be undefined |
| M2 | regex minus the two long omission literals | KILLED | 1F/120P | expected 'none observed' to be undefined |
| M3 | regex minus the optional trailing dot | KILLED | 1F/120P | expected 'None.' to be undefined |
| M4 | anchored regex → unanchored substring /none|n\/?a/i |
KILLED | 1F/120P | expected 'no constraints observed' to be undefined (long-literal miss fires before the over-drop narrowness assertion, which the same test also pins) |
| M5 | remove the fix_constraint snake_case fallback |
KILLED | 1F/120P | expected undefined to be 'any bound here must be <= MAX_SUBAGEN…' |
| C1 | positive control: remove the pre-existing fixWitness spread |
KILLED | 2F/119P | pre-existing test keeps fixWitness, and keeps it distinct from witness reds at expect(f.fixWitness).toContain(...); the new test also asserts the sibling's 'N/A' survives |
Survivors: none. C1 is the positive control landed in the same file as the mutants — the suite's kill power is proven on a pre-existing test, not assumed.
Vacuity (each production site reverted to base in a scratch worktree, head tests re-run):
| Site reverted | Red tests | Intended assertion (quoted) |
|---|---|---|
findings.ts → base |
1/121: keeps fixConstraint, and drops the N/A its sibling field allows |
expected undefined to be 'any bound here must be <= MAX_SUBAGEN…' |
agent-prompt.ts → base |
1/300: welds the fix-constraint format into the launched finder briefs (sibling fix-witness brief test stays green) |
expected '## The diff…' to contain '**Fix constraint:** <an existing fact…' |
SKILL.md + posting.md → base |
4/44: the three new pin tests + the pre-existing DESIGN-pointer test now covering the new incident | expected '---\nname: review…' to contain '**Fix constraint** — an existing fact…' (and siblings); DESIGN.md incident heading has no SKILL.md pointer: "### The fix whose premises were wrong (#10153)" |
All reds are expected-versus-actual assertion failures, not import/compile breaks; every non-target test in each suite stayed green, so the reverts introduced no collateral.
Targeted gates (at verified head)
| Gate | Result |
|---|---|
packages/cli — findings.test.ts |
121/121 pass |
packages/cli — agent-prompt.test.ts |
300/300 pass |
packages/core — SKILL.test.ts |
44/44 pass |
packages/cli — whole src/commands/review |
103 files, 5098 pass / 5 skipped, exit 0 (see Finding 2 for the split attribution) |
Gate liveness is proven, not assumed: the vacuity reverts and mutation C1 turned these exact suites red (above). Build/typecheck were run by CI at this HEAD before verification started; the A/B harness imports the compiled dist/ successfully, which is live evidence the new code compiles. compose-review read-site check: bodyCriticals entries are the one exit explicitly unbounded ("quoted as-is and left unbounded", compose-review.ts:302-303), so the prose rule that appends the constraint sentence to a relocated Critical's entry is effective — nothing truncates it there. The cross-round ledger (lib/ledger.ts) is a byte-budgeted work list carrying id/sev/file/title for neither fix-side field — sibling parity holds, no gap. The four vocabulary lists the Web Shell renderer duplicates are untouched (vocabulary contract test green).
Not covered
- No live review run. The changed surface is validator code + instruction text the agents read; whether a live finder obeys the witness-grade bar is model behaviour, explicitly out of scope in the PR body ("no live review run"), and not executable in this container. The harnesses replay the wire shape (what the validator receives and emits, what the brief carries), not the model-side trigger that produces those inputs.
- Per-commit attribution unreachable. Metadata lists 5 commits; the depth-2 checkout makes
git rev-list HEAD^1..HEAD^2return only the head commit (shallow boundary,is-shallow-repository = true). Verified the aggregateHEAD^1..HEADdiff instead. - The 3
shellcheck-gated and 1 Windows-only and 1 case-insensitive-FS tests (skipped here, see Finding 2). - The stale-base OID in the metadata snapshot (
83da7233, the PR's original base) was not used as the control: main moved since (the snapshot diff against it spans 57 files, most of them main's own later commits appearing in reverse), so the effective merge diff isHEAD^1..HEAD; diffing against the stale OID would have attributed unrelated main-side changes to this PR. - Repo-wide gates beyond the affected workspace; lint/format re-runs (covered by the PR's own CI).
Methodology
Environment: the CI verify container at merge commit f335f9b5ae (npm ci + npm run build completed before the clock started). The A/B drove the shipped dist/ for the head arm and esbuild bundles of HEAD^1 sources for the control arm (harness/build-bundles.sh), with same-toolchain head cross-checks (V9/B4) proving the bundler is not a confound; harness/ab-harness.mjs encodes the predicted base behaviour as assertions (53 checks). Vacuity and mutation work ran in a scratch worktree (tmp/mutant-tree, since removed) at HEAD with the main tree's dist builds and nested node_modules linked in to satisfy the vitest guard — every mutation applied surgically, suite re-run, file restored, tree verified clean (harness/mutation-matrix.sh). The sibling sweep (harness/sibling-sweep.mjs, 33 probes) drove boundary shapes through the head validator. Gates re-ran the PR's own named suites plus the whole src/commands/review directory. Raw per-cell logs live in logs/, harnesses in harness/, terminal captures of the A/B, the matrix, and the sweep in evidence/.
Flakiness gate log
rounds=5 files=3 skipped=0
file packages/cli/src/commands/review/agent-prompt.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/agent-prompt.test.ts
file packages/cli/src/commands/review/findings.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/findings.test.ts
file packages/core/src/skills/bundled/review/SKILL.test.ts: (cd packages/core) npx --no-install vitest run ./src/skills/bundled/review/SKILL.test.ts
per-file results (P=pass F=fail I=infra-exit, one letter per run):
packages/cli/src/commands/review/agent-prompt.test.ts: PPPPP
packages/cli/src/commands/review/findings.test.ts: PPPPP
packages/core/src/skills/bundled/review/SKILL.test.ts: PPPPP
verdict: pass
summary: 3 changed test file(s) x 5 identical rounds, no divergence
--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/commands/review/agent-prompt.test.ts: P (exit 0)
round 1 · packages/cli/src/commands/review/findings.test.ts: P (exit 0)
round 1 · packages/core/src/skills/bundled/review/SKILL.test.ts: P (exit 0)
round 2 · packages/cli/src/commands/review/agent-prompt.test.ts: P (exit 0)
round 2 · packages/cli/src/commands/review/findings.test.ts: P (exit 0)
round 2 · packages/core/src/skills/bundled/review/SKILL.test.ts: P (exit 0)
round 3 · packages/cli/src/commands/review/agent-prompt.test.ts: P (exit 0)
round 3 · packages/cli/src/commands/review/findings.test.ts: P (exit 0)
round 3 · packages/core/src/skills/bundled/review/SKILL.test.ts: P (exit 0)
round 4 · packages/cli/src/commands/review/agent-prompt.test.ts: P (exit 0)
round 4 · packages/cli/src/commands/review/findings.test.ts: P (exit 0)
round 4 · packages/core/src/skills/bundled/review/SKILL.test.ts: P (exit 0)
round 5 · packages/cli/src/commands/review/agent-prompt.test.ts: P (exit 0)
round 5 · packages/cli/src/commands/review/findings.test.ts: P (exit 0)
round 5 · packages/core/src/skills/bundled/review/SKILL.test.ts: P (exit 0)
Evidence images
Harness scripts and raw logs are in the workflow run artifacts (7-day retention).
— Qwen Code · sandboxed verification
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round: no changes neededWhat arrived: one new item since the last evaluation — the sandboxed verification report ([ic:5437542373]): ✅ passed — merge-ready (100/100 scripted assertions, mutation matrix 6/6 killed, flakiness gate clean at 3 files × 5 rounds), with no blocking findings. No inline comments, no reviews, no failed or still-red checks. Disposition of the two informational items:
Verification (evidence checks run this round):
中文说明Autofix 本轮:无需改动本轮收到的内容: 自上次评估以来只有一条新内容 —— 沙箱验证报告([ic:5437542373]):✅ 通过 — 可合入(100/100 脚本断言、变异矩阵 6/6 全部被杀、抖动门 3 个文件 × 5 轮无分歧),无阻断性发现。无行内评论、无评审、无失败或持续失败的检查。 两条信息性记录的处置:
验证(本轮实际运行的证据检查):
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
Review closeout — verified at head
|
yiliang114
left a comment
There was a problem hiding this comment.
Approved after re-verifying all 10 outstanding threads at head 82539fb: both Criticals (bodyCriticals carry, dedup fix-side preservation) and all Suggestions confirmed fixed and test-pinned; CI green, sandboxed verification 100/100. No blocking findings.
wenshao
left a comment
There was a problem hiding this comment.
Not explored to full depth (tool budget reached): "agent reverse-audit (round 4)": did not run npm run build / typecheck or the full packages/cli review suite — I ran only SKILL.test.ts (44/44 green, including both DESIGN.md cross-referenc…; "agent reverse-audit (round 4)": did not read buildLedger 's title derivation for bodyCriticals entries (only locator() 's use of it), so Finding 1's claim is scoped to the dedup key, not t…; "agent reverse-audit (round 4)": did not open save-artifact.ts:648 or the report_findings JSON schema directly — I relied on F8's read for the persistence/allow-list behaviour.; "agent reverse-audit (round 1)": did not read .github/workflows/qwen-autofix.yml 's handling of review bodies, so I could not check whether a file:line quoted by an appended fix-side sentenc…; "agent reverse-audit (round 1)": did not walk lib/ledger.ts 's shed-cascade internals for the enlarged bodyCriticals claims — F9 named that consumer and left it open, and I did not close it.…, and 6 more.
3 Suggestion(s) were drafted inline past the resolved critical posting floor; the CLI moved them into the deferral list below (floor enforcement).
Deferred under the convergence posture (round 6, not a blocker) — recorded, not requested in this round:
packages/core/src/skills/bundled/review/SKILL.md:970 — [review] R6-3: The carry antecedent — "an entry whose finding carries a fixWitness … appends the corresponding sentence" — is satisfied by fixWitness: "N/A" , whose corresponding sen…packages/cli/src/commands/review/agent-prompt.ts:401 — [review] R6-1: The gloss "a configured limit any new bound must stay within" states the opposite inequality from the incident the same paragraph cites — the field's worked example would…packages/core/src/skills/bundled/review/references/posting.md:43 — [review] R6-2: "copied from the artifact, not re-derived" is the pipeline's first plain-prose copy-verbatim mandate into bodyCriticals — the one body channel that skips m…
中文说明
未探索到全部深度(达到工具调用预算):"agent reverse-audit (round 4)":did not run npm run build / typecheck or the full packages/cli review suite — I ran only SKILL.test.ts (44/44 green, including both DESIGN.md cross-referenc…;"agent reverse-audit (round 4)":did not read buildLedger 's title derivation for bodyCriticals entries (only locator() 's use of it), so Finding 1's claim is scoped to the dedup key, not t…;"agent reverse-audit (round 4)":did not open save-artifact.ts:648 or the report_findings JSON schema directly — I relied on F8's read for the persistence/allow-list behaviour.;"agent reverse-audit (round 1)":did not read .github/workflows/qwen-autofix.yml 's handling of review bodies, so I could not check whether a file:line quoted by an appended fix-side sentenc…;"agent reverse-audit (round 1)":did not walk lib/ledger.ts 's shed-cascade internals for the enlarged bodyCriticals claims — F9 named that consumer and left it open, and I did not close it.…,另有 6 条。
3 条 Suggestion 在已解析的 critical 发布下限之外被起草为行内评论;CLI 已将其移入下方延后清单(下限强制执行)。
收敛姿态下延后(第 6 轮,非阻断)——已记录,本轮不要求修改:共 3 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-flash@e6bf8ffe via Qwen Code /review (v0.22.2)



What this PR does
Adds an optional
fixConstraintfield to a review finding, beside the shippedfixWitness, and carries it through every place a finding is asked for, recorded, and posted: the finder brief's finding format, the skill's Step 6 individual-finding list and Step 4 aggregate template, the findings artifact's field list, and the Step 7 posting rule. A fix constraint is an existing fact the suggested fix must not violate, with its source — a quoted constant or afile:line— such as a configured limit any new bound must stay within, a second site that reads the field a shape change touches, or a uniqueness a newly shared resource's key currently guarantees.Two properties differ from the sibling field, and both are deliberate. The line is omitted when nothing was observed, never
N/A:validateFindingsnormalises a literalN/A/n/a/NA/noneto absence, so the posting rule keys on presence alone and a finder that copies thefixWitnesshabit cannot hand the poster a placeholder. And the evidence bar is thewitnessbar, not thefixWitnessbar — quote the constant or give thefile:line, or omit — so a caution with no quoted fact ("be careful about concurrency") is forbidden in the field the same way "this looks risky" is forbidden in the failure scenario. LikefixWitness, the field never gates reporting. DESIGN.md records the incident that motivates it.Why it's needed
fixWitness(#9596) pins the fix's claim — the test that goes red when the fix is removed. Nothing pinned the fix's premises — the assumptions a fix newly introduces — and those are a different defect class that passes a witnessed test cleanly. Two Criticals on the merged nested-approval fix (#9793) were both of this class and both had afixWitness-grade test: a hand-pickedhops < 16lineage cap sat below the user-configurableMAX_SUBAGENT_DEPTH_LIMIT = 100, so deep lineages silently reintroduced the very hang the fix was for; and parking several runtimes' approvals on one registry entry broke acallIduniqueness that dedup and resolve relied on elsewhere, so a user's answer was routed to the wrong agent. The agent that found each defect had already run the greps that name the fact, so carrying it costs close to nothing — and it is the only mechanism that reaches a human fixer reading the posted comment, the loop with no other brake (the--fixpath's own audit is #10154).The two constraints on the field follow from the asymmetry of the costs: a wrong
fixWitnessis one test not written, while a wrong constraint is confidently-stated misdirection the fixer will follow; and an absent constraint carries no information, so aN/Aplaceholder would only lengthen every posted comment (#9177).Reviewer Test Plan
How to verify
Non-UI change (a finding field, the finder brief text, the skill/reference text, and the validator). The field is pinned at every site it must survive, so the unit suites are the verification:
What each pin proves, so a reviewer can read them instead of re-deriving: the validator round-trips
fixConstraintandfix_constraint, keeps it distinct fromfixWitness(fixWitness: 'N/A'beside a real constraint survives as-is), drops the placeholdersN/A/n/a/NA/none/None./N/A, and does not drop a real constraint that merely contains one of those words (none of the callers pass 0 (src/a.ts:12)). The built finder brief carries the format line, the omit-never-N/Aclause, the "quote the constant or give thefile:line, or omit the line" bar, the forbidden-prose clause, the never-gates-reporting clause, and the claim/premise split sentence. The skill corpus carries the Step 6 item, the Step 4 aggregate slot, the aggregate field list, the artifact field list entry, the posting rule, the not-posted-without-a-source clause, and the no-N/Asilence clause.Whole-directory run and repo checks, all green:
cd packages/cli && npx vitest run src/commands/review→ 103 files, 5101 passed, 2 skipped;npm run buildandnpm run typecheckexit 0;prettier --checkandeslintclean on every changed file.Evidence (Before & After)
N/A — no user-visible or TUI change. Before: a finding format with
Fix witnessas the last fix-side line and no place to record the fact a fix must respect. After: the same format with one optionalFix constraintline beneath it, omitted when nothing was observed.Tested on
Environment (optional)
Unit tests only (
npx vitest runper package);npm run build && npm run typecheckat the root.Risk & Scope
fixWitness. The validator-side placeholder drop is the one structural guard added beyond the issue's three-site proposal (about six lines plus tests); it exists because the posting rule keys on presence, and a finder copying the sibling field'sN/Ahabit would otherwise post the placeholder as a constraint. If the bar proves weak in practice, a validator check that the string names a constant or afile:lineis the natural follow-up.--fix-side audit of a fix's premises is /review: audit the applied fix for unpinned new assumptions (scoped, not a re-review) #10154.Linked Issues
Closes #10153
中文说明
本 PR 做了什么
在评审 finding 上、
fixWitness旁边新增一个可选字段fixConstraint,并贯穿 finding 被索取、记录、发布的每一处:finder brief 的 finding 格式、skill 的 Step 6 个体 finding 列表与 Step 4 聚合模板、findings artifact 的字段清单、以及 Step 7 的发布规则。Fix constraint 是"建议的修复不得违反的既有事实,带出处"——引用的常量或file:line——例如任何新上限都必须落在其内的可配置限制、形状变更所触及字段的另一处读取点、或者新共享资源的键当前保证的唯一性。它有两点与旁边的字段刻意不同。没观察到就整行省略,绝不写
N/A:validateFindings会把字面量N/A/n/a/NA/none归一为缺省,这样发布规则只按"字段是否存在"触发,照抄fixWitness习惯的 finder 也无法把占位符交给发布方。其次,证据门槛是witness级而非fixWitness级——引用常量或给出file:line,否则省略——因此没有引用事实的告诫("注意并发安全")在该字段中被明令禁止,正如"这看起来有风险"在 failure scenario 中被禁止一样。与fixWitness相同,该字段永不作为报告门槛。DESIGN.md 记录了促成它的事件。为什么需要
fixWitness(#9596)钉的是修复的声称——去掉修复就变红的测试。没有东西钉修复的前提——修复新引入的假设——而这是另一类缺陷,能干净地通过一个有见证的测试。已合入的嵌套审批修复(#9793)中的两个 Critical 都属于这一类,且都有fixWitness级的测试:手写的hops < 16lineage 上限低于用户可配置的MAX_SUBAGENT_DEPTH_LIMIT = 100,深层 lineage 悄悄带回了修复本要解决的挂起;把多个 runtime 的审批停靠到同一个 registry 条目破坏了 dedup 与 resolve 在别处依赖的callId唯一性,用户的应答被路由到错误的 agent。发现每个缺陷的 agent 都已经跑过能说出那条事实的 grep,所以把它带上几乎没有成本——而且这是唯一能抵达阅读 posted comment 的人工修复者的机制,那是没有其它刹车的闭环(--fix路径自身的审计是 #10154)。字段上的两条约束源自代价的不对称:
fixWitness猜错只是少写一个测试,而约束猜错是修复者会照做的、自信的错误指导;而缺失的约束不携带任何信息,N/A占位只会让每条发布的评论变长(#9177)。评审者测试方案
如何验证
非 UI 改动(一个 finding 字段、finder brief 文本、skill/reference 文本、以及校验器)。该字段在每一处必须存活的位置都有钉子,因此单元测试套件即为验证:
每个钉子证明什么,便于评审者直接阅读而不必重新推导:校验器往返
fixConstraint与fix_constraint,保持它与fixWitness分离(真约束旁边的fixWitness: 'N/A'原样保留),丢弃占位符N/A/n/a/NA/none/None./N/A,且不会丢弃仅仅包含这些词的真约束(none of the callers pass 0 (src/a.ts:12))。构建出的 finder brief 携带格式行、"省略而非N/A"条款、"引用常量或给出file:line,否则省略该行"的门槛、禁止无出处告诫的条款、永不作为报告门槛的条款、以及区分声称与前提的那句话。skill 语料携带 Step 6 条目、Step 4 聚合槽位、聚合字段列表、artifact 字段清单条目、发布规则、"无出处不发布"条款、以及"无N/A"的静默条款。整目录运行与仓库检查全部通过:
cd packages/cli && npx vitest run src/commands/review→ 103 个文件,5101 通过,2 跳过;npm run build与npm run typecheck退出码 0;每个改动文件的prettier --check与eslint干净。证据(改动前后)
N/A——无用户可见或 TUI 改动。改动前:finding 格式以
Fix witness作为修复侧最后一行,没有位置记录修复必须遵守的事实。改动后:同一格式在其下多一行可选的Fix constraint,没观察到即省略。测试平台
环境(可选)
仅单元测试(各包内
npx vitest run);根目录npm run build && npm run typecheck。风险与范围
fixWitness同级。校验器侧的占位符丢弃是在 issue 三处提案之外唯一新增的结构性守卫(约六行加测试);它存在是因为发布规则按"是否存在"触发,照抄旁边字段N/A习惯的 finder 否则会把占位符当作约束发出去。若实践中门槛不够,自然的后续是在校验器检查字符串是否指名了常量或file:line。--fix侧对修复前提的审计是 /review: audit the applied fix for unpinned new assumptions (scoped, not a re-review) #10154。关联 Issue
Closes #10153