Skip to content

Configuration Reference

File Purpose
~/.karajan/kj.config.yml Main configuration (or $KJ_HOME/kj.config.yml)
<project>/.karajan.yml Project-level pricing overrides only
<project>/.karajan/roles/*.md Project-level role instructions
<project>/.karajan/plugins/*.js Project-level plugins

CLI flags override config file values. Config file values override defaults.


coder: claude # AI agent that writes code
reviewer: codex # AI agent that reviews code
review_mode: standard # Review strictness profile
max_iterations: 5 # Max coder-reviewer loop iterations
review_rules: ./review-rules.md # Path to custom review rules
coder_rules: ./coder-rules.md # Path to custom coder rules
base_branch: main # Git base branch for diffs
max_budget_usd: null # Max budget in USD (null = unlimited)
Field Type Default Description
coder string claude Agent CLI name: claude, codex, gemini, aider, or a custom plugin
reviewer string codex Agent CLI name for code review
review_mode enum standard paranoid | strict | standard | relaxed | custom
max_iterations number 5 Maximum coder-reviewer loop iterations (1-20)
review_rules string ./review-rules.md Path to reviewer instruction file
coder_rules string ./coder-rules.md Path to coder instruction file
base_branch string main Git branch used for diff comparison
max_budget_usd number | null null Estimated session budget cap in USD (based on API-equivalent pricing). null = unlimited

Override provider and model per role:

roles:
coder:
provider: claude
model: claude-opus-4-6
reviewer:
provider: codex
model: null
planner:
provider: null
model: null
refactorer:
provider: null
model: null
solomon:
provider: null
model: null
researcher:
provider: null
model: null
tester:
provider: null
model: null
security:
provider: null
model: null
triage:
provider: null
model: null
discover:
provider: null
model: null
hu-reviewer:
provider: null
model: null
architect:
provider: null
model: null
audit:
provider: null
model: null
impeccable:
provider: null
model: null
commiter:
provider: null
model: null
Role Purpose
coder Writes code and tests
reviewer Reviews code for quality, security, correctness
planner Generates implementation plans before coding
refactorer Refactors code after approval
solomon Resolves conflicts between coder and reviewer
researcher Analyzes codebase before planning
tester Audits test quality after review
security OWASP security audit
triage Classifies task complexity
discover Pre-execution gap detection
hu-reviewer User story certification
architect Solution architecture design
audit Read-only codebase health audit
impeccable Automated UI/UX design audit
commiter Git automation

fallback: the chain that runs when the first choice cannot

Section titled “fallback: the chain that runs when the first choice cannot”

Any role accepts a fallback, and a fallback accepts its own, so the chain is as long as you need it (five links, then kj warns and ignores the rest):

roles:
reviewer:
provider: codex
model: gpt-5.6-terra
fallback:
provider: codex # same provider, another model
model: gpt-5.6
max_wait_hours: 12
fallback:
provider: claude # or another provider entirely
model: null # null = that provider's default
Field Type Default Description
provider string — The agent this link uses. Required.
model string | null null The model for this link. null asks for the provider’s own default.
max_wait_hours number 12 On a quota wall, wait rather than switch when the cooldown is shorter than this. A retired model never waits: nothing will bring it back.
fallback object none The next link. Same shape, recursively.

Two things worth knowing, because they are not obvious:

  • The chain is taken in the order you wrote it, and the provider’s default model is appended as the last link when (and only when) you pinned a model. That step used to happen silently inside each agent, ahead of anything you had declared; since 4.33.0 it is the tail of your chain, where you can see it.
  • A link that repeats the primary is skipped, and so is one whose provider does not exist, with a warning naming it. Retrying the same provider and model is not progress, it only looks like it.

When the whole chain is exhausted, the error says what was tried and in what order, and kj remembers a model it watched a provider retire so the next run does not pay for the same dead call. It never edits your pin: it names the line for you to change.


Enable or disable optional roles:

pipeline:
planner:
enabled: false
refactorer:
enabled: false
solomon:
enabled: false
researcher:
enabled: false
tester:
enabled: false
security:
enabled: false
triage:
enabled: false
reviewer:
enabled: true
discover:
enabled: false
hu-reviewer:
enabled: false
architect:
enabled: false
audit:
enabled: false
impeccable:
enabled: false
commiter:
enabled: false

All optional roles are disabled by default. Enable them with --enable-<role> CLI flags or in config.


development:
methodology: tdd
require_test_changes: true
test_file_patterns:
- /tests/
- /__tests__/
- .test.
- .spec.
source_file_extensions:
- .js
- .jsx
- .ts
- .tsx
- .py
- .go
- .java
- .rb
- .php
- .cs
Field Type Default Description
methodology enum tdd tdd (require tests first) or standard (tests optional)
require_test_changes boolean true When TDD, require test file changes alongside source changes
test_file_patterns string[] See above Patterns to identify test files
source_file_extensions string[] See above Source file extensions to monitor for TDD enforcement

coder_options:
model: null
auto_approve: true
Field Type Default Description
model string | null null Model override for coder (e.g., claude-opus-4-6)
auto_approve boolean true Allow coder to approve its own output if reviewer approves

reviewer_options:
output_format: json
require_schema: true
model: null
deterministic: true
retries: 1
fallback_reviewer: codex
Field Type Default Description
output_format string json Reviewer output format (always JSON for structured review)
require_schema boolean true Validate reviewer output matches expected schema
model string | null null Model override for reviewer
deterministic boolean true Use deterministic mode for reproducible reviews
retries number 1 Number of reviewer retries on parse error
fallback_reviewer string codex Fallback provider if primary reviewer fails

sonarqube:
enabled: true
host: http://localhost:9000
external: false
container_name: karajan-sonarqube
network: karajan_sonar_net
token: null
project_key: null
admin_user: admin
admin_password: null
quality_gate: true
enforcement_profile: pragmatic
max_scan_retries: 3
gate_block_on:
- new_reliability_rating=E
- new_security_rating=E
- new_maintainability_rating=E
- new_coverage<80
- new_duplicated_lines_density>5
fail_on:
- BLOCKER
- CRITICAL
ignore_on:
- INFO
volumes:
data: karajan_sonar_data
logs: karajan_sonar_logs
extensions: karajan_sonar_extensions
timeouts:
healthcheck_seconds: 5
compose_up_ms: 300000
compose_control_ms: 120000
logs_ms: 30000
scanner_ms: 900000
coverage:
enabled: false
command: null
timeout_ms: 300000
block_on_failure: true
lcov_report_path: null
scanner:
sources: "src,public,lib"
exclusions: "**/node_modules/**,**/dist/**,**/build/**,**/*.min.js"
test_inclusions: "**/*.test.js,**/*.spec.js,**/tests/**,**/__tests__/**"
coverage_exclusions: "**/tests/**,**/__tests__/**,**/*.test.js,**/*.spec.js"
disabled_rules:
- "javascript:S1116"
- "javascript:S3776"
Field Type Default Description
enabled boolean true Enable SonarQube scanning
host string http://localhost:9000 SonarQube server URL
external boolean false If true, assume an external SonarQube (don’t manage Docker)
token string | null null Authentication token. Prefer KJ_SONAR_TOKEN env var
quality_gate boolean true Check quality gate status after scan
enforcement_profile enum pragmatic pragmatic (block on ERROR only) or paranoid (block on anything not OK)
max_scan_retries number 3 Retry failed scans
Severity Meaning
BLOCKER App crash, data loss
CRITICAL Security hole, logic error
MAJOR Quality issue affecting function
MINOR Code smell, inconsistency
INFO Convention, clarification

