Skip to content

.cadence/config.yaml

.cadence/config.yaml is Cadence’s per-repo settings file. It lives at the repo root under .cadence/ and tells the commands where your designs and plans live, how plans get split and committed, which audits run, and how parallel execution behaves. Every key has a built-in default, so the file only needs to hold the values you want to change.

The canonical default for every key (with inline comments) ships at defaults/config.default.yaml. Your repo’s .cadence/config.yaml overrides only what differs from those defaults. There is no need to copy the whole file.

When a team commits .cadence/config.yaml to share settings, personal preferences need somewhere else to live. That place is .cadence/config.local.yaml: a gitignored sibling file holding only the keys you personally override. Resolution reads three layers in order, and the last layer that defines a key wins for that key:

  1. Plugin defaults (defaults/config.default.yaml)
  2. The repo’s .cadence/config.yaml (the team’s settings)
  3. Your .cadence/config.local.yaml (yours alone, never committed)

The local file is sparse: it contains only overrides, carries no config_version, and the config migrator never touches it. A typical one is a few lines:

.cadence/config.local.yaml
execute:
max_parallel: 2 # this laptop can't take the team default
worktree_confirm: false
authoring:
design_mode: all-at-once

Keys intended for local override are the per-person, per-machine ones: execute.max_parallel, execute.worktree_confirm, authoring.max_parallel, authoring.design_mode, authoring.plan_mode, mockups.dir, and the validate.browser_* and advisors.* keys. Everything else (paths, statuses, audits, plan policy, the whole worktree: section) is team policy: a local override of those still works, but Cadence prints a one-line notice so the divergence is never silent.

A single top-level integer that records which config schema this file was written against. It drives migration detection when Cadence’s schema changes.

KeyControlsDefaultAllowed values
config_versionSchema version of this file; used to detect when a migration is needed.8Integer

Where Cadence reads and writes documents. Paths are relative to the repo root. Commands resolve <paths.designs> / <paths.plans> from here, so changing these moves the whole document tree.

KeyControlsDefaultAllowed values
paths.designsFolder that holds design folders.docs/designsRepo-relative path
paths.plansFolder that holds plan folders.docs/plansRepo-relative path
paths.futureFolder for “future” / parking-lot notes (e.g. thought-partner /c-brainstorm notes).docs/futureRepo-relative path
paths.configFolder that holds this config and Cadence’s working state..cadenceRepo-relative path

Where Cadence keeps its artifacts (brainstorm stubs, designs, and plans). The backend is filesystem by default, exactly today’s behavior; setting backend: notion moves those artifacts into two Notion databases instead, leaving source code and git commits untouched. The whole storage block is team policy: it belongs in the committed .cadence/config.yaml, never in the personal .cadence/config.local.yaml overlay.

KeyControlsDefaultAllowed values
storage.backendWhich backend stores designs, plans, and stubs. filesystem keeps them as markdown folders under paths.*; notion stores them as rows in two Notion databases.filesystemfilesystem | notion
storage.notion.root_pageThe Notion page Cadence provisions the two databases under. A page URL or id you own, shared with the official Notion MCP’s integration. Required when backend is notion."" (empty)Notion page URL or id
storage.notion.designs_dbThe Designs database id. Left empty by you; auto-filled on the first Notion-mode run, then committed so the team shares it."" (empty)Notion database id (auto-filled)
storage.notion.plans_dbThe Plans database id. Left empty by you; auto-filled on the first Notion-mode run, then committed so the team shares it."" (empty)Notion database id (auto-filled)

With backend: filesystem (the default) the notion.* keys are ignored and nothing changes. To opt in, set backend: notion, fill notion.root_page, and leave the two *_db keys empty: the first Notion-mode run creates the databases and writes their ids back into the committed config. See the Notion mode reference for the full setup walkthrough.

Where mockup HTML files are written. A design that opts into the 95-visual-contract slot stores its mockups as local HTML files, on every storage backend, and records each version’s file:// URL in the 95 index.

KeyControlsDefaultAllowed values
mockups.dirThe directory mockup HTML is written to. A relative value resolves against the repo root; an absolute one is taken as given. The directory is created when missing.null (unset)Path, or null

How null resolves depends on the backend:

mockups.dirBackendResolves to
seteither<mockups.dir>/<slug>/
nullfilesystem<paths.designs>/<slug>/mockups/, the design’s own subfolder
nullnotionUnresolvable, so /c-design asks once before writing version 01

How /c-plan shapes the plan it writes.

KeyControlsDefaultAllowed values
plan.tddWhether plans bake in a test-driven workflow (write the test, then the code).truetrue | false
plan.commit_cadenceHow often the plan commits during execution.per-taskper-task (other cadences are judgment-based)
plan.parallel_grainThe finest granularity at which tasks within one plan may run in parallel. per-file keeps each file to one lane; in-file allows lanes to split work within a single file. Not set in the defaults file. Add it under plan to opt in.unset (per-file behaviour)per-file | in-file

There are deliberately no split thresholds. Whether and where to split a plan into phase docs is a judgment call /c-plan makes, not a number you tune. See Parallelism and worktrees for how grain relates to execution lanes.

