Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .cf-studio/config/rules/infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Use this when changing build tooling, CI, linting, releases, or dependency polic
## Tooling
- Use `Makefile` targets as the main local automation surface. Evidence: `Makefile:120-173`, `Makefile:218-320`
- Preserve fast PR Clippy and deeper validation split. Evidence: `Makefile:224-246`
- Keep custom Dylint rules aligned with architecture categories. Evidence: `tools/dylint_lints/README.md:16-70`
- Keep custom architecture lints aligned with architecture categories. Run via `cargo gears lint` (lints live in the `cargo-gears` CLI tool).

## CI and Releases
- Preserve cross-OS test matrix and DB integration jobs. Evidence: `.github/workflows/ci.yml:85-220`
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/gear-creator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Create files in this order (each layer builds on the previous):

1. `cargo build -p <gear-crate>` — must compile
2. `cargo clippy -p <gear-crate>` — no warnings
3. `make dylint` — architecture lints pass
3. `cargo gears lint` — architecture lints pass
4. `cargo test -p <gear-crate>` — tests pass

## Workflow: Edit an existing gear
Expand Down
44 changes: 13 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -392,45 +392,30 @@ jobs:
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }} # Uncomment if required for private repos

dylint:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm, I can't see how we replacing it, it's being just removed.
Where is the new 'cargo gears lint' command in CI?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maurolacy let's take the approach of installing the cargo-gears here and use the lint functionality.
Create a basic manifest target to lint all gears from here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right; will do.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

name: Dylint Tests
lint:
name: Architecture Lints (cargo gears lint)
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: nightly-2026-04-16
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Install Rust nightly toolchain
uses: dtolnay/rust-toolchain@5b842231ba77f5c045dba54ac5560fed2db780e2 # nightly
with:
toolchain: ${{ env.RUSTUP_TOOLCHAIN }}
components: llvm-tools-preview,rustc-dev

- name: Set Rust nightly for Dylint temp builds
run: rustup override set ${{ env.RUSTUP_TOOLCHAIN }} --path /tmp

- name: Install nextest
uses: taiki-e/install-action@6ef672efc2b5aabc787a9e94baf4989aa02a97df # v2.70.3
with:
tool: nextest

- name: Install cargo-dylint and dylint-link from source
run: cargo install --locked cargo-dylint dylint-link
persist-credentials: false

- name: Install protoc
uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Run dylint tests
working-directory: tools/dylint_lints
env:
RUSTFLAGS: "-C debuginfo=0"
run: cargo test
- name: Install Rust stable toolchain
uses: dtolnay/rust-toolchain@5b842231ba77f5c045dba54ac5560fed2db780e2 # stable
with:
toolchain: stable

- name: Run dylint on all crates
run: make dylint
- name: Install cargo-gears
run: cargo install --locked cargo-gears

- name: Run architecture lints
run: cargo gears lint --dylint

shear:
name: Unused Deps (cargo-shear)
Expand All @@ -454,13 +439,10 @@ jobs:
toolchain: ${{ env.RUSTUP_TOOLCHAIN }}
components: llvm-tools-preview,rustc-dev

- name: Install dylint-link from source
run: cargo install --locked dylint-link

- name: Install cargo-shear
uses: taiki-e/install-action@6ef672efc2b5aabc787a9e94baf4989aa02a97df # v2.70.3
with:
tool: cargo-shear@1.13.1

