Skip to content

ci(gate): lint the shipped configuration, not only the test one (#1418) - #1419

Merged
dc0sk merged 1 commit into
mainfrom
fix/1418-lint-shipped-config
Sep 19, 2026
Merged

dc0sk merged 1 commit into
mainfrom
fix/1418-lint-shipped-config

Conversation

@dc0sk

@dc0sk dc0sk commented Sep 19, 2026 •

Copy link
Copy Markdown
Owner

Closes #1418.

Both lint sites ran exactly one clippy pass, --workspace --no-default-features --all-targets -- -D warnings. --all-targets puts dev units in scope, and resolver 2 then unifies dev-dependency
features into the normal build. Three dev-deps enable openpulse-modem's instruments feature —
crates/openpulse-modem/Cargo.toml:41, openpulse-daemon:92, openpulse-kiss:59 — and under
--workspace any one suffices. So the lib was always linted with instruments ON, while
cargo build --release --no-default-features (release.yml:60) links it OFF. Nothing linted the
shipped configuration.

Not cosmetic — what the hole admits

An ungated production caller of an instruments-only accessor is invisible to both automated
checks and breaks the release build:

gate  cargo clippy --workspace --no-default-features --all-targets -D warnings  -> rc=0
hook  cargo test -p openpulse-modem --no-default-features --no-run              -> rc=0
ship  cargo clippy -p openpulse-daemon --no-default-features -D warnings        -> rc=101  E0599

Corollary: #1277's "a production call cannot compile without a visible Cargo.toml diff" was
enforced by release builds alone — not by the gate, not by the hook.

The change

An added pass, not a changed flag. Dropping --all-targets would stop linting test code — the rot
that put an unused binding in session_key.rs. It stays --workspace, because a downstream crate's
production code calling an instruments item escapes too: that crate's lib builds against the ON modem.
~1 s warm, 9.1 s from a cold modem lib. The hook gets it as well, since it is the only check that runs
on every push (#1144).

engine.rs carries the two items the new pass then found, both already unreachable in shipped builds:
five openpulse_core::fec imports move to an instruments-gated use, and stage_modulate_payload_iq
takes the same cfg as its only caller, transmit_iq. No product behaviour changes.

Sabotage-verified, in both directions

The control is what makes the failure attributable — with the probe planted, the OLD step still passes:

  cargo clippy -D warnings              ok
  cargo clippy (shipped cfg) -D warns   FAILED (exit 101)

And on a clean tree the new step reports ok, so it is not a step that always fails.

Test results

scripts/gate.sh on the branch tip, clean tree:

suites=339 tests_passed=2574 tests_failed=0
GATE: PASS b64d874926357084ca4669b54f8dce8b10f626c6 clean 20260919T164444Z

All 12 steps ok, including the new one. held-out (runtime, #1274): notch_rescues_interferer, ota_channel_adaptation — run scripts/slow-tests.sh

Not covered by this run, unchanged by this PR: the two #[ignore]d acceptance suites above.

Honesty note

The first gate run on this branch failed, on my own review artifact's frontmatter (doc: not equal
to the path, project: missing, status: living without a manifest entry). Fixed and amended; the
verdict above is the re-run. Worth stating plainly in a PR that adds a gate step.

Scope

This makes the shipped configuration linted. It was already type-checked in ci.yml's macOS build,
cross check and release.yml — all release-scoped. Do not read this as "the OFF configuration was
never compiled".

#1380 stays open. That is the inverse case — a feature that is OFF in the gate, whose code
is never type-checked — and it still needs its own --features cpal-backend step. The comment on #1380
records the distinction.

Verification-objective: the workspace lint must cover the feature configuration the release
build links, not only the one that includes dev units

Review: docs/dev/reviews/review-1418-shipped-config-lint.md

🤖 Generated with Claude Code

https://claude.ai/code/session_0188ATCj6DZ9aRVQ2vSirua6

Both lint sites ran exactly one clippy pass, `--workspace --no-default-features
--all-targets -- -D warnings`. `--all-targets` puts dev units in scope, and resolver 2
then unifies dev-dependency features into the normal build. Three dev-deps enable
`openpulse-modem`'s `instruments` feature — its own Cargo.toml:41, openpulse-daemon:92,
openpulse-kiss:59 — and under `--workspace` any one suffices. So the lib was always
linted with `instruments` ON, while `cargo build --release --no-default-features`
(release.yml:60) links it OFF. No pass linted the shipped configuration.

Not cosmetic. An ungated production caller of an instruments-only accessor is invisible
to BOTH automated checks and breaks the release build:

    gate  cargo clippy --workspace --no-default-features --all-targets -D warnings -> rc=0
    hook  cargo test -p openpulse-modem --no-default-features --no-run             -> rc=0
    ship  cargo clippy -p openpulse-daemon --no-default-features -D warnings       -> rc=101 E0599

Corollary: #1277's "a production call cannot compile without a visible Cargo.toml diff"
was enforced by release builds alone.

An ADDED pass, not a changed flag — dropping `--all-targets` would stop linting test
code, the rot that put an unused binding in session_key.rs. It stays `--workspace`: a
DOWNSTREAM crate's production code calling an instruments item also escapes, because
that crate's lib builds against the ON modem. ~1 s warm, 9.1 s from a cold modem lib.
The hook gets it too because it is the only check that runs on every push (#1144).

engine.rs carries the two items the new pass then found, both already unreachable in
shipped builds: five `openpulse_core::fec` imports move to an instruments-gated `use`,
and `stage_modulate_payload_iq` takes the same cfg as its only caller, `transmit_iq`.
No product behaviour changes.

Sabotage-verified, and the control is what makes it attributable: with the probe
planted, `gate.sh --quick` prints `cargo clippy -D warnings  ok` for the OLD step and
`cargo clippy (shipped cfg) -D warns  FAILED (exit 101)` for the NEW one.

Fable review corrected three things in my framing before this was built: the three
enabling dev-deps (I had blamed #1277's self dev-dep alone, whose removal would not have
closed it), `--all-targets` being a proxy for "dev units in scope" (`--tests` alone
flips it), and that during a gate run downstream crates link the ON lib — so the claim
is about shipped binaries, not downstream crates.

Verification-objective: the workspace lint must cover the feature configuration the
release build links, not only the one that includes dev units

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188ATCj6DZ9aRVQ2vSirua6
@dc0sk
dc0sk merged commit e58701f into main Sep 19, 2026
12 of 13 checks passed
@dc0sk
dc0sk deleted the fix/1418-lint-shipped-config branch September 19, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The gate's --all-targets enables a dev-dep feature, so the shipped (feature-off) configuration is never linted

1 participant