Browse documentation

Configuration Reference

eBrain keeps runtime state in private local configuration directories. Commands initialize required stores as needed and validate their schema on read. Do not commit local runtime configuration.

User-managed choices

Routing configuration

routing.yaml decides which provider the routing lane calls, which models each capability tries, and how much may be spent in a month.

$XDG_CONFIG_HOME/ebrain/routing.yaml     # defaults to $HOME/.config/ebrain/routing.yaml

ebrain up materializes it from config/routing.default.yaml on a first run — a fresh clone could otherwise not route at all — and never overwrites a copy that already exists. Delete yours and re-run ebrain up to start again from the template. Nothing in the file is a secret: the provider key is referenced by environment-variable name and read at call time.

KeyMeaning
budget.monthly_usdThe month’s ceiling for routed spend.
budget.hard_stopWhen true, a call that would exceed the ceiling is refused before it is made.
provider.idWhich provider receives the call. See the provider reference.
provider.base_url, provider.key_envEndpoint and key name; required for an id the registry does not know.
capabilities.<name>.modelsThe chain tried for that capability, in order.
classifyKeywords that orient a prompt toward a capability. An explicit --cap always wins.
frontier.auto_escalateRefused rather than obeyed: the routing lane never escalates on its own.

The file is parsed against a schema on every read, and a failure reports every problem at once with the YAML path of each. This matters more than it sounds: an unvalidated budget could hold a value that compares false against every number, which reads as a configured cap while enforcing nothing.

Repository deny policy

Some repositories must never enter eBrain — client work under NDA, an employer monorepo, a contractor tree. Which ones is a property of your machine, not of eBrain, so the list is yours:

$XDG_CONFIG_HOME/ebrain/denied-repos     # defaults to $HOME/.config/ebrain/denied-repos

One bare directory or source name per line; # starts a comment. A clean install ships no entries.

# never let these reach sessions, workspaces, federation, or memory
acme-client
internal-monorepo

EBRAIN_DENIED_REPOS (comma or whitespace separated) overrides the file for a single invocation, and EBRAIN_DENY_CONFIG points at a different policy file.

How entries are matched:

BoundaryMatchEffect
Sessions and workspaceswhole path segment, case-insensitive, after symlink resolutionlaunching or registering that directory is refused
Federation and sourcessubstring of the source id, display name, or local paththe source is never federated, and the daemon refuses to bind if one is present
Memory inputssubstring of the textepisodes, context, and recall queries referencing it are rejected

Segment matching is deliberate for paths: a directory named acme-client-notes is not acme-client, because over-blocking teaches people to switch the guard off.

The policy fails closed, identically in the CLI and in the shell harness. A policy file that exists but cannot be read, or an entry that is not a bare name, aborts the operation instead of continuing with a silently smaller policy — the shell half reports the offending line number and denies every repository until the file is fixed.

Both halves read the file under one grammar, so a policy means the same thing whichever one reads it. An entry is ASCII: letters, digits, ., _ and -, starting and ending with a letter or digit. Case is ignored and a . is a literal dot, never a wildcard. Entries are separated by newlines, commas, spaces, or tabs, and CRLF line endings are tolerated. Anything else — an accented or non-Latin character, a non-breaking space, a slash, a glob — is refused as malformed rather than interpreted, on both paths. If a repository you need to deny cannot be written this way, deny it by a substring of its name that can be.

An empty policy denies nothing by name — federation is already default-deny, so a source must be registered before it can be read at all; this list is the second gate for directories you want refused even if something tries to register them.

Upgrading: earlier builds carried a deny list compiled into the source. If you relied on it, create this file — a fresh install starts with no entries. Run ebrain doctor to see the policy state (sources:deny-policy reports the number of entries loaded, or that none are configured).

Safety constraints

Use ebrain profiles validate, ebrain workspaces list --json, and ebrain doctor to inspect supported configuration state without printing secret values.

Documentation

Search eBrain docs

Esc close CtrlK open