Skip to content

ci: bootstrap repo with workflows, rulesets, and project config#4

Closed
brettdavies wants to merge 3 commits intomainfrom
release/ci-setup
Closed

ci: bootstrap repo with workflows, rulesets, and project config#4
brettdavies wants to merge 3 commits intomainfrom
release/ci-setup

Conversation

@brettdavies
Copy link
Copy Markdown
Owner

Summary

Bootstrap main with the full project foundation: source code, CI workflows, rulesets, and repo configuration. This enables CI to run on subsequent PRs (including PR #2).

Changelog

Added

  • Add CI, release, finalize-release, guard-docs, and guard-provenance workflows
  • Add Protect main and Protect dev branch rulesets
  • Add initial agentnative source (Check trait, 11 checks, BinaryRunner, Project, CLI)

Type of Change

  • ci: CI/CD configuration changes
  • feat: New feature (initial project bootstrap)

Testing

Post-Deploy Monitoring & Validation

No additional operational monitoring required — project bootstrap.


Compound Engineered with Claude Opus 4.6 (1M context) via ce-work

brettdavies and others added 3 commits April 1, 2026 21:35
…cks (#1)

## Summary

Transform agentnative from an ast-grep spike into a full CLI linter.
Implements the core abstractions (Check trait,
Project struct with lazy file cache), project auto-detection for
Rust/Python/Go/Node, 8 behavioral checks via
BinaryRunner, 3 refactored source checks, and the clap CLI with
JSON/text scorecard output. Includes pre-push CI mirror
hook and cross-platform Windows support.

## Changelog

### Added

- Add `check` subcommand with `--binary`, `--source`, `--principle`,
`--output json`, `--quiet` flags
- Add 8 behavioral checks: help, version, json-output, bad-args, quiet,
sigpipe, non-interactive, no-color
- Add 3 source checks refactored from spike: unwrap detection, NO_COLOR
handling, global flag enforcement
- Add auto-detection for Rust, Python, Go, and Node projects with binary
discovery
- Add JSON scorecard output with `CheckResultView` serialization
- Add shell completions via `completions` subcommand
- Add exit codes: 0 (all pass), 1 (warnings), 2 (failures/errors)
- Add pre-push hook (`scripts/hooks/pre-push`) mirroring CI locally via
`core.hooksPath`

### Fixed

- Fix SIGPIPE handling so piped output (e.g., `agentnative check . |
head`) works correctly
- Fix recursive fork bomb when agentnative checks itself via
MAKELEVEL-pattern env var guard

## Type of Change

- [x] `feat`: New feature (non-breaking change which adds functionality)
- [x] `fix`: Bug fix (non-breaking change which fixes an issue)
- [x] `refactor`: Code refactoring (no functional changes)
- [x] `build`: Build system changes

## Related Issues/Stories

- Architecture:
`~/.gstack/projects/brettdavies-agentnative/brett-main-design-20260327-214808.md`
- Plan:
`docs/plans/2026-03-31-001-feat-check-trait-project-behavioral-plan.md`
- Solution:
`docs/solutions/logic-errors/cli-linter-fork-bomb-recursive-self-invocation-20260401.md`
- Solution:
`docs/solutions/best-practices/tracked-git-hooks-core-hookspath-20260401.md`

## Testing

- [x] Unit tests added/updated
- [ ] Integration tests added/updated
- [x] Manual testing completed
- [x] All tests passing

**Test Summary:**

- Unit tests: 67 passing, 1 ignored (slow timeout)
- Manual: dogfood (`agentnative check .`), external binary (`agentnative
check /bin/cat`)
- Code review: 9-persona review completed, safe_auto fixes applied

## Files Modified

**Created:**
- `src/check.rs` — Check trait (id, applicable, run)
- `src/cli.rs` — clap derive structs (check, completions subcommands)
- `src/error.rs` — AppError enum with thiserror
- `src/project.rs` — Project struct, language detection, binary
discovery, lazy file cache
- `src/runner.rs` — BinaryRunner with timeout, caching, ETXTBSY retry,
partial read
- `src/scorecard.rs` — CheckResultView, text/JSON output formatting,
exit code logic
- `src/checks/behavioral/*.rs` — 8 behavioral checks
- `src/checks/source/rust/*.rs` — 3 refactored source checks (unwrap,
no_color, global_flags)
- `src/checks/source/python/mod.rs` — stub for fast-follow
- `scripts/hooks/pre-push` — local CI mirror (fmt, clippy, test, deny,
Windows compat)
-
`docs/plans/2026-03-31-001-feat-check-trait-project-behavioral-plan.md`
- `CLAUDE.md` — project conventions, CI instructions

**Modified:**
- `src/main.rs` — rewritten: clap CLI, orchestration, SIGPIPE fix, exit
codes
- `src/source.rs` — added public `has_pattern()`, removed unused
`scan_rust_files`/`walkdir`
- `src/types.rs` — `#[allow(dead_code)]` on future-reserved variants
- `Cargo.toml` — added `toml` dependency, `default-run`
- `deny.toml` — configured license allowlist

## Key Features

- Two-layer check system: behavioral (runs compiled binaries) + source
(ast-grep patterns)
- Auto-detection mode matrix: binary-only, source-only, or both based on
project + flags
- BinaryRunner with reader-thread timeout via Arc<Mutex<Child>> +
Condvar
- Result caching by (args, env) to avoid redundant binary invocations
- MAKELEVEL-pattern recursion guard scoped to NonInteractiveCheck
- `run_partial()` for SIGPIPE testing without full output capture
- Tracked pre-push hook via `core.hooksPath` — no symlinks, no copies

## 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] Tests added/updated and passing
- [x] No new warnings or errors introduced
- [x] Changes are backward compatible (or breaking changes documented)

## Post-Deploy Monitoring & Validation

No additional operational monitoring required — CLI tool with no runtime
deployment.

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary

Add missing CI infrastructure for the dev→main workflow pattern.

## Changelog

### Added

- Add guard-main-provenance workflow to verify commits in PRs to main
came from squash-merged dev PRs
- Add Protect dev branch ruleset (deletion, force-push, signed commits)
- Add guard-docs and guard-provenance required status checks to Protect
main ruleset

## Type of Change

- [x] `ci`: CI/CD configuration changes

## Testing

- [x] Workflow files match templates from github-repo-setup and
rust-tool-release skills
- [x] Rulesets applied via GitHub API and stored in `.github/rulesets/`
for version control

## Post-Deploy Monitoring & Validation

No additional operational monitoring required — CI workflow
configuration only.

---

> **Compound Engineered** with Claude Opus 4.6 (1M context) via ce-work

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Strip docs/plans/ and docs/solutions symlink to pass guard-main-docs
workflow. These remain on dev.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@brettdavies brettdavies closed this Apr 1, 2026
@brettdavies brettdavies deleted the release/ci-setup branch April 1, 2026 21:47
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 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
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.

1 participant