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

# Config file

> Commit your repo's version policy to zerv.toml once. Shared by version and flow; CLI flags still win.

Commit your repo's stable version policy to a `zerv.toml` once instead of repeating the same
flags on every zerv invocation.

## Discovery

`zerv` walks up from the current directory to the nearest VCS repository root (Git's `.git`
today) and reads `zerv.toml` there, or the hidden `.zerv.toml` fallback. Config is
**repo-scoped**: one policy per repo, no subdirectory shadowing, so a version never depends
on which directory you run from.

```bash theme={null}
# Commit a zerv.toml at your repo root (stable fields only)
cat > zerv.toml <<'EOF'
source          = "stdin"
output_template = "v{{ major }}.{{ minor }}.{{ patch }}"
EOF

# zerv reads zerv.toml automatically; no flags repeated
# (stdin carries the version payload; in a git repo use source = "git")
zerv version
# → v1.2.3

# Shared-top fields shape flow too
zerv flow --schema standard
# → v1.2.3

# A CLI flag still wins over the file
zerv version --output-template "release-{{ major }}"
# → release-1
```

## Precedence

Top wins:

```
CLI flag  >  --config-file <path>  >  discovered zerv.toml  >  builtin default
```

`--config-file <path>` reads that file **instead of** discovering `zerv.toml`; the
discovered file is never read. Pass the null device to disable config entirely: the empty
file yields no overrides, restoring builtin behavior. There is no `--no-config` flag; the
null device is the escape hatch (`/dev/null` on Unix and macOS, `NUL` on Windows).

```bash theme={null}
# An explicit --config-file is read instead of discovering zerv.toml
cat > explicit.toml <<'EOF'
source          = "stdin"
output_template = "EXPL{{ major }}"
EOF

zerv --config-file ./explicit.toml version
# → EXPL1

# The null device disables all config (the empty file yields no overrides).
# /dev/null on Unix and macOS, NUL on Windows.
zerv --config-file /dev/null version
# → 1.2.3
```

## File structure

Stable fields live at the shared top (apply to both subcommands); `[version]` and `[flow]`
sections override per-subcommand:

```toml theme={null}
# shared top: applies to every subcommand
source          = "stdin"
output_format   = "semver"
output_template = "v{{ major }}.{{ minor }}.{{ patch }}"
schema          = "standard-context"

[version]                 # optional: override the shared schema for `version` only
schema = "standard-no-context"

[flow]                    # flow-only stable policy
post_mode         = "tag"
pre_release_label = "beta"
hash_branch_len   = 7
```

<Note>
  `output_prefix` and `output_template` conflict: they cannot both be set. Put the prefix
  directly in the template (`"v{{ major }}..."`), or use `output_prefix` with `output_format`
  and no template.
</Note>

Ephemeral per-build fields (`--dirty`, `--bump-minor`, `--major`, …) are **not** allowed in
the file: a typo'd or stale key fails loud at parse (`deny_unknown_fields`) rather than
shipping silently on the next CI run.
