refactor: enforce check_x → CheckStatus convention + toolchain supply-chain pin - #17
Merged
Merged
Conversation
…checks Tier 1: Document the Source Check Convention in CLAUDE.md — check_x() returns CheckStatus (not CheckResult), run() is the sole CheckResult constructor using self.id()/self.group()/self.layer(). Tier 2: Apply the convention to all 16 Rust source checks. Each check_x() function now returns CheckStatus directly, eliminating ID/group/layer string literal triplication. Net -132 lines. Tier 3: Add convention_check_x_returns_check_status_not_check_result integration test that greps source check files for the old pattern and fails if any check_x() still returns CheckResult.
Rewrite convention_check_x_returns_check_status_not_check_result as
pure Rust using std::fs. The previous implementation shelled out to rg
which is not available in GitHub Actions runners, causing the test to
panic with "No such file or directory" and blocking all CI runs.
The new implementation:
- Uses CARGO_MANIFEST_DIR for a stable absolute path (no CWD fragility)
- Walks src/checks/source/ recursively with only std::fs
- Catches all visibility modifiers (pub, pub(crate), pub(super), private)
- Handles multi-line signatures by accumulating text until the opening {
- Reports specific file:line:code references on failure
Also corrects CLAUDE.md Source Check Convention claims:
- check_x() signature is (source: &str) or (source: &str, file: &str)
- "Every" → "Most" with noted exceptions for output_module.rs and
error_types.rs which use different helper shapes
clippy 1.95 flags the nested `if` inside `CheckStatus::Pass =>` as collapsible. Use a match guard instead. Local toolchain was 1.94 so the lint didn't fire pre-push — ran into this as a CI-only failure.
Run `rustup update stable --no-self-update` before the other checks so local clippy/rustc match what CI will use. CI reinstalls stable on every run, so if the local toolchain is behind, a newer lint can fail CI while pre-push reports green — exactly what happened with the collapsible_match lint that landed in clippy 1.95. Fast no-op when already current; takes a few seconds on first push after a new stable release.
Pin rust-toolchain.toml to a specific release instead of floating `stable`. Rustup verifies component SHA256s from the distribution manifest — the version pin is effectively a SHA pin. Trailing comment documents the rustc commit SHA for audit, mirroring the GitHub Actions pin pattern (action@<sha> # vN.N.N). Both local and CI now read rust-toolchain.toml and install identical bits. Removes the pre-push rustup-update hook introduced earlier in this branch — pinning is the right fix, not runtime sync. Policy: bump the channel only via reviewed PR, after the new stable has aged ≥7 days. This matches the UV_EXCLUDE_NEWER / bun minimumReleaseAge / npm_config_min_release_age quarantine already in dotfiles, and guards against the `tj-actions/changed-files`-class supply-chain attack on the toolchain itself.
This was referenced Apr 16, 2026
brettdavies
referenced
this pull request
in brettdavies/bird
Apr 16, 2026
## Summary Pin `rust-toolchain.toml` to a specific `X.Y.Z` release with a trailing rustc commit-SHA comment, replacing the floating `channel = "stable"`. Rustup verifies component SHA256s from the distribution manifest, so the version pin is effectively a SHA pin (the manifest is the toolchain's lockfile). Both local and CI now read the same file and install identical bits. Mirrors the pattern just shipped in [`agentnative` PR #17](brettdavies/agentnative#17), which was motivated by a real CI-only clippy failure during PR review: local clippy 1.94 passed a lint that CI clippy 1.95 rejected because `channel = "stable"` let rustc drift between environments. ## Changelog <!-- No user-facing changes — supply-chain hardening only. --> ## Type of Change - [x] `chore`: Maintenance tasks (supply-chain toolchain pin) ## Related Issues/Stories - Related PRs: [brettdavies/agentnative#17](brettdavies/agentnative#17) — pattern source ## Testing - [x] All tests passing **Test Summary:** - Unit tests: 185 passing - Integration tests: 38 + 14 = 52 passing - Live integration tests: 1 ignored (requires live X API) - Clippy: clean with `-Dwarnings` on rustc 1.94.1 (pinned) - Fmt: clean - Pre-push hook: passed (fmt, clippy, test, windows compat) ## Files Modified **Modified:** - `rust-toolchain.toml` — pinned `channel = "1.94.1"` with trailing comment naming the rustc commit SHA and release date; bumped from floating `channel = "stable"`. Added 4 lines of header comments documenting the supply-chain rationale and the ≥7-day quarantine policy. ## Key Details **Toolchain pin format:** `channel = "1.94.1" # rustc e408947bfd200af42db322daf0fadfe7e26d3bd1, released 2026-03-25`. Comment mirrors the GitHub Actions SHA-pin pattern (`action@<sha> # vN.N.N`). **Policy:** bump the channel only via reviewed PR, after the new stable has aged ≥7 days. Matches the broader brettdavies supply-chain posture (`UV_EXCLUDE_NEWER`, bun `minimumReleaseAge`, `npm_config_min_release_age` already in dotfiles). **MSRV compatibility:** bird's `rust-version = "1.87"`; 1.94.1 satisfies it comfortably. **No hook / workflow changes needed:** neither `scripts/hooks/pre-push`, `.githooks/pre-push`, nor any `.github/workflows/*.yml` file references `rustup update` or pins a specific toolchain version — rustup reads `rust-toolchain.toml` automatically on every `cargo` invocation, so the single-file change is sufficient. ## Benefits - Local and CI toolchains are guaranteed identical — no more "local clippy older than CI clippy" false greens - Toolchain updates route through reviewed PRs with a 7-day quarantine - Consistent with the supply-chain-pin pattern applied across brettdavies repos (GitHub Actions SHA pins, Docker image digest pins, package-manager lockfiles) ## Breaking Changes - [x] No breaking changes ## Deployment Notes - [x] No special deployment steps required ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) - [x] Self-review of code completed - [x] No new warnings or errors introduced - [x] Changes are backward compatible
brettdavies
referenced
this pull request
in brettdavies/xurl-rs
Apr 16, 2026
## Summary Pins `rust-toolchain.toml` to a specific `X.Y.Z` release instead of floating `channel = "stable"`. Rustup verifies component SHA256s from the distribution manifest, so the version pin is effectively a SHA pin (the manifest is the toolchain's lockfile). Trailing comment documents the rustc commit SHA for audit, mirroring the GitHub Actions SHA-pin pattern (`action@<sha> # vN.N.N`). Both local and CI now read `rust-toolchain.toml` and install identical bits. Prevents "local clippy older than CI clippy" drift. Matches the pattern applied in [agentnative PR #17](brettdavies/agentnative#17). ## Changelog <!-- No user-facing changes — supply-chain hardening + CI reliability. --> ## Type of Change - [x] `chore`: Maintenance task (supply-chain toolchain pin) ## Testing - [x] All tests passing - [x] Clippy clean with `-Dwarnings` - [x] `cargo fmt --check` clean **Test Summary:** - Unit tests: 17 passing (unchanged — same code, new pinned toolchain) - Clippy: clean on rustc 1.94.1 ## Policy Bump the channel only via reviewed PR, after the new stable has aged ≥7 days. This matches the `UV_EXCLUDE_NEWER` / bun `minimumReleaseAge` / `npm_config_min_release_age` quarantine already in dotfiles. A central automated bump workflow is tracked as a follow-up in `brettdavies/dot-github` todo #4. - [x] No breaking changes - [x] No special deployment steps required
brettdavies
referenced
this pull request
in brettdavies/xurl-rs
Apr 16, 2026
## Summary Pins `rust-toolchain.toml` to a specific `X.Y.Z` release instead of floating `channel = "stable"`. Rustup verifies component SHA256s from the distribution manifest, so the version pin is effectively a SHA pin (the manifest is the toolchain's lockfile). Trailing comment documents the rustc commit SHA for audit, mirroring the GitHub Actions SHA-pin pattern (`action@<sha> # vN.N.N`). Both local and CI now read `rust-toolchain.toml` and install identical bits. Prevents "local clippy older than CI clippy" drift. Matches the pattern applied in [agentnative PR #17](brettdavies/agentnative#17). ## Changelog <!-- No user-facing changes — supply-chain hardening + CI reliability. --> ## Type of Change - [x] `chore`: Maintenance task (supply-chain toolchain pin) ## Testing - [x] All tests passing - [x] Clippy clean with `-Dwarnings` - [x] `cargo fmt --check` clean **Test Summary:** - Unit tests: 17 passing (unchanged — same code, new pinned toolchain) - Clippy: clean on rustc 1.94.1 ## Policy Bump the channel only via reviewed PR, after the new stable has aged ≥7 days. This matches the `UV_EXCLUDE_NEWER` / bun `minimumReleaseAge` / `npm_config_min_release_age` quarantine already in dotfiles. A central automated bump workflow is tracked as a follow-up in `brettdavies/dot-github` todo #4. - [x] No breaking changes - [x] No special deployment steps required
brettdavies
referenced
this pull request
in brettdavies/xurl-rs
Apr 16, 2026
## Summary Pins `rust-toolchain.toml` to a specific `X.Y.Z` release instead of floating `channel = "stable"`. Rustup verifies component SHA256s from the distribution manifest, so the version pin is effectively a SHA pin (the manifest is the toolchain's lockfile). Trailing comment documents the rustc commit SHA for audit, mirroring the GitHub Actions SHA-pin pattern (`action@<sha> # vN.N.N`). Both local and CI now read `rust-toolchain.toml` and install identical bits. Prevents "local clippy older than CI clippy" drift. Matches the pattern applied in [agentnative PR #17](brettdavies/agentnative#17). ## Changelog <!-- No user-facing changes — supply-chain hardening + CI reliability. --> ## Type of Change - [x] `chore`: Maintenance task (supply-chain toolchain pin) ## Testing - [x] All tests passing - [x] Clippy clean with `-Dwarnings` - [x] `cargo fmt --check` clean **Test Summary:** - Unit tests: 17 passing (unchanged — same code, new pinned toolchain) - Clippy: clean on rustc 1.94.1 ## Policy Bump the channel only via reviewed PR, after the new stable has aged ≥7 days. This matches the `UV_EXCLUDE_NEWER` / bun `minimumReleaseAge` / `npm_config_min_release_age` quarantine already in dotfiles. A central automated bump workflow is tracked as a follow-up in `brettdavies/dot-github` todo #4. - [x] No breaking changes - [x] No special deployment steps required
brettdavies
added a commit
that referenced
this pull request
Apr 16, 2026
…-chain pin (#17) ## Summary Two related hardening efforts bundled: 1. **Convention enforcement** — standardizes all source checks on a single pattern (`check_x()` returns `CheckStatus`; `run()` is the sole `CheckResult` constructor, using `self.id()`/`self.group()`/`self.layer()`). Documents the convention in CLAUDE.md, refactors all 16 Rust source checks to match, and adds a Rust-only integration test that walks the source tree and fails CI if any `check_x()` still returns `CheckResult`. 2. **Toolchain supply-chain pin** — `rust-toolchain.toml` now pins to a specific `X.Y.Z` release with a trailing rustc commit-SHA comment. Rustup verifies component SHA256s from the distribution manifest, so the pin is effectively a SHA pin (the manifest is the toolchain's lockfile). Both local and CI read the same file and install identical bits. Motivated by a CI-only clippy failure during this PR's own review: local clippy 1.94 passed a lint that CI clippy 1.95 rejected. Convention enforcement was identified during the [PR #15 code review](#15) — the 3 new Python checks were fixed in that PR, but the 16 existing Rust checks still used the old pattern. The toolchain pin was added mid-review after the clippy divergence exposed that floating `channel = "stable"` leaves local and CI on different rustc versions. ## Changelog <!-- No user-facing changes — internal refactor + supply-chain hardening. --> ## Type of Change - [x] `refactor`: Code refactoring (no functional changes) - [x] `chore`: Maintenance tasks (supply-chain toolchain pin) - [x] `docs`: Documentation update (CLAUDE.md conventions + toolchain policy) - [x] `test`: Adding or updating tests (convention enforcement test) ## Related Issues/Stories - Related PRs: #15 (review finding that identified the convention drift) - Follow-up: `dot-github` todo #4 — determine the automated bump workflow for `rust-toolchain.toml` across repos (central reusable workflow vs. local script vs. hybrid) ## Testing - [x] Unit tests added/updated - [x] Integration tests added/updated - [x] All tests passing **Test Summary:** - Unit tests: 304 passing (unchanged count — refactor preserves behavior) - Integration tests: 39 passing (+1 new: `convention_check_x_returns_check_status_not_check_result`) - Clippy: clean with `-Dwarnings` on rustc 1.94.1 (pinned) ## Files Modified **Modified:** - `CLAUDE.md` — added Source Check Convention section (Tier 1) and Toolchain Pin section documenting the 7-day quarantine policy - `rust-toolchain.toml` — pinned `channel = "1.94.1"` with trailing comment naming the rustc commit SHA and release date; bumped from floating `channel = "stable"` - `scripts/hooks/pre-push` — removed `rustup update stable` step; pin + rustup's manifest verification now handle toolchain integrity - 16 files in `src/checks/source/rust/` — `check_x()` returns `CheckStatus`, `run()` uses `self.id()`/`self.group()`/ `self.layer()` instead of duplicated string/enum literals - `src/checks/source/rust/no_pager.rs` — collapsed nested `if` inside a `match` arm into a match guard (fixes clippy `collapsible_match` lint introduced in clippy 1.95) - `tests/integration.rs` — added `convention_check_x_returns_check_status_not_check_result` enforcement test ## Key Details **Tier 1 (Document):** CLAUDE.md now codifies the source check structure. Covers the `Check` trait impl shape, the `check_x() → CheckStatus` separation, and the convention that `run()` is the sole `CheckResult` constructor. Also adds a new Toolchain Pin section explaining the supply-chain pin policy. **Tier 2 (Refactor):** All 16 Rust source checks aligned to the convention. Net -132 lines by removing duplicated `CheckResult` construction (previously the `id` / `label` / `group` / `layer` fields were hardcoded in both `run()` and every `check_x()` helper). **Tier 3 (Enforce):** Integration test walks `src/checks/source/` with `std::fs` (no shell dependencies), finds every `fn check_` signature (any visibility, single-line or multi-line), and fails if any return `CheckResult` instead of `CheckStatus`. Uses `CARGO_MANIFEST_DIR` for a stable absolute path. **Toolchain pin format:** `channel = "1.94.1" # rustc e408947bfd200af42db322daf0fadfe7e26d3bd1, released 2026-03-25`. Comment mirrors the GitHub Actions SHA-pin pattern (`action@<sha> # vN.N.N`). Policy: bump only via reviewed PR after the new stable has aged ≥7 days (supply-chain quarantine consistent with `UV_EXCLUDE_NEWER` / bun `minimumReleaseAge` / `npm_config_min_release_age` in dotfiles). ## Benefits - Eliminates ID string literal triplication (3 copies per check → 1 authoritative source in `fn id()`) - New checks can't drift — the convention is documented AND enforced by CI - -132 lines of boilerplate removed - Local and CI toolchains are guaranteed identical — no more "local clippy older than CI clippy" false greens - Toolchain updates route through reviewed PRs with a 7-day quarantine, matching the broader brettdavies supply-chain posture ## Breaking Changes - [x] No breaking changes ## Deployment Notes - [x] No special deployment steps required ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed - [x] Tests added/updated and passing - [x] No new warnings or errors introduced - [x] Changes are backward compatible
brettdavies
added a commit
that referenced
this pull request
Apr 22, 2026
Flip the Key Technical Decision on audience label serialization from snake_case to kebab-case, update the inline string literals and the "classify() emits snake_case label" prose, and add an Implementation Log entry describing why the change landed post-review (the ce:review pass flagged the mixed snake/kebab casing inside one JSON document as P3 #17; audit_profile's kebab-case is non-negotiable, audience's snake_case was convention-inertia, and v0.1.2 / site H6 hadn't yet pinned on the old values).
18 tasks
brettdavies
added a commit
that referenced
this pull request
Apr 22, 2026
…-case (#27) ## Summary - Applies all 26 findings from the ce-review of commit dc5d741 (P1 coverage_summary filter, P2 Check::label() trait migration, Pattern 2 extraction, P3 audience_reason / audit_profiles matrix / codified regression tests). - Unifies `audience` values to kebab-case (`agent-optimized` / `mixed` / `human-primary`) post-review — closes the mixed-casing asymmetry that ce-review P3 #17 flagged. Agentnative-site H6 plan already updated for the pre-regen adaptation. - 452 tests passing (402 unit + 50 integration, net +11 new). Pre-push green (fmt, clippy -Dwarnings, test, cargo-deny, windows-compat). Dogfood on the repo confirms kebab-case emission and suppressed-coverage filter. ## Reviewer orientation Big changeset (50 files), but mechanically simple once you understand the groupings: - **P1 fix + test:** `src/scorecard/mod.rs::build_coverage_summary` now filters via `audience::is_audit_profile_suppression`; regression test pins the behavior. - **Prefix extraction:** `SUPPRESSION_EVIDENCE_PREFIX` in `src/principles/registry.rs` is the single source of truth; consumed by `main.rs`, `audience.rs`, and `build_coverage_summary`. - **Label trait:** `Check::label()` added abstractly; mechanical migration across 40 check impls. Suppressed/errored `CheckResult` now shows the human label instead of the id. - **Help_probe extraction:** `git mv` rename preserves blame; `EnvHintSource` enum at parent scope so both patterns can tag their emissions. - **Scorecard field additions:** `audience_reason` + `audit_profiles` matrix section + kebab-case classify() output; all additive to v1.1. - **Codified tests:** exit_code behavior under suppression, JSON casing contract, `CheckResult`-only-in-run() convention, Pattern 2 bracketed rejection, duplicate-signal debug_assert, AuditProfile ↔ ExceptionCategory parity, full-shape JSON snapshot, --principle + audience interaction. ## Test plan - [x] `cargo fmt --check` clean - [x] `cargo clippy --all-targets -- -Dwarnings` clean - [x] `cargo test` 402 unit + 50 integration passing - [x] `cargo deny check` clean - [x] Windows compat check clean - [x] `anc generate coverage-matrix --check` no drift - [x] Dogfood `anc check . --output json`: `schema_version: "1.1"`, `audience: "agent-optimized"`, `audit_profile: null`, `audience_reason` absent - [x] Dogfood `anc check . --audit-profile human-tui`: `audience: null`, `audience_reason: "suppressed"`, `coverage_summary.must.verified` drops from 17 → 15 - [x] Pre-push hook full local-CI mirror green ## Related - Plan doc recording the post-review deviation: `docs/plans/2026-04-21-v013-handoff-5-cli-audience-classifier.md` (committed directly to dev as `6fdca00`) - Site-side adaptation plan: `agentnative-site/docs/plans/2026-04-21-v013-handoff-6-site-leaderboard-launch.md` (Unit 0.5 covers kebab-case absorption; must land before the v0.1.3 scorecard regen wave) - CE-review artifacts: `.context/compound-engineering/ce-review/20260422-134229-565fc6d7/` (10 reviewer JSONs + metadata; local-only) ## Breaking changes None for v1.1 consumers that pin on `audience: null`. v1.1 consumers that had pinned on hypothetical snake_case audience values need to update — the site's H6 renderer hasn't shipped, so the only such consumer is in-house and tracked by the site-side plan.
11 tasks
brettdavies
added a commit
that referenced
this pull request
May 4, 2026
## Summary Opts agentnative-cli into the two new shared-workflow inputs that landed in `brettdavies/.github` PR #18, so future releases ship Alpine/musl artifacts. No source changes; the binary is identical to v0.3.0. After this PR merges (and ships via a `release/v0.3.1` cherry-pick to `main`), every release will produce 7 archives instead of 5 — adding `agentnative-x86_64-unknown-linux-musl.tar.gz` and `agentnative-aarch64-unknown-linux-musl.tar.gz`. Alpine and other musl-libc-host distros gain a first-class install path beyond `cargo install` and the existing glibc Linux artifact. Bundled: a small `RELEASES.md` polish that was already dirty in the working tree (cliff.toml chore-skip warning + "never hand-written" rule under `Releasing dev to main`), plus the necessary 5 → 7 target table update. ## Changelog ### Added - Ship `x86_64-` and `aarch64-unknown-linux-musl` static binaries on every release. Statically linked against musl libc, so they run on Alpine and other musl-libc-host distros without glibc, and on every glibc distro too. ### Documentation - Document the `cliff.toml` chore-skip footgun and the "CHANGELOG is generated, never hand-written" rule in `RELEASES.md` under `Releasing dev to main`. Adds a new review step (renumbered to 9) and tightens the existing "PRs and changelog generation" section. ## Type of Change - [x] `feat`: New feature (non-breaking change which adds functionality) ## Related Issues/Stories - Story: n/a - Issue: n/a - Architecture: n/a - Related PRs: brettdavies/.github#17 (shared workflow musl rows + soft-fail input), brettdavies/.github#18 (release of #17 to main). agentnative-cli `spike/musl-build` (throwaway) was the validation surface. ## Testing - [x] Manual testing completed - [x] All tests passing **Test Summary:** - Unit tests: n/a (workflow opt-in only; no Rust source change) - Integration tests: n/a - Coverage: n/a End-to-end validation completed in the throwaway `spike/musl-build` workflow before either upstream or this PR opened: - `cross build --release --locked --target x86_64-unknown-linux-musl` — green, ~1m45s, statically linked - `cross build --release --locked --target aarch64-unknown-linux-musl` — green, ~1m45s, statically linked - `file target/.../release/anc` matched `statically linked` for both arches - x86_64 host smoke test (`anc --version`) — `anc 0.3.0` - Belt-and-suspenders: `docker run --rm --pull always -v $PWD/target/.../release:/musl-bin:ro alpine:latest /musl-bin/anc --version` — `anc 0.3.0`. Confirms exec compatibility with musl-libc host (Alpine), not just static linkage. `actionlint` clean on the modified `release.yml`. The pre-push hook (`scripts/hooks/pre-push`: fmt, clippy `-Dwarnings`, test, cargo-deny, Windows compat) passed. ## Files Modified **Modified:** - `.github/workflows/release.yml` — passes `linux_musl_required: true` and `linux_musl_verify_alpine: true` to the shared `rust-release.yml` workflow. - `RELEASES.md` — updates the release-pipeline table from 5 → 7 targets (naming the two musl rows and the two opt-in inputs), and bundles a separate cliff.toml chore-skip + "never hand-written" docs improvement that was already dirty in the working tree. **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Key Features - Alpine support: musl-static binaries run on Alpine without glibc, and on every glibc distro too. - Belt-and-suspenders Alpine exec verification in CI catches dynamic-link surprises (`dlopen`, NSS, locale) that pass the static-link `file` assertion. - Hard-fail behavior (`linux_musl_required: true`) means a musl regression blocks the release, not a silent artifact omission. ## Benefits - Closes the install gap for Alpine users — the existing Homebrew bottle is glibc-linux only, and `cargo install` requires the full Rust toolchain. Now: `wget` + `tar xf` + run. - Distroless / `scratch` containers gain a usable artifact too. - The Alpine exec check turns a class of "ship now, find out later in a user bug report" failures into "fail at CI time." ## Breaking Changes - [x] No breaking changes ## Deployment Notes - [x] Standard release flow per `RELEASES.md` After this PR squash-merges to `dev`, ship via the standard cherry-pick: 1. Branch `release/v0.3.1` from `origin/main`. 2. Cherry-pick this commit; bump `Cargo.toml` 0.3.0 → 0.3.1; `cargo update -p agentnative`. 3. Run `./scripts/generate-completions.sh`, `bash scripts/sync-skill-fixture.sh`, `./scripts/generate-changelog.sh`. Cross-check the generated CHANGELOG section against this PR's `## Changelog` bullets per the cliff.toml chore-skip warning. 4. Triple-diff verify, push, open `release: v0.3.1` PR. 5. After merge, annotated tag and push triggers the release pipeline (now with musl). 6. After the release publishes, run `./scripts/sync-dev-after-release.sh v0.3.1 && git push origin dev` per the new convention. The throwaway `spike/musl-build` branch in this repo can be pruned (locally + remotely) any time after this PR opens; it served its purpose and was never merged anywhere. ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed - [x] Tests added/updated and passing (validated via spike workflow before upstream PR opened) - [x] No new warnings or errors introduced (`actionlint` clean; pre-push hook clean) - [x] Changes are backward compatible
brettdavies
added a commit
that referenced
this pull request
May 4, 2026
## Summary Releases v0.3.1, an artifact-set release: ships `x86_64-unknown-linux-musl` and `aarch64-unknown-linux-musl` static binaries on every release. No source change versus v0.3.0 — the binary is identical; only the artifact set is wider. Consolidates one dev commit: - **#48 — `feat(release): opt into linux-musl artifacts via shared workflow`** — passes `linux_musl_required: true` and `linux_musl_verify_alpine: true` to the shared `rust-release.yml@main` (those inputs landed in brettdavies/.github#18). Bundled with the inputs change is a `RELEASES.md` polish: 5 → 7 target table update plus a separate cliff.toml chore-skip + "never hand-written" rule that was pre-existing dirty in the working tree. Triple-diff verification before opening: A is exactly the 6 expected ship-surface files; B contains only release-prep files (Cargo.toml, Cargo.lock, CHANGELOG.md) plus the always-divergent completions/; no guarded engineering-doc paths leaked. ## Changelog ### Added - Ship `x86_64-` and `aarch64-unknown-linux-musl` static binaries on every release. Statically linked against musl libc, so they run on Alpine and other musl-libc-host distros without glibc, and on every glibc distro too. ### Documentation - Document the `cliff.toml` chore-skip footgun and the "CHANGELOG is generated, never hand-written" rule in `RELEASES.md` under `Releasing dev to main`. - Update the release-pipeline target table from 5 → 7 targets, naming the two musl rows and the two opt-in inputs (`linux_musl_required`, `linux_musl_verify_alpine`). ## Type of Change - [x] `feat`: New feature (non-breaking change which adds functionality) ## Related Issues/Stories - Story: n/a - Issue: n/a - Architecture: n/a - Related PRs: #48 (this release's only consolidated dev commit), brettdavies/.github#17 (shared-workflow musl matrix rows + soft-fail), brettdavies/.github#18 (release of #17 to main) ## Testing - [x] Manual testing completed - [x] All tests passing **Test Summary:** - Unit tests: pass on dev as part of #48 CI (fmt, clippy, test, audit, package check, drift-check) - Integration tests: n/a (no source change vs v0.3.0) - Coverage: unchanged End-to-end musl validation completed pre-merge in the throwaway `spike/musl-build` workflow: - `cross build --release --locked --target x86_64-unknown-linux-musl` — green, statically linked - `cross build --release --locked --target aarch64-unknown-linux-musl` — green, statically linked - `file target/.../release/anc` matched `statically linked` for both arches - x86_64 host smoke test (`anc --version`) — `anc 0.3.0` - Belt-and-suspenders: `docker run --rm --pull always -v ".../release:/musl-bin:ro" alpine:latest /musl-bin/anc --version` — `anc 0.3.0` The `release` pipeline (now 7 targets) re-runs all of the above on the v0.3.1 tag push, so the binaries shipped to the GitHub Release will be the freshly-built ones, not the spike's. ## Files Modified **Modified:** - `.github/workflows/release.yml` — passes the two new shared-workflow inputs. - `Cargo.toml` — version 0.3.0 → 0.3.1. - `Cargo.lock` — `cargo update -p agentnative` regen. - `CHANGELOG.md` — `scripts/generate-changelog.sh` extracted #48's `## Changelog` section into a v0.3.1 entry. Cross-checked: cliff.toml chore-skip didn't drop anything (commit subject was `feat`, not `chore`). - `RELEASES.md` — release-pipeline table 5 → 7 targets + bundled cliff.toml/never-hand-written documentation. - `src/skill_install/skill.json` — fixture refresh from upstream agentnative-site dev (caught by drift-check on #48; brought along here). **Created:** - None. **Renamed:** - None. **Deleted:** - None. ## Breaking Changes - [x] No breaking changes The binary surface is unchanged. New consumers on Alpine gain an install path; existing consumers see no difference. ## Deployment Notes After this PR squash-merges to `main`: ```bash git checkout main && git pull git tag -a -m "Release v0.3.1" v0.3.1 git push origin main --tags ``` The tag push triggers the now-7-target release pipeline. After the GitHub Release reaches `published` (homebrew dispatch and finalize-release flip), backport per the new convention: ```bash ./scripts/sync-dev-after-release.sh v0.3.1 git push origin dev ``` The throwaway `spike/musl-build` branch (local + remote) can be pruned any time after this PR opens; it served its purpose. ## Checklist - [x] Code follows project conventions and style guidelines - [x] Commit messages follow Conventional Commits - [x] Self-review of code completed (PR #48 review applies; release-prep commits are bump/completions/CHANGELOG/skill-fixture as scripted) - [x] Tests added/updated and passing (validated via spike + #48 CI) - [x] No new warnings or errors introduced - [x] Changes are backward compatible
brettdavies
added a commit
that referenced
this pull request
May 29, 2026
A five-agent parallel audit of the full diff (both directions) plus follow-up sweeps found the rename had over-applied "check"→"audit" to generic verbs, external identifiers, and grammar. Behavior is unchanged; 793 tests pass.
Code:
- Generic verbs restored to "check" in comments and doc-comments: source.rs pattern helpers, color.rs NO_COLOR routing, project.rs binary discovery ("existence check", "[[bin]] entries"), runner condvar/parser comments, several test comments (contract, bidirectional, RFC-3339 shape), and the sys_exit/env_flags/list_style comments.
- `audit_destination` reverted to `check_destination` (a skill-install precondition guard, not an `Audit`-trait audit; dev named it check_destination) along with its doc comments and test message.
- `bin/check-update` doc reference (the real script in agentnative-skill, not `bin/audit-update`).
- "a audit" / "A audit" corrected to "an audit" (article slips from the mechanical rename).
- Restored the perfect-rust test fixture, an arbitrary fake CLI, to its consistent dev form.
Top-level docs:
- CLAUDE.md: "Windows compatibility check", "the pre-push hook checks this", "Check CI status", "existence check".
- RELEASES.md: "required status checks" (GitHub branch-protection term).
Planning docs (historical references the rename falsified):
- PR #17 branch `refactor/check-status-convention`, the design-doc heading "Behavioral Check Error Handling", the `behavioral-checks.md` handoff, `gh pr checks` (not `gh pr audits`), "CI checks passed", and "status checks page".
- Restored `check_destination` and the conflict-check prose in the skill-subcommand plan, and the old-verb did-you-mean examples in the remove-implicit-default-subcommand plan, keeping the genuine domain renames (the `Audit` subcommand variant, behavioral/source audits, the renamed test).
- Re-fixed `audit-version-extract.sh`: the agentnative-site scoring script is correctly named "audit-", distinct from the CLI's `check-version` release job.
The CLI's domain noun stays "audit" throughout: the `anc audit` verb, the `Audit` trait, audit IDs, the `audit_id` field, and behavioral/source/project audits.
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related hardening efforts bundled:
check_x()returnsCheckStatus;run()is the soleCheckResultconstructor, usingself.id()/self.group()/self.layer()). Documents theconvention in CLAUDE.md, refactors all 16 Rust source checks to match, and adds a Rust-only integration test that
walks the source tree and fails CI if any
check_x()still returnsCheckResult.rust-toolchain.tomlnow pins to a specificX.Y.Zrelease with a trailing rustccommit-SHA comment. Rustup verifies component SHA256s from the distribution manifest, so the pin is effectively a
SHA pin (the manifest is the toolchain's lockfile). Both local and CI read the same file and install identical
bits. Motivated by a CI-only clippy failure during this PR's own review: local clippy 1.94 passed a lint that CI
clippy 1.95 rejected.
Convention enforcement was identified during the PR #15 code review.
The 3 new Python checks were fixed in that PR, but the 16 existing Rust checks still used the old pattern. The
toolchain pin was added mid-review after the clippy divergence exposed that floating
channel = "stable"leaveslocal and CI on different rustc versions.
Changelog
Type of Change
refactor: Code refactoring (no functional changes)chore: Maintenance tasks (supply-chain toolchain pin)docs: Documentation update (CLAUDE.md conventions + toolchain policy)test: Adding or updating tests (convention enforcement test)Related Issues/Stories
dot-githubtodo ci: bootstrap repo with workflows, rulesets, and project config #4: determine the automated bump workflow forrust-toolchain.tomlacross repos(central reusable workflow vs. local script vs. hybrid)
Testing
Test Summary:
convention_check_x_returns_check_status_not_check_result)-Dwarningson rustc 1.94.1 (pinned)Files Modified
Modified:
CLAUDE.md: added Source Check Convention section (Tier 1) and Toolchain Pin section documenting the 7-dayquarantine policy
rust-toolchain.toml: pinnedchannel = "1.94.1"with trailing comment naming the rustc commit SHA and releasedate; bumped from floating
channel = "stable"scripts/hooks/pre-push: removedrustup update stablestep; pin + rustup's manifest verification now handletoolchain integrity
src/checks/source/rust/:check_x()returnsCheckStatus,run()usesself.id()/self.group()/self.layer()instead of duplicated string/enum literalssrc/checks/source/rust/no_pager.rs: collapsed nestedifinside amatcharm into a match guard (fixes clippycollapsible_matchlint introduced in clippy 1.95)tests/integration.rs: addedconvention_check_x_returns_check_status_not_check_resultenforcement testKey Details
Tier 1 (Document): CLAUDE.md now codifies the source check structure. Covers the
Checktrait impl shape, thecheck_x() → CheckStatusseparation, and the convention thatrun()is the soleCheckResultconstructor. Also addsa new Toolchain Pin section explaining the supply-chain pin policy.
Tier 2 (Refactor): All 16 Rust source checks aligned to the convention. Net -132 lines by removing duplicated
CheckResultconstruction (previously theid/label/group/layerfields were hardcoded in bothrun()and every
check_x()helper).Tier 3 (Enforce): Integration test walks
src/checks/source/withstd::fs(no shell dependencies), finds everyfn check_signature (any visibility, single-line or multi-line), and fails if any returnCheckResultinstead ofCheckStatus. UsesCARGO_MANIFEST_DIRfor a stable absolute path.Toolchain pin format:
channel = "1.94.1" # rustc e408947bfd200af42db322daf0fadfe7e26d3bd1, released 2026-03-25.Comment mirrors the GitHub Actions SHA-pin pattern (
action@<sha> # vN.N.N). Policy: bump only via reviewed PR afterthe new stable has aged ≥7 days (supply-chain quarantine consistent with
UV_EXCLUDE_NEWER/ bunminimumReleaseAge/npm_config_min_release_agein dotfiles).Benefits
fn id())posture
Breaking Changes
Deployment Notes
Checklist