Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
541408c
feat(review): swap re-review rounds to a fix-audit shape under the cr…
wenshao Aug 26, 2026
b8611dd
Merge branch 'main' into feat/review-critical-round-shape
wenshao Aug 26, 2026
8e1fd85
fix(review): align fix-audit shape readers and key the deferral claim…
qwen-code-dev-bot Aug 26, 2026
bd704ce
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 26, 2026
a20cb48
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 27, 2026
d0b2db7
Merge branch 'main' into feat/review-critical-round-shape
wenshao Aug 27, 2026
774531b
fix(review): plug the fix-audit shape gaps the round findings named (…
qwen-code-dev-bot Aug 27, 2026
f85bf21
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 27, 2026
7e42977
fix(review): align fix-audit prose with the roster and floor code (#1…
qwen-code-dev-bot Aug 27, 2026
72903be
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 28, 2026
ae1cf2f
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 28, 2026
81b1749
Merge remote-tracking branch 'origin/main' into feat/review-critical-…
qwen-code-dev-bot Aug 28, 2026
fe8944c
fix(review): close the round-shape Criticals on the posture machinery…
qwen-code-dev-bot Aug 28, 2026
08bfeca
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 28, 2026
0be9a32
fix(review): close the round-11 Criticals on the seam bound and round…
qwen-code-dev-bot Aug 29, 2026
06b944c
Merge branch 'main' into feat/review-critical-round-shape
wenshao Aug 29, 2026
18ce3b3
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 29, 2026
eb018fb
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 29, 2026
9590c5a
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 30, 2026
8edaa56
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 30, 2026
e9d5a24
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 31, 2026
98f9506
Merge branch 'main' into feat/review-critical-round-shape
qwen-code-dev-bot Aug 31, 2026
9f7fc90
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 3, 2026
66bc461
fix(review): lex the seam oracle, state the wave rule, and close the …
wenshao Sep 3, 2026
3e35d01
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 3, 2026
b58e4b3
fix(review): read the seam oracle through TypeScript's parser and clo…
wenshao Sep 5, 2026
00380a7
test(review): pin the seam parser's default base order and its older-…
wenshao Sep 5, 2026
6dd917b
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 5, 2026
8ca4ce6
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 8, 2026
8a9197e
fix(review): address round 17-18 review findings on the fix-audit shape
wenshao Sep 8, 2026
4ca5b58
fix(review): record and disclose a seam oracle that never ran (#10136…
wenshao Sep 8, 2026
a6d9c5d
fix(review): invert the seam oracle's doubt default (#10136 R18-1)
wenshao Sep 8, 2026
ce1225c
fix(review): refuse a still-wrapped promise at every binding terminal…
wenshao Sep 8, 2026
7ed971a
docs(review): update DESIGN.md for the continuity gate and doubt inve…
wenshao Sep 8, 2026
d0d998f
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 8, 2026
7797ae9
fix(review): address round 19 review findings on the fix-audit shape
wenshao Sep 8, 2026
531a17d
Merge remote-tracking branch 'origin/feat/review-critical-round-shape…
wenshao Sep 8, 2026
51a519e
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 8, 2026
7fe1986
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 9, 2026
469cd0f
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 10, 2026
91a5e2e
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 10, 2026
b966202
fix(review): close the round 20/21 findings on the fix-audit shape
wenshao Sep 10, 2026
f823cc1
fix(review): audit-round repairs on the round 20/21 fixes
wenshao Sep 10, 2026
5eb7f38
fix(review): second audit round — fail-closed siblings and a wired chain
wenshao Sep 10, 2026
39b5975
fix(review): name an unproven base in the posted body, not only on st…
wenshao Sep 10, 2026
ef584da
fix(review): say what the seam census actually counts
wenshao Sep 10, 2026
6e2e02f
Merge remote-tracking branch 'origin/main' into pr-10136
wenshao Sep 10, 2026
831f792
fix(review): put the seam helpers under their own comment
wenshao Sep 10, 2026
b191331
test(review): pin the batch path's narrowing note, and correct the us…
wenshao Sep 10, 2026
5b6bcec
fix(review): rule the within-round sibling on the round, not on its l…
wenshao Sep 10, 2026
23a7a51
fix(review): read a numbered findings entry as an entry
wenshao Sep 10, 2026
52d7c9f
test(review): cover the two guards the audit found untested
wenshao Sep 10, 2026
da90e41
docs(review): say which round the continuity stamp names
wenshao Sep 10, 2026
6601797
docs(review): say what the narrowing branch reads, at the two contracts
wenshao Sep 10, 2026
47b19c0
Merge branch 'main' into feat/review-critical-round-shape
wenshao Sep 11, 2026
f6ac16a
fix(review): close the round 22 findings on the seam oracle and the wave
wenshao Sep 11, 2026
f948f86
feat(review)!: drop the seam-bounded widening from the fix-audit shape
wenshao Sep 11, 2026
e9b6c30
refactor(review): clear what the removal left behind
wenshao Sep 11, 2026
4f2d2b5
test(review): make the fixtures the removal left say what they prove
wenshao Sep 11, 2026
a041bd4
fix(review): disclose the two narrowing rules the round added
wenshao Sep 12, 2026
61ed643
docs(review): say which levers ran and why the third is absent
wenshao Sep 12, 2026
20c21d4
fix(review): close the round 23 findings on the token reader and the …
wenshao Sep 12, 2026
0594fda
fix(review): list the fourth staleness arm where the other three are …
wenshao Sep 12, 2026
d1fed08
docs(review): follow the two rulings this round changed
wenshao Sep 12, 2026
6a4f2ee
Merge remote-tracking branch 'origin/main' into feat/review-critical-…
wenshao Sep 13, 2026
2f3ec71
fix(review): refuse a round counter an anonymous walk adopted
wenshao Sep 13, 2026
6a5f223
fix(review): narrow reverse-audit waves on launch order, not list ren…
wenshao Sep 13, 2026
5bc5451
Merge remote-tracking branch 'origin/main' into feat/review-critical-…
wenshao Sep 14, 2026
60b8471
fix(review): count a launch the scheduler cannot tie to a record
wenshao Sep 14, 2026
721f257
Merge remote-tracking branch 'origin/main' into feat/review-critical-…
wenshao Sep 14, 2026
8f3a289
Merge remote-tracking branch 'origin/main' into feat/review-critical-…
wenshao Sep 14, 2026
4703fe6
fix(review): refuse the narrowing on a partial merge the bytes tripwi…
wenshao Sep 15, 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
2 changes: 2 additions & 0 deletions docs/users/features/code-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ If you switch models (via `/model`) and re-review the same PR, `/review` detects

The model match also gates incremental scoping, not just the skip: "clean up to the cached commit" is the previous model's verdict, so when new commits have landed since the cached review, a model mismatch never scopes to `lastCommitSha..HEAD` — the range is the full diff, noting "Previous round was reviewed by qwen3-coder. Running full review with gpt-4o." — unless an anchor certified by the model now running is recovered from the last posted review (below), which scopes the range instead. The previous round's findings still carry over to be re-ruled; only the anchor does not. The same gate binds the anchor recovered from the last posted review's machine-ledger marker when the cache is absent or its anchor is unusable (CI, another clone): it scopes the incremental range only if the model now running certified it — a marker certified by a different model, or carrying no model (a review posted with `review.attribution` off, or one from before the field), falls back to the full diff. A round that did not close cleanly posts its marker without an anchor (it cannot certify a range), but that loss is not sticky when the round's work list survived whole: recovery grafts the anchor forward from the most recent earlier marker your own account posted with one, so a single non-clean round no longer forces every later round to re-read the full diff — the next round scopes `anchor..HEAD`, which re-covers the range the non-clean round could not certify. A size-capped round's graft is refused (dropped findings would fall outside the grafted scope and retire silently), so later rounds keep re-reading the full diff until a complete marker lands.

**Critical-posture re-reviews run a narrower round (fix-audit shape).** Once a PR's re-review resolves the round-adaptive posting floor to critical-only (from round 6, or earlier when the flat first-time-finding trend latches — see the convergence posture) _and_ a usable incremental anchor exists, the round stops re-running round 1's shape. The capture command predicts the floor from the previous round's posted marker and records `incremental.posture: "critical"` in the plan, and the round then: fans out one territory agent per chunk of the delta (whatever its size — no 3A dimension set, but keeping the issue-fidelity agent: it re-checks head against the issue whatever the delta displays, and is the one auditor that can see a fix commit removing behaviour the issue required when the removal appears on neither side of the narrowed range); republishes each still-clean _interaction_ file seam-bounded — only the hunks displaying a line that imports or uses what changed, with a `seam: {kept, total}` census in the plan and a header-only section when nothing qualifies, so the file still gets an agent briefed to check the seam from the worktree; and narrows the reverse-audit waves instead of capping them — from wave 3, a chunk holding no delta file leaves the schedule after one substantive dry audit, while delta territories keep the full retirement rules, so the late waves (where fix-induced Criticals measurably surface) keep running over a shrinking front. Severities are unchanged — the posture governs what posts, never what is found — and every reduction is disclosed: in the plan, in the agents' briefs, in the round's `posture narrowing:` note, and as a one-sentence "Round shape" disclosure in the posted review body. The plan's posture record is itself an arm of the compose-time floor resolution, so a fix-audit round's posting bar cannot disagree with the shape it ran (sub-Critical findings defer even if the floor's usual inputs are unavailable at compose time). An explicit `--severity-floor suggestion` turns the shape off along with the posture (and outranks a stale plan record at posting time); an explicit `--severity-floor critical` enables it from the first anchored re-review.

Cache is stored in `.qwen/review-cache/` and tracks both the commit SHA and model ID. Make sure this directory is in your `.gitignore` (a broader rule like `.qwen/*` also works). On GitHub, if the cached commit was rebased or force-pushed away, it falls back to a full review; Aone rules the cached anchor differently — see its paragraph below. Only high-effort reviews consult or write the cache — a `--effort low|medium` quick pass never counts as "already reviewed".

## Review Reports
Expand Down
149 changes: 149 additions & 0 deletions packages/cli/src/commands/review/agent-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5057,6 +5057,92 @@ describe('per-chunk retirement — cold territories stop costing a round', () =>
expect(rounds).toContain(2);
});

it('a fix-audit round narrows the wave and the note names it (#10104)', () => {
// Chunk 13 is the delta territory; 14 and 15 hold interaction files.
const fixAuditPlan = {
...PLAN,
incremental: {
since: 'a'.repeat(40),
effective: true,
posture: 'critical',
postureCause: 'round',
scope: {
anchor: 'a'.repeat(40),
deltaFiles: ['packages/cli/src/commands/review/x.test.ts'],
interaction: [
{
path: 'a.ts',
importsChanged: ['packages/cli/src/commands/review/x.test.ts'],
},
{
path: 'bundle.min.js',
importsChanged: ['packages/cli/src/commands/review/x.test.ts'],
},
],
},
},
};
writeFileSync(plan, JSON.stringify(fixAuditPlan));
const old = new Date(2020, 0, 1);
utimesSync(plan, old, old);

answerRound(1, { 13: YIELD, 14: DRY, 15: YIELD });
answerRound(2, { 13: DRY, 14: DRY, 15: YIELD });
const out = runRound(3);

expect(process.exitCode).toBeUndefined();
// 13 is delta (ordinary rules, yield+dry: hot); 15 yielded last wave;
// 14 is a non-delta territory whose latest audit is dry — narrowed out
// after ONE dry receipt, where plain retirement would need two.
expect(out).toContain('2 auditors required this round');
expect(out).toContain('— chunk 13 ─');
expect(out).toContain('— chunk 15 ─');
expect(out).not.toContain('— chunk 14 ─');
expect(out).toContain('posture-narrowed chunk(s) skipped');
expect(out).toContain('posture narrowing (#10104)');
expect(out).toContain('chunk 14 — not a delta territory, dry in round 2');
});

it('a delta list no chunk covers degrades to the ordinary schedule, never an empty narrowing (#10104)', () => {
// A hand-edited plan can name delta files no chunk holds — an honest
// capture cannot produce the disjoint state, so the input class is the
// corrupted plan these gates exist for. An EMPTY delta-territory set
// would treat every chunk as non-delta: from round 3 each leaves after
// one dry receipt, the round exits 5 on a false "clean convergence",
// and the territory this round exists to audit was examined only in
// rounds 1-2. Every sibling reader fails malformed input toward MORE
// coverage; the schedule must too — null restores the byte-for-byte
// ordinary schedule.
const fixAuditPlan = {
...PLAN,
incremental: {
since: 'a'.repeat(40),
effective: true,
posture: 'critical',
postureCause: 'round',
scope: {
anchor: 'a'.repeat(40),
deltaFiles: ['src/disjoint.ts'],
interaction: [],
},
},
};
writeFileSync(plan, JSON.stringify(fixAuditPlan));
const old = new Date(2020, 0, 1);
utimesSync(plan, old, old);

answerRound(1, { 13: YIELD, 14: DRY, 15: DRY });
answerRound(2, { 13: DRY, 14: DRY, 15: DRY });
const out = runRound(3);

expect(process.exitCode).toBeUndefined();
// Chunk 13 yielded in round 2, so the ordinary rules keep it hot; 14
// and 15 retire on two dry rounds.
expect(out).toContain('1 auditors required this round');
expect(out).toContain('— chunk 13 ─');
expect(out).not.toContain('posture narrowing (#10104)');
});

it('round 3 skips a chunk dry in rounds 1 and 2, and the note names it', () => {
answerRound(1, { 13: DRY, 14: YIELD, 15: YIELD });
answerRound(2, { 13: DRY, 14: YIELD, 15: YIELD });
Expand Down Expand Up @@ -6924,6 +7010,69 @@ describe('incremental-scope briefs', () => {
expect(seam).toContain('src/changed.ts');
});

it('a fix-audit round frames the brief and discloses the seam bound (#10104)', () => {
const fixAudit = {
...INCREMENTAL_PLAN,
incremental: {
since: 'abc1234def5678900000',
effective: true,
posture: 'critical',
postureCause: 'round',
scope: {
...INCREMENTAL_PLAN.incremental.scope,
interaction: [
{
path: 'src/caller.ts',
importsChanged: ['src/changed.ts'],
seam: { kept: 1, total: 4 },
},
],
},
},
};
const delta = buildChunkAgentPrompt(fixAudit, 1);
expect(delta).toContain('Fix-audit round (critical posting posture)');
expect(delta).toContain('the floor governs posting, never');
// The banner's deferral claim carries the deterministic carve-out the
// reroute applies — an auditor trusting "never posted" unqualified
// could drop a `[test]` finding the floor keeps inline at any floor.
expect(delta).toContain('never posted — except pre-confirmed');

const seam = buildChunkAgentPrompt(fixAudit, 2);
expect(seam).toContain('SEAM-BOUNDED: 1 of 4 hunk(s)');
expect(seam).toContain('still yours in full, from the worktree');

// Without the posture, no fix-audit frame and no seam clause — the seam
// census is a fix-audit fact, and a plan without one renders none.
const plain = buildChunkAgentPrompt(INCREMENTAL_PLAN, 2);
expect(plain).not.toContain('Fix-audit round');
expect(plain).not.toContain('SEAM-BOUNDED');
});

it('a malformed seam census renders no seam clause', () => {
const bad = {
...INCREMENTAL_PLAN,
incremental: {
since: 'abc1234def5678900000',
effective: true,
posture: 'critical',
scope: {
...INCREMENTAL_PLAN.incremental.scope,
interaction: [
{
path: 'src/caller.ts',
importsChanged: ['src/changed.ts'],
seam: { kept: 5, total: 2 },
},
],
},
},
};
const seam = buildChunkAgentPrompt(bad, 2);
expect(seam).toContain('INTERACTION only');
expect(seam).not.toContain('SEAM-BOUNDED');
});

it('whole-diff role briefs carry the frame once, up front', () => {
const p = buildRoleBrief(INCREMENTAL_PLAN, '2');
expect(p).toContain('Incremental round');
Expand Down
Loading
Loading