Qwen Code 0.21.1: stop polling CI inside AI review agents
Quick answer
Qwen Code 0.21.1 changes its triage workflow: the AI reviewer no longer spends part of its turn polling CI and no longer approves while a required result is still pending. It records the reviewed commit and current evidence once, then a deterministic GitHub Actions finalizer wakes after CI completes, refreshes the facts, and resolves the decision.
The reusable pattern is:
- Let the agent analyze the change and produce a provisional verdict.
- Bind that verdict and its evidence to one head commit.
- If required checks are pending, emit a narrowly scoped “approve on green” intent instead of approving.
- Wake a non-model finalizer from
workflow_run. - Re-read PR state, head SHA, check suites, and existing reviews.
- Approve only when the evidence set is closed and green; otherwise defer or fail closed.
This is not a new Qwen Code toggle for every repository. The official release exposes the pattern through Qwen Code’s own triage implementation. You can adapt the architecture, but you still have to build and secure the workflow for your repository.
Who this is for
This guide is for maintainers building AI pull-request reviewers, autofix bots, or coding-agent pipelines on GitHub Actions. It applies when the agent finishes before CI, so polling wastes resources or expires before the slowest check.
If your first problem is proving what the agent actually finished, start with the Qwen Goal evidence checklist. If issues are creating agent work automatically, keep the confidence and approval gate in front of any write action.
What changed and why it matters
The Qwen Code 0.21.1 release notes say its triage flow now stops in-agent CI polling and finalizes evidence and approval after CI completes. The merged implementation records that the old loop polled for roughly ten minutes while the long unit suite took about thirty; in the measured example, approval arrived before that suite finished.
The replacement splits reasoning from waiting. The agent fetches check runs once and records pending checks honestly. A deterministic finalizer, triggered after CI activity, updates the bounded evidence region and can post a commit-pinned approval only after rechecking the current state.
That separation matters because “wait” is not an intelligence problem. A model turn is a poor scheduler, and a stale conversation is a poor source of truth for current CI.
The two-lane architecture
| Lane | Responsibility | Must not do |
|---|---|---|
| Agent review lane | Understand intent, inspect the diff, identify risks, run available probes, and produce a provisional verdict | Sleep until CI finishes or claim a pending result passed |
| Deterministic finalizer | Wake on CI events, read current GitHub state, enforce invariants, and perform the allowed terminal write | Reinterpret the code change or broaden the agent’s authority |
The handoff should contain bounded identifiers, not “finish the PR”: repository, PR, reviewed SHA, required checks, provisional verdict, and evidence record.
A six-stage finalization workflow
1. Freeze the review revision
Record the PR head SHA before analysis. Bind all evidence and proposed approval to it. If the head moves, mark the old intent stale.
2. Fetch CI once
Read relevant workflow runs and check suites once. Separate success, failure, cancelled, skipped, and pending. If anything required is pending, stop waiting and defer.
3. Emit a narrow handoff
Store an authenticated, idempotent record meaning only: “this reviewed SHA may be approved if the named evidence closes green.” Do not let arbitrary comments mint authority; Qwen accepts only its bot-authored marker.
4. Wake from workflow_run
Use the completed workflow_run activity; GitHub requires the finalizer workflow file on the default branch. Serialize by PR or SHA so finishing checks cannot race or duplicate reviews.
5. Re-read every terminal invariant
Before any write, fetch the current PR and verify:
- the PR is open and not a draft;
- the head SHA still equals the reviewed SHA;
- the handoff came from the expected identity;
- every required check for that SHA is present and settled;
- no required result is failed, cancelled, or missing;
- the approval for this SHA does not already exist;
- repository-specific guardrails still permit approval.
Use GitHub’s review API commit_id field so the approval is tied to the reviewed commit. A comment saying “approved for abc123” is weaker than an API write that actually carries that SHA.
6. Resolve one terminal state
Write one outcome: approved, failed, stale, guarded, or still_pending. Preserve surrounding evidence and make repeated events converge.
Copyable finalizer contract
agent_ci_handoff:
repository: "owner/repo"
pull_request: 123
reviewed_head: "full commit SHA"
provisional_verdict: "approve_if_green"
required_workflows:
- "unit"
- "integration"
evidence_record: "bot-authored comment or artifact ID"
terminal_checks:
require_open_pr: true
reject_draft: true
require_same_head: true
require_closed_green_set: true
pin_review_to_commit: true
outcomes:
- approved
- failed
- stale
- guarded
- still_pending
This is an architecture contract, not Qwen Code configuration.
Eight acceptance tests
| Test | Expected result |
|---|---|
| One required check is still running | No approval; state remains pending |
| A required check fails or is cancelled | Fail closed and record the result |
| The PR head changes after review | Mark stale; require a new agent review |
| A third party copies the handoff marker | Ignore it |
| The finalizer event fires twice | One terminal write, same final state |
| The PR is closed or converted to draft | No approval |
| Check data is empty or incomplete | Preserve prior evidence and defer |
| All required checks for the reviewed SHA pass | Post one commit-pinned approval |
Common mistakes
Polling inside the model turn. It spends time without improving the review and creates a budget-boundary race.
Running untrusted code in the privileged finalizer. GitHub recommends least privilege and careful treatment of untrusted checkout. A finalizer usually needs API reads and one narrow write, not PR-branch execution.
Treating every check as required evidence. Define the trusted set; bot plumbing, superseded suites, and the finalizer itself can pollute the gate.
FAQ
Does Qwen Code 0.21.1 automatically add this finalizer to my repository?
No. The release includes the behavior in Qwen Code’s own triage workflow. Treat it as a verified reference implementation and design pattern unless your chosen Qwen workflow explicitly installs equivalent automation.
Top comments (0)