# The agent-native CLI standard Source: https://agentnative.dev/ Canonical-Markdown: https://agentnative.dev/index.md # The agent-native CLI standard CLI tools are how AI agents touch everything else. Compilers, databases, git, the cloud, the shell. An agent asked to ship code, rotate a credential, grep a log, or deploy a branch does not call a SaaS API — it shells out to a binary, reads the output, decides what went right or wrong, and picks the next move. There is no human between the request and the process. The CLI either makes that loop tractable or it does not. This is the specification for CLIs that make it tractable. Seven principles, each expressing a requirement with [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) tiers — **MUST** for the contract, **SHOULD** for the default, **MAY** for the optional affordance. The companion linter, [`agentnative`](/check), scores any CLI against them and reports results by stable check ID (`p1-non-interactive`, `p4-process-exit`, …). Cite a principle by its anchor slug (`#p1-non-interactive-by-default` through `#p7-bounded-high-signal-responses`) — those are permanent. Each of the seven principles below has its own page (`/p1` through `/p7`) for deep-linking, and the same text is available as raw markdown at `/p1.md` … `/p7.md` for agent consumption. The entire spec as one file lives at [`/llms-full.txt`](/llms-full.txt); a curated index for retrieval-heavy agents lives at [`/llms.txt`](/llms.txt). --- # P1: Non-Interactive by Default Source: https://agentnative.dev/p1 Canonical-Markdown: https://agentnative.dev/p1.md # P1: Non-Interactive by Default ## Definition Every automation path MUST run without human input. A CLI tool that blocks on an interactive prompt is invisible to an agent — the agent hangs, the user sees nothing, and the operation times out silently. ## Why Agents Need It An agent calling a CLI cannot type. When the tool prompts for a confirmation or a credential, the agent's process stalls until timeout: no tokens recovered, no structured signal that interaction was requested, and no way to distinguish "waiting for input" from "still processing." Interactive prompts in automation paths are the single most common cause of agent-tool deadlock. ## Requirements **MUST:** - Every flag settable via environment variable. Use a falsey-value parser for booleans so that `TOOL_QUIET=0` and `TOOL_QUIET=false` correctly disable the flag rather than being treated as truthy non-empty strings. In Rust / clap: ```rust #[arg(long, env = "TOOL_QUIET", global = true, value_parser = FalseyValueParser::new())] quiet: bool, ``` - A `--no-interactive` flag gating every prompt library call (`dialoguer`, `inquire`, `read_line`, `TTY::Prompt`, `inquirer`, equivalents in other frameworks). When the flag is set, or when stdin is not a TTY, the tool uses defaults, reads from stdin, or exits with an actionable error. It never blocks. - A headless authentication path if the CLI authenticates. The canonical flag is `--no-browser`, which triggers the OAuth 2.0 Device Authorization Grant ([RFC 8628](https://www.rfc-editor.org/rfc/rfc8628)): the CLI prints a URL and a code; the user authorizes on another device. Agents cannot open browsers. Non-canonical alternatives (`--device-code`, `--remote`, `--headless`) are acceptable but should migrate toward `--no-browser`. **SHOULD:** - Auto-detect non-interactive context via TTY detection (`std::io::IsTerminal` in Rust 1.70+, `process.stdin.isTTY` in Node, `sys.stdout.isatty()` in Python) and suppress prompts when stderr is not a terminal, even without an explicit `--no-interactive` flag. - Document default values for prompted inputs in `--help` output so agents can pass them explicitly instead of accepting whatever default ships. **MAY:** - Offer rich interactive experiences — spinners, progress bars, multi-select menus — when a TTY is detected and `--no-interactive` is not set, provided the non-interactive path remains fully functional. ## Evidence - `--no-interactive` flag in the CLI struct with an env-var binding. - Boolean env vars parsed with a falsey-value parser (not the default string parser). - TTY guard wrapping every `dialoguer`, `inquire`, or equivalent prompt call. - `--no-browser` flag present on authenticated CLIs. - `env = "TOOL_..."` attribute on every flag that takes user input. ## Anti-Patterns - Bare `dialoguer::Confirm::new().interact()` with no TTY check and no `--no-interactive` override — agents hang indefinitely. - Boolean environment variables parsed as plain strings, so `TOOL_QUIET=false` is truthy because the string is non-empty. - `stdin().read_line()` in a code path reached during normal operation without a TTY check first. - Hard-coded credentials prompts with no env-var or config-file alternative. - OAuth flow that unconditionally opens a browser with no headless escape hatch. Measured by check IDs `p1-non-interactive` (behavioral) and `p1-non-interactive-source` (source). Run `agentnative check --principle 1 .` against your CLI to see both. --- # P2: Structured, Parseable Output Source: https://agentnative.dev/p2 Canonical-Markdown: https://agentnative.dev/p2.md # P2: Structured, Parseable Output ## Definition CLI tools MUST separate data from diagnostics and offer machine-readable output formats. Mixing status messages with data forces agents into fragile regex extraction that breaks on any format change. ## Why Agents Need It An agent calling a CLI needs three things from each invocation: the data, the error (if any), and the exit code. When data goes to stdout, diagnostics go to stderr, and errors carry machine-readable fields, the agent parses the result reliably without heuristics. Mix these channels or ship human-formatted output only, and the agent falls back to best-effort text parsing that fails unpredictably across versions, locales, and edge cases — silently at first, catastrophically later. ## Requirements **MUST:** - A `--output text|json|jsonl` flag selects the output format. Text is the default for humans; JSON and JSONL are the agent-facing formats. Implementation surfaces an `OutputFormat` enum and an `OutputConfig` struct threaded through every function that produces output. - Data goes to stdout. Diagnostics, progress indicators, and warnings go to stderr. An agent consuming JSON from stdout must never encounter an interleaved progress message. - Exit codes are structured and documented: | Code | Meaning | | ---: | -------------------------------------------- | | 0 | Success | | 1 | General command error | | 2 | Usage error (bad arguments) | | 77 | Authentication / permission error | | 78 | Configuration error | - When `--output json` is active, errors are emitted as JSON (to stderr) with at least `error`, `kind`, and `message` fields. Plain-text errors in a JSON run break the agent's parser on the only output it was told to expect. **SHOULD:** - JSON output uses a consistent envelope — a top-level object with predictable keys — across every command so agents can rely on the same shape. **MAY:** - Additional output formats (CSV, TSV, YAML) beyond the core three. The core three remain mandatory. - A `--raw` flag for unformatted output suitable for piping to other tools. ## Evidence - `OutputFormat` enum with `Text`, `Json`, `Jsonl` variants deriving `ValueEnum`. - `OutputConfig` struct with `format`, `use_color`, and `quiet` fields. - `serde_json` in `Cargo.toml`. - No `println!` in `src/` outside the output module — every print goes through `OutputConfig`. - Exit-code constants or match arms mapping error variants to distinct numeric codes. - `eprintln!` (or an equivalent diagnostic macro) for every diagnostic line. ## Anti-Patterns - `println!` scattered across handlers instead of routing through the output config. - A single exit code (1) for everything — agents cannot distinguish auth failures from config errors. - Status lines ("Fetching data…") printed to stdout where they contaminate JSON output. - `process::exit()` in library code, bypassing structured error propagation. - Human-formatted tables as the only output mode with no JSON alternative. Measured by check IDs `p2-output-json`, `p2-output-format`, `p2-stderr-diagnostics`. Run `agentnative check --principle 2 .` against your CLI to see each. --- # P3: Progressive Help Discovery Source: https://agentnative.dev/p3 Canonical-Markdown: https://agentnative.dev/p3.md # P3: Progressive Help Discovery ## Definition Help text MUST be layered so agents (and humans) can drill from a short summary to concrete usage examples without reading the entire manual. The critical layer is the one that appears **after** the flags list, because that is where readers look for invocation patterns. ## Why Agents Need It Agents discover how to use a tool by calling `--help` and scanning the output. They skip past flag definitions (which describe what is *possible*) and hunt for examples (which describe what to *do*). A flags list alone is enough rope to produce a failed invocation; examples are what turn discovery into action. Without examples in the help output, an agent trial-and-errors its way into a working call, burning tokens and sometimes landing on a wrong-but-silent success. ## Requirements **MUST:** - Every subcommand ships at least one concrete invocation example showing the command with realistic arguments, rendered in the section that appears after the flags list. In clap this is the `after_help` attribute. - The top-level command ships 2–3 examples covering the primary use cases. **SHOULD:** - Examples show human and agent invocations side by side — a text-output example followed by its `--output json` equivalent. Readers see the pair; agents see the JSON form. - Short `about` for command-list summaries; `long_about` reserved for detailed descriptions visible with `--help` but not `-h`. **MAY:** - A dedicated `examples` subcommand or `--examples` flag that outputs a curated set of usage patterns for agent consumption. ## Evidence - `after_help` (or `after_long_help`) attribute on the top-level parser struct. - `after_help` attribute on every subcommand variant. - Example invocations in `after_help` text that include realistic arguments, not placeholder `` tokens. - Both `about` (short) and `after_help` (examples) present on each subcommand. ## Anti-Patterns - Relying solely on `///` doc comments — those populate `about` / `long_about`, not `after_help`, so no examples render after the flags list. - A single `about` string serving as both summary and usage documentation. - Examples buried in a README or man page but absent from `--help` output. - `after_help` text that describes the flags in prose instead of demonstrating them in code. Measured by check IDs `p3-help`, `p3-after-help`, `p3-version`. Run `agentnative check --principle 3 .` against your CLI to see each. --- # P4: Fail Fast with Actionable Errors Source: https://agentnative.dev/p4 Canonical-Markdown: https://agentnative.dev/p4.md # P4: Fail Fast with Actionable Errors ## Definition CLI tools MUST detect invalid state early, exit with a structured error, and tell the caller three things: what failed, why, and what to do next. An error that says "operation failed" gives an agent nothing to act on. ## Why Agents Need It Agents operate in a retry loop: attempt, observe, decide. When an error is vague or unstructured — a bare stack trace, a one-word failure, a mixed-channel splurge — the agent cannot tell whether to retry, re-authenticate, fix configuration, or escalate to the user. Distinct exit codes with actionable messages let the agent act correctly on the first read. The difference between exit code 77 (re-authenticate) and exit code 78 (fix config) determines whether the agent retries OAuth or asks the user to check their config file. Getting that wrong wastes entire conversation turns. ## Requirements **MUST:** - Parse arguments with `try_parse()` instead of `parse()`. Clap's `parse()` calls `process::exit()` directly, bypassing custom error handlers — which means `--output json` cannot emit JSON parse errors. `try_parse()` returns a `Result` the tool can format: ```rust let cli = Cli::try_parse()?; ``` - Error types map to distinct exit codes. At minimum: | Code | Meaning | | ---: | ----------------------------- | | 0 | Success | | 1 | General command error | | 2 | Usage / argument error | | 77 | Auth / permission error | | 78 | Configuration error | - Every error message contains **what failed**, **why**, and **what to do next**. Example: ```text Authentication failed: token expired (expires_at: 2026-03-25T00:00:00Z). Run `tool auth refresh` or set TOOL_TOKEN. ``` **SHOULD:** - Error types use a structured enum (via `thiserror` in Rust) with variant-to-kind mapping for JSON serialization. Agents match on error kinds programmatically rather than parsing message text. - Config and auth validation happen before any network call. A three-tier dependency gating pattern (meta-commands, local-only commands, network commands) fails at the earliest possible point. - Error output respects `--output json`: JSON-formatted errors go to stderr when JSON output is selected. ## Evidence - `Cli::try_parse()` in `main()`, not `Cli::parse()`. - Error enum with `#[derive(Error)]` and distinct variants for config, auth, and command errors. - `exit_code()` method on the error type returning variant-specific codes. - `kind()` method returning a machine-readable string for JSON serialization. - `run()` function returning `Result<(), AppError>`, not calling `process::exit()` internally. - Error messages containing remediation steps ("run X" or "set Y") alongside the cause. ## Anti-Patterns - `Cli::parse()` anywhere in the codebase — it silently prevents JSON error output. - `process::exit()` in library code or command handlers. Only `main()` may call it, after all error handling. - A single catch-all error variant that maps everything to exit code 1. - Error messages that state the symptom without the cause or fix ("Error: request failed"). - Panics (`unwrap()`, `expect()`) on recoverable errors in production code paths. Measured by check IDs `p4-bad-args`, `p4-process-exit`, `p4-unwrap`, `p4-exit-codes`. Run `agentnative check --principle 4 .` against your CLI to see each. --- # P5: Safe Retries and Explicit Mutation Boundaries Source: https://agentnative.dev/p5 Canonical-Markdown: https://agentnative.dev/p5.md # P5: Safe Retries and Explicit Mutation Boundaries ## Definition Every CLI MUST support `--dry-run` so agents can preview any command before committing it. Write operations MUST clearly separate destructive actions from read-only queries. An agent that cannot distinguish a safe read from a dangerous write will either avoid the tool or execute mutations blindly — both are failure modes. ## Why Agents Need It Agents retry failed operations by default. If a write operation is not idempotent, a retry creates duplicates, corrupts data, or trips rate limits. When destructive operations require explicit confirmation (`--force`, `--yes`) and support preview (`--dry-run`), an agent can safely explore what a command would do before committing to it. Read-only tools are inherently safe for retries, but they still benefit from help text that names the mutation contract — "this does not modify state" is a better sentence to put in `--help` than to assume. ## Requirements **MUST:** - Destructive operations (delete, overwrite, bulk modify) require an explicit `--force` or `--yes` flag. Without it, the tool refuses the operation or enters dry-run mode — never mutates silently. - The distinction between read and write commands is clear from the command name and help text alone. An agent reading `--help` immediately knows whether a command mutates state. - A `--dry-run` flag is present on every write command. When set, the command validates inputs and reports what it would do without executing. Dry-run output respects `--output json` so agents can parse the preview programmatically. **SHOULD:** - Write operations are idempotent where the domain allows it — running the same command twice produces the same result rather than doubling the effect. ## Evidence - `--dry-run` flag on commands that create, update, or delete resources. - `--force` or `--yes` flag on destructive commands. - Command names that signal intent: `add`, `remove`, `delete`, `create` for writes; `list`, `show`, `get`, `search` for reads. - Dry-run output that shows what *would* change without executing. ## Anti-Patterns - A `delete` command that executes immediately without `--force` or confirmation. - Write commands sharing a name pattern with read commands (e.g., a `sync` that silently overwrites local state). - No `--dry-run` option on bulk operations, where a preview prevents costly mistakes. - Operations that fail on retry because the first attempt partially succeeded — non-idempotent writes without rollback. Measured by check IDs `p5-dry-run`, `p5-destructive-guard`. Run `agentnative check --principle 5 .` against your CLI to see each. --- # P6: Composable and Predictable Command Structure Source: https://agentnative.dev/p6 Canonical-Markdown: https://agentnative.dev/p6.md # P6: Composable and Predictable Command Structure ## Definition CLI tools MUST integrate cleanly with pipes, scripts, and other tools. That means handling SIGPIPE, detecting TTY for color and formatting decisions, supporting stdin for piped input, and maintaining a consistent, predictable subcommand structure. ## Why Agents Need It Agents compose CLI tools into pipelines: ```bash tool list --output json | jaq '.[] | .id' | xargs tool get ``` Every link in that chain has to behave predictably. A tool that panics on SIGPIPE when piped to `head` breaks the pipeline. A tool that emits ANSI color codes into a pipe pollutes downstream JSON parsing. A tool with inconsistent subcommand naming forces the agent to memorize exceptions rather than apply patterns. Composability is what makes a CLI tool a building block rather than a dead end. ## Requirements **MUST:** - A SIGPIPE fix is the first executable statement in `main()`. Without it, piping output to `head`, `tail`, or any tool that closes the pipe early causes a panic: ```rust unsafe { libc::signal(libc::SIGPIPE, libc::SIG_DFL); } ``` - TTY detection, plus support for `NO_COLOR` and `TERM=dumb`. When stdout or stderr is not a terminal, color codes are suppressed automatically. - Shell completions available via a `completions` subcommand (clap_complete in Rust; equivalents elsewhere). This is a Tier 1 meta-command — it works without config, auth, or network. - Network CLIs ship a `--timeout` flag with a sensible default (30 seconds). Agents operating under their own time budgets need to fail fast rather than block on a slow upstream. - If the CLI uses a pager (`less`, `more`, `$PAGER`), it supports `--no-pager` or respects `PAGER=""`. Pagers block headless execution indefinitely. - When the CLI uses subcommands, agentic flags (`--output`, `--quiet`, `--no-interactive`, `--timeout`) are `global = true` so they propagate to every subcommand automatically. **SHOULD:** - Commands that accept input read from stdin when no file argument is provided. Pipeline composition depends on it. - Subcommand naming follows a consistent `noun verb` or `verb noun` convention throughout the tool. Mixing patterns (e.g., `list-users` alongside `user show`) forces agents to learn exceptions. - A three-tier dependency gating pattern: Tier 1 (meta-commands like `completions`, `version`) needs nothing; Tier 2 (local commands) needs config; Tier 3 (network commands) needs config + auth. `completions` and `version` always work, even in broken environments. - Operations are modeled as subcommands, not flags. `tool search "query"` is correct; `tool --search "query"` is wrong. Flags modify behavior (`--quiet`, `--output json`); subcommands select operations. **MAY:** - A `--color auto|always|never` flag for explicit color control beyond TTY auto-detection. ## Evidence - `libc::signal(libc::SIGPIPE, libc::SIG_DFL)` (or the equivalent in the target language) as the first statement of `main()`. - `IsTerminal` trait usage (`std::io::IsTerminal` or the `is-terminal` crate). - `NO_COLOR` and `TERM=dumb` checks. - `clap_complete` in `Cargo.toml`. - A `completions` subcommand in the CLI enum. - Tiered match arms in `main()` separating meta-commands from config-dependent commands. ## Anti-Patterns - Missing SIGPIPE handler — `cargo run -- list | head` panics with "broken pipe". - Hard-coded ANSI escape codes without TTY detection. - Color output in JSON mode — ANSI codes inside JSON string values break downstream parsing. - A `completions` command that requires auth or config to run. - No stdin support on commands where piped input is a natural use case. Measured by check IDs `p6-sigpipe`, `p6-no-color`, `p6-completions`, `p6-timeout`, `p6-agents-md`. Run `agentnative check --principle 6 .` against your CLI to see each. --- # P7: Bounded, High-Signal Responses Source: https://agentnative.dev/p7 Canonical-Markdown: https://agentnative.dev/p7.md # P7: Bounded, High-Signal Responses ## Definition CLI tools MUST provide mechanisms to control output volume. Agent context windows are finite and expensive — a tool that dumps 10,000 lines of unfiltered output wastes tokens and may exceed the context limit entirely, breaking the conversation that invoked it. ## Why Agents Need It Every token of CLI output an agent consumes has a cost — both monetary (API tokens) and cognitive (context window capacity). Unbounded output forces the agent to either truncate (losing potentially important data) or consume the full response (wasting context on noise). Bounded output with `--quiet`, `--verbose`, and `--limit` flags gives the agent precise control over how much data arrives, keeping responses high-signal and inside budget. ## Requirements **MUST:** - A `--quiet` flag suppresses non-essential output: progress indicators, informational messages, decorative formatting. When `--quiet` is set, only requested data and errors appear. Implementations typically route diagnostics through a macro that short-circuits when quiet is on: ```rust macro_rules! diag { ($cfg:expr, $($arg:tt)*) => { if !$cfg.quiet { eprintln!($($arg)*); } } } ``` - List operations clamp to a sensible default maximum. A `list` without `--limit` does not return more than a configurable ceiling (e.g., 100 items). If more items exist, the output indicates truncation — `"truncated": true` in JSON, a stderr note in text mode. **SHOULD:** - A `--verbose` flag (or `-v` / `-vv`) escalates diagnostic detail when agents need to debug failures. - A `--limit` or `--max-results` flag lets callers request exactly the number of items they want. - A `--timeout` flag bounds execution time. An agent waiting indefinitely on a hung network call cannot proceed. **MAY:** - Cursor-based pagination flags (`--after`, `--before`) for efficient traversal of large result sets. - Automatic verbosity reduction in non-TTY contexts (the same behavior `--quiet` explicitly requests). ## Evidence - `--quiet` flag with a falsey-value parser and env-var binding. - A diagnostic macro (or equivalent gate) that short-circuits when `quiet` is true. - `--limit` or `--max-results` on every list / search command. - Pagination clamping logic (e.g., `min(requested, MAX_RESULTS)`). - `--timeout` flag with a sensible default. - `--verbose` flag for diagnostic escalation. - A `suppress_diag()` method that returns true when quiet is set or when the output format is JSON / JSONL. ## Anti-Patterns - List commands that return all results with no default limit — an agent listing 50,000 items floods its context window. - No `--quiet` flag — agents consuming JSON output still receive interleaved diagnostic text on stderr. - `--verbose` as the only output control. If there is no way to reduce output, bounded responses do not exist. - Progress bars or spinners that write to stderr in non-TTY contexts, adding noise to agent logs. - No `--timeout` on network operations. A stalled request blocks the agent indefinitely. Measured by check IDs `p7-quiet`, `p7-limit`, `p7-timeout`. Run `agentnative check --principle 7 .` against your CLI to see each. --- # Check your CLI Source: https://agentnative.dev/check Canonical-Markdown: https://agentnative.dev/check.md # Check your CLI `agentnative` is the reference linter for this standard. It scores any CLI tool against the seven principles and tells you, by check ID, where it passes and where it falls short. ## Install ```bash cargo install agentnative ``` Or with [cargo-binstall](https://github.com/cargo-bins/cargo-binstall) for a prebuilt binary: ```bash cargo binstall agentnative ``` ## Run it ```bash # Against the current project (cargo workspace, binary, or source tree) agentnative check . # Against a compiled binary directly agentnative check ./target/release/mycli # Agent-friendly output agentnative check . --output json # Narrow to one principle agentnative check . --principle 3 ``` ## Read the output ```text P1 — Non-Interactive by Default [PASS] Non-interactive by default (p1-non-interactive) [PASS] No interactive prompt dependencies (p1-non-interactive-source) P3 — Progressive Help [PASS] Help flag produces useful output (p3-help) [WARN] after_help section missing on subcommand (p3-after-help) P4 — Fail Fast with Actionable Errors [FAIL] `process::exit` found outside main (p4-process-exit) [PASS] Rejects invalid arguments (p4-bad-args) 30 checks: 20 pass, 8 warn, 1 fail, 1 skip, 0 error ``` Each line ends with a stable check ID (`p4-process-exit`, `p1-non-interactive`, etc.). Cite those IDs in issues, commits, and agent output; they do not change between versions. ## Three check layers - **Behavioral** — runs your compiled binary and inspects `--help`, `--version`, `--output json`, SIGPIPE, NO_COLOR, and exit codes. Language-agnostic. - **Source** — ast-grep pattern matching on source code. Catches `.unwrap()`, missing error types, naked `println!`. Rust today; more languages as they land. - **Project** — file and manifest inspection. Looks for `AGENTS.md`, recommended dependencies, dedicated error and output modules. Pass `--binary` to skip source analysis, `--source` to skip behavioral. Most projects want the default, which is "run everything." ## What a score means A `[PASS]` is a requirement met, not a compliment. A `[WARN]` is a SHOULD the tool doesn't satisfy; ignoring it is a choice, not a bug. A `[FAIL]` is a MUST the tool doesn't satisfy; agents will hit the edge it describes and the tool will surprise them. Nothing here is a vanity metric — the checks map one-to-one to the requirements on the [principles page](/). Source: [github.com/brettdavies/agentnative](https://github.com/brettdavies/agentnative). --- # About this standard Source: https://agentnative.dev/about Canonical-Markdown: https://agentnative.dev/about.md # About this standard The agent-native CLI standard is a specification for command-line tools that behave predictably under agent control. Seven principles, enforced by RFC 2119 requirement tiers (MUST / SHOULD / MAY), and measured by a companion linter ([`agentnative`](/check)) that scores any CLI against them. ## Versioning The spec uses semver-adjacent versioning with three tiers: MAJOR changes break citation IDs or remove MUSTs; MINOR changes add MUSTs or promote SHOULDs; PATCH changes edit prose without shifting requirements. The current version appears in the footer of every page. Principle anchor slugs (`#p1-non-interactive-by-default` through `#p7-bounded-high-signal-responses`) are permanent. If a principle merges with another or splits into two, the old slug resolves as a permanent redirect to wherever the requirement now lives — no citation you made yesterday will 404 tomorrow. ## RFC 2119 MUST, SHOULD, MAY, MUST NOT, and SHOULD NOT on this site carry their [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) meanings. They are not emphatic; they are contractual. A tool that does not satisfy a MUST is non-conformant with the version of the standard it claims to target. ## License Spec text on this site is available under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The `agentnative` linter is dual-licensed under MIT and Apache-2.0; see [its LICENSE files](https://github.com/brettdavies/agentnative). ## Contributing Pressure-testing is how the spec evolves. Three ways to contribute: 1. **Grade a real CLI** against a principle you think the spec gets wrong, and open an issue on the [site repo](https://github.com/brettdavies/agentnative-site) with your findings. Name the CLI, the principle, and the specific MUST/SHOULD/MAY that failed (or passed unexpectedly). 2. **Report a check that produces a false positive or false negative** on the [`agentnative` repo](https://github.com/brettdavies/agentnative). Include the command, the output, and the check ID. 3. **Propose a principle edit** — merge, split, rewording, demotion of a MUST to a SHOULD — via an issue with `[pressure-test]` in the title. The pressure-test protocol is documented in the spec's working repo. ## Colophon Built with Cloudflare Workers. Typeset in Uncut Sans and Monaspace Xenon. Source: [github.com/brettdavies/agentnative-site](https://github.com/brettdavies/agentnative-site). ---