qwen-code/packages/core
Shaojin Wen 769cdf5f1d
feat(review): build every Step 5 auditor of a round in one call, identity first (#7150)
* feat(review): build every Step 5 auditor of a round in one call, identity first

Post-merge dogfood named the last hand-assembly that survives the pipeline,
with the transcript to prove both of its shapes.

The per-chunk reverse-audit form asked for one build-and-capture round trip
per chunk per round, and the run answered with `for i in 1..10; do
agent-prompt … | head -5; done` — it SAMPLED each build instead of capturing
it, never possessed a single full prompt, hand-reconstructed all ten
launches, and every one was flagged rewritten: a full repair round spent
recovering from a shortcut that saved nothing. `--all-chunks` is the same
medicine --roster was for Step 3: one call, one labelled numbered block per
chunk, an end-of-round marker for the truncation self-check, records keyed
per chunk per findings digest, and a header that says outright what the
for-loop got wrong — never sample this output; the text IS the deliverable.
SKILL.md's Step 5 3B carries the call, the redirect-and-page protocol, and
the sampling ban with the measured cost attached.

And the one edit that same run made to a prompt it fully possessed was at the
head: it swapped the verifier's identity line for a context sentence of its
own. The findings fold now leaves the identity line FIRST — a context wrap
lands above it instead of replacing it, and the delivery check keeps its
anchor. The record remains the exact printed prompt either way.

The findings-free-tail attack pin is rebuilt for the new layout (a launch
carrying the block without the findings section still matches no record), and
the batch is mutation-checked three ways: cross-wiring every block to one
chunk's ranges, recording less than what was printed, and demoting the
identity line each turn exactly one test red — the first of those needed a
two-chunk assertion, because checking only the first block cannot see a batch
built entirely from it.

* fix(review): refuse an all-chunks round whose every chunk id is unusable

Review caught the asymmetry: the single-chunk path throws on a chunk it
cannot use, while the batch filter silently emptied the list and printed
'0 auditors required this round' with a valid end marker, recording nothing —
a zero-coverage round wearing a receipt. Same corruption, same refusal now,
with a test driving a plan whose every chunk id is a string.

* fix(review): refuse corrupt batch plans, stray --all-chunks modes, and rules-blind brief keys

Three holes in the Step 5 batch, all caught in review:

- A malformed or duplicated chunk id shrank the round instead of stopping
  it: [13, "x", 15] printed a complete-looking two-auditor round with one
  territory silently gone, and a duplicate id keyed two territories to one
  record -- the second never audited, under an end marker that says the
  round is whole. The batch now refuses exactly what coverage's readPlan
  refuses, via one shared definition (chunkIdsProblem in diff-plan.ts),
  before writing any brief, record or stdout block.

- --all-chunks was validated only inside the findings-role branch, so
  --roster --all-chunks, --whole-diff --all-chunks, a bare --chunk 13
  --all-chunks, and --all-chunks alone all ran the other mode and exited 0
  with the batch silently dropped. Every combination is now ruled on at
  the primary-mode boundary.

- The findings digest keyed the brief by findings alone: a round rebuilt
  with corrected rules kept its key, so the corrected brief landed at the
  same path an earlier agent had already opened, and delivery credited
  that old transcript with reading rules it never saw. The digest now
  hashes a JSON tuple of the findings and the effective rules, so a rules
  change is a fresh key, a fresh brief, a fresh launch.

Plus the two review-suggested regression pins: an empty findings file
still builds one auditor per chunk, each carrying the early-round
framing, and --rules lands in every brief of the batch.

* fix(review): pin foldFindings to the identity-first invariant it splits on

The fold assumed line one of the launch prompt IS the identity line, which
holds today because buildRoleLaunchPrompt writes it first — but a future
prompt shape that moves it would make the split silently rebuild the
buried-identity layout the fold exists to prevent. Refuse loudly instead:
folding under the wrong first line is corruption, not a formatting choice.

Verified by mutation: rewording the identity line in buildRoleLaunchPrompt
now turns every batch test red with the fold's own error, instead of
shipping prompts with the findings misplaced.

* test(review): pin the batch's first guard — a plan with no chunks[] is refused

The id-validation tests all pass a populated chunks[], so the guard ahead
of them (missing or empty chunks[]) had no test of its own: deleted or
inverted, nothing went red. Covers both shapes — chunks: [] and the key
absent entirely — because an inverted condition still throws on the empty
array and only the missing key exposes it.
2026-07-18 09:17:11 +00:00
..
scripts Fix: Improve ripgrep binary detection and cross-platform compatibility (#1060) 2025-11-18 19:38:30 +08:00
src feat(review): build every Step 5 auditor of a round in one call, identity first (#7150) 2026-07-18 09:17:11 +00:00
vendor feat test tool permissions 2026-03-10 16:30:22 +08:00
index.ts fix: Remove remaining ClearcutLogger export from packages/core/index.ts 2026-02-01 14:52:14 +08:00
package.json feat(core): overhaul web_fetch — content fidelity, binary handling, security, and resilience (#7146) 2026-07-18 07:03:55 +00:00
test-setup.ts feat(memory): managed auto-memory and auto-dream system (#3087) 2026-04-16 20:05:45 +08:00
tsconfig.json fix: upgrade @lydell/node-pty to 1.2.0-beta.10 to fix PTY FD leak 2026-04-01 07:55:56 +08:00
vitest.config.ts Sync upstream Gemini-CLI v0.8.2 (#838) 2025-10-23 09:27:04 +08:00