This document describes the knobs. For the operator workflow, read Operator Manual. For the invariants behind these settings, read Architecture.
JSON Schema for Editor Tooling
A JSON Schema is available at
https://wstein.github.io/cx-cli/schemas/cx-config-v1.schema.json to
enable editor autocomplete, linting, and validation for cx.toml files.
Inherited overlays such as cx-mcp.toml can use
https://wstein.github.io/cx-cli/schemas/cx-config-overlay-v1.schema.json.
These files are the source of truth for the public Pages endpoints, and
the published npm package also ships schemas/ for offline use. GitHub
Releases mirror the same files as immutable snapshots. These schemas
validate structural shape and enforce enum constraints.
Published schema endpoints are latest-only. This is a breaking public contract: retired schema versions are removed from Pages and from the npm package instead of kept as compatibility endpoints.
Using the schema in VS Code with Taplo
Add the following comment directive to the top of your cx.toml:
#:schema https://wstein.github.io/cx-cli/schemas/cx-config-v1.schema.json
schema_version = 1
project_name = "myproject"
The schema directive comment is automatically included in generated
cx.toml files by cx init, and the MCP overlay template points at the
overlay schema. The TOML parser safely ignores these comments; they do
not affect `cx’s deterministic loading pipeline.
Use the published Pages URLs in checked-in repo files and external documentation so editors always resolve the same canonical schema location.
Schema validation vs. runtime validation
The JSON Schema provides structural validation for IDE and language server use. It ensures that:
-
Required fields exist (
schema_version,project_name,source_root,sections) -
Types are correct (strings, numbers, booleans, arrays)
-
Enum constraints are enforced (e.g.,
dedup.modemust befail,warn, orfirst-wins) -
Reserved section names (
manifest,assets,bundle) are forbidden
However, runtime validation in src/config/load.ts is the ultimate authority and enforces relational invariants that schemas cannot easily express:
-
A catch-all section must not specify
includepatterns -
Duplicate glob patterns are detected and handled per the configured mode
-
Project names are filesystem-safe
-
Pattern arrays contain no empty strings
The schema provides a fast, helpful ergonomic layer before running cx,
but cx load remains the deterministic, authoritative validator.
One-Level Inheritance for Agent Profiles
Project configs can opt into a single inheritance step by setting
extends at the top level:
extends = "cx.toml"
This is intended for colocated overlays such as cx-mcp.toml inheriting
from the local cx.toml baseline. The loader resolves the path relative
to the file that declares extends, loads the base config first, and
then overlays the child config on top.
Inheritance is deliberately shallow:
-
The base config must not declare its own
extends. -
A second inheritance hop is a hard error during loading.
-
Child values override base values for scalars and tables.
-
Array values concatenate so baseline exclusions remain in force.
This matters most for security-sensitive arrays such as files.exclude:
the inherited baseline stays present, and the child can only append more
entries.
File Discovery
cx builds the master file list from the version control system.
Section globs then classify files within that list; they never extend
it.
[files]
| Key | Default | Description |
|---|---|---|
|
|
Additional glob patterns to add to the VCS master list. |
|
|
Glob patterns removed from the master list after all inclusions. |
|
|
Whether to follow symbolic links during filesystem fallback discovery. |
|
|
What to do with master-list files not claimed
by any section: |
files.include extends the VCS-derived master list with files that
match the provided patterns. Use it when you need to bundle generated
artefacts that are intentionally not tracked by VCS. An empty list means
the master list is exactly the tracked set.
files.exclude removes paths from the master list after all
extensions have been applied. VCS-internal files are always excluded
regardless of this setting. Use exclude to keep scratch directories,
build output, or vendored trees out of planning entirely.
[sections.*]
Each section is declared as [sections.<name>] in
cx.toml.
| Key | Required | Default | Description |
|---|---|---|---|
|
Yes, unless |
— |
Glob patterns that select files from the master list for this section. |
|
No |
|
Glob patterns that remove files from this section after include matching. |
|
No |
|
Numeric priority for overlap resolution. Higher values win. |
|
No |
Inherits |
Output style: |
|
No |
|
If |
catch_all = true declares a sweep-up section. It runs after all
normal sections have claimed their files and absorbs whatever remains in
the master list. At most one catch-all section may be defined per
project.
[sections.rest]
catch_all = true
exclude = ["generated/**"]
Section globs are classifiers, not discoverers. An include pattern
can only select files already present in the master list. A pattern that
matches nothing does not cause an error; it simply contributes no files
to the section.
Example:
[sections.src]
include = ["src/**"]
exclude = ["src/**/*.test.ts"]
priority = 10
[sections.tests]
include = ["tests/**", "src/**/*.test.ts"]
priority = 5
Shared Handover
The shared handover is the single companion artifact that travels with the rendered section outputs. It can optionally include bounded repository history for operator and agent context.
[handover]
| Key | Default | Description |
|---|---|---|
|
|
Include recent Git, Mercurial, or Fossil commit messages in the shared handover when bundling from a supported VCS worktree. |
|
|
Maximum number of recent commit messages to include when repository history is enabled. |
Example:
[handover]
include_repo_history = true
repo_history_count = 25
When enabled, cx records the newest bounded commit messages in
deterministic newest-first order for Git, Mercurial, and Fossil
repositories. Multiline messages are preserved, diffs are never embedded
in the shared handover, and this setting does not affect proof-path
section outputs or manifest hashing rules.
For json bundles, both the shared handover and JSON section output
artifacts must satisfy their published schema-shaped contracts:
The repo also keeps the current source files in schemas/ for offline
use. Older schema versions are intentionally not retained on Pages or in
the package:
-
schemas/shared-handover-v2.schema.json -
schemas/json-section-output-v1.schema.json
Notes Gating
Notes remain conditional cognition, but higher-assurance pipelines can require bundled notes to meet a minimum effective cognition score before bundling proceeds.
[notes]
| Key | Default | Description |
|---|---|---|
|
unset |
Minimum effective cognition
score for gated notes. Uses the same drift- and contradiction-adjusted
scoring model as |
|
|
When |
|
|
When |
|
|
Optional section names whose bundled notes should be gated. When omitted, the gate applies to all bundled notes. |
Example:
[notes]
require_cognition_score = 80
strict_notes_mode = true
fail_on_drift_pressured_notes = true
applies_to_sections = ["docs"]
strict_notes_mode does not create a separate scoring system.
It uses the existing cognition labels and requires every gated note to
stay high_signal. When the gate is active, cx bundle aborts with
the same non-zero notes exit family used for malformed or duplicate
notes.
[notes.frontmatter.fields.<name>]
Note frontmatter fields can be constrained per project. Values are open by
default except for note ids, which must remain timestamp ids in
YYYYMMDDHHMMSS form.
| Key | Default | Description |
|---|---|---|
|
field-specific |
Whether the field must be present. |
|
|
Field type. Supported values are |
|
|
Optional allowed values. Entries can be exact strings,
wildcards using |
Example:
[notes.frontmatter.fields.tags]
required = false
type = "string_array"
values = ["/^[a-z][a-z0-9-]*$/"]