nils-agent-docs 0.4.4

CLI crate for nils-agent-docs in the nils-cli workspace.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
# agent-docs

## Overview

`agent-docs` is a deterministic policy-document discovery CLI for Codex/agent workflows.

It resolves required Markdown documents by context and scope, with explicit precedence rules for:

- startup policy files (`AGENTS.override.md` > `AGENTS.md`)
- home vs project extension config (`AGENT_DOCS.toml`)
- strict vs non-strict missing-doc behavior

The CLI does not replace runtime `AGENTS.md` loading. It provides a testable resolution contract.

## Non-goals

- Replacing or bypassing how any runtime natively loads `AGENTS.md`.
- Auto-editing arbitrary existing policy files in-place.
- Discovering non-markdown policy files without explicit `AGENT_DOCS.toml` entries.
- Remote policy sync or network-backed policy lookups.

## Path Resolution Precedence

Path resolution is deterministic and applies to all commands.

### `AGENT_HOME`

1. `--agent-home <path>` (command flag)
2. `AGENT_HOME` environment variable
3. `$HOME/.agents`

### `PROJECT_PATH`

1. `--project-path <path>` (command flag)
2. `PROJECT_PATH` environment variable
3. `git rev-parse --show-toplevel` from current working directory
4. current working directory

### Normalization Rules

- Paths are normalized lexically (`.` removed, duplicate separators collapsed).
- Relative document paths in `AGENT_DOCS.toml` are resolved from their declared `scope` root.
- Absolute document paths are kept absolute and ignore scope root joining.

## Scope and Context Model

### Scopes

- `home`: rooted at effective `AGENT_HOME`
- `project`: rooted at effective `PROJECT_PATH`

### Built-in contexts

- `startup`
- `skill-dev`
- `task-tools`
- `project-dev`

### Built-in required docs by context

| Context | Scope | Required document contract | Required |
| --- | --- | --- | --- |
| `startup` | `home` | Use `AGENTS.override.md` when present; else `AGENTS.md` | `true` |
| `startup` | `project` | Use `AGENTS.override.md` when present; else `AGENTS.md` | `true` |
| `skill-dev` | `home` | `DEVELOPMENT.md` | `true` |
| `task-tools` | `home` | `CLI_TOOLS.md` | `true` |
| `project-dev` | `project` | `DEVELOPMENT.md` | `true` |

`AGENTS.override.md` precedence is evaluated per scope independently.

## Command Surface

```text
Usage:
  agent-docs <command> [options]

Commands:
  resolve            Resolve required docs for a context
  contexts           List supported contexts
  add                Upsert one AGENT_DOCS.toml entry
  scaffold-agents    Scaffold default AGENTS.md template
  baseline           Check baseline doc coverage
  scaffold-baseline  Scaffold missing baseline docs
```

Use `agent-docs --help` (or `agent-docs <command> --help`) for CLI help text.

## Commands and Flags

### `contexts`

Print supported context names.

Flags:

- `--format text|json` (default: `text`)
- `--agent-home <path>`
- `--project-path <path>`

### `resolve`

Resolve effective required/optional docs for one context.

Flags:

- `--context startup|skill-dev|task-tools|project-dev` (required)
- `--format text|json|checklist` (default: `text`)
- `--strict` (missing required docs become exit code `1`)
- `--agent-home <path>`
- `--project-path <path>`

Format guidance:

- `text`: human-readable output for manual inspection and debugging.
- `json`: machine-readable output for structured parsing/integration.
- `checklist`: line-oriented required-doc contract for shell verification and CI guards.

### `add`

Create/update one `AGENT_DOCS.toml` entry in home or project scope.

Flags:

- `--target home|project` (required)
- `--context startup|skill-dev|task-tools|project-dev` (required)
- `--scope home|project` (required; target root for `path` resolution)
- `--path <doc-path>` (required)
- `--required` (set `required=true`; omitted means `required=false`)
- `--when <condition>` (default: `always`)
- `--notes <text>`
- `--agent-home <path>`
- `--project-path <path>`

### Copy-pastable `resolve` + `add` flow

```bash
# 1) Resolve built-in project-dev requirements
agent-docs resolve --context project-dev --format text

# 2) Register BINARY_DEPENDENCIES.md as required for project-dev
agent-docs add \
  --target project \
  --context project-dev \
  --scope project \
  --path BINARY_DEPENDENCIES.md \
  --required \
  --when always \
  --notes "External runtime tools required by the repo"
```

`add` stdout shape:

