Complete reference for all
.anatoly.ymloptions (schema v2), CLI overrides, and environment variables that control Anatoly's audit behavior.
Overview#
Anatoly reads configuration from a .anatoly.yml file at the project root. If no file exists, all values fall back to schema defaults defined in src/schemas/config.ts. The file is loaded by loadConfig() in src/utils/config-loader.ts, parsed with js-yaml, and validated against ConfigSchema (Zod). A malformed YAML file or an invalid field value throws an AnatolyError with code CONFIG_INVALID.
Generate a commented template interactively via:
anatoly initUse --force to overwrite an existing file.
The --config <path> global flag loads an alternate file instead of the project-root default:
anatoly run --config ./configs/anatoly.ci.ymlSchema Reference#
project#
| Key | Type | Default | Description |
|---|---|---|---|
name |
string |
— | Display name for the project |
monorepo |
boolean |
false |
Enables monorepo-aware scanning |
scan#
Controls which files are included in each audit run.
| Key | Type | Default | Description |
|---|---|---|---|
include |
string[] |
[] |
Glob patterns for files to audit. Authoritative — anatoly does not silently augment this list and does not assume a language. The first-run wizard emits a starter appropriate to the detected project. To scan additional languages, add their patterns explicitly (e.g. '**/*.py', '**/*.go'). |
exclude |
string[] |
['node_modules/**', 'dist/**'] |
Glob patterns to exclude from include matches. Defaults are minimal and Node-leaning. Add per-language test/build patterns yourself (e.g. '**/*.test.ts', 'target/**'). |
The --file <glob> CLI flag narrows the scan scope at runtime without modifying .anatoly.yml.
coverage#
When enabled, Anatoly runs the configured command to produce a JSON coverage report, then attaches coverage data to each file's review task.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enable coverage integration |
command |
string |
'npx vitest run --coverage.reporter=json' |
Shell command that generates the report |
report_path |
string |
'coverage/coverage-final.json' |
Path to the JSON coverage output |
providers (v2)#
Declares one or more LLM providers. Each provider entry configures its transport mode (subscription-based CLI vs. direct API), concurrency ceiling, and — for OpenAI-compatible providers — the base_url and env_key.
At least one provider must be configured. anthropic is present by default (mode: subscription, concurrency: 24).
| Key | Type | Default | Description |
|---|---|---|---|
mode |
'subscription' | 'api' |
'api' ('subscription' for anthropic and google) |
Transport mode for all calls |
concurrency |
integer 1–32 |
8 (24 for anthropic, 10 for google) |
Max concurrent in-flight calls to this provider |
single_turn |
'subscription' | 'api' |
— | Override transport for single-turn (axis) calls |
agents |
'subscription' | 'api' |
— | Override transport for agentic (multi-turn tool-use) calls |
base_url |
string |
— (from registry for known providers) | Base URL for OpenAI-compatible providers |
env_key |
string |
— (from registry for known providers) | Name of the env var holding the API key |
Known providers (see src/core/providers/known-providers.ts):
| Provider | Default env_key |
Default base_url |
Transport |
|---|---|---|---|
anthropic |
ANTHROPIC_API_KEY |
— | native |
google |
GOOGLE_GENERATIVE_AI_API_KEY |
— | native |
openai |
OPENAI_API_KEY |
— | native |
qwen |
DASHSCOPE_API_KEY |
https://dashscope-intl.aliyuncs.com/compatible-mode/v1 |
openai-compatible |
groq |
GROQ_API_KEY |
https://api.groq.com/openai/v1 |
openai-compatible |
deepseek |
DEEPSEEK_API_KEY |
https://api.deepseek.com/v1 |
openai-compatible |
mistral |
MISTRAL_API_KEY |
https://api.mistral.ai/v1 |
openai-compatible |
openrouter |
OPENROUTER_API_KEY |
https://openrouter.ai/api/v1 |
openai-compatible |
ollama |
OLLAMA_API_KEY |
http://localhost:11434/v1 |
openai-compatible |
Unknown providers are accepted as long as they supply a base_url (they are treated as openai-compatible).
providers:
anthropic:
mode: subscription
concurrency: 24
google:
mode: api
concurrency: 10models (v2)#
Selects the concrete model used for each pipeline role. Model strings use provider/model-id form (e.g. anthropic/claude-sonnet-4-6, google/gemini-2.5-flash-lite).
| Key | Type | Default | Description |
|---|---|---|---|
quality |
string |
'anthropic/claude-sonnet-4-6' |
Primary model for axis evaluations |
fast |
string |
'anthropic/claude-haiku-4-5-20251001' |
Fast model for triage and fallback code summaries |
deliberation |
string |
'anthropic/claude-opus-4-6' |
Model used for the tier-3 deliberation pass |
code_summary |
string |
— (falls back to models.fast) |
Model used for per-file code summaries during RAG indexing |
code_summary is typically pointed at a cheap/fast non-Claude model (e.g. google/gemini-2.5-flash-lite) to offload the Claude quota — it is invoked once per indexed file. When unset, models.fast (Haiku) is used.
agents (v2)#
Controls agentic (multi-turn tool-use) behavior.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enable agentic tool use during review |
scaffolding |
string |
— | Optional model override for scaffolding agents |
review |
string |
— | Optional model override for review agents |
deliberation |
string |
— | Optional model override for the deliberation agent |
max_turns |
integer 1–200 |
30 |
Maximum agentic turns per multi-turn query (tier 3, doc generation) |
runtime (v2)#
Audit-pipeline runtime limits. These replace the former llm.* timing/retry fields from schema v1.
| Key | Type | Default | Description |
|---|---|---|---|
timeout_per_file |
integer ≥ 1 |
600 |
Seconds before a single file review times out |
max_retries |
integer 1–10 |
3 |
Retry count per file on transient errors |
concurrency |
integer 1–10 |
8 |
Number of parallel file reviews |
min_confidence |
integer 0–100 |
70 |
Minimum confidence score for a finding to be reported |
max_stop_iterations |
integer 1–10 |
3 |
Maximum agent loop iterations before a forced stop |
Per-provider SDK concurrency is controlled by providers.<id>.concurrency (not a global runtime field).
axes (v2, top-level)#
Each axis can be individually enabled or disabled, optionally overridden with a specific model, and optionally skipped for matching file globs.
| Axis | Default |
|---|---|
utility |
enabled: true |
duplication |
enabled: true |
correction |
enabled: true |
overengineering |
enabled: true |
tests |
enabled: true |
best_practices |
enabled: true |
documentation |
enabled: true |
Each axis entry accepts:
| Key | Type | Description |
|---|---|---|
enabled |
boolean |
Whether the axis runs |
model |
string |
Optional model override (e.g. google/gemini-2.5-flash). Ignored if its provider is not configured. |
skip |
string[] |
Glob patterns (relative paths) to skip for this axis |
axes:
correction:
enabled: true
model: anthropic/claude-opus-4-6
documentation:
enabled: false
tests:
skip:
- src/generated/**The axis-to-model resolution is defined in resolveAxisModel() (src/core/axis-evaluator.ts): per-axis model → else models.fast or models.quality based on the evaluator's default tier.
rag#
Controls the semantic RAG index used for cross-file analysis. RAG mode (lite vs. advanced) is auto-detected from hardware and can be forced with --rag-lite or --rag-advanced. The external mode (third-party provider) is selected by setting rag.embedding.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enable RAG cross-file analysis |
code_model |
string |
'auto' |
Embedding model for code vectors (lite/advanced tiers); 'auto' selects the best available model for the detected hardware |
nlp_model |
string |
'auto' |
NLP embedding model for lite mode; 'auto' resolves to all-MiniLM-L6-v2 |
code_weight |
number 0–1 |
0.6 |
Weight for code similarity in hybrid search; NLP weight = 1 − code_weight |
embedding |
{ code?: ProviderConfig, nlp?: ProviderConfig } |
absent | Third-party embedding provider configuration, split per axis. See Embedding Providers guide. |
Each ProviderConfig is { provider: string, model?: string, base_url?: string, env_key?: string }. Either or both axes may be set; if only one is set the other duplicates it at runtime. When rag.embedding is absent, Anatoly falls back to lite or advanced based on hardware detection.
Advanced RAG mode requires Docker with the NVIDIA container toolkit. External mode requires only an HTTPS-reachable provider endpoint and the corresponding API key (e.g. OPENAI_API_KEY, VOYAGE_API_KEY).
logging#
| Key | Type | Default | Description |
|---|---|---|---|
level |
'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' |
'warn' |
Minimum level written to stderr |
file |
string |
— | Optional path to write structured ndjson logs |
pretty |
boolean |
true |
Pretty-print when stderr is a TTY |
output#
| Key | Type | Default | Description |
|---|---|---|---|
max_runs |
integer ≥ 1 |
— | Maximum number of runs to retain under .anatoly/runs/ |
badge#
Controls README badge injection after a completed audit.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Inject or update the badge in README.md |
verdict |
boolean |
false |
Include the audit verdict text inside the badge |
link |
string (URL) |
'https://github.com/r-via/anatoly' |
URL the badge links to |
documentation#
| Key | Type | Default | Description |
|---|---|---|---|
docs_path |
string |
'docs' |
Directory scanned for documentation files during RAG indexing |
module_mapping |
Record<string, string[]> |
— | Map from doc page name (key) to source module globs (values) the page covers |
search#
| Key | Type | Default | Description |
|---|---|---|---|
provider |
'exa' | 'brave' |
— | Optional web-search provider used by agentic tools |
notifications.telegram#
Optional Telegram notifications at run completion.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable Telegram notifications |
username |
string |
— | Telegram username (without @). Resolved to chat_id automatically. |
chat_id |
string |
— | Telegram chat ID (channel, group, or user) |
bot_token_env |
string |
'ANATOLY_TELEGRAM_BOT_TOKEN' |
Env var holding the bot token. Never store tokens in YAML. |
report_url |
string (URL) |
— | Optional URL to the published report, appended to the message |
When enabled: true, either chat_id or username is required.
Examples#
Minimal production config#
# .anatoly.yml
project:
name: my-api
scan:
include:
- src/**/*.ts
exclude:
- node_modules/**
- dist/**
- '**/*.test.ts'
- '**/*.spec.ts'
providers:
anthropic:
mode: subscription
runtime:
concurrency: 2
output:
max_runs: 5
badge:
enabled: falseDual-provider config (Anthropic + Gemini for summaries)#
# .anatoly.yml
project:
name: my-service
providers:
anthropic:
mode: subscription
concurrency: 24
google:
mode: api
concurrency: 10
env_key: GOOGLE_GENERATIVE_AI_API_KEY
models:
quality: anthropic/claude-sonnet-4-6
fast: anthropic/claude-haiku-4-5-20251001
deliberation: anthropic/claude-opus-4-6
code_summary: google/gemini-2.5-flash-lite
axes:
correction:
model: anthropic/claude-opus-4-6
duplication:
model: google/gemini-2.5-flashFull annotated config#
# .anatoly.yml — all sections with defaults shown
project:
name: my-service
monorepo: false
scan:
include:
- src/**/*.ts
- src/**/*.tsx
exclude:
- node_modules/**
- dist/**
- '**/*.test.ts'
- '**/*.spec.ts'
coverage:
enabled: true
command: npx vitest run --coverage.reporter=json
report_path: coverage/coverage-final.json
providers:
anthropic:
mode: subscription
concurrency: 24
models:
quality: anthropic/claude-sonnet-4-6
fast: anthropic/claude-haiku-4-5-20251001
deliberation: anthropic/claude-opus-4-6
# code_summary: google/gemini-2.5-flash-lite # optional — offloads RAG summaries off the Claude quota
agents:
enabled: true
max_turns: 30
runtime:
timeout_per_file: 600
max_retries: 3
concurrency: 8
min_confidence: 70
max_stop_iterations: 3
axes:
utility: { enabled: true }
duplication: { enabled: true }
correction: { enabled: true }
overengineering: { enabled: true }
tests: { enabled: true }
best_practices: { enabled: true }
documentation: { enabled: true }
rag:
enabled: true
code_model: auto
nlp_model: auto
code_weight: 0.6
logging:
level: warn
file: .anatoly/anatoly.ndjson
pretty: true
output:
max_runs: 10
badge:
enabled: true
verdict: false
link: https://github.com/r-via/anatoly
documentation:
docs_path: docs
module_mapping:
auth:
- docs/auth/overview.md
- docs/auth/jwt.md
search:
provider: exa
notifications:
telegram:
enabled: false
username: myhandle
bot_token_env: ANATOLY_TELEGRAM_BOT_TOKENCLI Flags that Override Config#
The following flags override config values at runtime without modifying .anatoly.yml.
| Flag | Config equivalent |
|---|---|
--config <path> |
loads alternate config file |
--concurrency <n> |
runtime.concurrency |
--sdk-concurrency <n> |
providers.<id>.concurrency (applied to the active provider) |
--no-rag |
rag.enabled = false |
--rag-lite |
forces lite RAG mode |
--rag-advanced |
forces advanced RAG mode |
--rebuild-rag |
forces full RAG re-indexation |
--code-model <model> |
rag.code_model |
--nlp-model <model> |
rag.nlp_model |
--no-triage |
disables the triage pass entirely |
--deliberation / --no-deliberation |
toggles the Opus deliberation pass |
--no-badge |
badge.enabled = false |
--badge-verdict |
badge.verdict = true |
--no-cache |
bypasses the SHA-256 file cache |
--file <glob> |
restricts scan scope to matching files |
--axes <list> |
restricts the run to a comma-separated subset of axes |
--flush-memory |
clears deliberation memory before running |
--dry-run |
simulates the run (scan + estimate + triage only) |
--log-level <level> |
logging.level |
--log-file <path> |
logging.file |
--verbose |
forces logging.level = debug |
Environment Variables#
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY |
Authentication for the Claude API when providers.anthropic.mode: api. |
GOOGLE_GENERATIVE_AI_API_KEY |
Authentication for Gemini when providers.google is configured in api mode. |
OPENAI_API_KEY, GROQ_API_KEY, DASHSCOPE_API_KEY, DEEPSEEK_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY |
Provider API keys for the corresponding registry entry. Override the env var name with providers.<id>.env_key. |
ANATOLY_TELEGRAM_BOT_TOKEN |
Default env var read when notifications.telegram.enabled: true. Rename via bot_token_env. |
ANATOLY_LOG_LEVEL |
Sets the log level when --log-level and --verbose are absent. Accepts the same values as logging.level. |
NO_COLOR |
When set to any value, disables all chalk color output (no-color.org). |
Log Level Resolution Priority#
resolveLogLevel() (src/utils/logger.ts) resolves the effective log level using the following priority (highest first):
--log-level <level>CLI flag--verboseflag → maps todebugANATOLY_LOG_LEVELenvironment variable- Default:
warn
See Also#
- 02-Configuration — Initial setup and first config file
- 02-Global-Options — Full list of CLI flags
- run command — Per-run flags and dry-run mode
- init command — Generate a config template