How /c-execute drives a plan to implemented code, including the parallel-lane machinery. The 01-… / 02-… files inside a single plan are its phases; the keys below govern how those phases run, in lanes that may use git worktrees.

KeyControlsDefaultAllowed values
execute.branch_checkRefuse to start unless you’re on an appropriate branch.truetrue | false
execute.auto_resolve_driftAuto-resolve drift between plan and code instead of surfacing it for a decision.falsetrue | false
execute.parallelMaster switch for parallel execution. When false, execution is the legacy sequential path (sub-agents, no worktrees) and execute.mode is ignored.truetrue | false
execute.modePre-flight execution-mode gate: ask presents parallel lanes (recommended) vs inline sequential, parallel runs the lane engine, inline runs every task in the PM session itself — no worktrees, no implementer sub-agents (the completion audit stays a sub-agent).askask | parallel | inline
execute.max_parallelMaximum concurrent implementer lanes (one worktree per lane). Reviewers are uncapped.4Positive integer
execute.worktree_confirmShow a one-time pre-flight confirmation before creating worktrees.truetrue | false
execute.resume_on_dirty_treeAllow resuming execution when the working tree is dirty.falsetrue | false

See Parallelism and worktrees for the model behind lanes and the max_parallel cap. Where lane worktrees live and how they merge back is governed by the worktree section below.

The shared git-worktree lifecycle: where worktrees live, how branches go home, the merge lock, and the optional repo-specific hooks. Two commands read this section: /c-worktree (the interactive lifecycle) and /c-execute (its parallel lanes use dir and integrate, and its merge-on-land honors the lock).

KeyControlsDefaultAllowed values
worktree.dirWhere worktrees are created: interactive /c-worktree worktrees and /c-execute lane worktrees alike. Relocated from execute.worktree_dir..cadence/worktreesRepo-relative path
worktree.integrateHistory policy when a worktree branch merges back. Relocated from execute.integrate.rebase-ffrebase-ff | merge-commit
worktree.merge_lockWhether local merges acquire the shared repo-global merge lock, so concurrent merges serialize instead of colliding. Honored by /c-worktree’s local-merge exit and /c-execute’s lane landings; /c-worktree’s PR exit performs no local merge and never takes it.truetrue | false
worktree.lock_stale_thresholdSeconds after which a held lock is reported stale and surfaced as a “steal it?” question. Never auto-stolen.600Positive integer (seconds)

Six optional shell-command hooks let a repo plug its own scripts into fixed lifecycle points. Every hook is null by default, and a null hook means that lifecycle phase simply does not exist; with all hooks empty, /c-worktree runs its generic core only.

KeyControlsDefaultAllowed values
worktree.hooks.provisionRuns after git worktree add (dependency install, env files, similar setup).nullShell command string or null
worktree.hooks.provision_verifyRuns after provision to assert the worktree environment is usable; non-zero surfaces the output and offers repair / remove / keep.nullShell command string or null
worktree.hooks.port_assignAllocates a dev port for the worktree. Must print the port to stdout.nullShell command string or null
worktree.hooks.port_releaseFrees the worktree’s port at cleanup.nullShell command string or null
worktree.hooks.dev_serverStarts the worktree’s dev server.nullShell command string or null
worktree.hooks.deploy_guardExits non-zero when a deploy is not allowed from the current location; the deploy is then refused.nullShell command string or null
  • Environment. Every hook runs with WT_PATH (absolute worktree path), MAIN_ROOT (absolute main-worktree path), and BRANCH (the worktree’s branch) exported. dev_server additionally gets DEV_PORT, captured from port_assign’s stdout or read back from git config branch.<branch>.devPort.
  • Working directory. provision, provision_verify, port_assign, and dev_server run with cwd = $WT_PATH. port_release runs with cwd = $MAIN_ROOT (the worktree may already be removed). deploy_guard runs in the directory the deploy was attempted from: that location is what it judges.
  • Stdout. Only port_assign’s stdout carries meaning (the assigned port, persisted as git config branch.<branch>.devPort). Every other hook’s output is informational and shown to you. provision’s stderr is shown at create time even on a zero exit, so a best-effort provisioner’s warnings surface immediately rather than at the first push.
  • Non-zero exit. provision: surfaced, with an offer to remove the half-created worktree. provision_verify: surfaced, with an offer to repair (re-run provision, then re-verify), remove the worktree, or keep it as-is. port_assign: surfaced; the lifecycle continues without a port, and the dev-server phase is then unavailable. dev_server: surfaced. port_release: surfaced, but cleanup continues. deploy_guard: the deploy is refused, with an explanation of the merge-first-then-deploy-from-main flow.

See the /c-worktree reference for the phase-by-phase lifecycle these keys drive.

How doc-generator agents run when /c-design materializes a design folder. These agents do not use worktrees (they only write docs), so they are cheap to parallelize.

