Configuration Reference
Config file location
Section titled “Config file location”| 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.
Top-level fields
Section titled “Top-level fields”coder: claude # AI agent that writes codereviewer: codex # AI agent that reviews codereview_mode: standard # Review strictness profilemax_iterations: 5 # Max coder-reviewer loop iterationsreview_rules: ./review-rules.md # Path to custom review rulescoder_rules: ./coder-rules.md # Path to custom coder rulesbase_branch: main # Git base branch for diffsmax_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.
pipeline
Section titled “pipeline”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: falseAll optional roles are disabled by default. Enable them with --enable-<role> CLI flags or in config.
development
Section titled “development”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
Section titled “coder_options”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
Section titled “reviewer_options”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
Section titled “sonarqube”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"Key SonarQube settings
Section titled “Key SonarQube settings”| 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 |
Issue severity levels
Section titled “Issue severity levels”| 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
Section titled “session”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
Section titled “budget”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
Section titled “output”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 |
planning_game
Section titled “planning_game”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
Section titled “becaria”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
Section titled “serena”serena: enabled: false| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable Serena integration for codebase-aware context |
model_selection
Section titled “model_selection”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-6Disable with --no-smart-models CLI flag.
failFast
Section titled “failFast”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.
release_check
Section titled “release_check”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.
Environment variables
Section titled “Environment variables”| 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.
Review mode profiles
Section titled “Review mode profiles”The review_mode setting controls how strictly the reviewer evaluates code:
standard (default)
Section titled “standard (default)”- Priority: Security → Correctness → Tests → Architecture → Style
- Blocking: Security issues, logic errors, broken tests, file overwrites
- Non-blocking: Style suggestions
paranoid
Section titled “paranoid”- 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
strict
Section titled “strict”- 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
relaxed
Section titled “relaxed”- 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
custom
Section titled “custom”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.
File resolution hierarchy
Section titled “File resolution hierarchy”Role instructions are resolved in this order (first found wins):
- Project-local:
<project>/.karajan/roles/{role}.md - Global:
~/.karajan/roles/{role}.md - Built-in:
templates/roles/{role}.md(shipped with Karajan)
Review mode profiles follow the same pattern:
.karajan/roles/reviewer-{mode}.md~/.karajan/roles/reviewer-{mode}.mdtemplates/roles/reviewer-{mode}.md
Plugins are loaded from all locations (not first-wins):
<project>/.karajan/plugins/*.js~/.karajan/plugins/*.js
Directory structure
Section titled “Directory structure”~/.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 guidelinesConfiguration recipes
Section titled “Configuration recipes”review_mode: paranoiddevelopment: methodology: tddsonarqube: enabled: true enforcement_profile: paranoid quality_gate: truepipeline: security: enabled: true tester: enabled: truemax_iterations: 5git: auto_commit: falsereview_mode: relaxeddevelopment: methodology: standardsonarqube: enabled: falsemax_iterations: 2session: max_total_minutes: 30review_mode: strictdevelopment: methodology: tddsonarqube: enabled: true enforcement_profile: paranoidpipeline: tester: enabled: true security: enabled: truegit: auto_commit: true auto_push: true auto_pr: truemax_iterations: 5max_budget_usd: 5.00pipeline: planner: enabled: true researcher: enabled: true refactorer: enabled: true security: enabled: truedevelopment: methodology: tddsession: max_total_minutes: 240max_iterations: 7becaria: enabled: true review_event: becaria-review comment_event: becaria-comment comment_prefix: truepipeline: triage: enabled: true planner: enabled: true tester: enabled: true security: enabled: true solomon: enabled: truereview_mode: strictdevelopment: methodology: tddmax_iterations: 5