# src
Source for the `normalize-native-rules` crate. `lib.rs` re-exports the `build_*_report` functions, domain report types, `NATIVE_RULES` descriptor array (each with `default_enabled`), and the `FileRule` trait with `run_file_rule` framework function. `boundary_violations.rs` implements the `boundary-violations` native rule: reads `BoundaryViolationsConfig.boundaries` (list of `"A/ cannot import B/"` strings) from `[rules.rule."boundary-violations"]` config, opens the structural index, and flags any resolved import edge where the importer path matches the `from_glob` and the imported path matches the `to_glob`; default disabled, requires `normalize structure rebuild`. `high_fan_out.rs` implements the `high-fan-out` native rule: queries the structural index for per-file distinct resolved import target counts (fan-out) and flags files that import from more than `threshold` (default 20) distinct modules; default disabled, requires index. `high_fan_in.rs` implements the `high-fan-in` native rule: queries the structural index for per-file distinct resolved importer counts (fan-in) and flags files that are imported by more than `threshold` (default 20) distinct files; default disabled, requires index. Both coupling rules are tagged `["architecture", "coupling"]` and read `threshold` via `rule_config::<ThresholdConfig>()`. `walk.rs` provides `gitignore_walk()` and `filtered_gitignore_walk()` (applies `PathFilter` during walk) shared by all checks; both accept a `&WalkConfig` to control which ignore files are respected and which directories are excluded (configurable via `[walk]` in `.normalize/config.toml`). Individual check modules: `check_refs.rs`, `stale_summary.rs`, `stale_docs.rs`, `check_examples.rs` — each defines a domain `*Report` struct implementing `OutputFormatter` and `From<*Report> for DiagnosticsReport`. `ratchet.rs` and `budget.rs` follow the same pattern with `RatchetRulesReport` and `BudgetRulesReport` newtypes wrapping the `DiagnosticsReport` produced by their respective service crates. `stale_summary.rs` exposes two separate report builders: `build_missing_summary_report` (fires when a directory has no committed doc file — `missing-summary` rule) and `build_stale_summary_report` (fires when a doc file exists but hasn't been updated recently — `stale-summary` rule). Both accept a `filenames` slice (from `RuleOverride::filenames`) for alternate doc filenames and a `paths` slice (from `RuleOverride::paths`) to scope the rule to specific directory globs; empty slices apply the default behavior (check everywhere for `SUMMARY.md`). `stale_summary.rs` uses `gix` (pure-Rust) exclusively — no git binary required. Git helpers (`git_batch_commit_stats`, `git_incremental_commit_stats`, `git_has_uncommitted_content_changes`, `git_summary_has_uncommitted_changes`) use gix commit-walk diffs and the gix status API. `git_incremental_commit_stats` walks only the commits between the cached HEAD and the current HEAD, updating cache entries in-place to avoid re-walking all history on every pre-commit run. `stale_doc.rs` implements the `stale-doc` native rule (Pillar 8 step 5): queries `co_change_edges` from the normalize index to find code files that co-change with each doc file, then compares last-commit timestamps via gix to flag doc files whose co-changed code partners were updated more recently. Configurable via `StaleDocConfig` (min_co_changes, min_lag_days, doc_patterns). Default disabled; requires `normalize structure rebuild`. `cache.rs` provides `FindingsCache` (SQLite-backed, stored at `.normalize/findings-cache.sqlite`), `file_mtime_nanos()`, the `FileRule` trait, and `run_file_rule()` framework function. `FileRule` abstracts file-based native rules: implementors define `check_file()` (per-file analysis) and `to_diagnostics()` (finding-to-report conversion); the framework handles file walking, SQLite caching (keyed by path/mtime/config_hash/engine), and parallel execution via rayon. Advisory threshold rules: `long_file.rs` (`LongFileRule`, respects `[rules.rule."long-file"] allow` in config.toml), `high_complexity.rs` (`HighComplexityRule`, cyclomatic complexity via tree-sitter), `long_function.rs` (`LongFunctionRule`, function line span via tree-sitter tags) — all implement `FileRule` and default disabled. All three accept an optional `files: Option<&[PathBuf]>` parameter via their `build_*_report` wrapper functions to bypass the file walker when an explicit file list is provided (e.g. from `--files` flag). Thresholds and allow patterns are configurable via `[rules.rule."<id>"] threshold = N` and `allow = [...]` in `.normalize/config.toml`; the service layer reads these via `RuleOverride::rule_config::<ThresholdConfig>()` and `RuleOverride::allow` and passes them to the rule constructor. Each rule module includes tests covering default and custom threshold behaviour. `stale_doc.rs` also accepts `files: Option<&[PathBuf]>` for `--files` flag support. `dead_parameter.rs` (`DeadParameterRule`) uses `normalize-scope`'s `ScopeEngine::find_unused_parameters()` to flag function parameters never referenced in their function body; requires `@local.definition.parameter` captures in the language's `locals.scm`; default disabled.