Configuration

Configuration reference

All knobs that control Auriga's routing behavior — environment variables, batch caps, human filter, review squad rules, agent registry, and runtime capacity.

Environment variables

These are read at startup and override defaults without requiring a code change.

VariableDefaultEffect
AURIGA_CONFIG — Path to an optional JSON override file. Any key present replaces the corresponding export from config.mjs or config-substrate.mjs. Absent keys keep defaults.
AURIGA_PER_CYCLE_TOTAL 5 Max new dispatches per cycle. Overrides CAPS.perCycleTotal.
AURIGA_PER_CYCLE_PER_AGENT 2 Max dispatches to a single agent per cycle. Overrides CAPS.perCyclePerAgent.
AURIGA_CYCLE_MS 75000 Sleep between cycles in milliseconds. Overrides CAPS.cycleMs.
AURIGA_PIDFILE /tmp/auriga-router.pid Path to the pidfile that enforces single-instance locking.
AURIGA_LOG /tmp/auriga-router.log Path to the human-readable log file.
AURIGA_MEMORY_ADAPTER mnemosyne Which MemoryAdapter implementation to use. Set to stub for local testing without a live Mnemosyne instance.

Log files

In addition to AURIGA_LOG, the router also writes a structured JSONL log at /tmp/auriga-router.jsonl (not overridable). The supervisor has its own log at /tmp/auriga-supervisor.log and /tmp/auriga-supervisor.pid.


CAPS

The CAPS object in lib/config.mjs controls all cycle timing and per-cycle dispatch limits. Every cap is a hard bound — once hit, no further mutations of that type happen in that cycle. Can be overridden entirely via the AURIGA_CONFIG external file.

KeyDefaultDescription
perCyclePerAgent 2 Max new dispatches to a single agent within one cycle. Prevents any one agent from being mass-assigned.
perCycleTotal 5 Max new dispatches across all agents in one cycle.
cycleMs 75000 Milliseconds to sleep between cycles.
zombieStaleMs 1200000 (20 min) Age in ms at which an in_progress issue with no run activity is considered a zombie.
zombieMaxAttempts 3 Max times a zombie is re-queued before giving up and setting it to blocked.
verifyDelayMs 6000 Milliseconds to wait after assigning an issue before verifying a run actually started.
perCycleReview 1 Max review squad dispatches per cycle. Kept tight because review runs share the Claude account.
perCycleFalseDone 3 Max false-done corrections (done → in_review) per cycle.
perCycleCascade 5 Max cascade (completed issue → dependent enqueue) operations per cycle.
// Example: external override file to slow the cycle
{
  "CAPS": {
    "perCycleTotal": 3,
    "cycleMs": 120000,
    "zombieMaxAttempts": 2
  }
}

HUMAN_NAMES

The list of human names that trigger the human-todo filter. An issue with waiting_on: <value> in its metadata is excluded from agent dispatch if value case-insensitively contains any name in this list.

// Default in lib/config.mjs
export const HUMAN_NAMES = _ext.HUMAN_NAMES ?? ['mathew', 'dostal'];

// Override via AURIGA_CONFIG:
{ "HUMAN_NAMES": ["mathew", "dostal", "alice"] }

Add a name here when a new human joins the team and needs issues flagged for their attention routed to the human queue instead of an agent lane. See Human-todo filter for full semantics.


REVIEW_SQUAD_RULES

The explicit, inspectable rule table that reviewSquadPlan(issue, cfg) uses to size the review squad for each ticket. Keyword lists classify issues into tiers; the tier determines which perspectives run and whether Playwright is required.

// lib/config.mjs — edit keyword lists to change how tickets are sized
export const REVIEW_SQUAD_RULES = _ext.REVIEW_SQUAD_RULES ?? {
  ui: ['ui', 'ux', 'page', 'react', 'dashboard', 'css', ...],
  backend: ['api', 'endpoint', 'router', 'service', 'schema', ...],
  light: ['docs', 'readme', 'chore', 'config', 'typo', ...],
  tiers: {
    full:     { product: true,  technical: true, qa: true, ux: true,  playwright: true  },
    backend:  { product: true,  technical: true, qa: true, ux: false, playwright: false },
    light:    { product: false, technical: true, qa: true, ux: false, playwright: false },
    standard: { product: true,  technical: true, qa: true, ux: true,  playwright: true  },
  },
};

Classification scans the issue title and description for keywords. The first matching tier wins. If no keyword matches, the issue gets the standard tier (full four perspectives). No code change is needed to tune the keyword lists — update them in the override file via AURIGA_CONFIG.


AGENTS

The agent registry in lib/config-substrate.mjs. Maps agent IDs (Multica UUIDs) to agent metadata used during dispatch.

// Each entry in AGENTS:
{
  "<uuid>": {
    name:       "auriga-build",    // display name
    runtime:    "claude",          // runtime bucket for RUNTIME_CAP
    maxInflight: 3,                   // max concurrent in_progress issues
    lane:       "hive",            // routing lane (optional — overrides PROJECT_LANE)
  }
}

Add an entry here when a new agent joins the swarm. The runtime field must match a key in RUNTIME_CAP. The maxInflight per-agent cap is checked independently of the per-runtime cap — both must have room for an issue to be dispatched to that agent.


RUNTIME_CAP

A map from runtime bucket name to the maximum number of concurrently in_progress issues that bucket can hold. Defined in config-substrate.mjs and mutated in config.mjs to add the review bucket.

// config-substrate.mjs — base runtime caps
export let RUNTIME_CAP = {
  claude:          4,
  codex:           6,
  opencode:        4,
  'claude-planning': 1,
};

// config.mjs — review gets its own bucket
RUNTIME_CAP['claude-review'] = 1;

The runtime cap check is: count the in_progress issues assigned to all agents in the same runtime bucket, then compare against the cap. If the bucket is full, no further dispatches happen to any agent in that bucket this cycle.


Lane configuration

Lane maps are in config-substrate.mjs. They determine which Multica agent lane receives each dispatched story.

ExportRole
PROJECT_LANE Map from Multica project ID → lane name. Defines which lane stories from each project go to.
DEFAULT_LANE Fallback lane when no PROJECT_LANE entry matches (used for non-hive stories).
HIVE_LANE Lane used for hive stories (requires Claude + plugin-hive).
REVIEW_LANE Lane used for review squad dispatches.
REVIEW_REPO_OWNER GitHub org/user to search for PRs linked to in_review issues.
REVIEW_SEARCH_REPOS List of repo names to search for linked PRs (within REVIEW_REPO_OWNER).

External JSON override

Set AURIGA_CONFIG=/path/to/override.json to a JSON file with partial overrides. Only keys present in the file replace the in-source defaults — absent keys keep their values from the source files.

# Start with a custom config file
AURIGA_CONFIG=/etc/auriga/prod.json node src/router/auriga-router.mjs
// /etc/auriga/prod.json — only override what differs from defaults
{
  "CAPS": {
    "perCycleTotal": 8,
    "cycleMs": 60000
  },
  "HUMAN_NAMES": ["mathew", "dostal", "alice"],
  "RUNTIME_CAP": {
    "claude": 6,
    "claude-review": 2
  }
}

The override is processed at startup by lib/config-loader.mjs via loadExternalConfig(). If the file path is invalid or the file is malformed JSON, the router logs a warning and uses the built-in defaults.

Not a merge — a replace

If you override CAPS, you must provide all CAPS keys you want to keep — the external value completely replaces the in-source default for that key. Partially overriding nested objects is not supported; the whole top-level key is replaced.