How it works
Test a pull request
Walk a plan at a pull request's head with qaren pr, then post the result with qaren publish.
Your agent writes the plan and runs qaren pr; it publishes the result only after you confirm. Here is what it means.
qaren pr <number|url> --plan-file plan.md --device <simulator-UUID> --json
qaren publish <run-id> --json
Both require the GitHub CLI (gh); follow the authoritative
GitHub authentication contract
for token-only CI, stored authentication and lookup refusals.
qaren pr
qaren pr runs the same pipeline as qaren check, from the app's
directory with the same .qaren/config.yaml and plan. It walks a detached worktree at the
pull request's head in the run directory's wt/ instead of your working tree; see the run storage contract.
- It refuses unless origin's
pull/<n>/headis the head GitHub reports and the worktree is clean at that commit, both before the lease and again before the walk. - When the pull request moves during the run, the receipt names the tested commit in
tested_older_commit. - Blocks the walk saved are copied to the run's
blocks/directory before the worktree is removed. - Teardown removes the worktree only after the run's build, core, Metro, recorder and runner
host are proven gone. Otherwise it stays recorded for
qaren cleanup <run-id>.
See the authoritative PR recording contract for platform and Android API requirements, media tools, video-unavailable outcomes and recorder cleanup recovery.
qaren publish
qaren publish <run-id> publishes a finished qaren pr run. It refuses before any upload,
comment, label change or block write-back when:
| Condition | Result |
|---|---|
| The run has no persisted terminal result | RUN_RECORD_INVALID |
| The run was cancelled | RUN_CANCELLED (exit 4) |
| The tested candidate did not verify unchanged | CANDIDATE_DRIFTED (exit 1) |
| Teardown did not prove ownership | OWNERSHIP_UNPROVEN (exit 4) |
A plain QA fail can still be published as a report. A later recovery does not upgrade the
original result; re-run qaren pr to get publishable evidence.
The comment
Publish posts one comment with:
- the PASS, FAIL or REFUSED verdict and the refusal code;
- the tested commit;
- the video, when it is eligible;
- the plan with ✓ or ✗ per walked line, taken from the walk's own rows, never from the raw plan file, so typed values stay out;
- the failing screenshot, when one is available;
- collapsed run details.
The host name, home directory, user name, absolute paths, device IDs, serials, ports and
private network addresses are removed from the comment. Publish then removes the needs-qa
label, but only when the pull request's head is still the tested commit.
The description
For the opt-in description section, video eligibility, marker recovery, retry outcomes and concurrent-edit limits, follow the authoritative publication contract.
Saved blocks
For saved-block publication eligibility and withholding outcomes, follow the publication contract.
Published blocks are committed to the pull request branch with a Qaren-Run: <run-id>
trailer, using your own git identity and a push lease on the tested commit. When the branch
moved, the pull request comes from a fork, or the push destination cannot be verified, a
second comment carries the blocks' YAML instead.
Only one publisher runs per run at a time. Retrying qaren publish reuses a comment it
already posted rather than posting a duplicate.
Video
See the authoritative video publication contract for trim boundaries, withholding rules and public reason codes, login replay behavior and local recording privacy limits.