> ## Documentation Index
> Fetch the complete documentation index at: https://docs.whyfile.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI reference

> Every whyfile flag, exit code, per-pass model default, and pipeline output file.

## CLI flags

| Flag                | Default                   | Description                                                                                                                                                                                                                                                                                                                                                                                          |
| ------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--graph`           | `graphify-out/graph.json` | Path to the graphify output `graph.json`                                                                                                                                                                                                                                                                                                                                                             |
| `--docs`            | `docs/`                   | Directory containing markdown source files                                                                                                                                                                                                                                                                                                                                                           |
| `--passes`          | `A,B,C`                   | Comma-separated passes: `A` extract, `B` anchor, `C` cross-doc relate, `D` cross-doc concept resolution (opt-in)                                                                                                                                                                                                                                                                                     |
| `--backend`         | *(auto)*                  | Backend selection (see [LLM backend](installation.md#llm-backend))                                                                                                                                                                                                                                                                                                                                   |
| `--progress`        | `auto`                    | Progress reporting mode: `auto` (live line on TTY, heartbeat when piped), `plain` (heartbeat lines only), `json` (NDJSON events on stderr), `none` (silent). stdout stays results only; warnings and progress go to stderr.                                                                                                                                                                          |
| `--min-confidence`  | `0.75`                    | Minimum `confidence_score` for Pass C **and Pass D** edges                                                                                                                                                                                                                                                                                                                                           |
| `--max-concurrency` | `4`                       | Maximum number of concurrent LLM requests                                                                                                                                                                                                                                                                                                                                                            |
| `--max-tokens`      | `500000`                  | Estimated-token ceiling for the **whole run** (all passes, summed). Enforced three ways (a pre-flight prompt, a mid-Pass-A breaker, and a post-Pass-A checkpoint before Pass B), so a run stays within the estimate it showed you. Nothing is written on an abort; `--yes` skips only the pre-flight prompt, never the checkpoint. `0` = unlimited. Full semantics in [`AGENTS.md`](../../AGENTS.md) |
| `--max-cost-usd`    | `2.00`                    | Cost guard for **API** backends: prompts if the pre-flight estimate exceeds this (the subscription backend has no per-token bill to guard, so it skips this check; `--max-tokens` is the guard that applies there). Pre-flight only; the post-Pass-A checkpoint gates tokens, not cost                                                                                                               |
| `--yes`             | `false`                   | Skip the pre-flight ceiling prompt (non-interactive / CI); does *not* skip the post-Pass-A whole-run checkpoint                                                                                                                                                                                                                                                                                      |
| `--dry-run`         | `false`                   | Project calls/tokens/cost/time as JSON and exit: no extraction (one tiny backend liveness ping only). JSON shape documented in [`AGENTS.md`](../../AGENTS.md)                                                                                                                                                                                                                                        |
| `--no-cache`        | `false`                   | Bypass the Pass A cache entirely: no reads, no writes; every section re-extracts. See [Caching & resume](caching-and-cost.md#caching--resume)                                                                                                                                                                                                                                                        |
| `--doctor [--json]` | `false`                   | Check the environment (runtime, backend auth, graph/docs shape, version drift) and exit; `--json` for machine output. Version drift is advisory only; a stale editable install no longer fails the run                                                                                                                                                                                               |
| `--version`         | n/a                       | Print the installed version and exit                                                                                                                                                                                                                                                                                                                                                                 |

Set `--backend` to `subscription`, `api`, or an explicit provider name (see [LLM backend](installation.md#llm-backend)).

**stdout is strictly results-only.** The pre-flight projection line (`Pass A: ~… tokens
(whole run) …`), the `Pass A: gated N section(s)` prefilter notice, and every
ceiling/prompt/abort message print to stderr; stdout carries only the per-pass result lines,
the sidecar path, and `Done.`.

### Exit codes

Stable across releases (`src/whyfile/errors.py`), safe for scripts/agents to branch on:

| Code | Meaning                                                                                                                                                                                                                                                       |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0`  | Success                                                                                                                                                                                                                                                       |
| `1`  | Unexpected error (unhandled exception; never raised deliberately)                                                                                                                                                                                             |
| `2`  | Bad input: invalid `--passes`, `graph.json` missing, no `.md` docs found                                                                                                                                                                                      |
| `3`  | Token/cost ceiling: pre-flight decline, non-interactive over-ceiling, the Pass A budget breaker, or the post-Pass-A whole-run checkpoint before Pass B                                                                                                        |
| `4`  | Backend unusable: none configured, the graphify runtime missing, or all Pass A sections failed                                                                                                                                                                |
| `5`  | Policy gate: `changed --fail-on-constraint` (a changed file is governed by a constraint), `intent-diff --gate` (constraint-governed code changed with no superseding record in the PR), or `check` (a compiled constraint in `intent-rules.json` is violated) |