git:
auto_commit: false
auto_push: false
auto_pr: false
auto_rebase: true
branch_prefix: feat/
Field Type Default Description
auto_commit boolean false Commit all changes after approval
auto_push boolean false Push branch to origin after commit
auto_pr boolean false Create pull request to base_branch
auto_rebase boolean true Rebase on base_branch before pushing
branch_prefix string feat/ Prefix for branch names (e.g., feat/, fix/)

The Git automation flow after approval: rebase (if enabled) → commit → push → PR.


session:
max_iteration_minutes: 15
max_total_minutes: 120
max_planner_minutes: 60
max_agent_silence_minutes: 20
fail_fast_repeats: 2
repeat_detection_threshold: 2
max_sonar_retries: 3
max_reviewer_retries: 3
max_tester_retries: 1
max_security_retries: 1
expiry_days: 30
Field Type Default Description
max_iteration_minutes number 15 Time limit per coder-reviewer cycle
max_total_minutes number 120 Total session time limit
max_planner_minutes number 60 Hard runtime cap for planner-only execution (kj_plan/kj plan)
max_agent_silence_minutes number 20 Kill agent run if no output is received for this many minutes
fail_fast_repeats number 2 Exit after N repeated identical failures
repeat_detection_threshold number 2 Iterations before detecting repeating patterns
max_sonar_retries number 3 Max SonarQube scan retries
max_reviewer_retries number 3 Max reviewer retries on parse error
max_tester_retries number 1 Max test audit retries
max_security_retries number 1 Max security audit retries
expiry_days number 30 Auto-cleanup sessions older than this

