mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
* feat(verify-pr): give the sandboxed round the PR's review threads The sandboxed /verify round had no token and no review context. Its only inputs were the metadata snapshot and, on a follow-up round, the previous report. On #13652, Critical R1-26 was confirmed and then marked fixed three days before a round that published merge-ready without mentioning it. Eight hours later the review bot, at the head that round had certified, still could not rule out its residual. The verify job's trusted resolve step now writes review-threads.json beside pr.json. It holds every review thread, resolved ones included, since resolving is the author's claim, together with each reviewer's standing CHANGES_REQUESTED review. It comes from one paginated GraphQL query reshaped with jq. The snapshot is best-effort: on failure no file is written and the step warns. verify-pr-prepare.mjs sends the same query and writes the same shape for the local path. It removes a previous copy first, so a failed fetch cannot leave a stale file. A test runs the workflow's block verbatim and prepare's transform over the same pages and requires equal output. The skill adds report item 4, Existing review findings. Each term the verdict turns on is computed from snapshot fields: - a thread is blocking when its first comment is tagged Critical, Blocker, P0 or P1 by an owner, member or collaborator; - a blocking thread is open when it is unresolved, or when that comment belongs to a standing change request, resolved or not. That is the rule GitHub's review decision applies. An open blocking thread left unmeasured rules out merge-ready, and with nothing failed the verdict is inconclusive. Findings at fail 0 would publish as "passed with non-blocking findings". Other blocking threads are re-measured as budget allows, and the verdict line counts those left unmeasured. Change request bodies are listed but do not hold the verdict, because their severities are prose. The duty is also a line in the scope budget. A missing file reads as unknown, never as "nothing open". The file adds 2396 bytes, so the size baseline records the exact 378242. * test(verify-pr): pin the review snapshot's jq guard, copy order and odd answers - The CI/local parity test runs the step's real jq program. Like the file's four other jq cases, it now skips when jq is missing, instead of failing one assertion later with a message that names neither jq nor the missing tool. - The local recipe must clear the cached review-threads.json before it copies prepare's file. The test pinned the three lines but not their order. With rm after cp, every local round would read the review state as unknown. - prepare's two other failure arms are now driven through the CLI: an answer that is not JSON, and pages without a pull request. Each must leave no file and say why. An empty state there would read as "nothing open". * test(verify-pr): drive the review snapshot through the shared gh harness The review-snapshot case had its own copy of the executed-step harness: a temp dir, a stub gh on PATH and GitHub's bash flags. makeGhHarness exists so that fidelity contract lives in one place. The factory now records every call's argv, returns its temp dir, and has an empty-stdout arm for paginated reads, GH_STUB_EMPTY_LIST. The snapshot case runs through it. Its failure arms are the factory's GH_STUB_FAIL_LIST and GH_STUB_EMPTY_LIST. Deleting the shared stub's fail arm, its empty-stdout arm or its argv capture turns the case red, and so does recording only the first argument.