qwen-code/.github/scripts
Shaojin Wen 027772d2ab
test(ci): stage on-disk session state in the serve A/B (#9444)
* test(ci): stage on-disk session state in the serve A/B

The serve A/B drives every scenario against a freshly started, empty daemon,
so the entire session-admission surface — case resolution, transcript
integrity, active/archive conflicts, reserved sources — is unreachable and a
PR that rewrites it diffs as "no response changes". #9341 is the worked
example: the posted A/B reported no change across 4 scenarios while the same
build pair, driven with transcripts on disk, answers differently on six
requests.

Scenarios can now stage transcripts before their request and capture a reduced
projection of the response, and the HTTP status is recorded on every capture so
a status-only difference is visible. Six session-admission scenarios use that:
a healthy restore, the legacy uppercase spelling, case-only twins, an
unreadable transcript, one id in both the active and the archive directory, and
creation carrying a source type.

The staged fixtures depend on the on-disk project layout, which the harness
mirrors rather than imports. If that mirror ever drifts the transcripts land
nowhere and every staged scenario would quietly answer 404 on both arms, so the
healthy restore doubles as a canary that fails the drive instead of publishing
a reassuring all-clear.

* test(ci): address the R1 review round on the serve A/B harness

Clears the capture directory before a drive writes into it, so a re-run can
never let an earlier run's files stand in for scenarios this run did not
capture, and writes a completion marker once every scenario is captured. A
baseline without that marker is now reported as partial, because a base drive
that stopped part-way leaves the scenarios it never reached rendering as "this
PR adds these responses" — the same shape a genuinely new scenario produces.

Both arms are driven by the head checkout's harness, so a capture pair always
carries the status field on both sides and the compatibility shim for a base
that predates it was unreachable; it and its tests are removed rather than left
to teach a transition the wiring cannot produce. Non-object response bodies are
now nested instead of spread, which dropped scalars and re-keyed arrays.

The source-type scenario probed a type today's daemon does not reserve, so it
never reached the refusal branch it was named for. It is split: one scenario
pins the source the daemon actually reserves, the other keeps an ordinary type
that a future reservation would move from admitted to refused. A second canary
covers the archive directory, which nothing certified before — a drifted
archive name would have left the conflict scenario loading from the active copy
on both arms and diffing clean. The remaining inert request body key is gone
too; the client id is read from a header, never the body.

The harness tests were passing under mutations they appeared to cover: the
staging routing, the projection guards and the fixed-id requirement are now
pinned by assertions that fail when those are inverted.

* test(ci): close the R2 gaps in the serve A/B harness

The completion marker was declared twice, once by the writer and once by the
reader, with nothing pinning the copies together: renaming one side left both
suites green while CI would either flag every complete baseline as truncated or
stop noticing truncated ones. The drive now owns the constant and the diff
imports it.

Two invariants the code asserted in comments were not enforced. A response body
carrying its own status key overwrote the status the harness saw, so a
status-only regression on such a route would have diffed as an unchanged body;
the harness value now wins. And the canary check — the harness's only drift
alarm — had no test at all: inverting it so it could never fire left every test
passing. It is now a named helper with tests on both branches.

The archive canary pinned an exact status, which conflates its precondition
with the product's decision: if an archived-only load ever becomes loadable,
the precondition still held, but the drive would abort and suppress the very
row the captures already contained. It now fails only on the one answer that
means the staged file was never seen.

Finally, nothing pinned that a staged scenario probes an id it actually staged.
Staging the wrong id answers 404 on both arms, captures identically, and drops
that branch out of coverage with every test green.

* test(ci): close the R3 gaps in the serve A/B harness

The completion marker proved that some drive finished, never that this run's
did. The only reset lived inside the drive script, which does not run when an
arm is skipped before it starts — no merge-base resolved, the base checkout
failing, or its build dying — and on the persistent pool the capture paths
outlive a run. An inherited baseline then arrived complete, marker included, so
neither degraded-baseline warning fired and the comment would have diffed this
head against another run's base. The workflow now clears both capture paths in
an unconditional step, which is the only place that covers a skipped arm.

The in-script reset also turned a write-only script into an unguarded recursive
delete of a path taken straight off the command line, which the documented
local usage invites a reader to mistype. It now refuses any directory that
holds something other than captures.

The healthy canary's premise was wrong: the product validates transcripts
record by record and fails open, so a fixture whose records stop validating
restores as an empty session and still answers 200. Measured against a real
daemon, a wholly drifted fixture passed the canary and left every staged
scenario probing an empty daemon — the false all-clear this harness exists to
prevent. The canary now keeps a replay-size witness in its capture and fails
when it is zero.

Three test gaps behind the same theme: the marker's writer, the comment
subcommand that CI actually invokes, and the mixed-case scenario's existence
were all unpinned, and the staged-id check asserted against the union of every
scenario's staging rather than the one under test. The capture loop is
extracted so its ordering is testable without a daemon.

* test(ci): cover the setup-failure abort in the serve A/B capture loop

The capture loop was extracted so its ordering could be pinned without a
daemon, and three of its four abort branches were covered — but not the one
that fires when a scenario's setup request fails. Dropping that throw left the
whole suite green while a capture would be recorded against a daemon where the
setup never took effect, which is the masked diff the branch exists to prevent.

* test(ci): close the R5 gaps in the serve A/B harness

* fix(ci): send an admitted source in the serve A/B unreserved-source witness

---------

Co-authored-by: wenshao <nigolaschao777@gmail.com>
2026-08-20 14:09:03 +00:00
..
ci perf(ci): run docs-only automatic reviews at medium effort (#8648) 2026-08-07 17:00:32 +00:00
dsw-swe-verified feat: chain Terminal-Bench release evaluation (#9120) 2026-08-17 05:53:06 +00:00
fixtures test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
assign-issue-owner.mjs feat(ci): auto-assign issues to area owners from labels (#8668) 2026-08-08 23:01:03 +00:00
assign-issue-owner.test.mjs feat(ci): auto-assign issues to area owners from labels (#8668) 2026-08-08 23:01:03 +00:00
auto-minimize-spam.test.mjs fix(ci): minimize new spam comments on creation (#9266) 2026-08-17 05:12:04 +00:00
cap-release-notes.mjs fix(release): keep notes anchored and cap the release body (#8199) 2026-07-31 09:55:38 +00:00
cap-release-notes.test.mjs fix(release): keep notes anchored and cap the release body (#8199) 2026-07-31 09:55:38 +00:00
check-autofix-contracts.sh ci(autofix): add cross-package contract verification (#7642) 2026-07-24 05:13:04 +00:00
check-settings-schema.sh ci(autofix): recover from generated-artifact CI gates and stop silent stalls (#6998) 2026-07-17 03:26:43 +00:00
check-workflow-size.sh fix(ci): keep qwen-autofix.yml under GitHub's 500 KB start-runs limit (#9517) 2026-08-20 01:56:45 +00:00
ci-flaky-rerun.mjs feat(ci): auto-open a deflake fix issue for confirmed flaky tests (#7231) 2026-07-19 16:49:29 +00:00
ci-runner-routing.test.mjs fix(ci): back-port the checkout-heal wipe guard to the triage and serve-ab wipes (#9277) 2026-08-18 06:49:40 +00:00
classify-release-notes.mjs fix(ci): route workflow label mutations through REST (#8761) 2026-08-09 15:05:15 +00:00
classify-release-notes.test.mjs fix(ci): route workflow label mutations through REST (#8761) 2026-08-09 15:05:15 +00:00
create-desktop-update-manifest.mjs feat(desktop): add Aliyun OSS release mirror (#8976) 2026-08-12 10:59:10 +00:00
create-electron-bridge-manifest.mjs fix(desktop): bridge Electron users on Windows and Linux (#9079) 2026-08-13 15:42:31 +00:00
pr-safety-precheck.mjs fix(ci): limit fork PR precheck to safety signals (#6178) 2026-07-02 20:56:41 +08:00
pr-safety-precheck.test.mjs fix(ci): limit fork PR precheck to safety signals (#6178) 2026-07-02 20:56:41 +08:00
qwen-triage-workflow.test.mjs fix(triage): compute the flake-gate diff before the env -i re-exec (#9468) 2026-08-19 14:37:44 +00:00
resanitize-git-config.sh fix(ci): make autofix verification gates hermetic to runner git config (#8961) 2026-08-13 11:39:04 +00:00
resolve-owning-packages.sh fix(autofix): resolve owning package for nested paths; report verify-failed handoffs as not pushed (#7330) 2026-07-20 14:39:56 +00:00
resolve-sandbox-image.mjs ci(autofix): restore sandbox image flow (#6261) 2026-07-03 15:30:58 +00:00
resolve-sandbox-image.test.mjs ci(autofix): restore sandbox image flow (#6261) 2026-07-03 15:30:58 +00:00
run-autofix-review-verification.sh fix(autofix): make the brake's BLOCKED handoff a first-class round outcome (#9297) 2026-08-20 08:32:43 +00:00
serve-ab-diff.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
serve-ab-diff.test.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
serve-ab-drive.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
serve-ab-drive.test.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
upsert-bot-comment.sh perf(ci): run docs-only automatic reviews at medium effort (#8648) 2026-08-07 17:00:32 +00:00
upsert-bot-comment.test.mjs perf(ci): run docs-only automatic reviews at medium effort (#8648) 2026-08-07 17:00:32 +00:00
upsert-deferred-issue.sh feat(autofix): defer verified out-of-footprint findings to a surviving follow-up queue (#9189) 2026-08-16 11:28:05 +00:00
web-shell-visuals-compose.mjs ci(web-shell): denoise cross-job font-AA so visual previews stop false-flagging (#7210) 2026-07-19 11:27:08 +00:00
web-shell-visuals-compose.test.mjs ci(web-shell): denoise cross-job font-AA so visual previews stop false-flagging (#7210) 2026-07-19 11:27:08 +00:00
web-shell-visuals-publish.mjs fix(ci): don't let one failing scenario sink the whole visual preview (#7511) 2026-07-23 02:34:07 +00:00
web-shell-visuals-publish.test.mjs fix(ci): don't let one failing scenario sink the whole visual preview (#7511) 2026-07-23 02:34:07 +00:00