Files
qwen-code/scripts
Shaojin Wenandverify e447cbe0dd feat(triage): start the verify lane alongside /triage on a pull request (#8249)
A `@qwen-code /triage` comment on a PR now starts the sandboxed verify
lane too, in parallel. The two answer different questions — triage reads,
verify builds and runs — and neither waits on the other; they were
already sibling jobs on `needs: [authorize]`, so this is a trigger
change, not a new pipeline.

The trigger cannot be a second copy of the command patterns. authorize
publishes `verify_lane`, and the verify job's `if` and concurrency group
both read it, because re-matching the strings in the job predicate is
exactly what would let the trigger and the trust classification drift:
the classifier keyed on `/verify` while the predicate answered to
`/triage` as well, and a `/triage`-started run would then have executed
an external author's code with `verify_trust` empty — skipping the
head-OID pin, the risk screen and both workspace wipes, the four controls
that exist for untrusted code on a reused pool. Routing the new trigger
through the same classifier is what keeps them on.

The lane fails closed differently from an explicit `/verify`. An
unreadable author permission or a failed head-OID snapshot still denies
`/verify` outright, since the commenter asked for exactly that; on
`/triage` it closes the lane only, so a flaky permission API cannot cost
a reviewer their triage. Automatic per-PR triage (`pull_request_target`)
deliberately does not pull the lane: the constraint is the agent budget,
not runner capacity — a verify run is up to 110 minutes of model time,
and every `synchronize` would spend one. Commenting is what says the PR
is worth it. On a plain issue the lane stays off and no author lookup is
spent.

The verify lane's trigger turned out to be unpinned: deleting the gate
from the job predicate left the suite green. The new test pins both
predicates, and it took two tries — asserting over the whole job text
could not tell `if:` from `concurrency:`, so the first version survived
its own mutation, and so did the positive control written to vouch for
it. Both are now sliced per predicate. Mutation results: dropping the
gate from `if`, from `concurrency`, from authorize's `/triage` branch,
and making the piggybacked lane deny triage are all caught; the
unmutated control and the ECS kill-switch control behave as expected.

Verified by executing the real authorize step with a per-user permission
stub across twelve branches: /verify and /triage on a PR classify
identically (trusted for a write author, external plus a pinned OID
otherwise), /verify still denies on a lookup failure where /triage keeps
should_run with the lane off, /tmux and plain comments are unchanged, and
a commenter without write is denied throughout. actionlint, yamllint,
eslint clean; the prettier warning on this file is pre-existing (fails
identically with the change stashed).

Co-authored-by: verify <verify@local>
2026-07-31 17:33:25 +00:00
..
2025-08-27 15:23:21 +08:00