---
title: Configurability
description: "Everything ships as files in your repo \u2014 markdown agents, markdown skills, JSON config. Change what you need, from CLI commands to source-level edits. The parts that make verification work are fixed by design."
readingTime: 8
---

## CLI-supported settings

Settings the CLI manages for you. Change them with commands or `ana.json` edits — both survive `ana init`.

<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px",margin:"14px 0 18px"}}>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",background:"var(--bg-card)",border:"1px solid var(--border-soft)"}}>
<div style={{fontWeight:600,fontSize:"13px",marginBottom:"4px",color:"var(--fg)"}}>Agent models</div>
<div style={{fontSize:"12.5px",color:"var(--ink-60)",lineHeight:1.5}}>Each agent can run a different model.</div>
<div style={{fontFamily:"var(--font-mono)",fontSize:"11px",marginTop:"8px",color:"var(--ink-45)"}}>ana agents model ana-build sonnet</div>
</div>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",background:"var(--bg-card)",border:"1px solid var(--border-soft)"}}>
<div style={{fontWeight:600,fontSize:"13px",marginBottom:"4px",color:"var(--fg)"}}>Any ana.json field</div>
<div style={{fontSize:"12.5px",color:"var(--ink-60)",lineHeight:1.5}}>Read or write config values. Validates field types.</div>
<div style={{fontFamily:"var(--font-mono)",fontSize:"11px",marginTop:"8px",color:"var(--ink-45)"}}>ana config set branchPrefix "ana/"</div>
</div>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",background:"var(--bg-card)",border:"1px solid var(--border-soft)"}}>
<div style={{fontWeight:600,fontSize:"13px",marginBottom:"4px",color:"var(--fg)"}}>Build / test / lint commands</div>
<div style={{fontSize:"12.5px",color:"var(--ink-60)",lineHeight:1.5}}>Every agent reads these. Init detects them; you override. For monorepos, override per surface: <code>ana config set surfaces.cli.commands.test &quot;your-command&quot;</code></div>
<div style={{fontFamily:"var(--font-mono)",fontSize:"11px",marginTop:"8px",color:"var(--ink-45)"}}>ana config set commands.test "pnpm test -- --run"</div>
</div>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",background:"var(--bg-card)",border:"1px solid var(--border-soft)"}}>
<div style={{fontWeight:600,fontSize:"13px",marginBottom:"4px",color:"var(--fg)"}}>Merge strategy</div>
<div style={{fontSize:"12.5px",color:"var(--ink-60)",lineHeight:1.5}}>Set the GitHub PR merge method for <code>ana work complete --merge</code>. Valid values: <code>merge</code>, <code>squash</code>, <code>rebase</code>.</div>
<div style={{fontFamily:"var(--font-mono)",fontSize:"11px",marginTop:"8px",color:"var(--ink-45)"}}>ana config set mergeStrategy "squash"</div>
</div>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",background:"var(--bg-card)",border:"1px solid var(--border-soft)"}}>
<div style={{fontWeight:600,fontSize:"13px",marginBottom:"4px",color:"var(--fg)"}}>Test-evidence gate</div>
<div style={{fontSize:"12.5px",color:"var(--ink-60)",lineHeight:1.5}}>On by default for new projects. When on, a build-report save with no valid captured test evidence is blocked — but only if a test command resolves. Set <code>&quot;off&quot;</code> (or leave it absent) to disable. Valid values: <code>on</code>, <code>off</code>.</div>
<div style={{fontFamily:"var(--font-mono)",fontSize:"11px",marginTop:"8px",color:"var(--ink-45)"}}>ana config set testEvidenceGate "off"</div>
</div>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",background:"var(--bg-card)",border:"1px solid var(--border-soft)"}}>
<div style={{fontWeight:600,fontSize:"13px",marginBottom:"4px",color:"var(--fg)"}}>Custom data</div>
<div style={{fontSize:"12.5px",color:"var(--ink-60)",lineHeight:1.5}}>The <code>custom</code> namespace stores arbitrary team data. Collision-safe.</div>
<div style={{fontFamily:"var(--font-mono)",fontSize:"11px",marginTop:"8px",color:"var(--ink-45)"}}>ana config set custom.teamId "anatomia"</div>
</div>
</div>

Remove any field with `ana config delete <field>` — useful for clearing overrides and reverting to detected defaults.

### Surface management

If the scan missed a surface, add it manually with its path and commands:

```bash
ana config set surfaces.api.path "apps/api"
ana config set surfaces.api.commands.test "cd apps/api && pnpm test"
ana config set surfaces.api.commands.build "cd apps/api && pnpm build"
```

If the scan detected a false surface — an example app, a template package — remove it:

```bash
ana config delete surfaces.example-app
```

On re-init, the scan refreshes detected surfaces: new workspace packages with deployment indicators are added, and packages that no longer exist are silently dropped. Surfaces you added manually are preserved — but if the path doesn&apos;t exist on disk, init prints a warning. Surfaces you deleted manually stay deleted unless the scan re-detects them.