budget:
warn_threshold_pct: 80
currency: usd
exchange_rate_eur: 0.92
pricing:
claude:
input_per_million: 0.003
output_per_million: 0.015
Field Type Default Description
warn_threshold_pct number 80 Warn when estimated spending reaches this % of max_budget_usd
currency enum usd Display currency: usd or eur
exchange_rate_eur number 0.92 EUR to USD exchange rate
pricing object Built-in Per-agent pricing rates for estimation (input_per_million, output_per_million)

The pricing section can also be set in a project-level .karajan.yml file to override per-project estimation rates.


retry:
max_attempts: 3
initial_backoff_ms: 1000
max_backoff_ms: 30000
backoff_multiplier: 2
jitter_factor: 0.1
Field Type Default Description
max_attempts number 3 Max retry attempts for transient API errors
initial_backoff_ms number 1000 Initial backoff delay (1 second)
max_backoff_ms number 30000 Maximum backoff delay (30 seconds)
backoff_multiplier number 2 Exponential backoff multiplier
jitter_factor number 0.1 Random jitter as fraction of backoff (10%)

output:
report_dir: ./.reviews
log_level: info
Field Type Default Description
report_dir string ./.reviews Directory for session reports and logs
log_level enum info Logging level: debug | info | warn | error

Integration with Planning Game — an agile project management system (XP methodology) available as an MCP server.

planning_game:
enabled: false
project_id: null
codeveloper: null
Field Type Default Description
enabled boolean false Enable Planning Game MCP integration
project_id string | null null Planning Game project ID
codeveloper string | null null Developer ID for codeveloper field

becaria:
enabled: false
review_event: becaria-review
comment_event: becaria-comment
comment_prefix: true
Field Type Default Description
enabled boolean false Enable BecarIA Gateway — publish pipeline results as PR comments/reviews via GitHub App
review_event string becaria-review GitHub repository_dispatch event type for formal reviews (APPROVE/REQUEST_CHANGES)
comment_event string becaria-comment GitHub repository_dispatch event type for agent comments
comment_prefix boolean true Prefix comments with [Agent] (e.g., [Reviewer], [Sonar])

When enabled: true, Karajan automatically sets git.auto_commit, git.auto_push, and git.auto_pr to true. See Pipeline Flows for the full BecarIA architecture.


serena:
enabled: false
Field Type Default Description
enabled boolean false Enable Serena integration for codebase-aware context

model_selection:
enabled: true
tiers: {}
role_overrides: {}
Field Type Default Description
enabled boolean true Enable smart model selection based on task complexity
tiers object {} Named tiers with model assignments (e.g., fast, balanced, powerful)
role_overrides object {} Per-role model overrides that bypass tier selection

Example with tiers:

model_selection:
enabled: true
tiers:
fast:
model: claude-sonnet-4-6
balanced:
model: claude-opus-4-6
role_overrides:
reviewer:
model: claude-opus-4-6

Disable with --no-smart-models CLI flag.


failFast:
repeatThreshold: 2
Field Type Default Description
repeatThreshold number 2 Stop the pipeline after this many consecutive identical failures

This is separate from session.fail_fast_repeats — failFast applies to the orchestrator’s global repeat detection across all stages.


What kj release check verifies on top of the generic checks (manifest against CHANGELOG against tags, a privacy scan of the publishable files, the policy in force). Every item is the project’s own.

