Repository navigation
chore(hooks): close hawkeye pin/coverage gaps flagged on #474 - #475
Conversation
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The focused hook and regression-test changes correctly close the described coverage gaps.
Review effort: Balanced
Findings: None
What changed in this PR
Adds safeguards to keep local and CI hawkeye license-header checks aligned.
Changes:
- Adds a test enforcing consistent hawkeye version pins.
- Runs the local license-header hook for Markdown changes.
| File | Description |
|---|---|
xtask/src/main.rs |
Registers the pin-test module. |
xtask/src/hawkeye_pin.rs |
Verifies documented and CI hawkeye versions match. |
.pre-commit-config.yaml |
Includes Markdown in license-header hook triggers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
9fe963a to
4b87dcf
Compare
|
🔴 Automated review · pr-review-watcher · 4b87dcf This automation never files a GitHub approval, so no approving review will SummaryThe PR does two things. It adds a test-only xtask module that fails if the hawkeye version in CONTRIBUTING.md and in CI on this head: these checks had not reported when this review ran — E2E tests (MI300X), E2E tests (MI350P), E2E tests (Strix Halo, Ubuntu), Sphinx docs build (-W), Skill checks (skillscope). No check had failed. This review does not claim CI passed. 🚫 Blocking (must fix before merge)None. Non-blocking
|
|
Addressing the non-blocking findings: Fixed in 6764859 (the three Not changed, acknowledged as out of scope for this PR:
|
|
🔴 Automated review · pr-review-watcher · e4ae01b This automation never files a GitHub approval, so no approving review will SummaryThis round covers the new commit, e4ae01b. The hawkeye check now fails on any stale Reviewed: Verified:
Blocking: 0 · Non-blocking: 7. Note on classification: the review agent rated the first two items below as blocking. They are listed as non-blocking here, for these reasons:
🚫 Blocking (must fix before merge)None. Non-blocking
Carried from the previous round, not re-checked in this one: CI on this head: no check had failed when this review ran. The E2E GPU lanes (MI300X, Strix Halo Ubuntu/WSL2/Windows) were still queued or running. Sphinx docs build and Skill checks were skipped as not applicable. This review does not claim CI passed. On the reply aboveThanks. This round read e4ae01b and confirms all four fixes you listed:
The cargo-about check is weaker than its hawkeye twin (first item above). The new test has a dead panic branch (second item). Neither gates the merge. The two points you left as they are (the |
|
Addressed the blocking finding in fbf2084: moved the guard out of the standalone This also resolves three of the non-blocking points as a side effect of the deletion:
And fixes one more directly: Manually re-ran your mutation set against the new test: bumping only Left as-is, per your note that it's low risk and pre-existing: the
|
|
@jussielo-amd I've updated the automated review above for fbf2084 (report). The previous round's blocking finding is resolved, and nothing in this round blocks the merge. The failed E2E tests (MI300X) check comes from the CI runner, not this PR: the same failure shows up on unrelated PRs on the same machine. The report has the details. |
- hawkeye_pin_matches_ci_workflow now checks every `hawkeye@` line in CONTRIBUTING.md, not just that the correct one is present, so a stale duplicate left by an earlier bump can't silently pass. - Its doc comment now names HAWKEYE_SHA256 as the third, unguarded edit a version bump requires, alongside the two this test already guards. - pinned_version_matches_workflows now also checks CONTRIBUTING.md's cargo-about pin, which drifted independently of the ci.yml/ dependabot-manifests.yml pair it already covered. - A new license_header_hook_covers_licenserc_includes test ties .pre-commit-config.yaml's license-headers `types_or` to licenserc.toml's `[files].includes`, so a future include with no matching tag (the exact gap this PR closed for markdown) fails loudly instead of silently skipping files locally. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Addressed all remaining non-blocking points from the latest round (#5990125500, against fbf2084): Fixed in e4ae01b:
Left as-is, per your call:
|
|
@jussielo-amd I have updated the automated review above for e4ae01b (report). Nothing in this round blocks the merge. The fixes from your reply are confirmed. One point: the new cargo-about check in |
…475 review - tpn.rs: pinned_version_matches_workflows (renamed to pinned_version_matches_workflows_and_docs) now checks every cargo-about@ line in ci.yml, dependabot-manifests.yml, and CONTRIBUTING.md, anchored on the whole version token. A stale duplicate pin or a suffixed version (0.9.10) no longer false-passes, mirroring the hawkeye pin guard. The assert messages now describe the actual check instead of a stale --locked --features cli phrase. - workflow_contract.rs: license_header_hook_covers_licenserc_includes's extension lookup now splits on the last path segment before rsplit_once('.'), so an extension-less glob (**/Dockerfile) hits the intended "has no extension" panic instead of silently falling through to the misleading "(.**/Dockerfile); add its prek tag" message. - Doc comments on both tests now describe their actual scope and direction (workflows + CONTRIBUTING.md; includes -> types_or only) and point at the right file for the markdown tag. Verified each fix with a reverted mutation (stale duplicate pin, suffixed version, extension-less glob). cargo test -p xtask (253 passed), clippy --workspace --all-targets --exclude e2e-cucumber, and fmt --all --check are clean. The MANIFEST.md cargo-about pin (a 4th unguarded copy) is left as-is, per the prior round's call to track it as a follow-up. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Addressed the remaining non-blocking points from the latest round (#5990125500, against e4ae01b) in db0b696:
Left as-is: the MANIFEST.md 4th unguarded |
rominf
left a comment
There was a problem hiding this comment.
Stepping back from the line-level rounds: the hook fix is one line, but the PR has grown to +186, nearly all of it tests guarding config drift. I think most of that can be removed or folded together. None of this blocks the merge; it's a design suggestion.
1. Drop the types_or filter instead of guarding it. The hook has pass_filenames: false, so hawkeye always scans the whole repo per licenserc.toml. types_or only decides whether the hook fires, not what it checks. With always_run: true instead, license_header_hook_covers_licenserc_includes, its hand-maintained LICENSE_HEADER_EXTENSION_TAGS table, and the hand-rolled TOML/YAML parsing all become unnecessary. It also closes the remaining gap where a commit touching only licenserc.toml skips the hook. I checked locally (prek 0.4.5): with always_run: true and pass_filenames: false, the hook runs on a commit whose only file matches no types_or tag. The cost is one hawkeye run per commit. If you'd rather keep a filter, a files: regex in .pre-commit-config.yaml is still simpler than a Rust test that keeps two config files in sync.
2. One table-driven pin test instead of three copies. tpn.rs (workflow loop + CONTRIBUTING block) and hawkeye_pin_matches_ci_workflow repeat one pattern: collect every <tool>@ line and assert each contains <tool>@{ver} . A single test over a (tool, canonical-version source) table and a shared list of files to scan (CONTRIBUTING.md, MANIFEST.md, .github/workflows/*.yml) would cover both tools. It would extract the token after @ and compare it for equality, which removes the trailing-space anchor and the prefix-match class of bug. The next pinned tool then costs one row, not another ~30-line test.
3. That would also cover MANIFEST.md:747, which still has an unguarded cargo install cargo-about@0.9.1 (raised in round 2, not addressed). With a shared file list it can't be missed.
On proportion: a drifted CONTRIBUTING.md pin means a contributor installs the wrong tool locally, and CI stays the gate. So I'd keep these guards as small as possible.
|
@rominf Took all three suggestions in 1537518 — this was the right call, thanks for stepping back.
Net: 251 tests (down from 253 — two old tests removed, one unified test added), |
|
review-coverage · 1537518 High-effort review (primary pass + independent fork reviewer, same five scrutiny angles: parsing edge cases, coverage-scoping regression, visibility-change side effects, pre-commit hook/stage interaction, docs-vs-behavior drift) across all 3 changed files. Verified by actually running |
rominf
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · 1537518
This automation never files a GitHub approval, so no approving review will
appear here whatever the outcome — the merge decision stays with a human
reviewer.
Review — needs work
Full review of the whole change.
This is a follow-up to the gaps raised on #474 (that one is a PR, not a ticket), and it closes the two it names: the local hook coverage gap and the pin drift between files. No ticket is named.
Round history: every finding below is new this round. The change was reworked since the last automated round (at e4ae01b), so this round re-read the whole change rather than only the new commits. The MANIFEST.md cargo-about pin flagged last round is now covered by the unified pin test.
Blocking
- (new) CONTRIBUTING.md is now wrong about when the hawkeye hook runs —
CONTRIBUTING.md:57,.pre-commit-config.yaml:94
CONTRIBUTING.md:57still says the license-headers hook "runs on both commit and push for matching files". The change replacestypes_orwithalways_run: true, so there is no longer any file filter. The hook now runs on every commit and every push, whatever is staged.
The same paragraph warns that the hook "fails hard rather than skipping when the binary is missing". That warning now applies to every commit, including commits that only touch YAML, TOML or.ps1files. Before this change, those commits passed without hawkeye.
AGENTS.md §5 requires docs to be updated in the same change when observable behaviour changes. It also says to grep for every repeat of the claim. Here the code governs, becausealways_runis what the hook actually does, so the doc is the side to fix.
Confidence 85 · mechanical · Fix: drop "for matching files", and say that every commit and push needshawkeyeinstalled. Optionally mentionSKIP=license-headersas the escape hatch.
Non-blocking
- (new) The new pin test does not check the cargo-about cache keys —
.github/workflows/ci.yml:1059,.github/workflows/dependabot-manifests.yml:73
Both files hard-code the cache key${{ runner.os }}-cargo-about-0.9.1. That string contains no@, sopin_tokennever sees it. I confirmed this by changing only the ci.yml key to0.9.0: the test still passes.
Suppose a version bump forgets the key. CI then gets a cache hit, skips the install step and keeps the old binary, andtpn --checkstops with "must be version X". So the failure is loud, but it happens in a confusing place.
The test's doc comment says the versions "must never drift", which claims more than the test checks.
Confidence 100 (gap confirmed by a run) · logic · Fix: build each key from the version, or add acargo-about-marker row to the table. - (new)
assert_pins_matchalso matches pins inside YAML comments —xtask/src/workflow_contract.rs:2077-2098
The module doc (workflow_contract.rs:12-16) rejects matching against the whole file because it "can false-pass … found only in a comment". The new helper scans every raw line and never callsstrip_comment.
I tested this by rewriting ci.yml's install line tocargo install cargo-about --version 0.9.0, with the oldcargo-about@0.9.1kept in a trailing comment. The test stayed green.
This failure needs a contrived edit, but the helper breaks a rule that this file states for itself.
Confidence 85 · logic · Fix: strip#comments before matching in the YAML files. - (new) The new helpers have no extractor-guard fixture tests —
xtask/src/workflow_contract.rs:2070-2098
The file's own guidance at:2160-2161says extractors get fixture tests "so the contract tests above can't silently false-pass on a shape they don't handle". The doc comment forpin_tokenandassert_pins_matchclaims two guarantees: no prefix false-pass (0.9.10against0.9.1) and detection of a stale duplicate pin. Today only manual mutation checks back those claims; no test does.
Confidence 70 · mechanical · Fix: add a small fixture test for both cases. - (new) The prek check list in CONTRIBUTING.md omits license headers —
CONTRIBUTING.md:49
This gap existed before this change. It is the paragraph next to the stale line above, so both are cheap to fix together.
Confidence 85 · mechanical · Fix: add hawkeye/license headers to the list. - (new) The PR description overstates what existed on the base branch — PR body, "Summary" and "Why"
- It says the change replaces "two independent, differently-shaped tests". The base branch has only one:
tpn.rs::pinned_version_matches_workflows. The hawkeye test was added and then folded away within this same PR. - It says the cargo-about pin "had no guard tying them together". In fact
ci.ymlanddependabot-manifests.ymlwere already guarded. Only CONTRIBUTING.md and MANIFEST.md were not. - These misstate history, not the change's scope.
Confidence 85 · mechanical · Fix: reword both sentences against the base branch.
- It says the change replaces "two independent, differently-shaped tests". The base branch has only one:
Decisions for the author
- Tradeoff:
always_runagainst a widenedtypes_or. Foralways_run: CI's prek job runs--no-group local-tools(ci.yml:874-875), so this changes nothing in CI. It also leaves no second include list to drift away fromlicenserc.toml. Against it: every local commit and push now runs hawkeye on the whole working tree. So a contributor withouthawkeyecannot commit at all. An untracked scratch.md/.rsfile without a header also blocks unrelated commits, as the recent.supergoal/**exclude on the base branch shows. Usingtypes_or: [rust, python, shell, markdown]keeps the old cost profile, but it covers neither commits that only touchlicenserc.tomlnor future include changes. Confirm the stricter local cost is intended. - No test pins
always_run(non-blocking-improvement). The earlierlicense_header_hook_covers_licenserc_includesguard was removed along withtypes_or. Nothing now stops someone from bringing back a file filter that silently drops markdown. A one-line assertion inworkflow_contract.rswould close that.
Positive signals
- The test compares an exact token instead of using
contains, and it checks every pin line, not just the first. My mutation runs confirm both: a stale duplicate, a0.9.10prefix and a single-file bump each fail with a clear message. - It reads
HAWKEYE_VERSIONthrough the existing fixture-testedjob_block/job_mappingextractors on the CRLF-normalisedread_workflow, scoped to the one job, instead of copying the version into a constant.
Deployment notes
- The branch is 28 commits behind the base branch.
git merge-treereports no conflicts, but this head has not been run against the per-crate coverage floors added in #482. The test only moves withinxtask, so the effect should be neutral, but the new gate will run only after a rebase.
What this covered
I read the whole change (base branch ...1537518651b439a14486b21d55944402819e70fb, 3 files) completely. I also read the ci.yml license-headers and third-party-notices jobs, dependabot-manifests.yml, all of tpn.rs, the workflow_contract.rs extractors and their fixture tests, licenserc.toml, CONTRIBUTING.md and MANIFEST.md.
- Runs:
cargo test -p xtaskpasses on the head. I also ran 8 file mutations against the new test: 6 failed as they should, and 2 exposed the gaps reported above. - CI: every check on the head commit succeeded. Sphinx docs and skillscope were skipped.
- Passes: the code pass, the AGENTS.md pass, history (git log/blame), prior changes (comments on #474, #300, #277, #72, #51 and #55) and code comments all ran as independent workers. The design questions ran as one more worker.
- Not run:
- The full workspace test and clippy gates.
- prek's live behaviour with
always_run. The cost to contributors described above is reasoned from the config, not exercised. - An agent-instruction quality pass, because the change touches no agent-instruction files.
- Discussion: I did not reconcile this report with any PR discussion.
On the replies above
Thanks. Your three updates were read. This round re-read the whole reworked change at 1537518. The unified pin test now covers MANIFEST.md, and the exact-token comparison closes the prefix false-pass; mutation runs confirm both. The one blocking item is a single stale sentence in CONTRIBUTING.md that the always_run switch made untrue.
Guard CONTRIBUTING.md's hawkeye@7.0.0 pin against drifting from ci.yml's HAWKEYE_VERSION (mirrors the existing cargo-about pin guard in xtask/src/tpn.rs, as a test-only module since hawkeye has no xtask subcommand to host a production constant). Also widen the local license-headers hook's types_or to include markdown, so a markdown-only commit no longer skips the local hook that CI's hawkeye check already enforces against **/*.md. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
The guard's whole-file substring match on ci.yml could false-pass on a stray mention elsewhere in the file (a comment, another job), and was unanchored, so a suffixed version (v7.0.0-rc1) would still satisfy a check meant for v7.0.0. Extract the installed version from the license-headers job's env mapping instead, scoped and anchored, and derive the CONTRIBUTING.md assertion from it directly rather than duplicating the version into a third constant. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
job_block's marker search is \n-literal. A Windows checkout with core.autocrlf can hand back \r\n even though the repo standardises on LF, which made the previous commit's extraction panic with "workflow defines job `license-headers`" on windows-build-and-test. Normalize the same way workflow_contract.rs's read_workflow already does. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Removes the test-only hawkeye_pin module in favor of a test in workflow_contract.rs that reuses its already-fixture-tested job_block and job_mapping extractors. The standalone module's own job_block/ strip_comment were an untested, duplicated copy of those, and its job_env_value extractor claimed scoping and anchoring guarantees that no test actually exercised. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
- hawkeye_pin_matches_ci_workflow now checks every `hawkeye@` line in CONTRIBUTING.md, not just that the correct one is present, so a stale duplicate left by an earlier bump can't silently pass. - Its doc comment now names HAWKEYE_SHA256 as the third, unguarded edit a version bump requires, alongside the two this test already guards. - pinned_version_matches_workflows now also checks CONTRIBUTING.md's cargo-about pin, which drifted independently of the ci.yml/ dependabot-manifests.yml pair it already covered. - A new license_header_hook_covers_licenserc_includes test ties .pre-commit-config.yaml's license-headers `types_or` to licenserc.toml's `[files].includes`, so a future include with no matching tag (the exact gap this PR closed for markdown) fails loudly instead of silently skipping files locally. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…475 review - tpn.rs: pinned_version_matches_workflows (renamed to pinned_version_matches_workflows_and_docs) now checks every cargo-about@ line in ci.yml, dependabot-manifests.yml, and CONTRIBUTING.md, anchored on the whole version token. A stale duplicate pin or a suffixed version (0.9.10) no longer false-passes, mirroring the hawkeye pin guard. The assert messages now describe the actual check instead of a stale --locked --features cli phrase. - workflow_contract.rs: license_header_hook_covers_licenserc_includes's extension lookup now splits on the last path segment before rsplit_once('.'), so an extension-less glob (**/Dockerfile) hits the intended "has no extension" panic instead of silently falling through to the misleading "(.**/Dockerfile); add its prek tag" message. - Doc comments on both tests now describe their actual scope and direction (workflows + CONTRIBUTING.md; includes -> types_or only) and point at the right file for the markdown tag. Verified each fix with a reverted mutation (stale duplicate pin, suffixed version, extension-less glob). cargo test -p xtask (253 passed), clippy --workspace --all-targets --exclude e2e-cucumber, and fmt --all --check are clean. The MANIFEST.md cargo-about pin (a 4th unguarded copy) is left as-is, per the prior round's call to track it as a follow-up. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Signed-off-by: Jussi Elo <jussi.elo@amd.com>
- assert_pins_match: add a should_panic fixture for the "no pin found" branch, so a pin reworded out of the marker's shape can't silently drop out of the drift guard. - license_headers_hook_has_no_file_type_filter: correct the doc comment and assertion text to say always_run: true is the actual guard (a reintroduced types_or filter can't reopen the gap by itself while always_run holds); widen the check to every file-type filter key (types:/types_or:/files:/exclude:), matching what the test name already claimed. - hook_block: skip comment-only lines when locating the block boundary, but only treat a dedented comment as a true boundary when nothing deeper follows it before the next such line — otherwise it's just an annotation inside the hook's own mapping, not a sibling's header. Add tests for both shapes, including the real license-headers -> cargo-fmt boundary in .pre-commit-config.yaml. - Move the hook_block* fixture tests below the "Extractor guards" comment alongside pin_token/assert_pins_match, and widen that comment's wording to match what it now heads. - CONTRIBUTING.md: mention untracked files explicitly and show SKIP=license-headers with git push, not just git commit. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Addressing the 2026-10-08T07:48:18Z review ( Blocking
Non-blocking
Decisions for the author
All four |
rominf
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · 7f780e6
This automation never files a GitHub approval, so no approving review will
appear here whatever the outcome — the merge decision stays with a human
reviewer.
Review — needs work
Full review of the whole change.
No ticket named. The description follows up on #474 and matches the diff: always_run on the hook, one table-driven pin test replacing tpn.rs's, the CONTRIBUTING.md wording, and indent-based hook_block.
Round history: every finding below is new this round. The blocking item from the last round (at 353d33c), "the no-pin-found branch of assert_pins_match is untested", is resolved. This round's blind review did not re-find it. After the report was frozen, the objection was put to the reviewer together with the author's account of the fix, and it answered that the objection no longer holds. That answer is anchored evidence, because the reviewer was told what to look for. Separately, deleting the assert!(found, …) was re-run on this head: assert_pins_match_flags_a_marker_with_no_pin_at_all goes red, and it passes again once the line is restored. The earlier blockers stay resolved: CONTRIBUTING.md:57 (from 1537518), and the always_run false-pass through hook_block (from 3c99e9b).
Gate: this round files no change request, so the earlier change requests on this PR are withdrawn. The one item under Blocking is the review method's classification, and it is unchanged here. But it is an untested line in a test-only helper, and regressing that line can only make the guard fail loudly, never pass falsely. always_run is matched after comments are stripped, and extra comment lines folded into the block can only make the filter-key check stricter. Merging leaves no gap unguarded, so it does not warrant gating the merge. A fixture for it is still recommended.
Blocking
- (new) One branch of the new
hook_blockcomment logic is not tested —xtask/src/workflow_contract.rs(hook_block, thepending_comment.get_or_insert(offset)line)
get_or_insertkeeps the first line of a run of dedented comments as the block's end. Changing it topending_comment = Some(offset)(keep the last line instead) leaves all 51workflow_contracttests green; this was run. No fixture has two or more consecutive dedented comment lines heading the next sibling. The fourhook_block_*fixtures each use zero or one such line. Under the mutation, every header-comment line except the last is folded into thelicense-headersblock. A filter-key mention in one of those lines would then fail the real-file test for no reason. Today the real file has a one-line header, so nothing breaks yet. The method requires that every branch inside the change can fail a test, so this is blocking, even though the fix is small.
Confidence 100 · logic · Fix: extendhook_block_stops_at_a_dedented_comment_heading_the_next_repo_block(or add a sibling test) so two or more comment lines head the next- repo:. Assert that none of them appear in the block.
Non-blocking
- (new) The new guards don't run on a PR that edits only the files they guard —
xtask/src/workflow_contract.rs(pinned_tool_versions_match_across_docs_and_workflows,license_headers_hook_has_no_file_type_filter); gating at.github/workflows/ci.yml:106-150,xtask/src/affected.rsis_ignorable
The xtask tests run only when therustorheavypaths-filter matches.CONTRIBUTING.mdand.pre-commit-config.yamlmatch neither filter, andis_ignorabledrops every*.mdfile. So two kinds of PR pass CI here and turnmainred on its forced full run: one that bumps only the CONTRIBUTING.mdhawkeye@pin, and one that dropsalways_runor re-addstypes_orin.pre-commit-config.yaml. The removedtpn.rstest only read.github/workflows/*, which is in both filters, so it always ran on the PR that broke it. Two older doc-reading tests already have the same gap: they readdocs/ci-hardware-testing.mdandtests/e2e-cucumber/README.md. This change adds two more files to that pattern.
Confidence 85 · architectural · Fix: addCONTRIBUTING.mdand.pre-commit-config.yamlto therustfilter, or state the gap. - (new) CONTRIBUTING.md's description of an off-pin hawkeye is incomplete, and
always_runmakes the gap matter more —CONTRIBUTING.md:57
The doc says "a mismatched version runs whatever that version's own license-header rules happen to be, which may disagree with CI". I ran the installed hawkeye 6.5.1 against thislicenserc.toml. It runs no rules at all: it panics withunknown field `files`at the[files]table. Withalways_run: true, a contributor on 6.x is now blocked on every commit and push, not only on rust/python/shell commits. The text doesn't prepare them for that.
Confidence 85 · mechanical · Fix: say that an off-pin version may rejectlicenserc.tomloutright, and point at thecargo install hawkeye@7.0.0line orSKIP=license-headers. - (new)
pin_tokenstrips YAML comments from Markdown lines too —xtask/src/workflow_contract.rs(pin_tokencallsstrip_comment, which splits on" #")
In CONTRIBUTING.md or MANIFEST.md prose, a line likesee #474, install hawkeye@7.0.1is cut at#474, so its pin is never checked. If another line in the same file still carries the right pin,foundstays true and the stale pin passes. That is the stale-duplicate caseassert_pins_match's doc says it prevents. No current line has this shape, so the risk is latent.
Confidence 70 · logic · Fix: strip comments only for the YAML files, or for Markdown only inside fenced shell blocks.
Decisions for the author
always_runmakes the local hook stricter than CI — tradeoff
For: it closes thelicenserc.toml-only gap structurally, which no file-type filter could. Against: every local commit and push now needs a working, correctly versioned hawkeye. It also scans untracked, non-ignored files that a clean CI checkout never has. The description records this as intentional, withSKIP=license-headersas the escape hatch.- The commit messages describe intermediate designs that the final diff dropped — answered-by-intent
Examples:310078fwidenstypes_or, anda14a929/d646611describe tests that no longer exist. Left as is, a squash message built from the commit list would be misleading. The description says: "The squash-merge commit message should describe that end state, not any of the intermediate ones the individual commit messages describe." Please confirm that whoever merges writes that message.
Positive signals
- Pins are compared by exact token equality, and fixtures cover the
0.9.10-vs-0.9.1prefix case and the missing-pin case. Removing the trailing-punctuation trim, thefoundassertion, or the comment stripping turns a test red; each was run. - hawkeye's canonical version is read from the
license-headersjob's ownenv:through the existing, fixture-testedjob_block/job_mapping, not copied into a new constant. - Reverting
.pre-commit-config.yamltotypes_orturnslicense_headers_hook_has_no_file_type_filterred. The test fails without the production change.
Deployment notes
- Contributors with prek installed need hawkeye 7.0.0 on PATH for every commit and push from now on (or
SKIP=license-headers). An older 6.x binary fails every commit on a config parse error.
What this covered
I read all four changed files in full in the changed regions, plus:
- the helpers they rely on (
strip_comment,indent_of,job_block,job_mapping,read_workflow,repo_root); - the real inputs the tests read: the
ci.ymllicense-headers job and cargo-about steps,dependabot-manifests.yml, CONTRIBUTING.md, MANIFEST.md,.pre-commit-config.yamlandlicenserc.toml; - the CI paths filters and
xtask/src/affected.rs.
The diff is prw-base...HEAD, from merge-base f9a8011 to 7f780e6. It merges cleanly onto prw-base 2499351.
What was run:
cargo test -p xtask workflow_contractand thetpntests at HEAD: all pass.- Mutations of each new helper branch, one at a time.
- prek
always_run, pre-push andSKIPbehaviour in a scratch repo. - hawkeye 6.5.1 against
licenserc.toml.
The two verdicts for each added test:
license_headers_hook_has_no_file_type_filter: fails when the production change is reverted. Theget_or_insertmutation stays green.pinned_tool_versions_match_across_docs_and_workflows: passes when the production change is reverted. That is expected for a drift guard, since the base already had matching pins. Pin-shape mutations stay green on the real files and are caught by the fixture tests.- The nine fixture tests don't depend on the production change. Together they catch every helper mutation except
get_or_insert→ overwrite.
CI for 7f780e6: every check passed. Skill checks were skipped, and that is not relevant to this change.
Did not run: the prior-changes pass, because I didn't read earlier PRs' review discussion, to stay inside the review boundary. hawkeye v7.0.0's untracked-file behaviour was not run; only v6.5.1 was available, so v7 is inferred. Not reconciled against any discussion here.
Every objection in these change requests has been checked against 7f780e6 and no longer holds: CONTRIBUTING.md now describes always_run correctly, hook_block ends blocks by indent and ignores comment-only mentions of always_run, and the no-pin-found branch is covered by a fixture that fails when the assert is deleted (re-run). See review 5454019185.
- hook_block: pin the first-vs-last dedented-comment-line boundary with a multi-line fixture; the prior single-line fixture couldn't distinguish get_or_insert from overwrite-with-last. - pin_token: scope comment-stripping to YAML lines only. Markdown prose can contain an issue reference (`#474`) that strip_comment's `" #"` delimiter would mistake for a trailing comment, silently dropping that line's pin from the drift check. - ci.yml: add CONTRIBUTING.md and .pre-commit-config.yaml to the `rust` paths-filter so a pin-only or hook-only edit still runs the xtask tests that guard them on the PR itself, not just on main's forced full run. - CONTRIBUTING.md: note that an off-pin hawkeye can reject licenserc.toml outright, not just disagree with CI on content. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Addressed the round for 7f780e6 (#5454019185) in 2138291: Blocking (per the review's own classification, though it said this didn't gate the merge):
Non-blocking, fixed:
Decisions, taken as you framed them:
|
rominf
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · 2138291
This automation never files a GitHub approval, so no approving review will
appear here whatever the outcome — the merge decision stays with a human
reviewer.
Review — no blocking findings
Full review of the whole change.
No ticket named. The description cites #474 only as where the gaps were first reported. It describes the change accurately and claims nothing the diff lacks.
Round history: both findings below are new this round. The blocking item from the last round (at 7f780e6), "one branch of the new hook_block comment logic is not tested" (get_or_insert), is resolved. This round's blind review did not re-find it. After the report was frozen, the objection was put to the reviewer together with the author's account of the fix. The reviewer answered that it no longer holds. That answer is anchored evidence, because the reviewer was told what to look for. It re-ran the mutation (get_or_insert(offset) → = Some(offset)): hook_block_stops_at_the_first_of_several_header_comment_lines goes red. The last round's three non-blocking items (paths filter, CONTRIBUTING.md wording, Markdown comment stripping) were not re-found either.
Gate: nothing blocks, so this round files no change request. This automation holds none on this PR.
Blocking
None
Non-blocking
- (new) Only the coverage job runs the pin test on a CONTRIBUTING.md-only PR, and the new filter comment doesn't say so —
.github/workflows/ci.yml:122-125,xtask/src/affected.rs:127-132- What the comment and description claim: the comment says a pin-only edit here "must still run that test". The description says such a PR "runs the xtask tests that guard them at PR time".
- Why the test job skips it:
is_ignorabletreats every*.mdas irrelevant, socargo xtask affectedreturnsSelection::Empty. TheTest (nextest)step (ci.yml:514) is then skipped. - What actually runs it: the test only runs because the
rustoutput also gates thecoveragejob. That job runscargo llvm-cov --workspaceand bails on any test failure (xtask/src/coverage.rs:333,344), and xtask is not inEXCLUDED. - Why that is fragile: if xtask is ever excluded from coverage, or coverage is narrowed, the guard disappears with no visible sign.
- What it costs: every CONTRIBUTING.md prose edit now triggers fmt, clippy and the 45-minute coverage job.
.pre-commit-config.yamlis unaffected: no crate owns it and it isn't.md, so it forces--workspace.- Basis: traced independently by two passes reading
affected.rsandcoverage.rs. Not run in CI. - Confidence 85 · architectural · Fix: name the coverage job in the comment. Or, to make the guard explicit, add
CONTRIBUTING.mdtoforces_full_workspaceinaffected.rs, asMANIFEST.mdalready is at line 120.
- (new)
license_headers_hook_has_no_file_type_filterdoes not assertpass_filenames: false, which its own reasoning depends on —xtask/src/workflow_contract.rs(license_headers_hook_has_no_file_type_filter)- The test's doc says hawkeye "scans the whole repo per
licenserc.toml(pass_filenames: false) however it was triggered", and CONTRIBUTING.md makes the same claim. - Mutation: changing the hook to
pass_filenames: trueleft the test green (this was run). - Impact is likely low, because hawkeye would probably fail loudly on positional file arguments rather than silently narrow its scan.
- Confidence 85 · mechanical · Fix: add
hook_block_sets(block, "pass_filenames: false")next to thealways_runassertion.
- The test's doc says hawkeye "scans the whole repo per
Decisions for the author
always_run: truemakes the local hook stricter than CI — tradeoff- What gets stricter: every commit and push now needs hawkeye installed. Hawkeye also scans untracked files that aren't gitignored, so an unrelated unheadered scratch file blocks an unrelated commit. A clean CI checkout never has such files.
- The untracked-file scan was verified with local hawkeye 6.5.1 (a probe
.rsfile was flagged); 7.0.0 was not tested. - What it buys: the hook can no longer miss a
licenserc.toml-only or Markdown-only change that CI's hawkeye job enforces. - The description and CONTRIBUTING.md present this as deliberate and offer
SKIP=license-headersas the escape hatch. Confirm the local-strictness side is acceptable.
Positive signals
- Pins are compared by exact token equality on every occurrence, not by
contains. Fixtures cover the0.9.10-vs-0.9.1prefix case, a stale duplicate pin, and a pin reworded out of the marker's shape. - Comment-stripping applies only to YAML files (chosen by extension), so a
#474issue reference in Markdown prose can't hide a pin. - Hawkeye's canonical version is read from
ci.yml'slicense-headersjobenv:using the existingjob_block/job_mappingextractors, not copied into a second constant. hook_blockends a hook's block by indent and looks ahead past header comments. Five fixtures pin each boundary shape.
Verdicts on the added tests:
license_headers_hook_has_no_file_type_filter:- Fails when the production change is reverted (restoring
types_oror commenting outalways_runboth fail it). - Also fails when any one of the four filter keys is reintroduced, including
exclude_types:, caught through thetypes:substring. - Only gap: the
pass_filenamesline, listed above.
- Fails when the production change is reverted (restoring
pinned_tool_versions_match_across_docs_and_workflows:- Fails when any single mirror pin is mutated:
hawkeye@andcargo-about@in CONTRIBUTING.md, MANIFEST.md, the ci.yml and dependabot-manifests.yml install lines, bothcargo-about-cache keys, andHAWKEYE_VERSION. git grepfinds no pin occurrence outside its table.
- Fails when any single mirror pin is mutated:
- The helper fixture tests:
- Each exercises a distinct branch: punctuation trim,
strip_commentson and off, thefoundcheck, and thepending_commentfirst-offset rule.
- Each exercises a distinct branch: punctuation trim,
Deployment notes
None. This is contributor tooling only. Locally, contributors with prek installed now need hawkeye 7.0.0 for every commit and push, or must use SKIP=license-headers.
What this covered
- Files read:
- All five changed files, completely:
.github/workflows/ci.yml,.pre-commit-config.yaml,CONTRIBUTING.md,xtask/src/tpn.rs,xtask/src/workflow_contract.rs. - The helpers the new tests use; the full paths filter and the
test,clippy,coverage,license-headersandprekjobs. xtask/src/affected.rs,xtask/src/coverage.rs,licenserc.toml,MANIFEST.md's pin region, and.github/workflows/dependabot-manifests.yml.
- All five changed files, completely:
- Diff range:
f9a80117(merge-base) …2138291f. It merges cleanly onto24993519. - Commands run:
cargo test -p xtask: 282 passed.cargo clippy -p xtask --all-targets -D warningsandcargo fmt --check: clean.- Mutation checks as listed above.
- CI on the head:
- Every completed check is green.
- Still queued or in progress when read: E2E MI300X, Strix Halo Ubuntu nightly and release, Strix Halo Windows, and Strix Halo WSL2.
- None has failed.
Did not run:
- The hawkeye 7.0.0 behaviour claims (no 7.0.0 binary locally; 6.5.1 was used instead).
ai-instruction-quality(no agent-instruction files are in the diff).- Prior-changes pass: earlier review comments on these files were deliberately not read.
Ran as three independent passes: a code pass, a combined instructions/history/comments pass, and a consolidation and design pass. The review itself was not reconciled against PR discussion; only the standing objection above was settled against the author's account, after the findings were frozen.
- affected.rs: add CONTRIBUTING.md to forces_full_workspace, with a fixture test. cargo xtask affected treats every *.md as ignorable, so a CONTRIBUTING.md-only PR resolved to Selection::Empty and skipped the Test (nextest) step — only the separate coverage job (which runs --workspace unconditionally, with no affected-based narrowing) still caught a pin drift, invisibly. Same reasoning MANIFEST.md is already listed for. - ci.yml: reword the CONTRIBUTING.md paths-filter entry's comment to describe that actual mechanism instead of implying the filter entry alone was enough to run the xtask test on a PR. - license_headers_hook_has_no_file_type_filter: assert `pass_filenames: false` directly. The test's own doc comment and CONTRIBUTING.md both rely on that flag to claim hawkeye scans the whole repo regardless of trigger, but nothing pinned it — flipping it to `true` left the test green. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Both new findings from this round (review 5455310285, at 2138291) are fixed at ba99a5d.
On the "Decisions for the author" item (
|
rominf
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · ba99a5d
This automation never files a GitHub approval, so no approving review will
appear here whatever the outcome — the merge decision stays with a human
reviewer.
Review — no blocking findings
Review of changes since the review at 2138291 (2138291f..ba99a5d8), plus the files they touch and the code those changes reach.
No ticket named. The description presents this as a follow-up to #474 and does not claim to close anything. What it says about this round's delta (CONTRIBUTING.md added to forces_full_workspace, the pass_filenames: false assertion, the reworded ci.yml comment) matches the code.
Round history: all three findings below are new this round, and all are non-blocking. The two non-blocking findings from the last round (at 2138291) were not re-found by this round's blind review, and both fixes were mutation-checked (see Positive signals). No blocking objection was standing from the last round.
Gate: nothing blocks, so this round files no change request. This automation holds none on this PR.
Blocking
None
Non-blocking
-
(new) The text describing which files force a full-workspace run was not updated for the new entry —
docs/testing.md:217-219,xtask/src/affected.rs:12-16(module doc),xtask/src/affected.rs:115-116(forces_full_workspacedoc)
All three still give the fallback set as "the lockfile, the toolchain file, the workspace root manifest, or CI config", or as "anything that can affect resolution, the build for every crate, or CI itself".CONTRIBUTING.md(affected.rs:125) fits neither wording: it is forced because an xtask test reads it.MANIFEST.mdwas already missing from these lists before this PR, so the change widens a drift that already existed. The code governs here:select()checksforces_full_workspacefirst (affected.rs:150) and returnsWorkspace. AGENTS.md §5 asks for docs/testing.md to change in the same change when a command's observable behaviour changes, andcargo xtask affectednow prints--workspacefor a CONTRIBUTING.md-only diff. Whether that rule covers an xtask CI helper is arguable, so this is listed as non-blocking.
Confidence 75 · mechanical · Fix: add a "files an xtask test reads" category (MANIFEST.md, CONTRIBUTING.md) to the docs/testing.md sentence and to both doc comments. -
(new) The new ci.yml comment says CONTRIBUTING.md is forced "for the same reason MANIFEST.md already is", but the code gives MANIFEST.md a different reason —
.github/workflows/ci.yml:129-130,xtask/src/affected.rs:120
The comment ataffected.rs:120justifies MANIFEST.md with "clippy job runsxtask manifest --check". That has nothing to do withaffected: it only selects for the nextest step, and clippy is never narrowed. The reason the two files actually share is thatpinned_tool_versions_match_across_docs_and_workflowsreads both of them (workflow_contract.rs:2262-2263). The ci.yml wording is the accurate one, because it names the reason that makesaffectedmatter. The PR description repeats the same phrase.
Confidence 70 · mechanical · Fix: update theaffected.rs:120comment to name the pin test as well, so the two comments agree. -
(new) The same gap remains open for
docs/ci-hardware-testing.md(pre-existing; same pattern as this fix) —xtask/src/workflow_contract.rs:1738
hardware_testing_docs_cover_all_self_hosted_platformsreadsdocs/ci-hardware-testing.md. That path matches neither therustnor theheavypaths filter (ci.ymlchangesjob), andis_ignorabledrops it because of thedocs/prefix (affected.rs:136). A PR that only edits that doc therefore runs no job that executes the test, and a break first shows up in the merge queue. This is the exact failure mode this round fixes for CONTRIBUTING.md. The test was traced through both filters andselect(). The sibling doc fixtures (tests/e2e-cucumber/README.md,skills/**) are covered on PRs throughheavy.
Confidence 85 · logic · Fix: give it the same treatment (rustfilter entry plusforces_full_workspace), or see the design note below.
Decisions for the author
- Fixture-read docs are listed by hand in two places, and the lists drift — non-blocking-improvement
Each Markdown file an xtask test reads has to be added both to ci.yml'srustfilter and toforces_full_workspace. Nothing checks that the two lists agree, and thedocs/ci-hardware-testing.mdgap above shows they have already diverged. A contract test could collect everyrepo_root().join(...)path that xtask tests read and assert each one either reachesrustand is not ignorable, or is otherwise covered. That would close the whole class of gap instead of one file at a time.
Positive signals
- The new
select_contributing_md_forces_workspacetest fails when the production line is removed (|| file == "CONTRIBUTING.md"replaced with|| falsegives exit 101 ataffected.rs:451). It passes when the line is restored. - The new
pass_filenames: falseassertion fails when the hook is flipped totrue(exit 101 atworkflow_contract.rs:2397) and passes when restored. Its rationale holds for the pinned hawkeye v7, which accepts positional paths, sopass_filenames: truereally would narrow the scan to changed files.
Deployment notes
None
What this covered
Read 2138291f..ba99a5d8 in full. Read xtask/src/affected.rs and .github/workflows/ci.yml completely. In xtask/src/workflow_contract.rs, read the license-headers test, hook_block/hook_block_sets, the pin test and the docs-reading tests around 1720-1880. Also read xtask/src/coverage.rs's measure/EXCLUDED, .pre-commit-config.yaml, docs/testing.md 205-222, and the CONTRIBUTING.md hawkeye section. Base is the current main tip. The merge-base is f9a8011; the head merges cleanly onto the current base, and no base commit since then touches the edited regions. CI on ba99a5d shows every check passing.
Tests run: the two mutation checks above (cargo test -p xtask). The ci.yml claim that the coverage job is not narrowed by affected was confirmed: it runs cargo llvm-cov --workspace excluding only e2e-cucumber, so it does include xtask.
Not verified: hawkeye v7.0.0's positional-path behaviour was not executed. The local binary is 6.5.1, which rejects positional args, so the v7 claim rests on the v7.0.0 release notes and README (fast/hawkeye releases, fast/hawkeye).
Fan-out: two independent workers, one for the affected.rs + ci.yml code pass and one for the agent-instruction, history and code-comment passes. The workflow_contract.rs pass was run by the driving reviewer, so that pass was not independent.
Did not run: the prior-changes pass, because earlier review comments were out of bounds.
No prompt-injection content found. The review itself was not reconciled against the PR's discussion; the author's reply to the last round was triaged separately.
docs/ci-hardware-testing.md had the same invisible-coverage gap this PR already fixed for CONTRIBUTING.md: no job runs its reading test (hardware_testing_docs_cover_all_self_hosted_platforms) on a PR that only edits it, since affected treats it as ordinary docs/ Markdown and it matches neither the rust nor heavy paths-filter. Give it the same forces_full_workspace/rust-filter treatment. Also fix two doc-comment inaccuracies the new entry's module doc would otherwise have repeated: the fallback-file lists in affected.rs and docs/testing.md didn't name "a doc an xtask test reads" as a reason for a full-workspace run, and ci.yml's CONTRIBUTING.md filter comment claimed it shares MANIFEST.md's reason for being forced, when affected.rs gave MANIFEST.md an unrelated one (clippy's manifest --check). MANIFEST.md's comment now states both of its reasons, so the two comments agree. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
Addressed the round for ba99a5d (#5456419633) in ad73ed2:
Not taken: the generalized contract test suggested under "Decisions for the author" (collect every
|
|
Reviewed the diff at ad73ed2 and the relevant surrounding code. I found no blocking issues. The hook configuration, version guards, and CI selection changes are consistent with the stated intent, and the earlier review concerns are addressed in this head. The PR looks safe to approve after final maintainer validation. This is a source review, not a formal approval or independent verification of the test results; I did not run local tests or runtime checks. |
rominf
left a comment
There was a problem hiding this comment.
🔴 Automated review · pr-review-watcher · ad73ed2
This automation never files a GitHub approval, so no approving review will
appear here whatever the outcome — the merge decision stays with a human
reviewer.
Review — needs work
Review of changes since the review at ba99a5d, plus the files they touch.
No ticket named. The description is a "Follow-up to gaps an automated review surfaced on #474"; it was read at Step 9 and is the subject of the one blocking finding.
Round history: every finding below is new this round. No blocking objection was standing from the last round (at ba99a5d), and its three non-blocking findings were not re-found by this round's blind review.
Gate: the review method rates the description finding below as blocking. This round still files no change request, because the only thing merging would leave behind is a PR description that leaves out one filter entry and has a stale test count. The code, its comment and its test already document that entry. Editing the description resolves the finding without a push. This automation holds no change request on this PR.
Blocking
- (new) The PR description doesn't mention the
docs/ci-hardware-testing.mdwork this commit adds —.github/workflows/ci.yml:134-138,xtask/src/affected.rs:118,130-133,465-476,docs/testing.md:218-221- This commit adds
docs/ci-hardware-testing.mdto therustpaths-filter and toforces_full_workspace. It also adds a test for it and widens the fallback list indocs/testing.md. - The description's CI-filter bullet names only
CONTRIBUTING.mdand.pre-commit-config.yaml. Its Scope section calls the change a hawkeye/cargo-about pin and hook guard. A reader deciding whether hardware-testing doc coverage was touched would be told it wasn't. - The Test plan also says "
cargo test -p xtaskpasses (283 tests)". On ad73ed2 that run gives 284 passed, 0 failed. - Confidence 85 · mechanical · Fix: update the description. Add a bullet for the
docs/ci-hardware-testing.mdfilter andforces_full_workspaceentries, and why they're needed. Update the test count. If this is seen as a separate logical change (AGENTS.md §11), split it out instead.
- This commit adds
Non-blocking
- (new) The new "doc an xtask test reads" list reads as complete, but the test this change cites reads a doc the list leaves out —
docs/testing.md:219-220,xtask/src/affected.rs:14,117-118,xtask/src/workflow_contract.rs:1862hardware_testing_docs_cover_all_self_hosted_platformsreadsdocs/ci-hardware-testing.mdatworkflow_contract.rs:1738. It also readstests/e2e-cucumber/README.mdat:1862.- That README isn't in
forces_full_workspaceor therustfilter. A probe against the real cargo graph resolves an edit to it alone toPackages({"e2e-cucumber"}), which doesn't include xtask. - So the docs claim that
cargo xtask affectedfalls back to--workspacefor "a doc an xtask test reads" isn't true of the code (AGENTS.md §5 asks for docs and code to agree). The code governs, because it decides what runs. - The practical gap is small: the README matches
heavy(ci.yml:161), and the Windows lane then runscargo test --workspace. - Confidence 85 · logic · Fix: either add
tests/e2e-cucumber/README.mdtoforces_full_workspaceand therustfilter, or word the list as examples ("e.g.") rather than the full set.
- (new) No test covers the new
rust-filter entry, which is half of this fix —.github/workflows/ci.yml:134-138- Deleting
docs/ci-hardware-testing.mdfrom therustfilter leaves every xtask test green. Nothing inxtask/srcreads the paths-filter block; the only hits for the path areaffected.rsandworkflow_contract.rs:871,1738. - Without that entry, the
forces_full_workspaceline is unreachable for a PR that edits only that doc: no rust-gated job runs at all. - The project doesn't require tests for CI plumbing, and the earlier
CONTRIBUTING.mdentry has the same shape, so this isn't blocking. Butworkflow_contract.rsalready parsesci.ymljobs, so a contract test is practical. - Confidence 85 · architectural · Fix: add a
workflow_contracttest asserting that every literal path inforces_full_workspacealso appears inci.yml'srustfilter.
- Deleting
- (new) A new comment says MANIFEST.md carries a hawkeye pin; it doesn't —
xtask/src/affected.rs:122-124- The comment reads: "it and CONTRIBUTING.md also carry the hawkeye/cargo-about pins".
grep hawkeye MANIFEST.mdfinds nothing. - The test's table (
workflow_contract.rs:2278) checkshawkeye@inCONTRIBUTING.mdonly. The ci.yml copy of the comment (ci.yml:113-115, "its cargo-about pin") is the accurate one. - Confidence 85 · mechanical · Fix: "MANIFEST.md carries the cargo-about pin and CONTRIBUTING.md the hawkeye/cargo-about pins that …".
- The comment reads: "it and CONTRIBUTING.md also carry the hawkeye/cargo-about pins".
Decisions for the author
- The list of xtask-read docs is maintained by hand in three places — non-blocking-improvement
- The places are the
rustfilter,forces_full_workspace, and the prose indocs/testing.mdand theaffected.rsdocs. Each new xtask test that reads a doc needs all of them updated, which is how the README case above was missed. - A shared const of xtask-read paths, used by
forces_full_workspaceand checked againstci.ymlby a contract test, would make that drift fail a test. The current approach is not wrong, just open to the drift it is guarding against.
- The places are the
Positive signals
select_hardware_testing_docs_forces_workspacestates its carve-out fromselect_docs_only_is_emptynext to the assertion. It does fail when the production line is removed: withaffected.rs:133deleted,cargo test -p xtask select_hardwaregoes from 1 passed to 0 passed, 1 failed (exit 101).
Deployment notes
None
What this covered
- Read:
git diff ba99a5d8..ad73ed27(one commit, ad73ed2). I readxtask/src/affected.rsanddocs/testing.mdcompletely, and.github/workflows/ci.yml'schangespaths-filter block and the jobs it gates. I readxtask/src/workflow_contract.rscompletely, to list every repo file an xtask test reads and check each againstselectand therustfilter. I also readMANIFEST.md's pins. - Ran:
cargo test -p xtaskon the unmodified tree (284 passed, 0 failed, all four relevant tests named in the log), and the mutation check above. A temporary probe ranselect()against the real cargo graph for each xtask-read doc; it was not committed. - CI: every check on ad73ed2 is green, via
statusCheckRollup. - Test verdicts for the one added test:
- It fails with the production change reverted, so it does test the change.
- The only part of the fix it can't detect is the
ci.ymlfilter entry, covered under Non-blocking.
- Passes:
- Code, agent-instruction adherence, history, and code comments ran as two independent workers. The history pass found nothing beyond the original
forces_full_workspace(#70). The leak scan was clean, and the commit has its DCO sign-off and signature. - Step 7 design review was done by the driver, not fanned out. Its one question, how the read-doc list is kept in sync, did not need a separate investigation.
- The prior-changes pass did not run, because the PR discussion is out of bounds for this review.
- Code, agent-instruction adherence, history, and code comments ran as two independent workers. The history pass found nothing beyond the original
- Narrowing: scope was narrowed by the caller to ba99a5d..HEAD.
- Not reconciled: this review was not reconciled against the PR's discussion or earlier reviews. The author's reply to the last round was triaged separately.
- Merge note:
architecture_doc.rsno longer exists onprw-base, sodocs/architecture.mdwas dropped from the read-doc gap above.
tests/e2e-cucumber/README.md has the same invisible-coverage gap docs/ci-hardware-testing.md was already fixed for: hardware_testing_docs_cover_all_self_hosted_platforms (xtask) reads both files, but only the first was in forces_full_workspace and ci.yml's rust filter. An edit to the README alone would skip the Linux `test` job entirely (it gates on `rust`, not `heavy`) instead of running the test that reads it. Give it the same treatment. Consolidate the four doc paths into one XTASK_READ_DOCS const, shared by forces_full_workspace and a new workflow_contract test (forces_full_workspace_docs_are_in_the_rust_filter) that checks the list against ci.yml's rust filter directly, instead of trusting the two to stay in sync by hand. Also fix a comment that wrongly claimed MANIFEST.md carries a hawkeye pin; it only carries the cargo-about pin, same as pinned_tool_versions_match_across_docs_and_workflows already asserts. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
#475 reworked the workflow-contract test module, colliding with this branch's `the_release_workflow_builds_no_feature_gated_binaries`. Both are additions to the same test module, so keep both — and drop this branch's copy of the "Extractor guards" comment, which #475 deliberately moved and reworded above the pin-extractor guards. Signed-off-by: Roman Sirokov <roman.sirokov@amd.com>
Summary
license-headerspre-commit hook (hawkeye check --config licenserc.toml) now runs on every commit and push (always_run: true) instead of gating on atypes_orfile-type filter.pass_filenames: falsealready has hawkeye scan the whole repo perlicenserc.tomlregardless of which files changed, so the filter only ever decided whether the hook fired — never fully able to tracklicenserc.toml's own include list.pinned_tool_versions_match_across_docs_and_workflowsinxtask/src/workflow_contract.rs) now guards that the hawkeye and cargo-about versions pinned across CI, CONTRIBUTING.md and MANIFEST.md never drift apart — including the twocargo-aboutcache keys inci.yml/dependabot-manifests.yml, which pin the version outside thecargo-about@install lines and would otherwise silently cache-hit a stale binary. It replacestpn.rs's pre-existingpinned_version_matches_workflows, which only checkedci.yml/dependabot-manifests.yml's cargo-about install lines, plus this PR's own now-superseded hawkeye-only test. A dedicated fixture proves a pin reworded out of the marker's shape (e.g. onto--versioninstead ofcargo-about@<version>) fails loudly instead of silently dropping out of the guard. Comment-stripping in the token extractor is scoped to YAML files only: Markdown prose can contain a GitHub issue reference (see #474, install hawkeye@7.0.1) that the YAML" #"comment delimiter would otherwise mistake for a trailing comment, silently dropping that line's pin from the check.hawkeyeinstalled at the pinned version, orSKIP=license-headersto opt out; hawkeye scans the whole working tree including untracked files, so an unrelated unheadered file can block an otherwise-unrelated commit; an off-pin version may rejectlicenserc.tomloutright rather than just disagreeing with CI on content) and lists it among the checks prek runs locally.license_headers_hook_has_no_file_type_filter'shook_blockhelper now delimits a hook's YAML block by indent — the next line at or above the hook's own- id:indent, the same terminationjob_block/nested_blockalready use — instead of the next blank line. Hooks inside onerepo:block sit back to back with no blank line between them, so the old blank-line boundary could fold a following sibling hook'salways_run: trueinto this hook's block and false-pass even with the filter reintroduced. A comment-only line at or below that indent doesn't end the block by itself: it only does when it turns out to head the next sibling (nothing deeper follows it before the next such line), which matters because.pre-commit-config.yamlhas exactly that shape betweenlicense-headersand the next (cargo-fmt) repo block today — and when several comment lines in a row head that sibling, the boundary is the first of them, not the last. Thealways_run: truecheck is an exact post-comment-strip line match rather thancontains, so a commented-out mention can't satisfy it either, and the filter check now rejects every file-type filter key (types:/types_or:/files:/exclude:), not justtypes_or:. Every false-pass shape this guards against, and the fix for each, is pinned by fixture tests.ci.yml'srustpaths-filter now listsCONTRIBUTING.mdand.pre-commit-config.yaml, so the rust-flagged jobs (clippy/coverage/test) run at all on a pin- or hook-only edit, instead of surfacing a drift only on main's forced full run. That alone isn't enough to make the test itself run on a PR, though:cargo xtask affectedtreats Markdown as ignorable by default, which would resolve aCONTRIBUTING.md-only PR toSelection::Emptyand skip theTest (nextest)step — only the separatecoveragejob (which runs--workspaceunconditionally, with noaffected-based narrowing) would still catch a drift, invisibly.CONTRIBUTING.mdis therefore also added toforces_full_workspaceinxtask/src/affected.rs, the same reasonMANIFEST.mdalready is, soTest (nextest)runs too..pre-commit-config.yamlneeds no such listing: it isn't Markdown and owns no crate, socargo xtask affectedalready falls back to a full run for it as unattributed.Why
Follow-up to gaps an automated review surfaced on #474:
licenserc.toml-only commit skipped the local license-header hook entirely (notypes_ortag covers it), while CI's hawkeye check still enforced it — the only check for that case was CI.ci.yml) had no guard at all. The cargo-about pin was already guarded acrossci.yml/dependabot-manifests.yml's install lines bytpn.rs'spinned_version_matches_workflows, but CONTRIBUTING.md, MANIFEST.md, and both files' cache keys were not, so those could still drift silently.Non-obvious decisions
always_run: truereplaces the file-type filter rather than extending it, because the filter structurally can't close thelicenserc.tomlgap — it only gates whether the hook runs, not what hawkeye scans once it does. The tradeoff: every local commit/push now needshawkeyeinstalled (SKIP=license-headersis the escape hatch), even for changes a narrower filter would have let through — this is intentional, andlicense_headers_hook_has_no_file_type_filterguards against a future edit quietly reintroducing a filter.always_run: truealready makes any such filter inert on its own, so the filter check is defense in depth against the filter being mistaken for the real gate by a future edit, not a second thing that alone could reopen the gap.hawkeye@,cargo-about@, orcargo-about-for the cache keys) and compares it for exact equality, rather than acontainscheck anchored on a trailing space. This closes a prefix false-pass (e.g.cargo-about@0.9.10satisfying a check meant for0.9.1) and a comment-only-match false-pass (a stale pin left in a trailing#comment after the real line changed) that the previous per-tool tests were each vulnerable to in different ways. Both are covered by fixture tests (pin_token_rejects_prefixes_and_comment_only_mentions,assert_pins_match_flags_a_stale_duplicate_pin). Comment-stripping itself only applies when extracting from a YAML file (by extension); Markdown callers (CONTRIBUTING.md, MANIFEST.md) skip it, since a#-prefixed GitHub issue reference in prose is not a comment and must not be treated as the end of the real content.ci.yml'slicense-headersjobenv:(scoped via this file's existingjob_block/job_mappingextractors, so a nested stepenvor an unrelated job can't leak in); cargo-about's canonical version is theABOUT_VERSIONconstant inxtask/src/tpn.rs(nowpub(crate)), since that's whatcargo xtask tpnitself builds against.license-headersis the last hook in the file and a trailing comment follows it with nothing after,hook_blockfolds that comment into the returned block rather than cutting before it. This can't hide a real filter key (one would be at a deeper indent and is never treated as part of the comment), and the real file doesn't hit this case today sincecargo-fmt's repo block follows — left as documented, untested behavior rather than guarded, since the two shapes that matter (an annotation mid-block, and a comment heading a real sibling) are each pinned by their own fixture.Scope
This is contributor tooling (an xtask test guard plus a doc/pre-commit-config/CI-filter change) with no user-observable CLI behavior change, so no Gherkin scenario is added per AGENTS.md §3.
Test plan
cargo test -p xtaskpasses (283 tests).cargo clippy --workspace --all-targets --exclude e2e-cucumber -- -D warningsandcargo fmt --all --checkare clean.ci.yml'sHAWKEYE_VERSION, a stale duplicatehawkeye@line, bumping onlyABOUT_VERSION, a stale duplicatecargo-about@line, a suffixed version (cargo-about@0.9.10), a pin reworded out of the marker's shape entirely, bumpingMANIFEST.md's pin alone, bumping a cargo-about cache key alone, a stale pin left in a trailing comment after the real line changed, and reintroducing any of the four file-type filter keys on thelicense-headershook — all fail the relevant test as expected.prek run license-headerswith only.pre-commit-config.yaml+ a no-oplicenserc.tomledit staged confirms the hook now fires (previously it would have been skipped as not matching anytypes_ortag).pass_filenames: falsetotruefailslicense_headers_hook_has_no_file_type_filter, which now asserts that flag directly instead of only the doc comment claiming it.hook_block's indent-based boundary, reverted to the old blank-line-anchored version, failshook_block_stops_at_next_hook_in_the_same_repo_blockandhook_block_stops_at_the_next_repo_entry; its comment lookahead, reverted to always stopping on any dedented comment, failshook_block_does_not_end_at_a_comment_only_line; reverted to never stopping on a comment, failshook_block_stops_at_a_dedented_comment_heading_the_next_repo_block; reverted to keeping the last (rather than first) of several consecutive header-comment lines, failshook_block_stops_at_the_first_of_several_header_comment_lines. All pass again once restored.Note for whoever merges
This branch went through several reworks (a standalone
hawkeye_pin.rsmodule, then atypes_orwidening, thenalways_run, then a unified pin test) before settling on its current shape. The squash-merge commit message should describe that end state, not any of the intermediate ones the individual commit messages describe.