- name: cargo shear (workspace root + tools/dylint_lints)
- name: cargo shear (workspace root)
run: make shear
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ members = [
exclude = ["tools/fuzz"]
resolver = "3"

# Note: dylint_lints is a separate workspace for custom linters
# See tools/dylint_lints/README.md for usage instructions

[workspace.lints.rust]
deprecated = "warn"
non_ascii_idents = "forbid"
Expand Down
25 changes: 25 additions & 0 deletions Gears.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Gears manifest. Used by `cargo gears` CLI for linting and other tasks.
# See https://github.com/constructorfabric/cargo-gears for documentation.

[apps.gears-rust.dev]
config = "lint.yml"
gears = []

[apps.gears-rust.dev.lint]
fmt = false # already handled by `make fmt`
clippy = false # already handled by `make clippy`

[apps.gears-rust.dev.lint.dylint]
enabled = true
# Remove entries as violations are fixed or cargo-gears-lints is updated.
skip = [
# New lint not yet addressed in this repo.
"de0504_client_versioning",
# Path exclusion logic in cargo-gears-lints uses "modules/" prefix but this
# repo uses "gears/". Skipped until cargo-gears-lints adds "gears/" support.
"de1101_tests_in_separate_files",
# Scope broadened from /contract/ to /domain/ in cargo-gears-lints.
# Pre-existing code in domain/ layers needs migration.
"de0101_no_serde_in_contract",
"de0102_no_toschema_in_contract",
]
46 changes: 8 additions & 38 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ setup: .setup-stamp
cargo install lychee
cargo install cargo-geiger
cargo install cargo-deny
cargo install cargo-dylint
cargo install dylint-link
cargo install cargo-gears
cargo install cargo-fuzz
cargo install cargo-hack
cargo install gts-validator
Expand Down Expand Up @@ -169,7 +168,6 @@ setup: .setup-stamp
fmt:
$(call check_rustup_component,rustfmt)
cargo fmt --all --check
cargo fmt --all --check --manifest-path tools/dylint_lints/Cargo.toml

# -------- Gear naming validation --------

Expand Down Expand Up @@ -213,16 +211,8 @@ validate-gear-names:
# | | - Missing documentation warnings |
# | | - Ensures clean compilation across all targets and features |
# +-------------+----------------------------------------------------------------------+
# | dylint | - Project-specific architectural conventions (custom lints) |
# | | - DTO declaration and placement (only in api/rest folders) |
# | | - DTO isolation (no references from domain/contract layers) |
# | | - API endpoint versioning requirements (e.g., /users/v1/users) |
# | | - Contract layer purity (no serde, HTTP types, or ToSchema) |
# | | - Layer separation and dependency rules enforcement |
# | | - Use 'make dylint-list' to see all available custom lints |
# +-------------+----------------------------------------------------------------------+

.PHONY: clippy clippy-deep lychee docs-preview kani geiger safety lint dylint dylint-list dylint-test shear gts-docs cfs-ensure cfs-repair cfs-validate cfs-validate-kits cfs-validate-kit-local cfs-spec-coverage
.PHONY: clippy clippy-deep lychee docs-preview kani geiger safety lint dylint shear gts-docs cfs-ensure cfs-repair cfs-validate cfs-validate-kits cfs-validate-kit-local cfs-spec-coverage

CFS ?= cfs
CFS_PIPX_SPEC ?= git+https://github.com/constructorfabric/studio.git
Expand Down Expand Up @@ -297,7 +287,7 @@ cfs-validate-kit-local: cfs-repair
# Run markdown checks with 'lychee'
lychee:
$(call check_tool,lychee)
lychee --exclude-path 'docs/web-docs' docs examples tools/dylint_lints guidelines
lychee --exclude-path 'docs/web-docs' docs examples guidelines

# Preview the documentation website with local docs/web-docs content.
# Clones the web docs site into .web-docs-preview/ and serves it at localhost:4321.
Expand Down Expand Up @@ -335,34 +325,15 @@ gts-docs:
install-tools:
@command -v cargo-nextest >/dev/null 2>&1 || cargo install --locked cargo-nextest

## List all custom project compliance lints (see tools/dylint_lints/README.md)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, where do we replace current dylint by 'cargo gears xxx' ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maurolacy also it's a good UX improvement to have a list argument in the lint section for dylint. This way we offer a list of the available lints

dylint-list:
@cd tools/dylint_lints && \
DYLINT_LIBS=$$(find target/release -maxdepth 1 \( -name "libde*@*.so" -o -name "libde*@*.dylib" -o -name "de*@*.dll" \) -type f | sort -u); \
if [ -z "$$DYLINT_LIBS" ]; then \
echo "ERROR: No dylint libraries found. Run 'make dylint' first to build them."; \
exit 1; \
fi; \
for lib in $$DYLINT_LIBS; do \
echo "=== $$lib ==="; \
cargo dylint list --lib-path "$$lib"; \
done

## Test dylint lints on UI test cases (compile and verify violations)
dylint-test: install-tools
@cd tools/dylint_lints && cargo nextest run

# Run project compliance dylint lints on the workspace (see `make dylint-list`)
# Run architecture lints via cargo-gears (see Gears.toml for configuration).
dylint:
$(call check_tool,cargo-dylint)
$(call check_tool,dylint-link)
cargo dylint --all --workspace
$(call check_tool,cargo-gears)
cargo gears lint --dylint

# Check for unused dependencies with cargo-shear.
shear:
$(call check_tool,cargo-shear)
cargo +nightly-2026-04-16 shear --expand --deny-warnings
cd tools/dylint_lints && cargo shear --expand --deny-warnings

# Run all code safety checks
safety: clippy kani lint dylint # geiger
Expand Down Expand Up @@ -428,7 +399,6 @@ dev-fmt:
## Auto-fix clippy warnings
dev-clippy:
cargo clippy --workspace --all-targets --all-features --fix --allow-dirty
@cd tools/dylint_lints && cargo clippy --all-targets --workspace

# Auto-fix formatting and clippy warnings
dev: dev-fmt dev-clippy dev-test
Expand Down Expand Up @@ -815,14 +785,14 @@ oop-example:
cargo run --bin cf-gears-example-server --features oop-example,users-info-example,static-authn,static-authz,static-tenants,static-credstore -- --config config/quickstart.yaml run

# Run all quality checks
check: .setup-stamp fmt cfs-validate clippy lychee security dylint-test dylint gts-docs test
check: .setup-stamp fmt cfs-validate clippy lychee security dylint gts-docs test

ci_test: fmt clippy

ci_docs: lychee gts-docs

# Run CI pipeline locally, requires docker
ci: fmt clippy test-no-macros test-macros test-db deny test-users-info-pg lychee gts-docs dylint dylint-test
ci: fmt clippy test-no-macros test-macros test-db deny test-users-info-pg lychee gts-docs dylint

# Build the cf-gears-example-server release binary using a toolchain from the rust-toolchain.toml
cargo-build:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ See also:

**Engineering principles:**
- **Spec-Driven Development**: [Specification templates](docs/spec-templates/README.md) (PRD, Design, ADR, Feature) define what gets built *before* code is written. Every gear is well documented.
- **Shift Left**: Custom [dylint](tools/dylint_lints/) architectural lints enforce design rules at compile time, alongside Clippy, [tests](#testing), fuzzing, and security audits in CI
- **Shift Left**: Custom architecture lints (via `cargo gears lint`) enforce design rules at compile time, alongside Clippy, [tests](#testing), fuzzing, and security audits in CI
- **Quality First**: 90%+ test coverage target with unit, integration, E2E, performance, and security testing
- **Core in Rust**: Compile-time safety, deep static analysis including project-specific lints, so more issues are prevented before review/runtime
- **Monorepo**: All the core gears and contracts in one place for atomic refactors, consistent tooling/CI, and realistic local build + E2E testing
Expand Down Expand Up @@ -145,7 +145,7 @@ See [TOOLKIT UNIFIED SYSTEM](docs/toolkit_unified_system/README.md) and [TOOLKIT

Gears apply defense-in-depth security across the entire development lifecycle — from Rust's compile-time safety guarantees and custom architectural lints, through compile-time tenant isolation and PDP/PEP authorization enforcement, to continuous fuzzing, dependency auditing, and automated security scanning in CI.

See **[Security Overview](docs/security/SECURITY.md)** for the full breakdown, including: Secure ORM with compile-time tenant scoping, authentication/authorization architecture (NIST SP 800-162 PDP/PEP model), 90+ Clippy deny-level rules, custom dylint architectural lints, cargo-deny advisory checks, ClusterFuzzLite continuous fuzzing, CodeQL/Scorecard/Snyk/Aikido scanners, and AI-powered PR review bots.
See **[Security Overview](docs/security/SECURITY.md)** for the full breakdown, including: Secure ORM with compile-time tenant scoping, authentication/authorization architecture (NIST SP 800-162 PDP/PEP model), 90+ Clippy deny-level rules, custom architecture lints (via `cargo gears lint`), cargo-deny advisory checks, ClusterFuzzLite continuous fuzzing, CodeQL/Scorecard/Snyk/Aikido scanners, and AI-powered PR review bots.

## FIPS 140-3 support

Expand Down
2 changes: 2 additions & 0 deletions config/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Minimal config file required by the Gears manifest for linting.
server: {}
Loading
Loading