feat(launchpad): deterministic pre-review pass for batch PR review (#426) - #430
Open
serina-mcfall wants to merge 1 commit into
Open
feat(launchpad): deterministic pre-review pass for batch PR review (#426)#430serina-mcfall wants to merge 1 commit into
serina-mcfall wants to merge 1 commit into
Conversation
) Reviewing a batch of PRs has two halves. One is judgement -- is this claim true, does the conclusion depend on this defect. The other is bookkeeping applied identically to every PR. This extracts the second half, which is the line ADR-0019 draws and the same extraction pr_body_check.py and adr_boundary_check.py already did for their own rules. Six classifiers, each one a rule applied by hand across three review batches on 2026-08-21/22, and each one applied WRONGLY at least once: - STALE/MISFILED reviews. Four PRs carried change-requests already satisfied. #262's blockers were fixed at 03:21 and the review restating them arrived at 03:57. #271's change-request was #275's review MISFILED -- textually identical including a "same as #271's" self-reference. No change to #271 could have addressed it. - CI triage. #268's red CI was setup-mold timing out on a one-markdown-file PR. #288's log printed four inherited warnings above the real blocker. - Independence. #265 carried a commit written in the reviewing session. - Leak scan. #281 quoted a private hook's header in a public file. - Placement, per AGENTS.md section 3. - Drift calibration. #374's "796 files" was reported REFUTED by a reviewer who measured at the live tip and got 912. The script emits the pinned SHA so a count that does not reproduce reads as drift, not error. It emits no severity. Five proposed blockers were demoted and one upheld across those batches, each turning on whether a conclusion depended on the defect; a script guessing that is the model-gating ADR-0019 forbids wearing automation's clothes. test_the_briefing_states_no_severity_anywhere asserts the absence. It also posts nothing, so it can run read-only. Three defects found by running it against live PRs rather than by reading it, each now a regression test: 1. FALSE MISFILED on #374. The only path token in a genuine review was `launchpad/ARCHITECTURE.md`, cited as corroborating evidence rather than as a defect site. Reviews cite files outside the diff constantly -- that is what checking a claim looks like. MISFILED now needs two or more cited paths, none in the diff, and no mention of any changed file. 2. Selecting log lines BY POSITION. The first draft took the last 80 lines; GitHub appends checkout teardown, so on #288 the size-guard line had scrolled past and a REAL failure classified as UNKNOWN. Selection is by content now. 3. The path regex required `:\d+` with no space, so it saw compiler output (`lib.rs:276:15`) but not the file-size guard (`lib.rs: 1000 -> 1001`). Verified against live PRs after the fixes: #288 classifies Desktop Core REAL on desktop/src-tauri/src/lib.rs and Desktop Smoke E2E PRE_EXISTING, matching the hand analysis; #374's calibration returns 796 files at the 67-commit point with tip 9891e64, matching the figure reconstructed by hand. 41 tests in test_pr_review_batch, 256 across launchpad/scripts. Registered in test_no_model.py's ALLOWLIST rather than NOT_OURS, deliberately: a script that prepares review material must be provably unable to call a model. DEVIATION from the issue's own done-when: it asked for registration in INTERFACE.md. Not done -- INTERFACE.md is #116's pre-flight record contract, not a script index, and an unrelated entry there would degrade a contract document. The script's module docstring is its interface. Refs #426 Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall
marked this pull request as ready for review
August 21, 2026 22:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extracts the mechanical half of batch PR review into
launchpad/scripts/pr_review_batch.py: which change-requests are stale or misfiled, which CI failures belong to this diff, whether the reviewer is independent, leaks, placement, and drift calibration. Emits no severity and posts nothing. Same extractionpr_body_check.pyandadr_boundary_check.pyalready did for their own rules.Related issue
Refs #426
Issue type
Task
Agent provenance
Objective
Add
launchpad/scripts/pr_review_batch.pyand its controls — a deterministic pre-review pass over a batch of pull requests.Impacted components
launchpad/scripts/pr_review_batch.pylaunchpad/scripts/test_pr_review_batch.pylaunchpad/scripts/test_no_model.py— oneALLOWLISTentryApproach and rejected alternatives
ADR-0019 rules that a deterministic script may gate a merge while a model verdict may only annotate. That line runs straight through batch review: the bookkeeping is a fixed rule set, the verdicts are not. So this script does the first and refuses the second.
Rejected: emitting severity. Across three review batches five proposed blockers were demoted to High and one upheld, each turning on whether a document's conclusion depended on the defect. A script guessing that is exactly the model-gating ADR-0019 forbids, wearing automation's clothes.
test_the_briefing_states_no_severity_anywhereasserts the absence rather than trusting it.Rejected: posting reviews or filing issues from the script. Keeping side effects out means it runs read-only, and it could eventually be a required check without being able to act.
Rejected:
NOT_OURSintest_no_model.py. A script that prepares review material is precisely the thing that must be provably unable to call a model, so it belongs onALLOWLISTwith its imports named.Rejected: registering in
INTERFACE.md— see Escalations.Verification
Command run:
Raw output:
Both live runs reproduce conclusions previously reached by hand: #288's real blocker is the file-size guard on
lib.rswhile its E2E failures are inherited, and #374's disputed "796" is exact at the pinned point.Not verified
Three defects were found by running it against live PRs, not by reading it, and each is now a regression test. That is the honest headline: the suite passed 35/35 while all three were live.
MISFILEDon docs(research): 19 of the 796 upstream files in the current drop can reach the deployed relay (#355) #374 — the most damaging answer this script can give, since it tells an author to dismiss a valid review. The only path token in a genuine review waslaunchpad/ARCHITECTURE.md, cited as corroborating evidence rather than as a defect site.MISFILEDnow requires two or more cited paths, none in the diff, and no mention of any changed file.:\d+with no space — it saw compiler output (lib.rs:276:15) but not the file-size guard (lib.rs: 1000 -> 1001).Not verified beyond that: the flake-signature and toolchain-step lists are drawn from the failures actually seen in three batches, so they are certainly incomplete — an unrecognised infrastructure failure classifies as UNKNOWN, which is the safe direction but not the useful one.
UNKNOWNis deliberately notclean, but it is also not information.The
--authorand--review-requiredselection paths were exercised only against this repository; no other repo was tried.calibrate()assumes anupstreamremote is fetched and returnsNoneotherwise rather than explaining itself well.Security implications
Read-only by construction: every
ghandgitinvocation is a read, nothing is posted, no file is written.subprocessis permitted intest_no_model.py's allowlist for the same reasonpreflight_fetch.pyholds it — to spawnghandgit— and that allowlist is what proves the script cannot reach a model, which matters because ADR-0019 forbids a model verdict gating anything.One genuinely security-relevant behaviour: the leak scanner reads added diff lines for private-tooling references and prints the matching line. It prints from a public PR's own diff, so it discloses nothing not already public, and it skips removed lines so a cleanup commit is not punished for the string it deletes.
Escalations
INTERFACE.md. Not done:INTERFACE.mdis task: deterministic pre-flight for the PR review agent #116's pre-flight record contract, not a script index, and an unrelated entry would degrade a contract document. The module docstring is the interface. Flagging rather than quietly dropping it, since I wrote that criterion myself.FLAKEverdict without a glance.review-finalpass has run on this branch, so there is no READY verdict to justify a non-draft PR.🤖 Drafted by Claude Code (
claude-opus-5) for @serina-mcfall.