```text
add: target=project action=<inserted|updated> config=<PROJECT_PATH>/AGENT_DOCS.toml entries=<N>
```

Verify both built-in and extension docs are present:

```bash
agent-docs resolve --context project-dev --format checklist \
  | rg "REQUIRED_DOCS_BEGIN|REQUIRED_DOCS_END|DEVELOPMENT\\.md|BINARY_DEPENDENCIES\\.md"
```

### `scaffold-agents`

Scaffold default `AGENTS.md` template.

Flags:

- `--target home|project` (required)
- `--output <path>` (optional explicit output file path)
- `--force` (overwrite when file exists)
- `--agent-home <path>`
- `--project-path <path>`

Semantics:

- Default output: `<target-root>/AGENTS.md`
- Without `--force`, existing target file is not modified.

### `baseline`

Audit minimum baseline documents.

Flags:

- `--check` (required in Sprint contract)
- `--target home|project|all` (default: `all`)
- `--format text|json` (default: `text`)
- `--strict` (missing required docs become exit code `1`)
- `--agent-home <path>`
- `--project-path <path>`

### `scaffold-baseline`

Scaffold baseline docs from deterministic templates/inputs.

Flags:

- `--target home|project|all` (default: `all`)
- `--missing-only` (create only missing baseline docs)
- `--force` (overwrite existing files)
- `--dry-run` (print planned writes only)
- `--format text|json` (default: `text`)
- `--agent-home <path>`
- `--project-path <path>`

## Exit Codes

- `0`: success (or non-strict missing-doc report)
- `1`: strict policy failure (`--strict` and one or more required docs missing)
- `2`: usage error (invalid flags, invalid command, missing required argument)
- `3`: config/schema error (`AGENT_DOCS.toml` invalid)
- `4`: runtime error (I/O failure, git probe failure not recoverable)

## Strict Semantics

### `resolve --strict`

- Required docs are evaluated after built-ins + TOML merge.
- If any required doc is missing on disk, command exits `1`.
- Without `--strict`, missing required docs are reported but exit code remains `0`.

### `baseline --strict`

- Evaluates baseline required docs for selected target scope(s).
- Missing required baseline docs cause exit `1` only when `--strict` is set.

## Worktree fallback

Worktree fallback is deterministic and applies only to project-scope required docs when running
from a linked worktree in `auto` mode.

### Fallback order (project scope)

`startup` project policy:

1. `<PROJECT_PATH>/AGENTS.override.md`
2. `<PROJECT_PATH>/AGENTS.md`
3. `<PRIMARY_WORKTREE_PATH>/AGENTS.override.md` (fallback)
4. `<PRIMARY_WORKTREE_PATH>/AGENTS.md` (fallback)

`project-dev` required project docs (built-ins and required project-scope extension entries):

1. `<PROJECT_PATH>/<doc-path>`
2. `<PRIMARY_WORKTREE_PATH>/<doc-path>` (fallback)

### Strict and compatibility semantics

- `--strict` exits `1` only when all candidates in the deterministic order are missing.
- `local-only` mode disables `<PRIMARY_WORKTREE_PATH>` fallback candidates and enforces local
  project paths only.
- Non-worktree repositories are unchanged: only `<PROJECT_PATH>` candidates are evaluated.

### Output disclosure and local-only operation

When fallback is used, output must disclose fallback provenance in addition to required-doc
presence.

- `text`/`json`: include a fallback source marker and the resolved fallback path.
- `checklist`: keep required-doc status lines and include fallback provenance in the same report.

To disable fallback, run resolve/baseline in `local-only` mode.

```bash
agent-docs --worktree-fallback local-only resolve --context startup --strict --format checklist
agent-docs --worktree-fallback local-only baseline --check --target project --strict --format text
```

## Output Contract

### `resolve` text example

```text
$ agent-docs resolve --context startup
CONTEXT: startup
AGENT_HOME: /Users/example/.agents
PROJECT_PATH: /Users/example/work/nils-cli

[required] startup home /Users/example/.agents/AGENTS.override.md source=builtin status=present why="startup home policy (AGENTS.override.md preferred over AGENTS.md)"
[required] startup project /Users/example/work/nils-cli/AGENTS.md source=builtin-fallback status=present why="startup project policy (AGENTS.override.md missing, fallback AGENTS.md)"

summary: required_total=2 present_required=2 missing_required=0 strict=false
```

### `resolve` JSON example