release_check:
items:
- name: the deployed landing shows the version as current
command: curl -sf https://example.com/docs/ | grep -q 'v{version}'
remedied_by: firebase deploy
- name: the footer carries the version
file_contains:
path: public/footer.html
pattern: v{version}
Field Type Description
name string How the item is reported
command string Passed to sh -c; exit 0 is a pass. {version} is replaced by the manifest version
file_contains.path string File to read, relative to the project
file_contains.pattern string Substring that must be present; {version} is replaced too
remedied_by string The command that REPAIRS this item, if any

remedied_by exists because a red item must not block the one action that would turn it green. The landing check is the example: it wants the site deployed with the new version, and the deploy that does it was blocked by that very check. The words must appear in the command in order, so firebase deploy covers firebase --account a@b --project p deploy --only hosting:main.

The lifted item stays red in the report, because the fact has not changed, and the gate prints which one it lifted. Everything else still blocks, and a package publication is never excused: npm publish and gh release create are irreversible, whatever an item declares.


Variable Purpose Default
KJ_HOME Override Karajan config directory ~/.karajan
KJ_SONAR_TOKEN SonarQube authentication token From config
KJ_SONAR_ADMIN_USER SonarQube admin username admin
KJ_SONAR_ADMIN_PASSWORD SonarQube admin password From config
KJ_SONAR_PROJECT_KEY Override SonarQube project key From config
VISUAL / EDITOR Editor for kj config --edit vi

Environment variables take precedence over config file values for the fields they map to.


The review_mode setting controls how strictly the reviewer evaluates code:

  • Priority: Security → Correctness → Tests → Architecture → Style
  • Blocking: Security issues, logic errors, broken tests, file overwrites
  • Non-blocking: Style suggestions
  • Philosophy: Every change is suspect until proven safe
  • Priority: Security → Correctness → Tests → Data integrity → Architecture → Style
  • Blocking: All security checks, missing error handling, missing input validation, missing tests, entire file rewrites
  • Confidence threshold: Approve only if confidence > 0.85. Default to REJECTION
  • Priority: Security → Correctness → Tests → Architecture → Style
  • Blocking: All security issues, logic errors, insufficient test coverage, missing error handling for external calls
  • Confidence threshold: Reject if confidence < 0.80
  • Philosophy: Prefer approving with suggestions
  • Priority: Critical security → Clear bugs → Critical path tests
  • Blocking: Only critical security (secrets, SQL injection, XSS) and clear logic errors
  • Confidence threshold: Reject if confidence < 0.60

Uses the base reviewer.md file (project-local, global, or built-in) without a pre-defined profile. Full control via your review-rules.md file.


Role instructions are resolved in this order (first found wins):

  1. Project-local: <project>/.karajan/roles/{role}.md
  2. Global: ~/.karajan/roles/{role}.md
  3. Built-in: templates/roles/{role}.md (shipped with Karajan)

Review mode profiles follow the same pattern:

  1. .karajan/roles/reviewer-{mode}.md
  2. ~/.karajan/roles/reviewer-{mode}.md
  3. templates/roles/reviewer-{mode}.md

Plugins are loaded from all locations (not first-wins):

  1. <project>/.karajan/plugins/*.js
  2. ~/.karajan/plugins/*.js

~/.karajan/ # Global config ($KJ_HOME)
├── kj.config.yml # Main configuration
├── roles/ # Global role instructions
│ ├── coder.md
│ ├── reviewer.md
│ ├── reviewer-paranoid.md
│ └── ...
├── plugins/ # Global plugins
│ └── my-agent.js
├── sessions/ # Session logs
│ └── session-{id}/
└── docker-compose.sonar.yml # SonarQube Docker config
<project>/
├── .karajan/ # Project-level overrides
│ ├── roles/ # Project role instructions
│ │ └── reviewer.md
│ └── plugins/ # Project plugins
│ └── my-plugin.js
├── .karajan.yml # Project pricing overrides
├── coder-rules.md # Coder guidelines
└── review-rules.md # Review guidelines

review_mode: paranoid
development:
methodology: tdd
sonarqube:
enabled: true
enforcement_profile: paranoid
quality_gate: true
pipeline:
security:
enabled: true
tester:
enabled: true
max_iterations: 5
git:
auto_commit: false