The config command group reads and edits .codecharter/config.yml for you.
Every write keeps your comments, key order, and formatting intact, validates
the change before touching the file, and never leaves the file half-written.
codecharter config <subcommand> [arguments] [options]
For the configuration file format itself — profiles, parameters, severities, rule activation, and path scopes — see Configuration file. This page covers the commands that change it.
Inspecting the configuration
codecharter config explain <path>shows the effective configuration for one source file, with the layer each value came from. Add--jsonfor machine-readable output.codecharter config validatechecks the file for structural errors, unknown rules, invalid parameter values, and entries that never match anything.codecharter config schemaemits a JSON Schema for editor completion. Pass--out <file>to write it to disk.codecharter config get <key>prints the raw value of a single key.codecharter config list [section]prints a summary of all sections, or the entries of one section (profiles,params,overrides,ignore,include,exclude,scopes,coverage).
get takes a dotted key: params.<rule>.<name>, overrides.<rule>.severity,
profiles.<slug>, or one of the scalar coverage keys
coverage.minimum-percent, coverage.snippet-context-lines and
coverage.max-parallel-test-projects. Add --scope "<glob>" to read from a scope
whose match equals that glob instead of the base layer.
Editing values: set and unset
codecharter config set <key> <value> [--scope <glob>] [--local] [--dry-run] [--rules <dir>]
codecharter config unset <key> [--local] [--dry-run]
set writes a parameter, a severity override, or a profile version:
codecharter config set params.cyclomatic-complexity.max 15
codecharter config set overrides.magic-number.severity warning
codecharter config set profiles.dotnet-base 1.4.2
codecharter config set coverage.minimum-percent 99.5
The value is validated before the file is written: an unknown rule, a parameter
the rule does not expose, an out-of-range value, or an invalid severity is
rejected and the file is left untouched (exit code 10). unset removes a
params or overrides entry again.
To validate parameter values against your rules, point --rules at a directory
of .ccr files. When omitted, ./rules is tried, the same discovery
analyze uses.
Managing lists: add and remove
codecharter config add <section> [value] [--in <ns>] [--match <glob>] [--path <file>] [--scope <glob>] [--local] [--dry-run]
codecharter config remove <section> [value] [--in <ns>] [--match <glob>] [--path <file>] [--scope <glob>] [--local]
add and remove manage the list-valued sections:
codecharter config add exclude "**/Migrations/**"
codecharter config add profiles security@latest
codecharter config add ignore todo-comment --in Acme.Generated
codecharter config add include todo-comment --match "*Dto"
codecharter config add coverage.exclude "**/*.Designer.cs"
For ignore and include, --in narrows the entry to a namespace and
--match to entities whose reported name matches a glob. For a type, method,
property, or field that name is fully qualified (namespace plus simple name)
and a pattern without a leading * must start at the namespace root; events
and occurrence-level entities (parameters, member accesses, literals, and the
like) are reported under their plain, unqualified name instead. For profiles,
use --path to reference a local bundle file instead of a slug. remove deletes the matching
entry; an ambiguous removal that matches more than one entry is reported as a
usage error rather than guessing.
Coverage keys
The coverage gate is configured the same way, with two
differences. Its three scalar keys — minimum-percent, snippet-context-lines
and max-parallel-test-projects — go through set/unset/get, while the two
glob lists are managed as coverage.exclude and coverage.excluded-directories
through add/remove. And because the
section is repository-wide, --scope is rejected on any coverage key;
--local, --dry-run, promote, and demote work as they do everywhere else.
codecharter config set coverage.max-parallel-test-projects 1
codecharter config add coverage.excluded-directories "vendor/**"
config list coverage prints the keys your file actually sets, the scalars as
key: value and every glob on its own exclude: or excluded-directories:
line. In the summary the
section counts set keys rather than entries, so coverage: 2 means two of the
five keys are configured. A key you never set is left out instead of being
shown with its built-in default.
Targeting scopes and the local overlay
Two options change where a write lands; they apply to set, unset, add,
and remove:
--scope "<glob>"writes into the scope whosematchequals that glob, creating the scope at the end of the file if it does not exist yet. Without it, writes go to the base layer.--localtargets.codecharter/config.local.yml— your personal, machine-local overlay — instead of the committedconfig.yml.
--dry-run prints the unified diff of what would change and writes nothing.
Combine it with any write to preview the edit first.
Scaffolding and cleanup: init and tidy
codecharter config init [--at <dir>] [--profiles <csv>] [--local] [--force] [--dry-run]
codecharter config tidy [--local] [--dry-run]
init creates a minimal .codecharter/config.yml (just version: 1). Seed
profiles with --profiles "dotnet-base@1.4.2,security@latest", choose the
directory with --at, create the local overlay instead with --local, and
overwrite an existing file with --force.
init also ensures .codecharter/cache/ is listed in .gitignore (creating
the file if it does not exist, appending the entry if a narrower one is
missing) so the disk caches several tools use — restore's bundle cache and
graph diff's per-revision snapshot cache among them —
never end up committed by accident. A repo that already ignores the whole
.codecharter/ directory, or already carries the entry, is left untouched.
This step is best-effort: an I/O failure here never fails init itself, since
the config file it scaffolds has already succeeded.
tidy removes empty sections that earlier edits may have left behind, keeping
the file clean.
The local overlay: config local
codecharter config local clone [--force] [--dry-run]
codecharter config local diff
codecharter config local clear [keys...] [--dry-run]
.codecharter/config.local.yml overrides config.yml on your machine and is
never committed (add it to .gitignore). The local subgroup manages it:
clonecopies the committed config toconfig.local.ymlas a starting point.--forceoverwrites an existing overlay.diffshows what the overlay currently overrides.clearremoves specific dotted keys from the overlay, or deletes the whole overlay file when no keys are given.
Moving settings between layers: promote and demote
codecharter config promote [key] [--all] [--keep] [--dry-run] [--rules <dir>]
codecharter config demote [key] [--all] [--dry-run] [--rules <dir>]
promotemoves a setting out of your local overlay into the committedconfig.yml— for when a personal tweak should become the team default.--keepcopies instead of moving (the entry stays in the overlay), and--allpromotes the entire overlay and then clears it.demotecopies a committed setting into your local overlay, so you can then let it float locally without changing the shared file.--allcopies the whole committed config into the overlay.
A common pattern: demote profiles.dotnet-base followed by
set profiles.dotnet-base latest --local pins the team to an exact version
while you track the newest on your machine.
Exit codes
The reading commands get and list use:
0: success.1: no.codecharter/config.ymlwas found.2: usage error (for example an unparseable key).
The editing commands (set, unset, add, remove, init, tidy, the
local subgroup, promote, demote) use:
0: success, including--dry-runpreviews.2: usage error (bad arguments, or an ambiguousremove).10: validation error — the change was rejected and the file left untouched.