Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
afa3b4d
docs: add legacy code audit (/audit) design doc
wenshao Aug 2, 2026
522e23c
docs: revise legacy audit design with round-2 replication evidence
wenshao Aug 2, 2026
509e79a
docs: note cross-file tracer cost and budget rule in legacy audit design
wenshao Aug 2, 2026
7fd87c6
feat(audit): add legacy code audit workflow
wenshao Aug 2, 2026
2992d53
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
wenshao Aug 6, 2026
2b9cf83
feat(audit): align the audit workflow with the merged design doc
wenshao Aug 6, 2026
e4386ea
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
wenshao Aug 6, 2026
0ad3dd9
fix(audit): lift tokenizeArgs and anchor the guard probes at the invo…
wenshao Aug 6, 2026
ff9c53b
fix(audit): make check-anchors --callers conditional in the skill
wenshao Aug 6, 2026
94b0b95
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 6, 2026
6d633b9
fix(audit): name-record unreadable sidecar callers
qwen-code-dev-bot Aug 6, 2026
03c1519
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 7, 2026
5eb156e
fix(audit): close fail-open gates found in review across the pipeline
qwen-code-dev-bot Aug 7, 2026
0642802
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 7, 2026
d883ddc
fix(cli): harden audit helpers per review feedback (#8403)
qwen-code-dev-bot Aug 7, 2026
e1e6fcf
fix(cli): address second review round for audit helpers (#8403)
qwen-code-dev-bot Aug 11, 2026
67b1320
fix(external-context): read the response body with a reader, not for-…
wenshao Aug 9, 2026
7c33b0b
fix(audit): make fallback relocation paths explicit in the skill comm…
qwen-code-dev-bot Aug 12, 2026
8209913
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 12, 2026
319c0cf
fix(cli): apply review-round fixes to audit anchors, walk, and exit f…
qwen-code-dev-bot Aug 12, 2026
72a4d89
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 12, 2026
029231e
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 13, 2026
2dc868d
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 13, 2026
5df644a
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
qwen-code-ci-bot Aug 13, 2026
2581412
fix(audit): address round-3 review findings for the audit module (#8403)
qwen-code-ci-bot Aug 13, 2026
54c5cbe
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 13, 2026
722b06d
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 13, 2026
c714b90
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 14, 2026
216937d
fix(cli): apply round-4 review fixes to audit guard, anchors, and sid…
qwen-code-dev-bot Aug 14, 2026
538905d
fix(cli): apply round-6 review fixes to audit guard, anchors, and sid…
qwen-code-dev-bot Aug 14, 2026
d5c48e3
Merge branch 'main' into feat/legacy-code-audit
wenshao Aug 14, 2026
e528918
fix(cli): close round-6 audit guard, anchor, and hash holes (#8403)
qwen-code-dev-bot Aug 14, 2026
789b6e4
fix(cli): close round-8 audit anchor and guard criticals (#8403)
qwen-code-dev-bot Aug 15, 2026
25da0ff
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 15, 2026
cd1276a
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 15, 2026
92642bd
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 15, 2026
2afc1fb
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 16, 2026
5aabe7c
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 16, 2026
aed1ab5
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 16, 2026
afa923a
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 16, 2026
5af49e9
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 17, 2026
926aef8
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 17, 2026
1deabe8
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 17, 2026
580b439
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 18, 2026
a2638ea
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 18, 2026
a0ee238
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 18, 2026
caadc0c
Merge remote-tracking branch 'origin/main' into feat/legacy-code-audit
wenshao Aug 19, 2026
1897bd4
fix(core): stabilize the audit fallback root across symlink path spel…
wenshao Aug 19, 2026
daa8f6e
Merge remote-tracking branch 'origin/feat/legacy-code-audit' into fea…
wenshao Aug 19, 2026
1f97f93
Merge branch 'main' into feat/legacy-code-audit
qwen-code-dev-bot Aug 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/users/features/_meta.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export default {
commands: 'Commands',
'code-review': 'Code Review',
'legacy-audit': 'Legacy Code Audit',
'followup-suggestions': 'Followup Suggestions',
'tool-use-summaries': 'Tool-Use Summaries',
'markdown-rendering': 'Markdown Rendering',
Expand Down
67 changes: 67 additions & 0 deletions docs/users/features/legacy-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Legacy Code Audit

> Audit a module or directory of **existing, merged code** — no diff, no PR — using `/audit`.

`/review` is built for increments; `/audit` points the same machinery at code that is already merged: pre-refactor assessments, taking over an unfamiliar module, security review of a sensitive subsystem. The product is a verified, deduplicated, theme-clustered findings report.

## Quick Start

```bash
# Audit a module (default effort: medium)
/audit packages/core/src/permissions

# Quick unverified triage, one reader sub-agent
/audit packages/core/src/hooks --effort low

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.

[Suggestion] R3-1: The only --effort low example in the Quick Start targets packages/core/src/hooks — measured at exactly 8,516 subject lines, ~4× over the 2,000-line low gate documented two sections later on this same page; the command is refused at plan time. The Limitations section discloses that the calibration modules are this repo's permissions (7,638) and hooks (8,516) — both far above low's gate, so no example drawn from them can ever run at low. Failure scenario: a first-time user copy-pastes the Quick Start's second example and gets audit: 8516 subject lines exceeds low's 2000-line gate — run --effort medium instead. — their first low-effort run is an immediate refusal. Suggested fix: point the low example at a module under 2,000 subject lines, or state the gate in the example's comment.

中文说明

Quick Start 中唯一的 --effort low 示例指向 packages/core/src/hooks——实测恰为 8,516 个主题行,约为本页后两节所载 2,000 行 low 门限的 4 倍;该命令会在计划时被拒绝。Limitations 一节披露校准模块为本仓库的 permissions(7,638)与 hooks(8,516)——两者都远超 low 门限,因此取自它们的示例永远无法以 low 运行。失败场景:首次使用的用户复制 Quick Start 的第二个示例,得到 audit: 8516 subject lines exceeds low's 2000-line gate — run --effort medium instead.——第一次 low 尝试即被拒绝。建议修复:把 low 示例指向主题行低于 2,000 的模块,或在示例注释中写明门限。

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

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.

Deferred to a follow-up round (not dropped). Pointing the Quick Start low example at a module under the 2,000-line low gate requires measuring candidate modules against the live plan-files gate; that measurement and the doc fix land next round.

中文说明

推迟到后续轮次(并非丢弃)。把 Quick Start 的 low 示例指向低于 2,000 行 low 门限的模块,需要先对候选模块用真实 plan-files 门限测量;该测量与文档修复下一轮落地。


# Full pipeline plus reverse-audit rounds
/audit packages/core/src/permissions --effort high
```

Single files are not audited — `/review <file-path>` already covers that case, and `/audit` says so and stops.

## Effort Levels

`--effort low|medium|high` trades depth for cost. **The word means the opposite of what it does in `/review`**: `/review`'s medium _drops_ the adversarial personas while `/audit`'s medium _adds_ one (6a) — and both skills select the tier with the same `--effort` flag. If you run both, reset your expectation at the boundary.

| Level | What runs | Findings | Cost |
| -------- | --------------------------------------------------------------------------------------------------------- | --------------------------- | ---------------- |
| `low` | One reader sub-agent rotating through directed angles plus a gap sweep | ≤10, labeled **unverified** | Cheap |
| `medium` | The measured 8-dimension fan-out (1a, 1c, 2, 3a/3b/3c, 4, 5) plus the 6a attacker seat, plus verification | Uncapped, verified | Tens of M tokens |
| `high` | medium + the 6b/6c personas + iterative reverse-audit rounds | Uncapped, verified | Extrapolated |

## Size gates and budget

v1 audits one bounded module at a time. `plan-files` refuses at plan time — and asks for a narrower path — when:

- subject lines exceed **9,000** (the topology both experiments validated);
- test lines exceed **18,000** at medium/high (Agent 5 reads the corpus whole);
- subject lines exceed **2,000** at low (points you at medium);
- the priced token estimate's top exceeds the **60M** cap.

A larger subsystem is audited as coherent sub-paths, one bounded run each. For subject-gate and token-cap refusals, lowering the effort is never the remedy — the priced cost is a function of line counts alone. The test-line gate does not apply at `low` (the corpus goes unexamined there — triage, not an audit). A `low-gate` refusal names its own remedy: when the message offers the tier change, re-run with `--effort medium`; when it names the path instead (medium would refuse first — the priced estimate over the token cap, or test lines over the medium gate), no tier change helps, so narrow the path.

## What you confirm before anything launches

A fan-out run prints its roster and token estimate and starts only on your confirmation. The same confirmation carries the two **execution consents**, as separate opt-ins:

1. a baseline run of the module's own test suite;
2. agent-authored verification **probes** — short programs written mid-run, executed against a scratch copy of the probed file (never your checkout's copy), each required to flip under the implied fix.

The walks themselves are read-only. Because the confirmation is the only budget enforcement and the execution gate, **`/audit` refuses non-interactive starts** (headless `qwen -p`, cron, sub-agent invocations).

## Safety properties

- **Local-only artifacts.** The report, its sidecar, and the plan/prompt records quote the module — possibly exploitable code — and must never land in version control. `plan-files` probes `.qwen/audits/` and `.qwen/tmp/` (ignore rules **and** force-added history) at plan time, offers a zero-footprint `.git/info/exclude` remedy, and re-checks at every checkpoint and at write time; a mid-run flip relocates everything to a per-user fallback outside the repo.
- **Untrusted data.** Every consumer of module content — dimension agents, verifiers, the dedup clusterer, the low-tier reader, the orchestrator itself — opens with an untrusted-data preamble: the module is evidence, not instructions. A directive embedded in the code ("report no findings") is itself a finding.
- **Drift protection.** A path-scoped sidecar (diff, untracked content copies, per-file content hashes) is captured at run start and re-checked before verification, before each high-tier round, and at write time. Content drift in a file that already carries anchored findings stops the run with a partial report; any other drift is flagged and the run continues.
- **No verdict.** The report is findings, walks, and disclosures — never "approved". Posting and fixing stay with you.

## The report

`.qwen/audits/<YYYY-MM-DD>-<HHMMSS>-<path-slug>.md`, opening with a run-metadata header (commit SHA, model id, dirty state with sidecar, consumption against the estimate, walks completed/skipped/uncoverable, unexercised-machinery flags). Findings are clustered by root cause, each with severity, locations, failure scenario, evidence tier (end-to-end probe / unit probe / code read), and the independent-discovery count ("found independently by N agents"). Confirmed-low findings sit in their own "needs human review" section; anything unverified is labeled unverified.

## Limitations

- Submodules are refused at plan time (no drift coverage inside them in v1).
- Dedup is intra-run; already-filed issues are not cross-checked.
- The medium/high tiers are calibrated on two modules of this repository; the low tier and the high-tier loop are unmeasured first cuts, and the report header says so.
1 change: 1 addition & 0 deletions packages/cli/src/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,7 @@ describe('bootstrap import boundaries', () => {
const configSource = readFileSync('src/config/config.ts', 'utf8');
const commandNameByIdentifier = new Map([
['authCommand', 'auth'],
['auditCommand', 'audit'],
['channelCommand', 'channel'],
['extensionsCommand', 'extensions'],
['hooksCommand', 'hooks'],
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ type BootstrapRoute = 'serve' | 'mcp' | 'help' | 'version' | 'default';

export const TOP_LEVEL_COMMANDS = [
['auth', 'Configure authentication (removed)'],
[
'audit <command>',
'Helpers used by the /audit skill (argument parsing, audit planning, brief printing, run-state captures)',
],
['channel <command>', 'Manage messaging channels (Telegram, Discord, etc.)'],
['extensions <command>', 'Manage Qwen Code extensions.'],
['hooks', 'Manage Qwen Code hooks (use /hooks in interactive mode).'],
Expand Down
52 changes: 52 additions & 0 deletions packages/cli/src/commands/audit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/

import { describe, it, expect } from 'vitest';
import { readFileSync } from 'node:fs';
import { auditCommand } from './audit.js';

describe('auditCommand', () => {
it('registers exactly the expected subcommands', () => {
const source = readFileSync('src/commands/audit.ts', 'utf8');
const subcommands = [...source.matchAll(/\.command\((\w+Command)\)/g)].map(
(m) => m[1],
);
expect(subcommands).toEqual([
'parseArgsCommand',
'planFilesCommand',
'agentPromptCommand',
'snapshotCommand',
'driftCheckCommand',
'guardCheckCommand',
'checkAnchorsCommand',
]);
});

it('demandCommand text names each subcommand', () => {
const source = readFileSync('src/commands/audit.ts', 'utf8');
// Assert against the demandCommand MESSAGE, not the whole file: the
// import lines also contain the subcommand module names.
const message = /\.demandCommand\(\s*1,\s*'([^']+)'/.exec(source)?.[1];
expect(message).toBeDefined();
for (const name of [
'parse-args',
'plan-files',
'agent-prompt',
'snapshot',
'drift-check',
'guard-check',
'check-anchors',
]) {
expect(message).toContain(name);
}
});

it('is a CommandModule with an empty dispatch handler', () => {
expect(auditCommand.command).toBe('audit');
expect(typeof auditCommand.builder).toBe('function');
expect(typeof auditCommand.handler).toBe('function');
});
});
41 changes: 41 additions & 0 deletions packages/cli/src/commands/audit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/

// `qwen audit`: the non-interactive helpers used by the bundled /audit skill
// for auditing existing code (no diff, no PR). The skill orchestrates via
// shell calls to these subcommands; see
// packages/core/src/skills/bundled/audit/SKILL.md.

import type { CommandModule } from 'yargs';
import { parseArgsCommand } from './audit/parse-args.js';
import { planFilesCommand } from './audit/plan-files.js';
import { agentPromptCommand } from './audit/agent-prompt.js';
import { checkAnchorsCommand } from './audit/check-anchors.js';
import { guardCheckCommand } from './audit/guard-check.js';
import { driftCheckCommand, snapshotCommand } from './audit/snapshot.js';

export const auditCommand: CommandModule = {
command: 'audit',
describe:
'Helpers used by the /audit skill (argument parsing, audit planning, brief printing, run-state captures)',
builder: (yargs) =>
yargs
.command(parseArgsCommand)
.command(planFilesCommand)
.command(agentPromptCommand)
.command(snapshotCommand)
.command(driftCheckCommand)
.command(guardCheckCommand)
.command(checkAnchorsCommand)
.demandCommand(
1,
'audit needs a subcommand: parse-args, plan-files, agent-prompt, snapshot, drift-check, guard-check, check-anchors',
)
.version(false),
handler: () => {
// Dispatch is per-subcommand.
},
};
111 changes: 111 additions & 0 deletions packages/cli/src/commands/audit/agent-prompt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import {
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
writeFileSync,
} from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { agentPromptCommand } from './agent-prompt.js';
import { writeStdoutLine } from '../../utils/stdioHelpers.js';
import { buildFilesPlan, collectAuditFiles } from './lib/files-plan.js';

vi.mock('../../utils/stdioHelpers.js', () => ({
writeStdoutLine: vi.fn(),
}));

let dir: string;

beforeEach(() => {
dir = mkdtempSync(join(tmpdir(), 'audit-agent-prompt-'));
mkdirSync(join(dir, 'mod'), { recursive: true });
writeFileSync(join(dir, 'mod', 'a.ts'), 'const a = 1;\n');
vi.mocked(writeStdoutLine).mockClear();
});

afterEach(() => {
rmSync(dir, { recursive: true, force: true });
});

function writePlan(effort: 'low' | 'medium' | 'high'): string {
const plan = buildFilesPlan(
join(dir, 'mod'),
join(dir, 'mod'),
effort,
collectAuditFiles(join(dir, 'mod')),
);
const planPath = join(dir, `plan-${effort}.json`);
writeFileSync(planPath, JSON.stringify(plan));
return planPath;
}

const run = (argv: Record<string, unknown>) =>
(agentPromptCommand.handler as (a: unknown) => void)({
_: ['audit', 'agent-prompt'],
...argv,
});

describe('agentPromptCommand handler', () => {
it('prints a role brief for a role in the roster', () => {
run({ plan: writePlan('medium'), role: '1a', probes: 'declined' });
const printed = vi.mocked(writeStdoutLine).mock.calls[0][0];
expect(printed).toContain('You are Agent 1a');
// Declined probe opt-in strips the execution instructions.
expect(printed).toContain('Execution is NOT opted in');
});

it('maps the opted-in probe flag to the probe discipline', () => {
// The 'opted-in' → probesConsented === true mapping is load-bearing:
// without it every opted-in run prints the declined brief and the
// verifier tier silently caps at code reads.
run({ plan: writePlan('medium'), role: '1a', probes: 'opted-in' });
const printed = vi.mocked(writeStdoutLine).mock.calls[0][0];
expect(printed).toContain('A probe runs only against a scratch copy');
expect(printed).not.toContain('Execution is NOT opted in');
});

it('refuses the low reader at medium and a roster role at low', () => {
expect(() =>
run({
plan: writePlan('medium'),
role: 'low-reader',
probes: 'declined',
}),
).toThrow(/only valid for a low-tier plan/);
// Low plans carry an empty roster: every dimension role is refused.
expect(() =>
run({ plan: writePlan('low'), role: '1a', probes: 'declined' }),
).toThrow(/not in this plan's roster/);
});

it('refuses a stale-plan role that is not in the roster', () => {
// 'toString' rides the prototype-membership hole a raw .includes()
// call would leave open: it is an Object.prototype member, not a role.
expect(() =>
run({ plan: writePlan('medium'), role: 'toString', probes: 'declined' }),
).toThrow(/must be one of/);
});

it('fails closed when the plan carries a non-array roster', () => {
const planPath = writePlan('medium');
const parsed = JSON.parse(readFileSync(planPath, 'utf8')) as Record<
string,
unknown
>;
// A string roster ('1a' .includes('1a') === true, '12' admits '2')
// must fail closed, not reach substring membership.
parsed['roster'] = '12';
writeFileSync(planPath, JSON.stringify(parsed));
expect(() =>
run({ plan: planPath, role: '2', probes: 'declined' }),
).toThrow(/not in this plan's roster/);
});
});
94 changes: 94 additions & 0 deletions packages/cli/src/commands/audit/agent-prompt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/

// `qwen audit agent-prompt`: print the brief for one audit role — or the
// low tier's reader — with the plan's context assembled in. The /audit skill
// launches its agents with exactly these prompts (one call per roster role),
// so what every agent is told is fixed by code, not improvised by the
// orchestrator.

import type { CommandModule } from 'yargs';
import { writeStdoutLine } from '../../utils/stdioHelpers.js';
import { readPlanFile } from './lib/read-json.js';
import {
AUDIT_BRIEFS,
buildAuditPrompt,
buildLowReaderPrompt,
type AuditBriefRole,
} from './lib/audit-agent-briefs.js';

interface AgentPromptArgs {
plan: string;
role?: string;
probes?: 'opted-in' | 'declined';
}

function runAgentPrompt(args: AgentPromptArgs): void {
const plan = readPlanFile(args.plan, 'agent-prompt');
const probesConsented = args.probes === 'opted-in';

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.

[Suggestion] The handler's mapping of --probes opted-in to probesConsented = true has no test in either direction: agent-prompt.test.ts only ever passes probes: 'declined', and the brief-level tests bypass the handler by passing the boolean directly. — Failure scenario: mutation-tested — const probesConsented = false; ships the whole audit suite green; under it, every run where the user consented to probes in Step 2 receives briefs stating "Execution is NOT opted in for this audit: do not run any of the module's code" — verification silently capped at the code-read tier (probes are the audit's highest evidence tier per Steps 5/6). The inverse mutant is caught by the existing declined test; only the consent direction is unpinned. Suggested fix: run({ plan, role: '1a', probes: 'opted-in' }) asserting the prompt contains the probe-preference text and lacks the refusal text.

中文说明

handler 把 --probes opted-in 映射为 probesConsented = true 的逻辑在两个方向上都没有测试:agent-prompt.test.ts 只传 probes: 'declined',而 brief 层测试通过直接传布尔值绕过了 handler。失败场景(变异测试):const probesConsented = false; 能让整个 audit 套件绿着上线;在其影响下,用户在第 2 步同意了探针的每次运行收到的 brief 都会写着 “Execution is NOT opted in for this audit: do not run any of the module's code”——验证被静默限制在代码阅读层级(按第 5/6 步,探针是审计的最高证据层级)。反向变异会被现有的 declined 测试捕获;只有同意方向未被固定。建议修复:run({ plan, role: '1a', probes: 'opted-in' }),断言 prompt 包含探针偏好文本且不含拒绝文本。

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

// A stale plan JSON can carry anything in its roster — a non-array must
// fail closed (empty roster, every role refused), never reach .includes.
const roles = Array.isArray(plan.roster) ? (plan.roster as string[]) : [];
if (args.role === 'low-reader') {
if (plan.effort !== 'low') {
throw new Error(
`agent-prompt: low-reader is only valid for a low-tier plan (this plan is ${plan.effort}).`,
);
}
writeStdoutLine(buildLowReaderPrompt(plan));

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.

[Suggestion] R10-15: The low-reader happy path has no pinning test anywhere: the only low-reader test is the refusal arm (medium plan -> throws before emission). Deleting the writeStdoutLine(buildLowReaderPrompt(plan)) emission ships green across agent-prompt.test.ts + wiring.test.ts + audit-agent-briefs.test.ts (46 tests passed under the mutant). The /audit skill captures this stdout as the sub-agent's prompt, so a regression launches the low-tier reader with an empty brief: the tier 'completes' with zero findings and the module is reported triaged — silent coverage loss, exit 0, no error surface.

Failure scenario: Mutant executed: emission line deleted -> 46 tests green; qwen audit agent-prompt --plan --role low-reader exits 0 printing nothing; the low-tier reader runs with an empty brief and reports the module triaged with zero findings.

Witness:

probe: mutant run — agent-prompt.test.ts + wiring.test.ts + audit-agent-briefs.test.ts all green (46 tests passed) with the emission deleted.

Suggested fix: Add a handler test: writePlan('low'), run { plan, role: 'low-reader' } (no --probes, which the check exempts), assert writeStdoutLine called once and the output contains the low-reader brief markers (e.g. 'low-tier reader' and the read-only walk line).

中文说明

low-reader 正常路径无任何固定测试(突变已执行):唯一 low-reader 测试是拒绝臂(medium 计划 → 在 emit 前抛错)。删除 writeStdoutLine(buildLowReaderPrompt(plan)) 后 agent-prompt.test.ts + wiring.test.ts + audit-agent-briefs.test.ts 共 46 个测试全绿。/audit 技能把该 stdout 作为子代理提示逐字启动:回归后低层级阅读器以空 brief 启动、零发现'完成'、模块被报告为已分诊——静默覆盖损失,exit 0,无错误面。建议补处理器测试:writePlan('low') 后运行 { plan, role: 'low-reader' }(不带 --probes,检查豁免之),断言 writeStdoutLine 被调用一次且输出含 low-reader brief 标记(如 'low-tier reader' 与只读走查行)。

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

return;
Comment on lines +41 to +42

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.

[Suggestion] R10-15: The --role low-reader happy path (LOW plan → reader brief printed) is never exercised through the handler: agent-prompt.test.ts drives low-reader only with a MEDIUM plan (the throw arm), and wiring.test.ts stubs the handler. Re-detected and mutation-confirmed this round.

— Failure scenario: Executed mutant: replacing writeStdoutLine(buildLowReaderPrompt(plan)) with void buildLowReaderPrompt(plan) ships 13/13 green; adding the missing handler test makes the mutant fail. The low tier's single launch path would break at runtime with no red test.

Witness (executed this round):

probe: mutant without test: Test Files 2 passed (2), Tests 13 passed (13); same mutant with the missing test: × prints the low-reader brief for a low plan — 1 failed | 5 passed
中文说明

[Suggestion] --role low-reader 的正常路径(LOW plan → 打印 reader 简报)从未在 handler 层被测:agent-prompt.test.ts 只用 MEDIUM plan 驱动 low-reader(throw 分支),wiring.test.ts 则 stub 了 handler。本轮重新发现并经变异确认。

失败场景:已执行变异:把 writeStdoutLine(buildLowReaderPrompt(plan)) 换成 void buildLowReaderPrompt(plan),13/13 全绿;补上缺失的 handler 测试后该变异即失败。low 层唯一的启动路径会在运行时坏掉而无任何红灯。

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

}
const role = args.role as Exclude<AuditBriefRole, 'low-reader'> | undefined;
// Object.hasOwn, not `in`: a stale-plan role like "toString" matches
// inherited Object.prototype keys and would emit an undefined brief.
if (!role || !Object.hasOwn(AUDIT_BRIEFS, role)) {
throw new Error(
`agent-prompt: --role must be one of ${[...Object.keys(AUDIT_BRIEFS), 'low-reader'].join(', ')}.`,
);
}
if (!roles.includes(role)) {

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.

[Suggestion] R10-41: The roster-vs-effort invariant is never revalidated at read time: a stale/hand-edited medium plan whose roster is edited to include 6b/6c passes both gates (AUDIT_BRIEFS holds all 11 briefs; roles.includes reads the plan verbatim). Executed: the probe printed briefs containing 'You are Agent 6b' and 'You are Agent 6c' with no error — an invisible expansion past the roster the Step-2 confirmation discloses. buildLowReaderPrompt validates claim-vs-data under the identical stale-plan rationale while the roster gets only a shape check.

Failure scenario: The /audit skill 'launches its agents with exactly these prompts (one call per roster role)' — the run fans out 11 agents while the confirmation disclosed the 9-role medium roster; the expansion is undisclosed in the emitted briefs. Harm is cost/consistency (fail-open), triggered by the exact stale/hand-edited-plan threat model this file's comments defend against elsewhere.

Witness:

probe: hand-edited medium plan with 11-role roster — 6b/6c briefs printed for effort 'medium'; fix flip — read-time check throws 'the plan's roster carries roles its medium effort does not commission (6b, 6c) — regenerate the plan' with the 5 existing tests green.

Suggested fix: In runAgentPrompt, after validating plan.effort is one of low|medium|high, reject on mismatch mirroring the lowTier claim checks: if (roles.join(',') !== rosterForEffort(plan.effort).join(',')) throw new Error('agent-prompt: the plan's roster disagrees with its effort — regenerate the plan.').

中文说明

roster-vs-effort 不变量在读取时从不重新验证(已执行):陈旧/手工编辑的 medium 计划把 roster 改为含 6b/6c 即可通过两道门(AUDIT_BRIEFS 持有全部 11 个 brief;roles.includes 逐字读取计划)——探针观察到 effort 'medium' 打印出含 'You are Agent 6b' 与 'You are Agent 6c' 的 brief、无错误:越过 Step-2 确认披露的 roster 的不可见扩张。buildLowReaderPrompt 在同样的陈旧计划理由下验证 claim-vs-data,而 roster 只有形状检查。危害是成本/一致性(fail-open),由该文件注释在别处防御的确切陈旧/手工编辑计划威胁模型触发。修复翻转:读取时检查抛出 'the plan's roster carries roles its medium effort does not commission (6b, 6c) — regenerate the plan',既有 5 个测试保持绿。建议在 runAgentPrompt 验证 plan.effort 属 low|medium|high 后按 lowTier 声明检查的方式拒绝不匹配。

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

throw new Error(

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Suggestion] agent-prompt's roster-membership/tier/prototype guards (Object.hasOwn, roles.includes, low-reader only at low) are untested — the design invariant "roster is computed by code and cannot be shrunk" is enforced only here. — Failure scenario: deleting the roles.includes check ships green; agent-prompt --role 6b --plan <medium-plan> then emits a 6b brief for a tier whose plan never disclosed or priced 6b; the stale-plan toString guard is equally unprotected. Suggested fix: an agent-prompt.test.ts exercising medium-plan+low-reader, low-plan+1a, and stale-plan 'toString' roster cases.

中文说明

问题:agent-prompt 的 roster 成员/档位/原型守卫(Object.hasOwn、roles.includes、low-reader 仅限 low)没有任何测试——"roster 由代码计算、不可缩减"的设计不变量只在这里强制。失败场景:删掉 roles.includes 检查套件全绿;agent-prompt --role 6b --plan <medium计划> 会为计划从未披露/定价 6b 的档位输出 6b brief;过期计划的 toString 守卫同样无保护。修复建议:新增 agent-prompt.test.ts 覆盖 medium 计划+low-reader、low 计划+1a、过期计划 'toString' roster 等用例。

— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Suggestion] agent-prompt's roster-membership/tier/prototype guards (Object.hasOwn, roles.includes, low-reader only at low) are untested — the design invariant "roster is computed by code and cannot be shrunk" is enforced only here. — Failure scenario: deleting the roles.includes check ships green; agent-prompt --role 6b --plan <medium-plan> then emits a 6b brief for a tier whose plan never disclosed or priced 6b; the stale-plan toString guard is equally unprotected. Suggested fix: an agent-prompt.test.ts exercising medium-plan+low-reader, low-plan+1a, and stale-plan 'toString' roster cases.

中文说明

问题:agent-prompt 的 roster 成员/档位/原型守卫(Object.hasOwn、roles.includes、low-reader 仅限 low)没有任何测试——"roster 由代码计算、不可缩减"的设计不变量只在这里强制。失败场景:删掉 roles.includes 检查套件全绿;agent-prompt --role 6b --plan <medium计划> 会为计划从未披露/定价 6b 的档位输出 6b brief;过期计划的 toString 守卫同样无保护。修复建议:新增 agent-prompt.test.ts 覆盖 medium 计划+low-reader、low 计划+1a、过期计划 'toString' roster 等用例。

— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Suggestion] agent-prompt's roster-membership/tier/prototype guards (Object.hasOwn, roles.includes, low-reader only at low) are untested — the design invariant "roster is computed by code and cannot be shrunk" is enforced only here. — Failure scenario: deleting the roles.includes check ships green; agent-prompt --role 6b --plan <medium-plan> then emits a 6b brief for a tier whose plan never disclosed or priced 6b; the stale-plan toString guard is equally unprotected. Suggested fix: an agent-prompt.test.ts exercising medium-plan+low-reader, low-plan+1a, and stale-plan 'toString' roster cases.

中文说明

问题:agent-prompt 的 roster 成员/档位/原型守卫(Object.hasOwn、roles.includes、low-reader 仅限 low)没有任何测试——"roster 由代码计算、不可缩减"的设计不变量只在这里强制。失败场景:删掉 roles.includes 检查套件全绿;agent-prompt --role 6b --plan <medium计划> 会为计划从未披露/定价 6b 的档位输出 6b brief;过期计划的 toString 守卫同样无保护。修复建议:新增 agent-prompt.test.ts 覆盖 medium 计划+low-reader、low 计划+1a、过期计划 'toString' roster 等用例。

— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Suggestion] agent-prompt's roster-membership/tier/prototype guards (Object.hasOwn, roles.includes, low-reader only at low) are untested — the design invariant "roster is computed by code and cannot be shrunk" is enforced only here. — Failure scenario: deleting the roles.includes check ships green; agent-prompt --role 6b --plan <medium-plan> then emits a 6b brief for a tier whose plan never disclosed or priced 6b; the stale-plan toString guard is equally unprotected. Suggested fix: an agent-prompt.test.ts exercising medium-plan+low-reader, low-plan+1a, and stale-plan 'toString' roster cases.

中文说明

问题:agent-prompt 的 roster 成员/档位/原型守卫(Object.hasOwn、roles.includes、low-reader 仅限 low)没有任何测试——"roster 由代码计算、不可缩减"的设计不变量只在这里强制。失败场景:删掉 roles.includes 检查套件全绿;agent-prompt --role 6b --plan <medium计划> 会为计划从未披露/定价 6b 的档位输出 6b brief;过期计划的 toString 守卫同样无保护。修复建议:新增 agent-prompt.test.ts 覆盖 medium 计划+low-reader、low 计划+1a、过期计划 'toString' roster 等用例。

— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Suggestion] agent-prompt's roster-membership/tier/prototype guards (Object.hasOwn, roles.includes, low-reader only at low) are untested — the design invariant "roster is computed by code and cannot be shrunk" is enforced only here. — Failure scenario: deleting the roles.includes check ships green; agent-prompt --role 6b --plan <medium-plan> then emits a 6b brief for a tier whose plan never disclosed or priced 6b; the stale-plan toString guard is equally unprotected. Suggested fix: an agent-prompt.test.ts exercising medium-plan+low-reader, low-plan+1a, and stale-plan 'toString' roster cases.

中文说明

问题:agent-prompt 的 roster 成员/档位/原型守卫(Object.hasOwn、roles.includes、low-reader 仅限 low)没有任何测试——"roster 由代码计算、不可缩减"的设计不变量只在这里强制。失败场景:删掉 roles.includes 检查套件全绿;agent-prompt --role 6b --plan <medium计划> 会为计划从未披露/定价 6b 的档位输出 6b brief;过期计划的 toString 守卫同样无保护。修复建议:新增 agent-prompt.test.ts 覆盖 medium 计划+low-reader、low 计划+1a、过期计划 'toString' roster 等用例。

— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Suggestion] agent-prompt's roster-membership/tier/prototype guards (Object.hasOwn, roles.includes, low-reader only at low) are untested — the design invariant "roster is computed by code and cannot be shrunk" is enforced only here. — Failure scenario: deleting the roles.includes check ships green; agent-prompt --role 6b --plan <medium-plan> then emits a 6b brief for a tier whose plan never disclosed or priced 6b; the stale-plan toString guard is equally unprotected. Suggested fix: an agent-prompt.test.ts exercising medium-plan+low-reader, low-plan+1a, and stale-plan 'toString' roster cases.

中文说明

问题:agent-prompt 的 roster 成员/档位/原型守卫(Object.hasOwn、roles.includes、low-reader 仅限 low)没有任何测试——"roster 由代码计算、不可缩减"的设计不变量只在这里强制。失败场景:删掉 roles.includes 检查套件全绿;agent-prompt --role 6b --plan <medium计划> 会为计划从未披露/定价 6b 的档位输出 6b brief;过期计划的 toString 守卫同样无保护。修复建议:新增 agent-prompt.test.ts 覆盖 medium 计划+low-reader、low 计划+1a、过期计划 'toString' roster 等用例。

— DeepSeek/deepseek-v4-flash via Qwen Code /review (v0.21.8)

`agent-prompt: role ${role} is not in this plan's roster (${roles.join(', ') || 'empty'}). The roster is computed from the plan's effort — regenerate the plan if you need a different tier.`,
);
}
writeStdoutLine(buildAuditPrompt(role, plan, probesConsented));
}
Comment on lines +57 to +58

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.

[Suggestion] R13-60: plan.eventModule.detected is consumed by truthiness in buildAuditPrompt with no type validation, breaking the stale-plan validation discipline applied everywhere else in the chain. — Failure scenario: A hand-edited plan with "detected": "false" attaches the 1c EVENT-COVERAGE WALK addendum to a non-event module; null silently drops it from a real one — phantom walk or silently shrunk walk.

Witness:

probe: detected:"false" carries addendum true; strict === true fix → false.

Suggested fix: Validate typeof detected === 'boolean' in readPlanFile, or make the brief gate strict plan.eventModule?.detected === true.

中文说明

plan.eventModule.detected 在 buildAuditPrompt 中按真值消费且无类型校验,打破同一命令链处处执行的过期计划校验纪律。探针:手工计划 "detected": "false" 会给非事件模块挂上 1c EVENT-COVERAGE WALK 附录;null 则会静默丢弃真实模块的附录。修复:readPlanFile 校验 typeof detected === 'boolean' 或门改为严格 === true。

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

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.

Escalated to a maintainer decision — not resolved in this round. The workflow's deterministic diff-growth brake has engaged: this PR has stayed over the growth budget for 14+ consecutive rounds, and the review findings themselves are driving the growth, so the autofix loop is no longer permitted to keep patching it. Under the not-converging rule this round made no code fixes; the only change merged was the required origin/main conflict resolution. This finding remains open and is carried in the maintainer handoff alongside the options (split the PR, narrow the v1 threat model, accept with the tail deferred, or redesign).

中文说明

已升级至维护者决策 — 本轮未在代码中解决。 工作流的确定性 diff 增长刹车已触发:本 PR 已连续 14 轮以上超出增长预算,且审查发现本身就是增长的来源,因此 autofix 循环不再被允许继续打补丁。按照"不收敛"规则,本轮没有做任何代码修复;唯一合并的改动是按要求完成的 origin/main 冲突解决。该发现保持开放,并已纳入维护者交接文档,与各个选项一并列出(拆分 PR、收窄 v1 威胁模型、接受现状并延后尾部问题、或重新设计)。


export const agentPromptCommand: CommandModule = {
command: 'agent-prompt',
describe:
'Print the brief for an audit role or the low-tier reader — with plan context assembled',
builder: (yargs) =>
yargs
.option('plan', {
type: 'string',
demandOption: true,
describe: 'Plan JSON written by `qwen audit plan-files`',
})
.option('role', {
type: 'string',
describe: 'Print one role brief (must be in the plan roster)',
})
.option('probes', {
choices: ['opted-in', 'declined'] as const,
describe:
'The Step-2 probe opt-in verdict; declined prompts carry no execution instructions (not required for --role low-reader — low runs no execution classes)',
})
.check((argv) => {
if (!argv.role) {
throw new Error('agent-prompt: pass --role <id>.');

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.

[Suggestion] agent-prompt's yargs .check() — refusing roster roles invoked without --probes — has no test: agent-prompt.test.ts calls the handler directly (bypassing yargs) and wiring.test.ts pins only the happy path (it DOES pin the sibling demandOption refusals). — Failure scenario: executed — deleting the whole .check() leaves 13/13 suites green; a real-yargs probe with --role 1a and no --probes then throws nothing and runs the handler with probesConsented=false, printing the DECLINED brief — the inverse of the opted-in mapping the suite calls load-bearing. Fix: add a wiring test asserting ['agent-prompt','--plan',p,'--role','1a'] throws /--probes/.

Witness:

mutant (.check() deleted): 13/13 green
real-yargs probe under mutant: no throw -> handler ran, probesConsented=false (DECLINED brief)
中文说明

agent-prompt 的 yargs .check()——拒绝不带 --probes 调用的 roster 角色——没有测试:agent-prompt.test.ts 直接调用 handler(绕过 yargs),wiring.test.ts 只钉了 happy path(但它确实钉了兄弟的 demandOption 拒绝)。失败场景:已执行——删除整个 .check() 后 13/13 套件仍绿;真实 yargs 探针以 --role 1a 且无 --probes 调用时不再抛出,handler 以 probesConsented=false 运行并打印 DECLINED brief——与套件称为关键行为的 opted-in 映射正好相反。修复:增加 wiring 测试断言 ['agent-prompt','--plan',p,'--role','1a'] 抛出 /--probes/。

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

}
if (argv.role !== 'low-reader' && !argv.probes) {

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.

[Suggestion] (R8-6) agent-prompt.test.ts calls the handler directly (bypassing yargs checks) and wiring.test.ts always passes --probes; neither .check() arm has a witness. The --probes arm is load-bearing: dropping it lets qwen audit agent-prompt --plan p --role 1a pass silently with probesConsented=false. — Failure scenario: A skill regression or hand-typed call missing --probes builds the declined brief for a probes-opted-in run — the whole fan-out's evidence tier caps at code reads with no error.

Suggested fix: Add wiring-style cases asserting real yargs parse rejects missing --role and missing --probes (non-low-reader) and accepts low-reader without --probes.

中文说明

问题(R8-6):agent-prompt.test.ts 直接调用 handler(绕过 yargs check),wiring.test.ts 总是传 --probes,两个 .check() 臂都没有见证。--probes 臂是承重的:丢失它时 qwen audit agent-prompt --plan p --role 1a 会静默通过且 probesConsented=false。失败场景:技能回归或手工调用漏传 --probes → 为已选择启用探针的运行构建“拒绝探针”版 brief,整个扇出的证据层级被压到纯代码阅读,且无任何报错。

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

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.

[Suggestion] (R8-6) agent-prompt.test.ts calls the handler directly (bypassing yargs checks) and wiring.test.ts always passes --probes; neither .check() arm has a witness. The --probes arm is load-bearing: dropping it lets qwen audit agent-prompt --plan p --role 1a pass silently with probesConsented=false. — Failure scenario: A skill regression or hand-typed call missing --probes builds the declined brief for a probes-opted-in run — the whole fan-out's evidence tier caps at code reads with no error.

Suggested fix: Add wiring-style cases asserting real yargs parse rejects missing --role and missing --probes (non-low-reader) and accepts low-reader without --probes.

中文说明

问题(R8-6):agent-prompt.test.ts 直接调用 handler(绕过 yargs check),wiring.test.ts 总是传 --probes,两个 .check() 臂都没有见证。--probes 臂是承重的:丢失它时 qwen audit agent-prompt --plan p --role 1a 会静默通过且 probesConsented=false。失败场景:技能回归或手工调用漏传 --probes → 为已选择启用探针的运行构建“拒绝探针”版 brief,整个扇出的证据层级被压到纯代码阅读,且无任何报错。

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

throw new Error(
'agent-prompt: pass --probes opted-in|declined (the Step-2 probe opt-in).',
Comment on lines +84 to +86

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.

[Suggestion] R13-18: The --probes requirement is enforced only in the builder's .check(); deleting .check() ships green (wiring.test.ts delivers valid args; no rejection case exists for agent-prompt). — Failure scenario: Without .check(), audit agent-prompt --plan p --role 1a parses and silently prints the DECLINED brief (probesConsented = false) instead of failing loudly — a run whose Step-2 consent was never recorded proceeds.

Witness:

mutation: .check() removed → 13/13 tests green; proposed wiring case fails under mutation.

Suggested fix: Add a wiring case asserting parsedArgv(agentPromptCommand, [...without --probes]) throws matching /--probes/.

中文说明

--probes 要求只在 builder 的 .check() 中执行;删除 .check() 仍绿灯(wiring.test.ts 提供合法参数;agent-prompt 无拒绝用例)。后果:没有 .check() 时 audit agent-prompt --plan p --role 1a 会解析成功并静默打印 DECLINED brief——一次从未记录 Step-2 同意的运行继续执行。见证:突变 13/13 绿;建议的接线用例在突变下失败。修复:补断言 /--probes/ 的接线用例。

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

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.

Escalated to a maintainer decision — not resolved in this round. The workflow's deterministic diff-growth brake has engaged: this PR has stayed over the growth budget for 14+ consecutive rounds, and the review findings themselves are driving the growth, so the autofix loop is no longer permitted to keep patching it. Under the not-converging rule this round made no code fixes; the only change merged was the required origin/main conflict resolution. This finding remains open and is carried in the maintainer handoff alongside the options (split the PR, narrow the v1 threat model, accept with the tail deferred, or redesign).

中文说明

已升级至维护者决策 — 本轮未在代码中解决。 工作流的确定性 diff 增长刹车已触发:本 PR 已连续 14 轮以上超出增长预算,且审查发现本身就是增长的来源,因此 autofix 循环不再被允许继续打补丁。按照"不收敛"规则,本轮没有做任何代码修复;唯一合并的改动是按要求完成的 origin/main 冲突解决。该发现保持开放,并已纳入维护者交接文档,与各个选项一并列出(拆分 PR、收窄 v1 威胁模型、接受现状并延后尾部问题、或重新设计)。

);
}
return true;
}),
handler: (argv) => {
runAgentPrompt(argv as unknown as AgentPromptArgs);
},
};
Loading
Loading