agentnative
The agent-native CLI linter. Checks whether your CLI follows the 7 agent-readiness principles.
anc dogfoods the spec it enforces — the badge above is its own live score.
Install
The crate is published as agentnative. The binary is called anc.
# Homebrew (installs anc)
# From crates.io
# Pre-built binary via cargo-binstall
# Pre-built binaries from GitHub Releases
# https://github.com/brettdavies/agentnative-cli/releases
Install the skill
anc ships a companion skill bundle (agentnative-skill) that teaches AI coding agents how to operate the linter and
where to apply the principles. Install it with one command per host:
Inspect the resolved command before running it:
# git clone --depth 1 https://github.com/brettdavies/agentnative-skill.git /home/you/.claude/skills/agent-native-cli
JSON output (mode dry-run and install, success and error) is uniform — agents can rely on the same envelope shape
across every outcome:
If the site adds a host before this anc release knows about it, fall back to a manual git clone:
The host map is hardcoded in this binary; new hosts ship via patch release after the site updates skill.json.
Quick Start
# Check the current project (`check` is the default subcommand)
# Check a specific binary
# Resolve a command on PATH and run behavioral checks against it
# JSON output for CI
# Filter by principle
# Quiet mode (warnings and failures only)
The 7 Principles
agentnative checks your CLI against seven agent-readiness principles:
| # | Principle | What It Means |
|---|---|---|
| P1 | Non-Interactive by Default | No prompts, no browser popups, stdin from /dev/null works |
| P2 | Structured Output | --output json exists and produces valid JSON |
| P3 | Progressive Help | --help has examples, --version works |
| P4 | Actionable Errors | Structured error types, named exit codes, no .unwrap() |
| P5 | Safe Retries | --dry-run for write operations |
| P6 | Composable Structure | SIGPIPE handled, NO_COLOR respected, shell completions, AGENTS.md |
| P7 | Bounded Responses | --quiet flag, no unbounded list output, clamped pagination |
Example Output
P1 — Non-Interactive by Default
[PASS] Non-interactive by default (p1-non-interactive)
[PASS] Flags advertise env-var bindings in --help (p1-env-hints)
[PASS] TTY detection for color output (p1-tty-detection-source)
[PASS] No interactive prompt dependencies (p1-non-interactive-source)
P3 — Progressive Help
[PASS] Help flag produces useful output (p3-help)
[PASS] Version flag works (p3-version)
P4 — Actionable Errors
[PASS] Rejects invalid arguments (p4-bad-args)
[PASS] Structured error types (p4-error-types)
[PASS] Exit codes use named constants (p4-exit-codes)
[PASS] No process::exit outside main (p4-process-exit)
[PASS] Dedicated error module exists (p4-error-module)
P6 — Composable Structure
[PASS] Handles SIGPIPE gracefully (p6-sigpipe)
[PASS] Respects NO_COLOR (p6-no-color-behavioral)
[PASS] Shell completions support (p6-completions)
Code Quality
[PASS] No .unwrap() in source (code-unwrap)
33 checks: 28 pass, 1 warn, 0 fail, 4 skip, 0 error
🏆 Score: 97% — your tool qualifies for the agent-native badge.
Embed in your README:
[](https://anc.dev/score/anc)
Convention: https://anc.dev/badge
The badge hint appears in text output when a tool scores at or above the 80% eligibility floor. Below the floor, anc
prints nothing badge-related — the convention is to surface the embed only when earned.
Three Check Layers
agentnative uses three layers to analyze your CLI:
- Behavioral — runs the compiled binary, checks
--help,--version,--output json, SIGPIPE, NO_COLOR, exit codes. Language-agnostic. - Source — ast-grep pattern matching on source code. Detects
.unwrap(), missing error types, nakedprintln!, and more. Currently supports Rust. - Project — inspects files and manifests. Checks for AGENTS.md, recommended dependencies, dedicated error/output modules.
CLI Reference
When the first non-flag argument is not a recognized subcommand, check is inserted automatically. anc ., anc -q .,
and anc --command ripgrep all resolve to anc check …. Bare anc (no arguments) still prints help and exits 2 — this
is deliberate fork-bomb prevention when agentnative dogfoods itself.
Usage: anc check [OPTIONS] [PATH]
Arguments:
[PATH] Path to project directory or binary [default: .]
Options:
--command <NAME> Resolve a command from PATH and run behavioral checks against it
--binary Run only behavioral checks (skip source analysis)
--source Run only source checks (skip behavioral)
--principle <PRINCIPLE> Filter checks by principle number (1-7)
--output <OUTPUT> Output format [default: text] [possible values: text, json]
-q, --quiet Suppress non-essential output [env: AGENTNATIVE_QUIET=]
--include-tests Include test code in source analysis
--audit-profile <CATEGORY> Exemption category for the target [possible values:
human-tui, file-traversal, posix-utility, diagnostic-only]
-h, --help Print help
--command and [PATH] are mutually exclusive — pick one. --command runs behavioral checks only; source and project
checks are skipped because there is no source tree to analyze.
--audit-profile suppresses checks that legitimately do not apply to a class of tool (e.g., human-tui for TUI apps
like lazygit whose contract IS the TTY, posix-utility for stdin-primary tools like cat/sed/awk,
diagnostic-only for read-only tools like nvidia-smi, file-traversal reserved for upcoming subcommand-structure
relaxations on fd/find-class tools). Suppressed checks emit Skip with structured evidence. The full per-category
mapping lives in coverage/matrix.json under audit_profiles[] — agents should read it rather than scrape --help.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | All checks passed |
| 1 | Warnings present (no failures) |
| 2 | Failures, errors, or usage errors |
Exit 2 covers both check failures (a real [FAIL] or [ERROR] result) and usage errors (bare anc, unknown flag,
mutually exclusive flags). Agents distinguishing the two should parse stderr (usage errors print Usage:) or call
anc --help first to validate the invocation shape.
Shell Completions
# Bash
# Zsh (writes to the first directory on your fpath)
# Fish
# PowerShell
# Elvish
Pre-generated scripts are also available in completions/.
JSON Output
Produces a self-describing scoring run record (schema_version: "0.5") with results, summary, coverage against the 7
principles, plus contextual metadata identifying which tool was scored, by which anc build, on which platform, and
how:
coverage_summary— how many MUSTs/SHOULDs/MAYs the checks that ran actually verified, against the spec registry's totals. Seedocs/coverage-matrix.mdfor the per-requirement breakdown. Checks suppressed by--audit-profiledo not count towardverified— suppression means the requirement was not verified, even if the check is skipped rather than run.audience— derived classification from 4 signal behavioral checks (p1-non-interactive,p2-json-output,p7-quiet,p6-no-color-behavioral). Emitsagent-optimized(0-1 Warns),mixed(2 Warns), orhuman-primary(3-4 Warns). Returnsnullwhen any signal check failed to run (source-only mode, missing runner, or--audit-profilesuppression). Informational only — never gates totals or exit codes. Values serialize as kebab-case to matchaudit_profile's format within the same JSON document.audience_reason— present only whenaudienceisnull. Values:suppressed(at least one signal check was masked by--audit-profile) orinsufficient_signal(signal check never produced, e.g. source-only run). Additive to schema0.2; older consumers feature-detect.audit_profile— echoes the applied--audit-profile <category>flag value (human-tui,file-traversal,posix-utility, ordiagnostic-only).nullwhen no profile is set. Seecoverage/matrix.jsonunderaudit_profilesfor the committed per-category mapping of which check IDs each profile suppresses.tool— identifies what was scored.nameis always present (deterministic from path or command).binaryis the executable basename when one is located;nullfor project-mode runs without a built artifact.versionis best-effort: project-mode prefers the manifest version (Cargo.toml/pyproject.toml), command/binary mode probes<bin> --versionthen-V.nullwhen probing failed or was declined by the self-spawn guard. The site'sregistry.yamlversion_extractsnippets remain authoritative for tools whose self-report is unreliable. Schema0.4addition.anc— identifies theancbuild that produced the scorecard.versionis the crate version at compile time.commitis the short Git SHA at compile time, ornullfor builds outside a Git checkout (e.g.,cargo installfrom crates.io). Informational, not a signed provenance signal — pair with a Sigstore-signed release artifact if provenance is required. Schema0.4addition.run— run-level facts.invocationis the user's argv joined with shell-safe quoting, captured before default-subcommand injection so it reflects what the user typed (anc ., notanc check .).started_atis RFC 3339 UTC.duration_msis wall-clock milliseconds.platform.os/platform.archcome fromstd::env::consts. Schema0.4addition.target— whatancwas pointed at.kindis"project"(directory),"binary"(executable file), or"command"(PATH-resolved name from--command).pathis the basename of the resolved target (project directory name or binary file name) — never the absolute path, so home-dir usernames and employer directory layouts don't leak into scorecards committed to repos or posted by agents.commandcarries the user-supplied name for command mode. The unused field is alwaysnull, never missing — consumer code can access both unconditionally. Schema0.4addition.badge— agent-native badge derivation from the live run.score_pctispass / (pass + warn + fail)rounded (Skips and Errors excluded from both sides of the ratio).eligibleis true iffscore_pct >= 80and a tool slug was derivable.embed_markdownisnullbelow the floor — the convention is "do not nag" until earned;scorecard_urlandbadge_urlare populated whenever a slug exists, even below the floor, so the site renders an SVG for every scored tool (a regression below the floor shifts color rather than 404s).convention_urlalways points athttps://anc.dev/badge. Schema0.5addition.
Publishing a scorecard?
run.invocationmay carry usernames or absolute paths from the machine that produced the scorecard.target.pathis intentionally the basename only and is safe to commit. Reviewrun.invocationbefore publishing —ancdoes not silently redact, since that would surprise users debugging their own runs.
Contributing
Reporting issues
Open an issue at github.com/brettdavies/agentnative-cli/issues/new/choose. The chooser surfaces three structured templates plus a blank fallback for everything else:
| Template | Use it when |
|---|---|
| Blank issue | Anything outside the structured templates below. |
| False positive | A check flagged your CLI but you believe your CLI is doing the right thing. |
| Scoring bug | Results don't match what the check should be doing (wrong status, miscategorized group/layer, evidence pointing at the wrong line). |
| Feature request | Missing capability, flag, or output format in the checker itself. |
Spec questions, principle pressure-tests, and CLI grading live on the spec repo — brettdavies/agentnative. The chooser config redirects those automatically. Site bugs (rendering, performance) go to brettdavies/agentnative-site. See CONTRIBUTING.md on the spec repo for the full cross-repo routing table.
License
MIT OR Apache-2.0