The `path`, `language`, and `framework` fields on each surface are machine-managed — `ana config set` blocks writes to these fields because incorrect values would cause agents to misidentify your stack. Override commands freely; leave detection fields to the scan.

### What ana.json looks like

```json
{
  "branchPrefix": "feature/",
  "coAuthor": "Ana <build@anatomia.dev>",
  "artifactBranch": "main",
  "mergeStrategy": "squash",
  "testEvidenceGate": "on",
  "commands": {
    "build": "pnpm run build",
    "test": "pnpm test -- --run",
    "lint": "pnpm run lint"
  },
  "custom": { "teamId": "anatomia" }
}
```

<p style={{fontSize:"13px",color:"var(--ink-60)",margin:"0 0 16px"}}>User fields (`branchPrefix`, `coAuthor`, `artifactBranch`, `mergeStrategy`, `testEvidenceGate`, `commands`, `custom`) are yours. Machine fields (`anaVersion`, `lastScanAt`, `language`, `framework`) refresh on `ana init`. Unknown top-level keys you add are preserved across re-init.</p>

<p style={{fontSize:"13px",color:"var(--ink-60)",margin:"0 0 16px"}}>The `testEvidenceGate` field controls the captured-test-evidence gate. New projects are initialized with `"on"`. When it is `"on"` <em>and</em> a test command resolves (top-level or per-surface), saving a `build_report.md` that carries no valid captured test evidence is blocked — run `ana test` (it seals a harmless abstain even when no tests run), then re-save. `"off"` or an absent flag disables the gate; re-init preserves an explicit choice and never imposes `"on"` on a project that never set it.</p>

## Edit the files

The system is markdown in your repo. You own it.

### Skill rules

Every skill has four sections. **Detected** refreshes on init. **Rules, Gotchas, Examples** are yours — preserved across re-init. The next pipeline run picks up changes through Plan's Build Brief.

### Create a custom skill

```bash
# Create a domain-specific skill
mkdir -p .ana/skills/billing
cat > .ana/skills/billing/SKILL.md << 'EOF'
---
name: billing
description: "Stripe integration, subscription lifecycle, webhook handling."
---
# Billing

## Rules
- Always verify webhook signatures before processing
- Use idempotency keys on all payment mutations

## Gotchas
## Examples
EOF
```

### Wire a skill to an agent

Each agent declares which skills it loads in frontmatter. Platform-specific agent files deliver those declarations to the host tool; skills stay canonical in `.ana/skills/`. Plan loads `[coding-standards, testing-standards]`. Build loads `[git-workflow]`. Verify loads `[testing-standards, coding-standards]`. Add your skill to the agent that should know about it:

<ForPlatform platform="claude-code">
Claude Code users edit the markdown agent file under `.claude/agents/`:

```yaml
---
name: ana-plan
model: opus[1m]
skills: [coding-standards, testing-standards, billing]
---
```
</ForPlatform>

<ForPlatform platform="codex">
Codex users keep skill loading in the generated Codex prompt markdown and use `.agent.toml` only for Codex delivery settings such as model and sandbox mode:

```toml
developer_instructions = "Full instructions in ana-plan.md. Invoke via: ana run"
model = "gpt-5.5"
sandbox_mode = "danger-full-access"
```
</ForPlatform>

<Callout variant="rule">Plan curates relevant skill rules into the Build Brief. A rule in a skill that Plan doesn't load won't appear in the Brief — Build can invoke skills manually, but won't see rules by default. If you add a custom skill, add it to Plan's frontmatter.</Callout>

### Context files

`project-context.md` (architecture, domain vocabulary) and `design-principles.md` (how your team defines "good") in `.ana/context/`. Edit freely. Think, Plan, and Learn read them on every startup. Copied wholesale on re-init — your edits are always safe.

### Agent templates

The six agent files in platform-specific directories such as `.claude/agents/` and `.codex/agents/` are yours to edit. Adjust Verify&apos;s disposition, add constraints to Build, modify Think&apos;s scoping process. But the instruction content is machine-owned: on `ana init` the agent `.md` instruction bodies and `CLAUDE.md` are **overwritten** from the current stock so template updates reach your install. Your edits are recoverable from git (init warns when it overwrites a file whose content had changed — `git log -- .claude/agents/ana-build.md`). Your **basic config is preserved**: Claude frontmatter `model`/`tools` and Codex `.agent.toml` `model`/`sandbox_mode`/`model_reasoning_effort` are never reset.

<Callout variant="note">The pipeline assumes certain agent behaviors: Verify writes a report with a PASS/FAIL verdict, Build tags tests with `@ana`, Plan seals a contract. Removing these expectations breaks mechanical verification. Add behavior; be careful removing it.</Callout>

## Going further

It's open source. Everything below works but isn't governed by the CLI — no validation, no re-init behavior. You're editing the engine directly.

### Add a custom agent

