config/local.yaml. For initial setup and environment variables, see Initial configuration.
Secrets and the vault
Secrets are not configured in YAML or.env. They live in an encrypted vault (AES-256-GCM, stored in Postgres) and are resolved at runtime through a scoped accessor. Only four bootstrap values stay in .env: DB_USER, DB_PASSWORD, DATABASE_URL, and SECRET_ENCRYPTION_KEY (the base64 master key that decrypts the vault).
Seed a secret by setting it transiently and running the seed script — the value is read from the process environment, encrypted, and stored under its canonical vault key:
SECRET_ENCRYPTION_KEY in .env with the new key and recreate the container. See Secrets vault for the full workflow, the canonical key names, and backup guidance.
Rate limiting
Curia enforces two independent rate limits in the dispatch layer to protect against message flooding from malfunctioning channels, abusive senders, or compromised integrations.- Global limit — total messages per window across all senders, enforced before any policy-gate processing
- Per-sender limit — messages per sender per window, enforced after policy gates
message.rejected events with reason global_rate_limited or sender_rate_limited.
Working memory summarization
When a conversation grows long, Curia automatically condenses older turns into a summary to prevent silent context-window overflow. You can tune when summarization triggers and how much recent context is preserved.threshold must be 2 or greater, keepWindow must be 1 or greater, and keepWindow must be less than threshold.
Skill output length
All skill results are sanitized and truncated before being fed to the LLM. Raise this limit if you routinely hit it on large-payload skills (search results, page crawls, long calendar lists). Lower it to reduce LLM context pressure on installations with many concurrent agents.Security rules
Extra injection patterns
Extra injection patterns
Curia checks all inbound messages against a set of built-in prompt injection patterns. You can add your own patterns without changing any code.Built-in patterns include: “ignore previous instructions”, “you are now”, “system:”, “act as”, and others.
Trust score weights
Trust score weights
Each inbound message receives a trust score based on the channel it arrived on, the confidence of the sender’s contact record, and any detected injection risk. You can adjust the relative weights of these factors.Channel trust levels normalize as:
high = 1.0, medium = 0.6, low = 0.3. Contact trust levels follow a separate hierarchy: low < medium < high < ceo. See Contacts and trust for details.Action trust thresholds
Action trust thresholds
The coordinator checks a sender’s These thresholds are compiled into the coordinator’s system prompt at startup. Changes take effect on restart. See Contacts and trust for how these thresholds are enforced.
messageTrustScore against these thresholds before taking action on their behalf. All values must be between 0.0 and 1.0. This block is required — startup fails if it is missing or malformed.This replaces the previous top-level
trust_policy config key, which was dead config (typed but never read by the runtime). If you had overrides under trust_policy, move them to security.trust_thresholds.Custom PII patterns
Custom PII patterns
Curia redacts common PII from LLM-facing error messages by default: email addresses, phone numbers, credit card numbers, and US Social Security numbers. Add custom patterns for PII types specific to your deployment.
Contact creation limits
When Curia processes email, it auto-creates provisional contacts for unknown participants. These limits protect against spam campaigns that flood your contacts database.Knowledge graph decay
Curia’s dream engine runs a nightly background pass that reduces the confidence of facts in the knowledge graph based on their decay class. When a fact’s confidence falls below the archive threshold, it is soft-deleted — it no longer appears in queries but is retained in the audit log.Intent drift detection
For long-running scheduled tasks, Curia periodically compares the agent’s current progress against the original task description. If the agent has drifted significantly from its goal, the task is paused and you are notified. In unattended mode, drift detection blocks — it does not just advise.| Value | Behaviour |
|---|---|
high | Pause only on egregious, unambiguous deviations. Fewest false positives. (Default) |
medium | Pause on probable deviations. Some false positives expected. |
low | Pause whenever any drift is detected, regardless of LLM confidence. |
Model routing
Agents declare a capability tier rather than a specific model. Themodel_routing config maps each tier to a concrete model. The provider is inferred automatically from a centralized model registry based on the model name prefix (e.g., claude-* resolves to Anthropic, google/gemini-* resolves to OpenRouter).
OPENROUTER_API_KEY in .env), set the model to an OpenRouter model ID:
ModelRouter validates at startup that every configured model exists in the model registry. Unknown models cause a startup failure with a clear error message.
The
provider field was removed from tier config. The model registry infers the provider from the model name — you only need to specify the model.Delegation and scheduler timeouts
Two related timeouts can be tuned per deployment based on your model’s latency profile.delegate.defaultTimeoutMs if specialist agents are timing out under standard-tier models that run more slowly than the defaults assume. scheduler.defaultExpectedDurationSeconds is what the watchdog uses to compute the recovery timeout for a job — increase it if you run long jobs without an explicit expectedDurationSeconds hint. Both values are validated at startup; non-numeric or non-positive values cause a hard startup failure.
Outbound context bridge
Controls TTL for the registry that lets the coordinator link incoming replies to messages it previously sent. See Architecture › Outbound context bridge for the conceptual model.context_bridge input with expires_in_hours to override per-entry; that value wins over both defaults.
Meeting debrief
Configures the meeting-debrief specialist agent. The agent itself is defined inagents/meeting-debrief.yaml; this block controls runtime knobs.
contextBridgeTtlHours overrides the global contextBridge.explicitExpiryHours for the outbound-context entry the agent registers when it sends a debrief prompt — giving the CEO a longer window to reply before the entry expires.
Task management
Tunes the task backlog and heartbeat. The heartbeat is the deterministic loop that wakes idle or stale tasks so open work doesn’t linger.task-* skills, the executor-discipline prompt block, and heartbeat eligibility) is set per agent with enable_task_management: true in agents/<name>.yaml — not in this file. The coordinator and ceo-inbox ship with it enabled.
Autonomy engine
The autonomy score is stored in Postgres and controlled via natural-language commands or the CLI — you do not set it in a config file. Ask Curia directly:- “What is your current autonomy score?”
- “Set your autonomy score to 85.”