KeyControlsDefaultAllowed values
authoring.max_parallelMaximum concurrent doc-generator agents.6Positive integer
authoring.design_modeStanding default for how /c-design writes child docs: ask prompts you, all-at-once generates in parallel, one-by-one writes sequentially with a review per doc, inline writes every doc in the main session with no sub-agents or pauses.askask | all-at-once | one-by-one | inline
authoring.plan_modeStanding default for how /c-plan writes plan docs: ask prompts you, all-at-once generates in parallel, inline writes every doc in the main session.askask | all-at-once | inline

Opt-in advisor personas that can weigh in during brainstorm and design. Disabled by default.

KeyControlsDefaultAllowed values
advisors.enabledWhether advisors are offered at all.falsetrue | false
advisors.rosterThe set of advisor personas available when enabled.[] (empty)List of advisor entries

See Advisors for what advisors are and how the roster is defined.

Conventions for naming design/plan folders.

KeyControlsDefaultAllowed values
naming.date_formatDate stamp used in folder slugs.YYYY-MM-DDDate format string
naming.slug_caseCasing for the slug portion of folder names.kebabkebab (and similar case styles)

The allowed status values for design and plan documents. The order matters: it is the lifecycle progression Cadence expects.

KeyControlsDefaultAllowed values
status.designValid statuses for a design.[draft, in-review, approved, completed, superseded, on-hold]List of status strings
status.planValid statuses for a plan.[draft, in-progress, implemented, completed, superseded, on-hold]List of status strings

Frontmatter requirements Cadence enforces on documents it writes.

KeyControlsDefaultAllowed values
frontmatter.requiredFrontmatter keys that must be present on every document.[title, created, updated, status, tags]List of key names

Which checks /c-audit (and the completion auditor) run, split into blocking checks, non-blocking warnings, and an optional set. The build_validator sub-block configures the build check.

KeyControlsDefaultAllowed values
audits.defaultAudit checks that run and block on failure.checkbox-completeness, oos-justification, deferred-comment-scan, code-behind-checkbox, design-intent-alignment, build-validator, merge-integrityList of audit names
audits.warningsChecks that run but only warn (non-blocking).file-map-honesty, design-plan-consistency, validation-doc-presenceList of audit names
audits.optionalChecks available but off by default.[] (empty)List of audit names
audits.build_validator.commandShell command the build-validator audit runs. null means no build command is run.nullShell command string or null
audits.build_validator.expect_zero_exitTreat a non-zero exit from the build command as a failure.truetrue | false

How Cadence writes the plain-English narrative that accompanies designs.

KeyControlsDefaultAllowed values
plain_english.section_calloutAdd a callout marking the plain-English section.truetrue | false
plain_english.always_write_00aAlways write the 00a plain-English companion doc.truetrue | false
plain_english.length_targetTarget word-count range for the narrative."400-700"Range string

Rules for out-of-scope (OOS) entries in designs and plans.

KeyControlsDefaultAllowed values
oos.require_rationaleRequire a written rationale for each out-of-scope item.truetrue | false
oos.require_wikilinkRequire a wikilink (pointer) for each out-of-scope item.truetrue | false

How /c-validate walks a plan’s 96-validation.md post-deploy, including how it runs browser/automated checks.

KeyControlsDefaultAllowed values
validate.reset_checkboxes_on_rerunClear validation checkboxes when validation is re-run.truetrue | false
validate.browser_driverWhich driver runs browser-based checks. auto detects, playwright forces Playwright, manual walks you through by hand.autoauto | playwright | manual
validate.browser_commandThe CLI test command Cadence delegates browser checks to."npx playwright test"Shell command string
validate.browser_env_preambleOptional shell snippet run before the browser command (e.g. to set env vars). null means none.nullShell snippet string or null

Defaults for /c-find-bugs.

KeyControlsDefaultAllowed values
find_bugs.default_baselineThe git ref bug-finding diffs against by default.mainGit ref
find_bugs.excludePaths excluded from the bug scan.[node_modules, dist, build, __pycache__, target, .next, vendor]List of paths

This repo dogfoods Cadence, and its own .cadence/config.yaml is a good example of the “override only what differs” pattern. It keeps the default paths and audits, bumps execute.max_parallel to 5, and opts into plan.parallel_grain: in-file. The trimmed shape below shows the blocks that have arrived over the last few schema bumps: worktree: (relocated out of execute: in config_version: 4), storage: (new in 5), execute.mode (new in 7), and mockups: (new in 8). Each of those bumps is additive, so scripts/migrate-config.js appends the new block or key verbatim and leaves your values and comments alone:

config_version: 8
paths:
designs: docs/designs
plans: docs/plans
future: docs/future
config: .cadence
plan:
tdd: true
commit_cadence: per-task
parallel_grain: in-file
execute:
branch_check: true
auto_resolve_drift: false
max_parallel: 5
resume_on_dirty_tree: false
parallel: true
worktree_confirm: true
mode: ask
worktree:
dir: .cadence/worktrees
integrate: rebase-ff
merge_lock: true
lock_stale_threshold: 600
advisors:
enabled: false
roster: []
storage:
backend: filesystem
notion:
root_page: ""
designs_db: ""
plans_db: ""
mockups:
dir: null # filesystem backend: the design's own mockups/ subfolder
Built by Sentasity MIT licensed