qwen-code/docs
Shaojin Wen f829a02896
feat(review): validate Aone inline anchors against the captured diff before posting (#9634)
* feat(review): validate Aone inline anchors against the captured diff before posting

Aone Code performs no server-side anchor validation — a controlled probe
(scratch MR 29427547, a1 v0.2.51) proved any --line integer posts, and
an old-side number silently lands on the same-numbered new-side line.
The old side cannot be anchored at all, and file-level comments drop
their path.

Pin the removed-line semantics for the Aone write path: submit's Aone
branch now validates every well-formed inline anchor against the
review's captured diff before posting. An unanchorable Critical is
relocated into the summary body, an unanchorable Suggestion discarded
and counted — the GitHub 422-recovery dispose, performed in code — each
disclosed in the terminal. A missing captured diff refuses the whole
post; malformed shapes (missing path/line, reversed range,
renders-as-nothing) keep their consistency-gate refusals, and a garbage
state.bodyCriticals stands the gate down so compose's pinned refusal
fires. The GitHub path is untouched — its server performs this
validation.

Issue #9615

* fix(review): reject unpostable anchors and unify the Aone gate's shape refusals

- validateNewSideAnchors now rejects the input domain (fractional/zero/negative
  lines and reversed ranges) before the hunk scan, so its verdict can no longer
  certify an anchor the zero-validation Aone platform would post silently wrong.
- Extract the consistency gate's per-comment shape checks into one shared
  predicate (commentShapeProblems) read by both the loud refusal and the Aone
  anchor gate, so a shape the gate disposes is never a refusal the operator
  misses (open fence, start_line-without-side). The path check becomes a type
  check, closing truthy non-string paths that reached the write seam unvouched.

* fix(review): generalise the Aone gate's stand-down and harden its relocated entries

Round-2 review fixes for the Aone anchor gate:

- The stand-down now keys on ANY degrade that touches the payload and
  covers every compose-owned garbage shape: bodyCriticals that is not an
  array of strings, or a suggestionsDiscarded compose's counter refuses.
  The countability test reads compose's OWN acceptance table (toCount,
  exported as the total tryToCount), so the gate's merge and compose's
  counter can never drift — an integer-but-not-safe count now merges
  instead of silently dropping the gate's discards.
- The relocated entry's claim extraction strips a leading marker RUN
  (fixpoint, like every other strip) and treats a fence-delimiter claim
  line as absent — both shapes used to leak raw markers or junk
  delimiters into the posted summary-body blocker line.
- The gate keeps the model-authored comment indices through its removal
  (and floor enforcement keeps them through its own), so the consistency
  gate's refusal names the culprit in the model's payload JSON instead of
  a renumbered position the re-compose loop cannot act on.
- A --dry-run with a missing capture no longer exits 3: it writes
  nothing, so it skips the gate with a disclosure and reports
  wouldPost: false (reason: aone-diff-missing); the exit-3 refusal stays
  reserved for the real write.
- The MULTI_DIFF fixture's second hunk header becomes byte-exact git
  output (@@ -20,0 +22,2 @@, probed against git itself).