```json
{
  "context": "startup",
  "strict": false,
  "agent_home": "/Users/example/.agents",
  "project_path": "/Users/example/work/nils-cli",
  "documents": [
    {
      "context": "startup",
      "scope": "home",
      "path": "/Users/example/.agents/AGENTS.override.md",
      "required": true,
      "status": "present",
      "source": "builtin",
      "why": "startup home policy (AGENTS.override.md preferred over AGENTS.md)"
    },
    {
      "context": "startup",
      "scope": "project",
      "path": "/Users/example/work/nils-cli/AGENTS.md",
      "required": true,
      "status": "present",
      "source": "builtin-fallback",
      "why": "startup project policy (AGENTS.override.md missing, fallback AGENTS.md)"
    }
  ],
  "summary": {
    "required_total": 2,
    "present_required": 2,
    "missing_required": 0
  }
}
```

### `resolve` checklist example

Checklist mode is designed for copy-paste verification. The required-doc section is delimited by
`REQUIRED_DOCS_BEGIN` and `REQUIRED_DOCS_END`, with one required document per line:
`<filename> status=<present|missing> path=<absolute-path>`.

```text
$ agent-docs resolve --context project-dev --format checklist
REQUIRED_DOCS_BEGIN context=project-dev mode=non-strict
DEVELOPMENT.md status=present path=/Users/example/work/nils-cli/DEVELOPMENT.md
BINARY_DEPENDENCIES.md status=present path=/Users/example/work/nils-cli/BINARY_DEPENDENCIES.md
REQUIRED_DOCS_END required=2 present=2 missing=0 mode=non-strict context=project-dev
```

### `resolve` checklist strict + missing required example

When `--strict` is set and any required doc is missing, checklist output is still emitted and
the process exits with code `1`.

```text
$ agent-docs resolve --context skill-dev --format checklist --strict
REQUIRED_DOCS_BEGIN context=skill-dev mode=strict
DEVELOPMENT.md status=missing path=/Users/example/.agents/DEVELOPMENT.md
REQUIRED_DOCS_END required=1 present=0 missing=1 mode=strict context=skill-dev
$ echo $?
1
```

### `baseline --check` text example

```text
$ agent-docs baseline --check --target all
BASELINE CHECK: all
AGENT_HOME: /Users/example/.agents
PROJECT_PATH: /Users/example/work/nils-cli

[home] startup policy /Users/example/.agents/AGENTS.md required present source=builtin-fallback why="startup home policy (AGENTS.override.md missing, fallback AGENTS.md)"
[home] skill-dev /Users/example/.agents/DEVELOPMENT.md required missing source=builtin why="skill development guidance from AGENT_HOME/DEVELOPMENT.md"
[home] task-tools /Users/example/.agents/CLI_TOOLS.md required present source=builtin why="tool-selection guidance from AGENT_HOME/CLI_TOOLS.md"
[project] startup policy /Users/example/work/nils-cli/AGENTS.md required present source=builtin-fallback why="startup project policy (AGENTS.override.md missing, fallback AGENTS.md)"
[project] project-dev /Users/example/work/nils-cli/DEVELOPMENT.md required present source=builtin why="project development guidance from PROJECT_PATH/DEVELOPMENT.md"

missing_required: 1
missing_optional: 0
suggested_actions:
  - agent-docs scaffold-baseline --missing-only --target home
```

### `baseline --check` JSON example

```json
{
  "target": "all",
  "strict": false,
  "agent_home": "/Users/example/.agents",
  "project_path": "/Users/example/work/nils-cli",
  "items": [
    {
      "scope": "home",
      "context": "skill-dev",
      "label": "skill-dev",
      "path": "/Users/example/.agents/DEVELOPMENT.md",
      "required": true,
      "status": "missing",
      "source": "builtin",
      "why": "skill development guidance from AGENT_HOME/DEVELOPMENT.md"
    }
  ],
  "missing_required": 1,
  "missing_optional": 0,
  "suggested_actions": [
    "agent-docs scaffold-baseline --missing-only --target home"
  ]
}
```

### `baseline` extension merge order (deterministic)

`baseline --check` applies extension documents with explicit, deterministic merge rules:

1. Start with built-in baseline items for selected `--target`.
2. Load extension configs in fixed order: `$AGENT_HOME/AGENT_DOCS.toml` then `$PROJECT_PATH/AGENT_DOCS.toml`.
3. Consider only extension entries with `required = true` and `scope` included by `--target`.
4. Resolve each extension path, then de-dup by key: `(context, scope, normalized_path)`.
5. Same-key override order:
   - within one config file, later `[[document]]` wins (last-write-wins)
   - across files, project config wins over home config (loaded later)
6. Output order is stable:
   - built-ins stay in built-in declaration order
   - extension items keep first-seen key order; when overridden, the item is replaced in place

This ensures baseline output is reproducible while still honoring later overrides.

## `AGENT_DOCS.toml` Schema

Each scope may define `AGENT_DOCS.toml` at:

- `$AGENT_HOME/AGENT_DOCS.toml`
- `$PROJECT_PATH/AGENT_DOCS.toml`

Schema uses repeated `[[document]]` tables.

```toml
[[document]]
context = "project-dev"
scope = "project"
path = "BINARY_DEPENDENCIES.md"
required = true
when = "always"
notes = "Track required external CLIs for this project"
```

### Field contract

| Field | Type | Required | Rules |
| --- | --- | --- | --- |
| `context` | string | yes | One of: `startup`, `skill-dev`, `task-tools`, `project-dev` |
| `scope` | string | yes | One of: `home`, `project` |
| `path` | string | yes | Relative or absolute path to markdown doc |
| `required` | bool | no | Default `false` |
| `when` | string | no | Default `always`; supported values: `always` |
| `notes` | string | no | Free text, default empty string |

### Deterministic merge contract

For `resolve --context <ctx>`:

1. Start with built-in entries for `<ctx>`.
2. Load entries from `$AGENT_HOME/AGENT_DOCS.toml` (if file exists).
3. Load entries from `$PROJECT_PATH/AGENT_DOCS.toml` (if file exists).
4. Filter entries by exact `context == <ctx>`.
5. Normalize each entry path:
   - absolute path: keep as-is
   - relative path: join with root selected by entry `scope`
6. De-dup with merge key: `(context, scope, normalized_path)`.
7. Conflict resolution order:
   - built-in keys are immutable and cannot be removed or downgraded.
   - for non-built-in duplicates, later source wins (`project` config overrides `home` config).
   - within one file, later table wins (last-write-wins).
8. Final output order is stable:
   - built-ins in built-in declaration order
   - merged extension entries in load order after de-dup replacement

This merge behavior is deterministic and test-friendly.

### De-dup examples

- Same key appears twice in `$PROJECT_PATH/AGENT_DOCS.toml`: second entry wins.
- Same key appears in both home and project configs: project entry wins.
- Key matches built-in required doc (for example project `DEVELOPMENT.md` in `project-dev`): built-in contract remains required and present in output.

## Invalid Schema Behavior

If any `AGENT_DOCS.toml` entry is invalid, command exits `3` and prints actionable error.

### Error example: invalid context

```text
error[AGENT_DOCS_SCHEMA]: /Users/example/work/nils-cli/AGENT_DOCS.toml:4:11
invalid value for `context`: "project"
allowed: startup, skill-dev, task-tools, project-dev
```

### Error example: missing required field

```text
error[AGENT_DOCS_SCHEMA]: /Users/example/.agents/AGENT_DOCS.toml:1:1
missing required key `path` in [[document]]
```

### Error example: unsupported `when`

```text
error[AGENT_DOCS_SCHEMA]: /Users/example/work/nils-cli/AGENT_DOCS.toml:7:8
invalid value for `when`: "if-env:CI"
allowed: always
```

## Explicit `BINARY_DEPENDENCIES.md` Support Example

Add required `BINARY_DEPENDENCIES.md` for `project-dev` context.

CLI command:

```bash
agent-docs add \
  --target project \
  --context project-dev \
  --scope project \
  --path BINARY_DEPENDENCIES.md \
  --required \
  --when always \
  --notes "External runtime tools required by the repo"
```

Equivalent TOML entry:

```toml
[[document]]
context = "project-dev"
scope = "project"
path = "BINARY_DEPENDENCIES.md"
required = true
when = "always"
notes = "External runtime tools required by the repo"
```

`resolve --context project-dev` must include this document after merge, without removing built-in project `DEVELOPMENT.md`.

Verification command:

```bash
agent-docs resolve --context project-dev --format checklist \
  | rg "REQUIRED_DOCS_BEGIN|REQUIRED_DOCS_END|DEVELOPMENT\\.md|BINARY_DEPENDENCIES\\.md"
```

## Snapshot Fixture Maintenance

The `add` command has golden/snapshot fixtures under `tests/fixtures/add`.

- Run snapshot-related tests:

  ```bash
  scripts/ci/agent-docs-snapshots.sh
  ```

- Re-generate expected snapshots (`--bless`) and immediately verify:

  ```bash
  scripts/ci/agent-docs-snapshots.sh --bless
  ```

## Docs

- [Docs index]docs/README.md