ci: clippy the platform-gated code no gate ever compiled - #469
Conversation
`ci.yml`'s `gates` job runs on ubuntu-latest, and clippy only sees the code the active cfg set compiles. That left 262 lines of shipped Rust behind `#[cfg(windows)]` / `#[cfg(target_os = "macos")]` — 182 of them in `commands/model_reader_host.rs`, the v0.131.0 managed Windows host — checked by nothing at all. `release.yml` and `bridge-windows-packaged` do build the crate on Windows, but with `cargo build`, and rustc accepts a `clippy::` tool lint and then ignores it. So all three of CLAUDE.md §Code style's mechanised rules reached none of that code: `cargo clippy -D warnings`, the crate-root `deny(clippy::unwrap_used, clippy::expect_used)`, and the manifest's `undocumented_unsafe_blocks` deny. Measured rather than assumed: an `unwrap()` planted in the `#[cfg(windows)]` `process_is_alive` in `src/runtime/pidfile.rs` draws zero errors from the existing step and is rejected by the new one. Adds a check-only `cargo clippy --target x86_64-pc-windows-gnu` step to the same job, and `cli/tests/windows_target_gate.rs` to keep it honest: it asserts the step still carries `--target`, `--all-targets`, `--locked` and `-D warnings`, that the triple checked is the triple the toolchain step installs, that the host step was not merely retargeted, and that no `target_env` cfg exists — the condition that makes the gnu triple a faithful proxy for the shipped msvc one. Both classifiers carry negative controls over synthetic input.
|
@codex review Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6d7aa1bb07
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex review of 6d7aa1b, both findings P2, both real. 1. The windows cross-check closed only the windows half. A windows target compiles no `#[cfg(target_os = "macos")]` arm, so `commands/app.rs`'s macOS arm and `model_reader_host.rs`'s `not(target_os = "linux")` arm were still checked by nothing. A darwin cross-check from the ubuntu runner is not available, measured the same way `-msvc` was: `cargo clippy --target aarch64-apple-darwin` dies in `zstd-sys`'s build script with `cc: error: unrecognized command-line option '-arch'` — the runner's cc is not an Apple cross-compiler. Unlike msvc, darwin has no proxy triple, because what is missing is a toolchain and not a `target_env`. So macOS coverage is a `macos-latest` job, check-only, which is what this adds. 2. `target_env_branches` required `cfg` and `target_env` on one line, so a rustfmt-wrapped `all(...)` predicate — the ordinary way one arrives — read clean. It now accumulates complete predicates across lines, with quote-aware comment stripping and a runaway cap, and the negative control drives it over a wrapped fixture, a wrapped commented-out one, and a line carrying both a string and a trailing comment. Two flaws found while proving the new gate is not vacuous, and fixed: a job body kept its comment block, and a step's `name:` reads `cargo clippy -D warnings (macos)` — so the flag assertions were twice satisfied by prose, and deleting `-D warnings` from the real step left this file green. Flags are now read from `run:` commands only, and the negative control plants exactly that deletion. Also splits the empty-set guard in two: windows-gated code justifies the windows step, macOS-gated code the macOS job, so neither platform's lines excuse the other's missing gate. Verified on the pinned 1.95.0 toolchain: fmt --check, clippy host, clippy --target x86_64-pc-windows-gnu, and cargo test --locked (53 binaries, all ok). Mutations confirmed each new assertion fails when its gate is removed.
Codex round 1 — both P2 findings fixed in
|
| check | result |
|---|---|
cargo fmt --all -- --check |
pass |
cargo clippy --all-targets --locked -- -D warnings |
pass |
cargo clippy --target x86_64-pc-windows-gnu --all-targets --locked -- -D warnings |
pass |
cargo test --locked |
pass (53 binaries) |
Plus sync_stats.py --check, no-hardcoded-string-offsets.py --self-test and the trailers gate over this branch. Each new assertion was mutation-tested: retargeting the macOS job to ubuntu-latest fails it, dropping -D warnings fails it, and the planted wrapped predicate fails the scanner.
The macOS job itself is the one thing not runnable here — no macOS host — so CI on this PR is its first real execution.
Generated by Claude Code
|
@codex review Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e460a664d7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex review of e460a66, P2, and real. `crate_sources` walked `src/` and `tests/` only, so `cli/build.rs` sat outside the scan that asserts nothing in the crate branches on `target_env` — the condition that makes the gnu triple a faithful proxy for the shipped msvc one. That is the worst file to miss, not an edge case. A build script is compiled for the HOST and never for `--target`, so a `#[cfg(target_env = "msvc")]` in it is invisible to both ubuntu clippy runs, host and windows cross-check alike, while a Windows release build — whose host IS msvc — compiles the unlinted arm. The invariant this file exists to enforce was breakable in the one file most likely to break it. The walk now covers crate-root Rust targets (non-recursively, so `target/` build output stays out) and `benches/`/`examples/` should either ever appear. Since the inventory is itself a scan over sources that are clean today, it gets a tripwire naming `build.rs`, so a walk that quietly stops reaching it fails instead of reporting clean. Verified on the pinned 1.95.0 toolchain: fmt --check, clippy host, clippy --target x86_64-pc-windows-gnu, cargo test --locked (53 binaries, all ok). Mutation-tested: a wrapped msvc predicate planted in build.rs fails the scan and is named at build.rs:16; it passed before this change.
Codex round 2 — the one new P2 fixed in
|
| check | result |
|---|---|
cargo fmt --all -- --check |
pass |
cargo clippy --all-targets --locked -- -D warnings |
pass |
cargo clippy --target x86_64-pc-windows-gnu --all-targets --locked -- -D warnings |
pass |
cargo test --locked |
pass (53 binaries, 0 failed) |
Generated by Claude Code
|
@codex review Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 364ea3b114
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let Ok(source) = std::fs::read_to_string(&path) else { | ||
| continue; | ||
| }; | ||
| for (line, text) in target_env_branches(&source) { |
There was a problem hiding this comment.
Cover Windows-gated build-script branches
Even though build.rs is now included in the inventory, this loop only reports predicates containing target_env. If the build script adds an ordinary #[cfg(windows)] or cfg!(windows) branch, the Windows release activates it because the build script runs on a Windows host, while both Ubuntu clippy invocations compile the build script for their Linux host—even when the package target is Windows GNU—and this test remains green. Scan build.rs for all Windows-host predicates (and target information read from Cargo environment variables), or lint the package on a Windows runner.
Useful? React with 👍 / 👎.
Round 3 — stopping here, not merging. One P2 open for a human.Codex reviewed The sweeper gets two rounds per run, and this is the third. The rule exists for exactly this shape: each fix has drawn a new, adjacent finding rather than converging. Round 1 asked for macOS coverage and a multiline The finding is sound but is a hardening ask, not a defect in this diff. Codex is right about the mechanism — a build script is compiled for the host, so a It also reaches past where the author drew the line. Codex's own suggested remedy is "lint the package on a Windows runner" — and the PR body already declines to add a Windows job, deliberately, because the full suite could not be executed to know whether it is green. The narrower alternative, scanning State as it stands
Three earlier findings are fixed and their threads resolved: macOS clippy coverage and the multiline Ready for a maintainer to either accept the residual Generated by Claude Code |
Summary
ci.yml'sgatesjob runs onubuntu-latest, and clippy only ever sees the code the activecfgset compiles. That left 262 lines of shipped Rust behind#[cfg(windows)]/#[cfg(target_os = "macos")]checked by nothing at all — 182 of them incommands/model_reader_host.rs, the v0.131.0 managed Windows host, plusmanifest/loader.rs,runtime/pidfile.rs,runtime/invoker.rs,render/blender.rsandcommands/app.rs.release.ymlandbridge-windows-packageddo build the crate on Windows, but withcargo build, and rustc accepts aclippy::tool lint and then ignores it. So all three of CLAUDE.md §Code style's mechanised rules applied to none of that code:cargo clippy -D warnings, the crate-rootdeny(clippy::unwrap_used, clippy::expect_used)insrc/main.rs, andundocumented_unsafe_blocksinCargo.toml.cargo clippy --target x86_64-pc-windows-gnustep ingates, and agates-macosjob on a realmacos-latestrunner — pluscli/tests/windows_target_gate.rsso neither can be quietly removed or narrowed later.The finding, measured
Not inferred. An
unwrap()was planted in the#[cfg(windows)]process_is_aliveinsrc/runtime/pidfile.rsand both commands run against it:cargo clippy --all-targets --locked -- -D warnings(what CI ran before this PR)--target x86_64-pc-windows-gnuerror: used `unwrap()` on a `Result` valueThe plant was reverted; the branch contains no source change. The code behind those cfgs is clean today — the defect is that no gate would have told anyone otherwise.
Why a cross-check for Windows but a real runner for macOS
Both limits were measured, not assumed.
x86_64-pc-windows-msvcfrom a Linux runner is not available:ringandzstd-syscompile C for the target and their build scripts refuse an msvc target under GNU cc ("GNU compiler is not supported for this target"). The-gnutriple needs only mingw, which the step installs. The two triples agree onwindows,target_osandtarget_familyand differ only undertarget_env— so-gnuis an exact proxy exactly as long as nothing in the crate branches ontarget_env, whichno_target_env_cfg_leaves_the_gnu_proxy_faithfulnow forbids.--target aarch64-apple-darwindies insidezstd-sys's build script (cc: error: unrecognized command-line option '-arch') before reaching this crate at all. So macOS coverage has to be a macOS runner.release.ymlalready buildsosx-arm64there, but withcargo build— the same reason the Windows cross-check exists despiterelease.ymlbuilding for Windows.Negative controls
Per the repo's existing gate-test convention (
lockfile_gate.rs,agent_python_suites_gate.rs), every scan over artefacts that are correct today is paired with a classifier driven over synthetic input, so a scanner that has stopped matching anything fails loudly instead of reporting clean. Each was mutation-tested: retargeting the macOS job toubuntu-latestfails it, dropping-D warningsfails it, a planted wrapped predicate fails the scanner, and atarget_envbranch planted inbuild.rsfails it by name.The gate was vacuous twice over on first submission, and that is worth stating plainly — it is the exact failure mode the file exists to prevent. The job body kept its comment lines, and the comment block above the macOS step names every flag asserted over it; the step's own
name:also readscargo clippy -D warnings (macos). So the flag assertions were satisfied by prose, and deleting-D warningsfrom the real step left the test green. Flags are now read fromrun:commands only, andthe_job_reader_matches_its_contractplants exactly that deletion.Type of change
Decalog check
Quality bar
Not an agent, skill or app. On the pinned 1.95.0 toolchain, from
cli/:Plus the rest of the repo's own gates on this tree: the lockfile pair,
no-hardcoded-string-offsets.py,sync_stats.py --check,run-agent-python-tests.py,no-claude-coauthor-trailers.py, and thesteel-detailer-lookupcrate's fmt/clippy/test. All 14 CI checks are green on364ea3b1,clippy (macos)included — that job could not be run locally, so CI was its first real execution.Notes for reviewers — two things left open, both deliberate
1. One Codex P2 is outstanding on the head, unfixed. "Cover Windows-gated build-script branches." The mechanism is real: a build script is compiled for the host, so a
#[cfg(windows)]incli/build.rswould be activated by the Windows release build and compiled by neither ubuntu clippy run, the-gnucross-check included. Butcli/build.rscontains nocfgat all today — it is oneprintln!— so nothing is currently unlinted and this PR makes nothing worse. Codex's own suggested remedy is "lint the package on a Windows runner", which is point 2. The narrower alternative needs a judgement call about which of#[cfg(windows)],cfg!(windows),CARGO_CFG_TARGET_*andTARGET/HOSTenv reads should fail a build — a maintainer's design decision, not a sweeper's. Three earlier findings were fixed and their threads resolved (macOS coverage and multilinecfgscanning ine460a664,build.rsin thetarget_envinventory in364ea3b1); this run stopped at its two-round limit because the findings were widening rather than converging.2. Three
#[cfg(windows)]tests still run nowhere, because no job runscargo teston Windows:tests/app_id_is_a_segment.rs::a_drive_relative_id_is_refused_as_well— a path-traversal regression test (C:evilcarries no separator, andPath::joindiscards the base when the appended path has a prefix)src/commands/model_reader_host.rs::provider_is_created_suspended_until_its_job_is_attachedThis PR makes clippy compile all three; it does not make anything run them. Closing that means a
windows-latestjob, and the 53-binary suite could not be executed here to know whether it is green — pushing it unverified is the speculative red CI the engineering rules warn against. Awindows-latestclippy job would also settle point 1, and is the smaller of the two.Cost: roughly one to two minutes on
gates(a second dependency graph checked, not built, nothing linked or run) plus a shortmacos-latestjob.