- The design doc gains the gate-relocation doctrine (relocated entries
  deliberately inherit the model's own tag-exemption treatment), the
  dry-run carve-out in the failure-shape table, and the corrected
  fence/one-line-channel claim.

* fix(review): close the anchor-gate witness gaps and a footer-leak in the relocated entry

Gap-fill on top of the round-2 gate hardening:

- The relocated entry's claim extraction strips the canonical footer
  FIRST: with an empty claim line (a marker-plus-separator-only body),
  the separator strip eats the newline+colon and the extraction falls
  THROUGH into the appended footer's first line, posting it as the
  claim. Witness added for the placeholder shape.
- Pin the multi-line relocation entry CONTENT (it must cite the claimed
  end line, not the start — the start sits inside the hunk and looks
  fine) and the disclosure naming it.
- Witnesses for the remaining mutant-tested gaps: a range whose start
  sits outside every hunk and end inside (the startLine mapping), the
  dry-run compose parity (preview composes from the gate-corrected
  payload), the suggestionsDiscarded 0 merge boundary, the empty-path
  shape (loud refusal, never a gate disposal), a declared LEFT
  start_side without a start_line, and the equal-boundary range
  (start_line === line, a shape GitHub itself produces).
- The routing suites run from a per-test fixture cwd, so the
  captured-diff seeding and its cleanup can no longer overwrite or
  delete a same-numbered live capture in the real vitest cwd.

Issue #9615

* fix(review): sanitise relocated-entry paths and stand down over any compose-refused bodyCriticals

* fix(review): keep the anchor gate's captured diff when resetting the receipt state

The Aone receipt suite's beforeEach wiped the whole .qwen tree to start
from no receipt — deleting the captured diff the anchor gate needs along
with it. Every post then died at the gate's missing-capture refusal and
no receipt was ever written (ENOENT in the four receipt tests on CI).
Remove only the receipt file; the seeded diff survives.

* fix(review): close the anchor-gate entrances the review rounds demonstrated

Round-3 remediation of the review comments on the Aone anchor gate:

- R3-2 (structural): the BUILT relocated entry is now validated against
  compose's own ingestion (tryIngestBodyCriticals over the single entry)
  before the relocate is disclosed, and any refusal degrades the entry to
  the inert constant `finding — (no path):<line>` — the entrance space is
  unbounded model text and compose's acceptance is the authority, so a
  shape the enumerated guards never anticipated degrades the entry
  instead of refusing the whole post mid-degrade. The demonstrated
  entrance (a lone CR inside the claim: it passes the leading-fence
  guard, compose's CR normalisation then splits the entry and the second
  line leads with a fence delimiter) is covered by a witness.
- Ledger collision: the relocated entry flips to `<claim> — <path>:<line>`
  — the claim leads, so a carried id keeps position 0 and the ^-anchored
  ledger readback matches instead of silently renumbering a carried
  finding as new. Witness asserts the id survives the readback regex.
- R7-1: an explicit JSON null side/startSide reads as ABSENT (defaults
  to RIGHT), the model's idiom for an omitted optional field — never a
  declared old side. Unit and gate-level witnesses.
- R3-3: witness for the non-identity authoredIndices branch — the gate
  renumbers the array, floor enforcement keys on the post-gate array,
  and the remap drops the comment floor enforcement names.
- R4-2: the hostile-paths test gains the \r-bearing path (compose's
  ingestion normalises a bare CR to a line break — the same hostile
  shape as \n; the guard's \r half was unwitnessed).
- R3-5: the design doc states the carve-out — the non-RIGHT degrade runs
  for single-line comments only; a multi-line non-RIGHT comment keeps
  the consistency gate's whole-post refusal; null side is absent, not a
  declaration. The failure-shapes table splits the row accordingly.

Issue #9615

---------

Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-08-22 17:45:27 +00:00
..
assets feat: support workspace display names (#7179) 2026-07-20 15:16:44 +00:00
design feat(review): validate Aone inline anchors against the captured diff before posting (#9634) 2026-08-22 17:45:27 +00:00
developers feat(cli): restore each daemon session onto its last selected model (#9687) 2026-08-22 16:33:36 +00:00
e2e-tests fix(cli): Recover sessions across archive races (#9513) 2026-08-22 14:01:59 +00:00
images fix(web-shell): render built-in tag icons (#7024) 2026-07-17 15:33:34 +00:00
plans fix(serve): Harden standalone conversation primitives (#9512) 2026-08-20 08:09:44 +00:00
superpowers feat(cli): reference prior sessions via @ and add completion tabs (#7302) 2026-07-24 06:11:48 +00:00
users fix(review): clear the deferred Round-5 findings from the Aone write path (#9604) 2026-08-22 13:27:51 +00:00
verification/abort-controller-refactor fix(core): stop AbortSignal listener leak in long sessions (MaxListenersExceededWarning) (#4366) 2026-05-26 14:21:49 +08:00
_meta.ts feat: refactor docs 2025-12-05 10:51:57 +08:00
index.md fix: lint issues 2025-12-19 15:52:11 +08:00