Repository navigation
feat(review): write the preflight both guides have referenced since #2281 - #2500
Conversation
…2281 `REVIEW.md:18` and `CLAUDE.md:71` both tell reviewers the guide reaches them three ways: `review-preflight.py`, `scripts/review-checks.sh` in CI, and the managed GitHub-App reviewer. Only two of those exist. The script was never written. No commit in the repo`s history touches the path and no blob by that name appears on any ref, while the prose describing it has shipped since #2281 (2026-07-25, `0a36bf19`). That matters more than a stale doc line because of which channel is missing. The CI runner scans a diff during CI; the GitHub App reviews on GitHub. Neither surfaces anything to an agent or human reading a PR at a terminal -- the exact case CLAUDE.md points at ("when you review, `review-preflight.py` reads `REVIEW.md` and prints the criteria inline"). #2281`s stated goal was that following the guide be "structurally enforced, not dependent on an agent remembering to"; for interactive review it has been dependent on exactly that. An instruction naming a tool that does not exist is worse than no instruction: it reads as a completed step. Found by trying to run it before reviewing #2495 and getting `can't open file`. Behaviour: - guide resolution mirrors review-checks.sh exactly (`--guide` wins, else `<repo>/REVIEW.md`), so the two can never disagree on what is authoritative - prints the `## Lessons` section verbatim, summarizes the `checks:` block (counted 6 flag / 4 allow against the shipped guide) rather than dumping it - names the one-liner that actually scans a PR diff, and warns that a bare `review-checks.sh` compares the WORKING TREE and reports "empty diff" - a missing/unreadable guide exits 1. A preflight that prints nothing and succeeds is the failure mode this exists to prevent, so it is pinned by test. Adds no new dependency; stdlib only. `scripts/` is outside `gen-src-map.py`s scope (verified by regenerating: no diff), so no src-map churn. Stand: Echo Act IV Mini
…olver
CI caught the new script on PATTERN_REPO_WALK: its repo-root fallback is
`Path(__file__).resolve().parent.parent`, the historic anti-pattern the lint
exists to stop.
The lint`s own note says how to resolve this: check-python39-compat.py is
"listed explicitly rather than spelled `parents[1]` to dodge the regex --
evading the lint by rewording would defeat the point of having it." So this
adds the script to ALLOWED with its justification rather than renaming the
expression.
review-preflight.py is the same category as gen-src-map.py and
check-python39-compat.py: repo tooling that needs the REPO ROOT (to read
REVIEW.md) and has NO workspace to resolve. Going through the wrapper would
resolve the workspace, which is the wrong directory. It already prefers
`git rev-parse --show-toplevel` and only walks from __file__ when git is
unavailable.
Verified both directions:
--diff (what CI runs) : refused before, "no new anti-patterns" after
full tree : 9 offenders on this branch AND on origin/main --
unchanged, and review-preflight is not among them
Stand: Echo Act IV Mini
|
CI caught a real one and I've fixed it at
On the fix I did not make. The obvious dodge is rewriting it as
So I added the script to Verified both scan modes rather than just the one CI runs: The full-tree scan reports pre-existing offenders by design; the counts being identical to Tests still 7/7. Remaining checks were still running when I pushed. |
Coverage Gate✅ Diff coverage PASSES the 95% bar. Whole-tree (informational): 71%. Diff CoverageDiff: origin/main...HEAD, staged and unstaged changes
Summary
|
qingyun-wu
left a comment
There was a problem hiding this comment.
Blocking on the current head because Coverage Gate is failing at 91.8% diff coverage for scripts/review-preflight.py, with lines 45-47 and 120-122 uncovered. I did not find an additional code-level blocker in the new preflight script; focused local checks passed (tests/review-preflight.test.py, review-checks.sh, git diff --check, and py_compile with an isolated cache). Once the coverage gap is covered and CI is green, this should be straightforward to re-check.
Reviewed by Qingyun's Personal Codex.
Coverage Gate measured 91.8% on the diff, naming lines 45-47 and 120-122. Both
are error paths:
45-47 `git rev-parse` fails -> fall back to the script`s own location
120-122 the guide exists but cannot be read -> report and exit 1
These are exactly the paths that run when the environment is degraded, which
is when a reviewer most needs the tool to behave predictably instead of
tracebacking, so they are worth real cases rather than a coverage pragma.
Three tests added:
- git raising FileNotFoundError still resolves a root that contains REVIEW.md
(asserts the fallback is USEFUL, not merely that it returns something)
- git succeeding with empty stdout does not yield Path("") -- the `if out:`
guard, which a naive fallback test would skip
- an unreadable guide exits 1 with "cannot read" on stderr and nothing on stdout
Verified the lines are actually reached, because `coverage` collects nothing on
this host (its own positive control on a trivial script reports
no-data-collected, so any local percentage would be fabricated). Used sys.settrace
over the module during the suite:
positive control - line 43 executed : True
lines 45-47 : covered, none missing
lines 120-122 : covered, none missing
Suite 10/10. Claiming the branches are exercised; CI remains the authority on
the percentage.
Stand: Echo Act IV Mini
|
Fixed at Both gaps were error paths, so I covered them with real cases rather than a pragma:
The first one asserts the fallback is useful, not merely non-empty — a test that only checked "returns a Path" would pass against a broken fallback. The second covers the On how I verified it, since I can't quote you a percentage. The positive control is there so the two "covered" results mean something rather than reflecting a tracer that never attached. So: I'm claiming the branches are now exercised, not that the diff is at any particular percentage. CI is the authority on the number — re-checking once Coverage Gate re-runs. Suite is 10/10. |
qingyun-wu
left a comment
There was a problem hiding this comment.
No blocking findings on the refreshed head. The previously failing coverage paths are now covered, Coverage Gate has passed for this commit, and the focused local checks passed: tests/review-preflight.test.py, scripts/lint-workspace-resolution.sh --diff, review-checks.sh, git diff --check, review-preflight.py, and py_compile with an isolated cache. CI was still finishing when I checked, but the code path looks ready pending the remaining green checks.
Reviewed by Qingyun's Personal Codex.
|
@qingyun-wu — the coverage gap you blocked on is closed, at head You named the condition precisely: "Once the coverage gap is covered and CI is green, this should be straightforward to re-check."
Thanks for the focused local checks in your review — Re-requesting review. |
john-the-dev
left a comment
There was a problem hiding this comment.
Approved on exact head 60ab74ea after independent current-main and activated-path review.
Current main 654e4fe3 still has no scripts/review-preflight.py, so the documented terminal-review path is genuinely absent. On this head, the focused suite passes 10/10, the real shipped guide renders its full Lessons section and correct 6/4 check counts, missing/unreadable guides fail loudly, missing/empty git-root discovery falls back to a useful repo root, and --guide precedence matches review-checks.sh. Python compilation, diff hygiene, REVIEW.md hardcoded-path scanning, and the workspace-resolution diff lint pass; every exact-head CI/coverage/CLA gate is green.
Worst-case disruption is a false sense that criteria were loaded when the guide cannot be found/read or parsed. Missing/unreadable files fail nonzero, a missing Lessons section emits an explicit warning, and the real-guide regression pins the shipped format. The repo-root lint exception is scoped to this named repo tool and retains full-tree visibility. LGTM, non-blocking.
Not merge-ready yet: the branch is behind current main and maintainerCanModify is false, so the author must refresh it; after refresh, revalidate full CI/CLA and two qualifying current-head approvals before merge.
|
@cla-assistant check |
qingyun-wu
left a comment
There was a problem hiding this comment.
No blocking findings on the refreshed merge-main head. The PR's own files are unchanged from the previously approved 60ab74e tree, and focused checks still pass on 5625a126: tests/review-preflight.test.py, scripts/lint-workspace-resolution.sh --diff, review-checks.sh, git diff --check, review-preflight.py, and py_compile with an isolated cache. CI has restarted for the merge commit and was still in progress when I checked.
Reviewed by Qingyun's Personal Codex.
|
Correction to this PR's rationale, now that it's merged and is the durable record. I wrote that the script "was never written," evidenced by A
So the accurate framing is not "the docs named a tool nobody built." It's:
Why this is worth correcting rather than leaving. Two things change:
The behavioural claims in the PR body are unaffected and still hold as measured — guide resolution, the Method note on how I missed it: my |
The gap
REVIEW.md:18andCLAUDE.md:71both state the guide's lessons reach reviewers three ways:review-preflight.py,scripts/review-checks.shin CI, and the managed GitHub-App reviewer.Only two of those exist. The script was never written:
So the prose has shipped since #2281 while the file it names has never existed on any ref.
Why it matters more than a stale doc line
It's about which channel is missing. The CI runner scans a diff during CI; the GitHub App reviews on GitHub. Neither surfaces anything to an agent or human reading a PR at a terminal — the exact case CLAUDE.md points at: "when you review,
review-preflight.pyreadsREVIEW.mdand prints the criteria inline so you see them on every preflight run."#2281's stated goal was that following the guide be "structurally enforced, not dependent on an agent remembering to." For interactive review it has been dependent on precisely that.
An instruction naming a tool that doesn't exist is worse than no instruction — it reads as a completed step. I found this the honest way: tried to run it before reviewing #2495 and got
can't open file.Before / after
Before, at
origin/main:At this head:
The 6/4 counts were checked against the shipped guide (10 list items under
## Checks, 6 underflag:).Design choices
review-checks.shexactly —--guidewins, else<repo>/REVIEW.md. The two can't disagree about what's authoritative.## Lessonsverbatim, summarizeschecks:rather than dumping YAML a human doesn't need to read.review-checks.shcompares the working tree — it reportsempty diff — nothing to checkduring a PR review, which is easy to misread as "scan passed". I hit that myself on tidy: centralize optional bridge script execution #2495.Tests
tests/review-preflight.test.py, 7 cases — 7/7 pass. The load-bearing ones: missing guide exits non-zero with empty stdout; a guide lacking## Lessonswarns instead of printing nothing; guide-resolution order matchesreview-checks.sh; and one case runs against the real shippedREVIEW.mdso a future edit that breaks the parser fails here.Scope
Two new files, stdlib only, no new dependency, no existing file modified.
scripts/is outsidegen-src-map.py's scope — verified by regenerating and getting no diff — so there's no src-map churn.Runs under Python 3.9.6 locally, matching the CI floor (#2479). Ruff isn't installed on this host, so I'm claiming CI as the authority there rather than a local pass.
Note on the doc
I deliberately did not edit
CLAUDE.mdorREVIEW.mdhere. Their prose becomes true once this lands, and changing agent-instruction files is a separate call.@sonichi flagging you per usual.