Drop a custom agent file in your platform's agent directory, such as `.claude/agents/` for Claude Code or `.codex/agents/` for Codex. A security reviewer, a migration planner, a domain expert — any role that doesn't need pipeline integration.

<ForPlatform platform="claude-code">
Claude Code custom agents are markdown files under `.claude/agents/`. They can load canonical `.ana/skills/` entries through frontmatter.
</ForPlatform>

<ForPlatform platform="codex">
Codex custom agents live under `.codex/agents/`. Add a prompt markdown file, and add a matching `.agent.toml` manifest when you need Codex-specific model, `developer_instructions`, or `sandbox_mode` settings.
</ForPlatform>

```bash
# A reviewer that focuses on your API surface
$ ana run api-reviewer

# A migration helper for your specific ORM
$ ana run drizzle-migrator
```

Custom agents run outside the pipeline. They can read `ana.json`, load skills via frontmatter, and use their platform's tools — but they don't produce pipeline artifacts or proof chain entries. To gate work between stages, invoke your custom agent manually between Plan and Build (or any two stages). It can read `.ana/plans/active/{slug}/` to inspect the spec and contract.

### Store team config in ana.json

The `custom` namespace accepts arbitrary data and survives re-init. Nothing reads it automatically — the namespace is a convention for your own integrations. A custom agent that reads `custom.slackChannel` to post notifications, or `custom.reviewers` to tag PR reviewers — the config is there, the integration is yours to build.

```json
{
  "custom": {
    "teamId": "anatomia",
    "slackChannel": "#eng-proofs",
    "reviewers": ["@rsmith"],
    "maxBuildMinutes": 120
  }
}
```

### CI/CD scripting

`ana config` is scriptable. Set up a repo without interactive prompts:

```bash
# CI setup script
ana init --yes
ana config set branchPrefix "ci/"
ana config set coAuthor "Ana <build@anatomia.dev>"
ana config set custom.environment "staging"
ana agents model --all sonnet
```

### Fork the CLI

The nuclear option. Anatomia is MIT-licensed. Fork to change artifact formats, contract schemas, the proof chain entry structure, or the agent independence rules. If you're doing this, you're building your own verification system on top of the engine.

## What survives re-init

Updating the CLI (`npm update anatomia-cli`) changes the binary only. Your installed agents, skills, and config don't change until you choose to run `ana init` again. When you do:

<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px",margin:"14px 0 18px"}}>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",border:"1px solid var(--pass-border)",background:"var(--pass-bg)"}}>
<div style={{fontWeight:600,fontSize:"13px",color:"var(--pass)",marginBottom:"6px"}}>Preserved</div>
<ul style={{fontSize:"12.5px",color:"var(--ink-75)",lineHeight:1.6,margin:0,paddingLeft:"16px"}}>
<li>context/ directory (copied wholesale)</li>
<li>ana.json user fields + unknown keys</li>
<li>Agent basic config — Claude frontmatter model/tools, Codex model/sandbox_mode/model_reasoning_effort</li>
<li>Skill Rules, Gotchas, Examples</li>
<li>proof_chain.json + PROOF_CHAIN.md</li>
<li>plans/completed/ + plans/active/ (all archives + in-flight work)</li>
<li>AGENTS.md (still skip-if-exists)</li>
</ul>
</div>
<div style={{padding:"12px 14px",borderRadius:"var(--radius-sm)",border:"1px solid rgba(248,113,113,0.25)",background:"var(--fail-bg)"}}>
<div style={{fontWeight:600,fontSize:"13px",color:"var(--fail)",marginBottom:"6px"}}>Refreshed</div>
<ul style={{fontSize:"12.5px",color:"var(--ink-75)",lineHeight:1.6,margin:0,paddingLeft:"16px"}}>
<li>Agent .md instruction bodies (overwritten from stock — recover via git)</li>
<li>CLAUDE.md (overwritten + re-interpolated)</li>
<li>ana.json anaVersion + lastScanAt</li>
<li>scan.json (full regeneration)</li>
<li>Skill Detected sections</li>
</ul>
</div>
</div>

## What's fixed

Load-bearing opinions. Fixed because changing them breaks the verification guarantee.

- **Five pipeline stages** — Think, Plan, Build, Verify, Learn.
- **Agent independence** — session isolation. Verify can't read the build report.
- **Contract format** — YAML with typed assertions and matchers.
- **Proof seal** — SHA-256 hashes of every artifact.
- **Artifact structure** — the save commands validate format.

<p style={{fontSize:"13px",color:"var(--ink-60)",margin:"0 0 16px"}}>These constraints are what make the proof chain trustworthy. Every customization above works because these five things don't change.</p>

<NextCards cards={[
  {
    eyebrow: "Next guide",
    title: "Troubleshooting",
    href: "/docs/guides/troubleshooting",
    description: "Common problems and how to fix them."
  },
  {
    eyebrow: "Concept",
    title: "The toolbelt",
    href: "/docs/concepts/toolbelt",
    description: "Every CLI command agents use under the hood."
  }
]} />
