Guide: Unix Naming Conventions for Agent-Facing CLIs
The principle: Inherit Unix vocabulary and semantics. Replace Unix output format, exit code precision, interactivity, and glob contracts with agent-safe equivalents.
LLMs are trained on billions of shell sessions, man pages, scripts, and CLI documentation. That training encodes behavioral expectations into short names and flag patterns — a compressed semantic layer a CLI developer can exploit deliberately. This guide documents which Unix conventions to preserve, which to override, and how to align with the training corpora that give agents the strongest priors.
The Inherit/Override Split
Inherit — these activate correct agent priors
| Convention | Why it works |
|---|---|
| Unix verb vocabulary | list, get, apply, exec, diff, watch carry pre-trained behavioral expectations |
| Verb-noun subcommand grammar | tool resource create mirrors git commit, kubectl get pods; agent infers side-effect profile from the verb |
| Long-form flag names | --dry-run, --force, --recursive, --verbose, --output are near-universal; agents predict them correctly |
--format json |
Trained from aws --output json, kubectl -o json, gh --json; agents add it automatically for machine-readable output |
--dry-run / --apply two-phase |
Trained from rsync, ansible, terraform; agents use --dry-run before mutating unprompted |
| Man page document structure | SYNOPSIS / OPTIONS / EXAMPLES / EXIT STATUS; agents parse this with high fidelity |
| Exit codes 0 / 1 / 2 | 0=success, 1=error, 2=bad arguments — deeply trained across the entire Unix corpus |
Override — these break agent workflows
| Convention | Why it fails | Spec coverage |
|---|---|---|
Short cryptic flags -f -r -n |
Same letter means different things across tools; drives hallucination | §35 |
| Positional arguments | Order-sensitive, no schema representation | §69 |
| Silent success (no output) | Agents need structured confirmation | §2 |
| Non-error non-zero exits | grep exit 1 = no match, not error; corrupts retry logic |
§1 |
| Shell glob expansion | Bypassed when agent invokes via subprocess | §51 |
| Locale-dependent output | Breaks deterministic parsing across environments | §57 |
| Interactive prompts | Blocks indefinitely when stdin is not a TTY | §10 |
| Mixed stderr / stdout | No stable signal/noise boundary | §3 |
Command Naming
Use Unix verb analogues
Agents have pre-trained priors about what each verb implies:
| Verb | Implied semantics | Side-effect profile |
|---|---|---|
get / show |
Return one resource | Read-only, retry-safe |
list |
Return collection | Read-only, retry-safe |
create |
Create new resource | Has side effects, not idempotent |
apply |
Create-or-update | Idempotent, retry-safe |
update / set |
Modify existing | Has side effects |
delete / remove |
Destroy resource | Destructive, wants --dry-run |
describe / inspect |
Full resource detail | Read-only, more than get |
validate / check |
Verify without executing | Read-only, pre-flight |
diff |
Show what would change | Read-only, preview |
exec |
Run command in context | Context-dependent |
logs |
Stream event history | Read-only, streaming |
watch |
Stream state changes | Read-only, open-ended |
init |
One-time bootstrap | Has side effects, idempotent |
status |
Current state | Read-only |
Support verb synonyms
Agents guess synonyms. Supporting them costs one alias per command:
| Canonical | Synonyms |
|---|---|
delete |
remove, rm |
list |
ls |
create |
add, new |
apply |
sync, reconcile |
update |
set, edit |
Use up / down for multi-component systems
Trained from docker-compose, vagrant, terraform. up = bring described state into existence (dependency-ordered). down = tear everything down cleanly. These imply completeness and ordering that start/stop do not.
Use start / stop / restart / reload / status for daemons
Trained from systemctl, supervisorctl, pm2. Agents managing persistent processes know this five-verb lifecycle cold.
Flag Conventions
Flags worth inheriting exactly
| Flag | Convention | Trained from |
|---|---|---|
--dry-run / -n |
Preview without side effects | rsync, make, ansible |
--format json |
Machine-readable output | aws, kubectl, gh |
--output / -o |
Output destination or format | many |
--verbose / -v |
More output; stack for levels | ssh, curl, ansible |
--quiet / -q |
Less output | apt, many |
--force / -f |
Skip confirmation | rm, git |
--all / -a |
Include all items | ls, git, docker |
--recursive / -r |
Traverse depth | cp, rsync, grep |
--no-* negation |
--no-color, --no-pager |
git, many |
--timeout with suffixes |
30s, 5m, 1h |
curl, kubectl |
--since / --until |
Time-bounded queries | journalctl, git log |
--follow / -f |
Live-stream | tail, kubectl logs |
--watch |
Stream updates | kubectl, webpack |
--label / -l |
Filter by metadata | kubectl |
--namespace / -n |
Scope isolation | kubectl |
--output-file |
Write to file instead of stdout | many |
--color=auto\|always\|never |
Three-value color control | ls, grep, git |
- for stdin |
Pipe input as file argument | cat, diff, jq |
-- end-of-flags |
Protect downstream args | all shells |
Flags with well-trained interaction protocols
| Flag / Pattern | Protocol | Trained from |
|---|---|---|
--dry-run → --apply |
Preview then commit | terraform, ansible, rsync |
--wait / --no-wait |
Sync vs async invocation | kubectl, az |
--for=condition |
Bounded waiting | kubectl wait |
--var / --var-file |
Variable injection | terraform, ansible |
--set key=value |
Inline config override | helm |
--tags / --skip-tags |
Selective execution | ansible, pytest |
--on-error fail\|continue\|rollback |
Error strategy | make, helm |
--generate-skeleton + --input-file |
Complex input template | aws cli |
--from-file / --from-literal |
Multiple input sources | kubectl |
--idempotency-key |
Safe retry deduplication | aws sdk, stripe |
--jq <expr> |
Embedded output filter | jq (embedded) |
--porcelain |
Stable, versioned output | git |
Output Conventions
Formats in preference order for agent pipelines
| Format | When to use | Notes |
|---|---|---|
JSON (--format json) |
Default for agent consumption | Use response-envelope schema |
| JSONL | Streaming / --follow output |
One object per line, independently parseable |
| TSV | Tabular data without JSON | No quoting rules; safe for cut, awk |
KEY=VALUE per line |
Config/state output | Parseable without libraries |
| One item per line | ID lists, bulk piping | Safe for xargs, shell loops |
Output invariants
- One-item-per-line for lists enables
xargs -0composition ---document separator for multi-result YAML/text streams--no-headersfor tabular output — agents add this before piping toawk- Zero results → empty structure, not silence (
[],{},{"count": 0}) - Verb output contracts:
createreturns ID,getreturns full resource,listreturns array,deletereturns confirmation
Training Corpus Alignment
The most important design decision: which corpus does your tool most resemble? Match that corpus's conventions to activate the densest available prior.
| Tool type | Model after | Key patterns to inherit |
|---|---|---|
| Cloud resource manager | kubectl | -n namespace, -l selector, -o json, apply, wait --for, describe |
| HTTP / API client | curl | -X METHOD, -H header, -d data, --fail, --retry, --silent |
| Infrastructure provisioner | terraform | plan / apply / destroy, --var, --plan-file, workspaces |
| Configuration manager | ansible | --tags, --limit, --check, --diff, --extra-vars |
| Package / dependency manager | npm / pip | install, uninstall, upgrade, outdated, --frozen-lockfile |
| Deployment orchestrator | helm | --set, --values, --atomic, --dry-run, --wait |
| Container / process manager | docker | exec, logs --follow, -e KEY=VALUE, --rm, run |
| Multi-service orchestrator | docker-compose | up -d, down -v, logs -f, scale |
| Version control wrapper | git | --porcelain, ref syntax (HEAD~N), --patch, --stat |
| Project build system | make | install, test, clean, build as subcommand names |
| Data query / transform | jq | --jq flag accepting jq expressions; -r for raw output |
Mixed-corpus tools
A tool that manages versioned cloud resources should look like kubectl + terraform: kubectl's resource vocabulary (get, apply, describe, -l selector) combined with terraform's lifecycle (plan, apply, --var). Pick the dominant corpus for the primary interface and borrow selectively from secondary ones.
Environment Variables
Universal conventions (read without prefix)
| Variable | Convention |
|---|---|
NO_COLOR |
Disable ANSI output |
CI |
Headless mode: suppress prompts, spinners, color, telemetry |
HOME |
User home directory |
XDG_CONFIG_HOME / XDG_DATA_HOME / XDG_CACHE_HOME |
Config/data/cache locations |
HTTP_PROXY / HTTPS_PROXY / NO_PROXY |
Network proxy |
PAGER |
Pager program (set to cat for non-interactive) |
EDITOR / VISUAL |
Editor (must be no-op in non-TTY; see §62) |
Tool-specific variables (always use TOOLNAME_ prefix)
See REQ-F-073. All tool-specific env vars must be namespaced to prevent cross-tool contamination in multi-tool agent pipelines.
The Three Design Layers
A fully agent-compatible CLI operates at three levels:
┌─────────────────────────────────────────────────┐
│ Layer 3: Runtime Self-Documentation │
│ --explain, --help --format json, __complete, │
│ deprecation warnings, next_steps in errors, │
│ tool capabilities, --generate-skeleton │
│ → Reduces epistemic load at runtime │
├─────────────────────────────────────────────────┤
│ Layer 2: Mechanics (enforced by requirements) │
│ Structured output, precise exit codes, │
│ isatty detection, signal handling, │
│ atomic writes, fd cleanup, LF endings │
│ → Makes behavior predictable │
├─────────────────────────────────────────────────┤
│ Layer 1: Naming (this guide) │
│ Unix vocabulary, verb-noun grammar, │
│ flag conventions, corpus alignment │
│ → Activates correct pre-trained priors │
└─────────────────────────────────────────────────┘
Layer 1 is free — it costs nothing to name a command apply instead of upsert. Layers 2 and 3 require implementation effort but are covered by the spec's requirements. A tool that invests in all three layers achieves correct agent behavior on the first invocation, without documentation, across the full range of agent tasks.
Related
| Document | Relationship |
|---|---|
| challenges/index.md | Provides: failure modes that arise when Unix mechanics are inherited without override |
| requirements/index.md | Provides: implementation contracts for Layer 2 (mechanics) |
| schemas/manifest-response.md | Provides: manifest schema that supports Layer 3 runtime self-documentation |