Configuration
Purpose
The configuration system manages pave’s .pave.toml file, which controls documentation paths, validation rules, and template settings. It provides a consistent way to customize pave’s behavior per-project.
Non-goals:
- Not a global user configuration (each project has its own
.pave.toml) - Not environment variable overrides (all config is in the TOML file)
- Not configuration inheritance (no layered or merged configs)
Interface
Config File Location
Pave discovers configuration by searching for .pave.toml starting from the current directory and walking up to parent directories. The first file found is used.
project/
├── .pave.toml <- Found here
├── src/
│ └── main.rs
└── docs/
└── components/
└── foo.md <- Running from here still finds root config
PaveConfig Structure
The configuration is divided into sections:
| Section | Required | Description |
|---|---|---|
[pave] |
Yes | Tool metadata (version) |
[docs] |
Yes | Documentation paths |
[rules] |
No | Validation rules |
[templates] |
No | Template file mappings |
[mapping] |
No | Code-to-doc mapping settings |
[hooks] |
No | Git hooks configuration |
CLI Commands
pave config get <key> # Get a config value by dot notation
pave config set <key> <value> # Set a config value
pave config list # Show all configuration values
pave config path # Show path to config file
Configuration
[pave] Section
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
version |
string | Yes | "0.1" |
Configuration schema version |
[docs] Section
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
root |
path | Yes | "docs" |
Root directory for documentation |
templates |
path | No | None | Directory where custom templates are stored |
[rules] Section
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
max_lines |
integer | No | 300 |
Maximum lines per document |
require_verification |
boolean | No | true |
Require Verification section in documents |
require_examples |
boolean | No | true |
Require Examples section in documents |
strict_output_matching |
boolean | No | false |
Fail verification if output doesn’t match expected patterns |
[templates] Section
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
component |
string | No | None | Filename for component template |
runbook |
string | No | None | Filename for runbook template |
adr |
string | No | None | Filename for ADR template |
When set, pave looks for templates at {docs.templates}/{templates.<type>}. If not found, built-in templates are used.
[mapping] Section
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
exclude |
string[] | No | [] |
Glob patterns to exclude from code-to-doc mapping |
Exclude patterns support glob syntax:
target/- excludes the target directory*.generated.rs- excludes generated Rust filesnode_modules/- excludes node_modules
[hooks] Section
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
run_verify |
boolean | No | false |
Run pave verify in git hooks |
Verification
Verify configuration is loaded correctly:
./target/release/pave config path
Check that configuration is used by other commands:
./target/release/pave check docs/index.md
Examples
Minimal Configuration
The minimum viable .pave.toml:
[pave]
version = "0.1"
[docs]
root = "docs"
Full Configuration
A complete configuration with all options:
[pave]
version = "0.1"
[docs]
root = "docs"
templates = "templates"
[rules]
max_lines = 300
require_verification = true
require_examples = true
strict_output_matching = false
[templates]
component = "component.md"
runbook = "runbook.md"
adr = "adr.md"
[mapping]
exclude = ["target/", "node_modules/", "*.generated.rs"]
[hooks]
run_verify = true
Custom Docs Location
For projects with non-standard documentation paths:
[pave]
version = "0.1"
[docs]
root = "documentation"
templates = "documentation/templates"
Relaxed Validation Rules
For projects that don’t need strict validation:
[pave]
version = "0.1"
[docs]
root = "docs"
[rules]
max_lines = 500
require_verification = false
require_examples = false
Using Config Commands
# Show where config file is located
$ pave config path
/path/to/project/.pave.toml
# List all configuration
$ pave config list
docs.root = "docs"
docs.templates = "templates"
pave.version = "0.1"
rules.max_lines = 300
rules.require_examples = true
rules.require_verification = true
# Get a specific value
$ pave config get rules.max_lines
300
# Change a value
$ pave config set rules.max_lines 500
Gotchas
- Config not found: Pave searches from the current directory up to the filesystem root. If no
.pave.tomlis found, commands fail with an error. Runpave initto create one. - Empty values rejected:
pave.versionanddocs.rootcannot be empty strings. Validation fails if they are. - Zero max_lines invalid:
rules.max_linesmust be greater than 0. - Template path is relative:
docs.templatesis relative to the project root, not todocs.root. - Dot notation for nested keys: Use
docs.rootnot[docs] rootwhen usingpave config get/set. - Type coercion:
pave config setauto-detects types."300"becomes integer300,"true"becomes booleantrue. Quote strings if needed.
Decisions
Why TOML? TOML is human-readable, widely supported, and matches Cargo’s config format. It’s simple enough for both humans and AI agents to reliably edit.
Why no environment variable overrides? Simplicity. All configuration is in one place, making it easier to understand and debug. Projects needing env-based config can use wrapper scripts.
Why no config inheritance? Each project should be self-contained. Config inheritance creates implicit dependencies that are hard to reason about, especially for AI agents.
Why strict defaults for sections? require_verification and require_examples default to true because these sections are essential for useful documentation. Projects can opt out explicitly.
Why per-project config? Documentation standards vary by project. A monorepo might have different rules for different packages. Global config would be too inflexible.
Paths
src/config.rssrc/commands/config.rs