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.tomlentries. - Remote policy sync or network-backed policy lookups.
Path Resolution Precedence
Path resolution is deterministic and applies to all commands.
AGENT_HOME
--agent-home <path>(command flag)AGENT_HOMEenvironment variable$HOME/.agents
PROJECT_PATH
--project-path <path>(command flag)PROJECT_PATHenvironment variablegit rev-parse --show-toplevelfrom current working directory- current working directory
Normalization Rules
- Paths are normalized lexically (
.removed, duplicate separators collapsed). - Relative document paths in
AGENT_DOCS.tomlare resolved from their declaredscoperoot. - Absolute document paths are kept absolute and ignore scope root joining.
Scope and Context Model
Scopes
home: rooted at effectiveAGENT_HOMEproject: rooted at effectivePROJECT_PATH
Built-in contexts
startupskill-devtask-toolsproject-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
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 code1)--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 forpathresolution)--path <doc-path>(required)--required(setrequired=true; omitted meansrequired=false)--when <condition>(default:always)--notes <text>--agent-home <path>--project-path <path>
Copy-pastable resolve + add flow
# 1) Resolve built-in project-dev requirements
# 2) Register BINARY_DEPENDENCIES.md as required for project-dev
add stdout shape:
add: target=project action=<inserted|updated> config=<PROJECT_PATH>/AGENT_DOCS.toml entries=<N>
Verify both built-in and extension docs are present:
|
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 code1)--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 (--strictand one or more required docs missing)2: usage error (invalid flags, invalid command, missing required argument)3: config/schema error (AGENT_DOCS.tomlinvalid)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 remains0.
baseline --strict
- Evaluates baseline required docs for selected target scope(s).
- Missing required baseline docs cause exit
1only when--strictis 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:
<PROJECT_PATH>/AGENTS.override.md<PROJECT_PATH>/AGENTS.md<PRIMARY_WORKTREE_PATH>/AGENTS.override.md(fallback)<PRIMARY_WORKTREE_PATH>/AGENTS.md(fallback)
project-dev required project docs (built-ins and required project-scope extension entries):
<PROJECT_PATH>/<doc-path><PRIMARY_WORKTREE_PATH>/<doc-path>(fallback)
Strict and compatibility semantics
--strictexits1only when all candidates in the deterministic order are missing.local-onlymode 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.
Output Contract
resolve text example
$ 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
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>.
$ 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.
$ 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
$ 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
baseline extension merge order (deterministic)
baseline --check applies extension documents with explicit, deterministic merge rules:
- Start with built-in baseline items for selected
--target. - Load extension configs in fixed order:
$AGENT_HOME/AGENT_DOCS.tomlthen$PROJECT_PATH/AGENT_DOCS.toml. - Consider only extension entries with
required = trueandscopeincluded by--target. - Resolve each extension path, then de-dup by key:
(context, scope, normalized_path). - Same-key override order:
- within one config file, later
[[document]]wins (last-write-wins) - across files, project config wins over home config (loaded later)
- within one config file, later
- 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.
[[]]
= "project-dev"
= "project"
= "BINARY_DEPENDENCIES.md"
= true
= "always"
= "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>:
- Start with built-in entries for
<ctx>. - Load entries from
$AGENT_HOME/AGENT_DOCS.toml(if file exists). - Load entries from
$PROJECT_PATH/AGENT_DOCS.toml(if file exists). - Filter entries by exact
context == <ctx>. - Normalize each entry path:
- absolute path: keep as-is
- relative path: join with root selected by entry
scope
- De-dup with merge key:
(context, scope, normalized_path). - Conflict resolution order:
- built-in keys are immutable and cannot be removed or downgraded.
- for non-built-in duplicates, later source wins (
projectconfig overrideshomeconfig). - within one file, later table wins (last-write-wins).
- 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.mdinproject-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
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
error[AGENT_DOCS_SCHEMA]: /Users/example/.agents/AGENT_DOCS.toml:1:1
missing required key `path` in [[document]]
Error example: unsupported when
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:
Equivalent TOML entry:
[[]]
= "project-dev"
= "project"
= "BINARY_DEPENDENCIES.md"
= true
= "always"
= "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:
|
Snapshot Fixture Maintenance
The add command has golden/snapshot fixtures under tests/fixtures/add.
-
Run snapshot-related tests:
-
Re-generate expected snapshots (
--bless) and immediately verify: