Skip to content

Latest commit

 

History

History
407 lines (329 loc) · 18.5 KB

File metadata and controls

407 lines (329 loc) · 18.5 KB

agnix Technical Reference

Linter for agent configs. 443 rules across 40 categories.

What agnix Validates

Type Files Rules
Skills SKILL.md 34
Hooks settings.json 27
Memory (Claude Code) CLAUDE.md, CLAUDE.local.md, .claude/rules/*.md 13
Instructions (Cross-Tool) AGENTS.md, AGENTS.local.md, AGENTS.override.md 6
Agents agents/*.md 18
Plugins plugin.json 15
Claude Output Styles .claude/output-styles/*.md 6
Claude Settings .claude/settings.json 24
Prompt Engineering CLAUDE.md, AGENTS.md 6
Cross-Platform AGENTS.md 10
MCP tool definitions 26
XML all .md files 3
References @imports 4
GitHub Copilot .github/copilot-instructions.md, .github/instructions/.instructions.md, .github/agents/.agent.md, .github/prompts/*.prompt.md, .github/hooks/hooks.json, .github/workflows/copilot-setup-steps.yml 25
Cursor Project Rules .cursor/rules/.mdc, .cursorrules, .cursor/hooks.json, .cursor/agents/**/.md, .cursor/environment.json 20
Cline .clinerules, .clinerules/.md, .clinerules/.txt 7
OpenCode opencode.json, opencode.jsonc 47
Gemini Agents .gemini/agents/*.json 1
Gemini CLI GEMINI.md, GEMINI.local.md, .gemini/settings.json (hooks), gemini-extension.json (extensions), .geminiignore 10
Codex CLI .codex/config.toml/.json/.yaml 65
Version Awareness .agnix.toml 1
Cursor Skills .cursor/skills/*/SKILL.md 1
Cline Skills .cline/skills/*/SKILL.md 3
Copilot Skills .github/skills/*/SKILL.md 1
Codex Skills .agents/skills/*/SKILL.md 1
OpenCode Skills .opencode/skills/*/SKILL.md 1
Windsurf .windsurf/rules/.md, .windsurf/workflows/.md, .windsurfrules 4
Windsurf Skills .windsurf/skills/*/SKILL.md 1
Kiro Steering .kiro/steering/*.md 14
Kiro Skills .kiro/skills/*/SKILL.md 1
Kiro Agents .kiro/agents/**/*.{json,md} 14
Kiro Hooks .kiro/hooks/*.kiro.hook 10
Kiro MCP .kiro/settings/mcp.json 6
Kiro Powers .kiro/powers/*/POWER.md 8
Kiro Settings .kiro/settings/*.json 3
Amp Skills .agents/skills/*/SKILL.md 1
Amp Checks .agents/checks/.md, .amp/settings.json 4
Roo Code Skills .roo/skills/*/SKILL.md 1
Roo Code .roo/rules/*.md, .roomodes, .roorules, .roo/mcp.json, .rooignore 6

Architecture

agnix/
├── crates/
│   ├── agnix-rules/    # Rule metadata generated from rules.json
│   ├── agnix-core/     # Validation library
│   │   ├── parsers/    # YAML, JSON, Markdown
│   │   ├── schemas/    # Type definitions
│   │   └── rules/      # Validators
│   ├── agnix-cli/      # CLI binary
│   ├── agnix-lsp/      # LSP server
│   ├── agnix-mcp/      # MCP server
│   └── agnix-wasm/     # WebAssembly bindings
├── editors/            # Neovim, VS Code, JetBrains, Zed integrations
├── knowledge-base/     # 443 rules documented

├── scripts/            # Build/dev automation scripts
├── website/            # Docusaurus documentation website
└── tests/fixtures/     # Test cases

Validation Pipeline

The validation process follows these steps:

  1. Directory Walking (sequential) - Uses ignore crate to traverse directories
  2. File Collection - Gathers all relevant file paths with exclusion filtering
  3. File Type Resolution - resolve_file_type() applies [files] config overrides, then falls through to detect_file_type()
  4. CRLF Normalization - normalize_line_endings() converts CRLF and lone-CR to LF before validators run (zero-allocation fast path for LF-only files)
  5. Parallel Validation - Processes files in parallel using rayon
  6. Result Sorting - Deterministic ordering by severity (errors first) then file path

This architecture ensures fast validation on large projects while maintaining consistent, reproducible output.

Project-Level Validation

Cross-file validation rules (AGM-006, XP-004/005/006, VER-001) require analysis across multiple files to detect:

  • AGM-006: Nested AGENTS.md hierarchies across different directories
  • XP-004 to XP-006: Conflicting build commands, tool constraints, and instruction layers across CLAUDE.md, AGENTS.md, Cursor rules, and Copilot files
  • VER-001: Missing or incomplete version pinning in .agnix.toml

Project-level validation runs:

  • On workspace open (LSP initialized event)
  • After any configuration change (LSP didChangeConfiguration)
  • After file save events (LSP didSave)
  • Explicitly via agnix.validateProjectRules LSP command (VS Code Validate Workspace)

Results are published to all affected files as diagnostics, ensuring users see context-aware feedback for cross-file issues.

File Type Resolution

resolve_file_type(path, config) determines which validators apply to a file:

  1. Check [files].exclude patterns - if matched, return Unknown (skip)
  2. Check [files].include_as_memory patterns - if matched, return ClaudeMd
  3. Check [files].include_as_generic patterns - if matched, return GenericMarkdown
  4. Fall through to detect_file_type(path) (built-in path-based detection)

Priority: exclude > include_as_memory > include_as_generic > built-in detection.

Patterns use glob syntax, matched against paths relative to the project root. Backslashes are normalized to forward slashes for cross-platform compatibility. Invalid patterns are not silently discarded - validate_project() surfaces them as Warning diagnostics (rule config::glob) so consumers receive actionable feedback rather than seeing stderr output.

Security

agnix implements defense-in-depth security measures:

Feature Implementation Default
Symlink rejection file_utils::safe_read_file() Always on
File size limits DEFAULT_MAX_FILE_SIZE = 1 MiB Always on
File count limits max_files_to_validate 10,000
ReDoS protection MAX_REGEX_INPUT_SIZE = 64 KB Always on
Path traversal detection normalize_join() in imports validator Always on

See knowledge-base/SECURITY-MODEL.md for complete threat model.

Rule Reference

All rules in knowledge-base/VALIDATION-RULES.md

Rule ID Format: [CATEGORY]-[NUMBER]

  • AS-nnn: Agent Skills (agentskills.io)
  • CC-SK-nnn: Claude Code Skills
  • CC-HK-nnn: Claude Code Hooks
  • CC-MEM-nnn: Claude Code Memory
  • AGM-nnn: AGENTS.md (cross-tool instructions)
  • CC-AG-nnn: Claude Code Agents
  • COP-nnn: GitHub Copilot Instructions
  • CLN-nnn: Cline Rules
  • OC-nnn: OpenCode configuration
  • CDX-nnn: Codex CLI configuration
  • CC-PL-nnn: Claude Code Plugins
  • MCP-nnn: MCP protocol
  • XML-nnn: XML validation
  • REF-nnn: @import/reference validation
  • PE-nnn: Prompt engineering
  • XP-nnn: Cross-platform compatibility
  • VER-nnn: Version awareness

Key Rules

ID Severity Description
AS-001 ERROR YAML frontmatter required
AS-004 ERROR Name must be kebab-case
AS-010 WARN Missing trigger phrase
CC-SK-001 ERROR Invalid model value
CC-SK-002 ERROR Invalid context value
CC-SK-003 ERROR Context 'fork' requires agent field
CC-SK-004 ERROR Agent field requires context: fork
CC-SK-005 ERROR Invalid agent type
CC-SK-006 ERROR Dangerous skill without safety flag
CC-SK-007 WARN Unrestricted Bash access
CC-SK-008 ERROR Unknown tool name
CC-SK-009 WARN Too many dynamic injections
CC-HK-001 ERROR Invalid hook event
CC-HK-006 ERROR Missing command field
CC-HK-007 ERROR Missing prompt field
CC-HK-008 ERROR Script file not found
CC-HK-009 WARN Dangerous command pattern
CC-MEM-004 WARN Invalid command reference
CC-MEM-005 WARN Generic instruction detected
AGM-003 WARN Character limit exceeded (12000 chars)
AGM-005 WARN Platform features without guard
PE-001 WARN Critical content in middle
PE-002 WARN Chain-of-thought on simple task
CC-AG-001 ERROR Missing agent name field
CC-AG-002 ERROR Missing agent description field
CC-AG-003 ERROR Invalid model value
CC-AG-004 ERROR Invalid permission mode
CC-AG-005 ERROR Referenced skill not found
CC-AG-006 ERROR Tool/disallowed conflict
CC-PL-001 ERROR Plugin manifest not in .claude-plugin/
CC-PL-002 ERROR Components inside .claude-plugin/
CC-PL-003 ERROR Invalid semver format
CC-PL-004 ERROR/WARN Missing required/recommended plugin field
CC-PL-005 ERROR Empty plugin name
XML-001 ERROR Unclosed XML tag

CLI

agnix .                    # Validate directory
agnix --strict .           # Warnings = errors
agnix --target claude-code # Claude-specific rules
agnix --fix .              # Apply HIGH and MEDIUM confidence fixes
agnix --dry-run .          # Preview fixes without modifying files (respects fix mode flags)
agnix --fix-safe .         # Only apply HIGH confidence fixes
agnix --fix-unsafe .       # Apply all fixes, including LOW confidence
agnix --show-fixes .       # Show inline proposed fix diffs in text output
agnix --format json .      # JSON output for programmatic consumption
agnix --format sarif .     # SARIF 2.1.0 output for CI/CD
agnix --format github .    # GitHub Actions annotations
agnix explain MCP-018      # Explain a rule from rules.json
agnix --locale es .        # Spanish output
agnix --list-locales       # Show available locales

Config (.agnix.toml)

extend = []          # Optional base config paths; TOML files may use a string or array
severity = "Warning"
target = "Generic"  # Options: Generic, ClaudeCode, Cursor, Codex
locale = "en"       # Options: en, es, zh-CN
tools = ["claude-code", "cursor"]  # Preferred over target

[rules]
# Category toggles - enable/disable entire rule categories
skills = true       # AS-*, CC-SK-* rules
hooks = true        # CC-HK-* rules
agents = true       # CC-AG-* rules
copilot = true      # COP-* rules
cursor = true       # CUR-* rules
cline = true        # CLN-* rules
opencode = true     # OC-* rules
memory = true       # CC-MEM-* rules
plugins = true      # CC-PL-* rules
mcp = true          # MCP-* rules
prompt_engineering = true  # PE-* rules
xml = true          # XML-* rules
imports = true      # REF-*, imports::* rules
cross_platform = true  # XP-* rules
agents_md = true       # AGM-* rules

# Legacy flags (still supported)
generic_instructions = true
frontmatter_validation = true
xml_balance = true
import_references = true

# Disable specific rules by ID
disabled_rules = []  # e.g., ["CC-AG-001", "AS-005"]

[rules.severity]
# Per-rule severity overrides, e.g. MCP-008 = "Error"

[rules]
# Disable entire validators by name
disabled_validators = []  # e.g., ["XmlValidator", "ImportsValidator"]

exclude = ["node_modules/**", ".git/**", "target/**"]

# Per-file rule overrides (array of tables).
# Each block disables `disabled_rules` for files matching any of `paths`.
# Multiple blocks stack (set union); ordering does not matter.
[[overrides]]
paths = ["CLAUDE.md", "AGENTS.md"]
disabled_rules = ["CC-MEM-005"]

Per-File Rule Overrides

[[overrides]] is an array of tables. Each entry has two fields:

Field Type Description
paths [String] Glob patterns matched against project-relative paths (forward-slash separators; same matcher as [files].exclude, with require_literal_separator = true).
disabled_rules [String] Rule IDs to disable for matching files.

For each file linted, the effective disabled-rule set is the union of [rules].disabled_rules and every [[overrides]].disabled_rules whose paths matched the file. The override mechanism is purely additive: it cannot re-enable a globally disabled rule or override a disabled category ([rules].skills = false, etc.).

Files excluded entirely via [files].exclude are skipped before any rule runs, so [[overrides]] on excluded paths is moot. A block with paths = [] is a no-op (no file is ever matched). When .agnix.toml is loaded without a project root (single-file mode), paths patterns are matched against the file name only.

extend loads one or more parent config files relative to the current config file before applying the child file. Tables merge recursively; child scalar values and arrays replace parent values.

Inline suppressions are supported for local exceptions. The configuration guide documents the exact same-line and next-line markers.

Config Validation

agnix validates .agnix.toml files semantically before running validation:

  • Rule ID validation: disabled_rules (in [rules] and [[overrides]]) and [rules.severity] keys must match known patterns (AS-, CC-SK-, CC-HK-, CC-AG-, CC-MEM-, CC-PL-, XML-, MCP-, REF-, XP-, AGM-, COP-, CUR-, CLN-, OC-, CDX-, PE-, VER-, imports::)
  • Removed rule redirects: removed rule IDs such as AS-007, AS-010, and AS-014 warn with replacement guidance from knowledge-base/removed-rules.json
  • Tool validation: tools array must contain valid tool names (claude-code, cursor, codex, copilot, github-copilot, cline, opencode, generic)
  • Glob validation: [files].* and [[overrides]].paths patterns must be syntactically valid glob expressions. Invalid patterns surface as warnings (CLI flow drops them at load and continues; programmatic LintConfigBuilder::build() promotes them to errors).
  • Override path safety: [[overrides]].paths entries must be project-relative. Absolute paths (/...) and traversal segments (..) surface as warnings via the CLI (the override becomes a silent no-op because the pattern can never match a project-relative path); programmatic LintConfigBuilder::build() and build_lenient() both reject these as hard errors at build time.
  • Deprecation warnings: mcp_protocol_version is deprecated (use spec_revisions.mcp_protocol)

Warnings are displayed before validation output with suggestions for fixes.

Target Tool Filtering

When target is set to a specific tool, only relevant rules run:

  • ClaudeCode or Generic: All rules enabled
  • Cursor or Codex: CC-* rules disabled (Claude Code specific)

Rule Categories

Category Config Key Rules Description
Skills skills AS-, CC-SK- Agent skill validation
Hooks hooks CC-HK-* Hook configuration validation
Agents agents CC-AG-* Subagent validation
GitHub Copilot copilot COP-* Copilot instruction validation
Memory memory CC-MEM-* Memory/CLAUDE.md validation
Plugins plugins CC-PL-* Plugin validation
MCP mcp MCP-* MCP tool validation
Prompt Engineering prompt_engineering PE-* Prompt engineering best practices
XML xml XML-* XML tag balance
Imports imports REF-* Import reference validation
Cross-Platform cross_platform XP-* Cross-platform consistency checks
AGENTS.md agents_md AGM-* AGENTS.md-specific validation
Cursor cursor CUR-* Cursor project rule validation
Cline cline CLN-* Cline rules validation
OpenCode opencode OC-* OpenCode configuration validation
Codex CLI codex CDX-* Codex CLI configuration validation

Version awareness (VER-*) is always active and controlled through tool_versions / spec_revisions pins.

Performance Characteristics

Performance Targets

Metric Target Typical
Single file validation < 100ms < 10ms
100-file project < 500ms ~200ms
1000-file project < 5s ~2s
Peak memory < 100MB ~50MB
Binary size < 10MB ~5MB

Architecture Optimizations

  • Parallel validation: Uses rayon par_bridge() for file processing across all CPU cores
  • Registry caching: ValidatorRegistry is constructed once and shared (7x speedup vs per-file)
  • Import cache: Arc<RwLock<HashMap>> shared across files reduces redundant @import parsing
  • Static regex patterns: static_regex! macro (in regex_util.rs) wraps OnceLock for one-time initialization with descriptive panic messages
  • Directory walking: Sequential via ignore crate (required for .gitignore compatibility)
  • Deterministic output: Results sorted by severity then path for reproducible runs

Release Build Optimizations

[profile.release]
lto = "fat"          # Link-time optimization
codegen-units = 1    # Single codegen unit for better optimization
strip = true         # Strip symbols from binary
opt-level = 3        # Maximum optimization
panic = "abort"      # Smaller binary, no unwinding

Measurement Methodology

agnix uses a dual-methodology approach for performance measurement:

CI (blocking on regression): iai-callgrind

  • Measures CPU instruction counts (100% deterministic)
  • Immune to system load, CPU frequency scaling, background processes
  • Results are reproducible across CI runs with zero variance
  • Blocks merge on regression above configurable threshold

Development (fast feedback): Criterion

  • Wall-clock timing for intuitive performance understanding
  • Statistical sampling for reliable measurements
  • HTML reports with historical comparison

Running Benchmarks

# Fast feedback during development (wall-clock)
./scripts/bench.sh criterion

# Pre-PR validation (instruction counts, matches CI)
./scripts/bench.sh iai

# Check binary size breakdown
./scripts/bench.sh bloat

# Run all benchmarks
./scripts/bench.sh all

Interpreting iai-callgrind Results

iai-callgrind reports several metrics:

Metric Description What It Tells You
Instructions CPU instructions executed Primary performance metric
L1 Hits/Misses Level 1 cache performance Memory access efficiency
L2 Hits/Misses Level 2 cache performance Working set size
RAM Hits Main memory accesses Cache effectiveness
Estimated Cycles Weighted cycle estimate Overall CPU cost

Instruction counts directly correlate with wall-clock time but without noise from:

  • Background processes
  • CPU frequency scaling
  • VM/container overhead
  • Disk I/O variance

Platform Considerations

  • Linux: Full support for both iai-callgrind and Criterion
  • macOS x86: Full support for both iai-callgrind and Criterion
  • macOS ARM: Valgrind support is experimental; use Criterion for local development
  • Windows: No Valgrind support; use Criterion only (CI runs iai on Linux)