See [`AGENTS.md`](../../AGENTS.md) for the full contract (per-code agent actions, `--dry-run`/`--doctor`
JSON shapes, progress events, and manifest fields) for driving this tool non-interactively.

### Per-pass models (subscription backend)

On the subscription (`claude-cli`) backend, each pass defaults to a different model rather
than one blanket choice, which kills the old Opus-for-everything default:

| Pass                   | Default model |
| ---------------------- | ------------- |
| A (extract)            | `sonnet`      |
| B (anchor)             | `haiku`       |
| C (cross-doc relate)   | `haiku`       |
| D (concept resolution) | `haiku`       |

Pass A keeps the stronger model because it does the actual reasoning (deriving a claim,
rationale, and alternatives from prose); B/C/D are comparatively mechanical, so `haiku`
carries them at a fraction of the cost. Set `GRAPHIFY_CLAUDE_CLI_MODEL` to override the
model for **every** pass, e.g. `GRAPHIFY_CLAUDE_CLI_MODEL=haiku` if your corpus is
code-heavy enough that even Pass A doesn't need `sonnet`-level reasoning.

**`--max-concurrency` changes wall-clock time only, not cost, and only on the API backend.**
The actual cost levers are the model (per-pass tiering above), the call count (Pass A's
structural gate on trivial sections), and per-call context; raising concurrency just runs the
same calls faster in parallel, there. On the subscription backend, claude-cli calls serialize
upstream in graphify (a lock around the CLI subprocess), so `--max-concurrency` has little
effect: raising it does not make subscription runs faster.

## Outputs

All outputs are written to the same directory as `graph.json`:

| File                      | Contents                                                                                                                                                                                                                                                                                                                                                      |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `.whyfile.json`           | Sidecar: all intent nodes and edges added across runs                                                                                                                                                                                                                                                                                                         |
| `graph.enriched.json`     | Original graph merged with the intent layer (graphify node-link format)                                                                                                                                                                                                                                                                                       |
| `enrichment_report.md`    | Before/after metrics: node/link/isolated counts, intent breakdown by kind, anchored vs orphaned, grounding coverage                                                                                                                                                                                                                                           |
| `.whyfile_progress.jsonl` | Progress stream (NDJSON, one event per line): `run_start`, `pass_start`, `tick`, `unit_fail`, `pass_end` events for agents to tail or poll. Written for any `--progress` mode except `none`.                                                                                                                                                                  |
| `intent_run.json`         | Per-run manifest: `status`/`error`, `metrics`, `artifacts`, and per-pass records (`passes[]`, including `s_per_call`, `cache_hits`, and `cache_misses`; the cache fields are nonzero only for Pass A). Written on every run (independent of `--progress` mode). At run end, an estimated-vs-actual runtime/duration reconciliation line is printed to stderr. |
| `intent_runs.jsonl`       | History: the same manifest object appended as one line per run, oldest first: a run-over-run log without snapshotting `intent_run.json` yourself.                                                                                                                                                                                                             |
| `.whyfile.prev.json`      | Snapshot of the sidecar as it was *before* this run's merge. Written every run (skipped on the first run). Powers `digest --since last-run`. Git-ignored under `graphify-out/`.                                                                                                                                                                               |
