OAra Labs | Docs

Reference

Configuration

Two files decide how Prometheus behaves: a YAML file for settings and a separate env file for secrets. The split is deliberate, and the rule that follows from it is the only one you have to remember — nothing secret ever belongs in the YAML.

Where the config is found

Prometheus looks in a fixed order and takes the first hit. This is quoted from the shipped template itself, so it cannot drift from the search the code actually performs:

oara config --show-defaultsheader
oara config --show-defaults | head -14
# Prometheus configuration — reference defaults
# Copy to config/prometheus.yaml and customize (or run `prometheus setup`).
# config/prometheus.yaml is gitignored — your secrets stay local.
#
# CONFIG SEARCH ORDER (first hit wins):
#   1. an explicit --config path
#   2. config/prometheus.yaml          — repo-local (checkout installs)
#   3. $PROMETHEUS_CONFIG_DIR/prometheus.yaml
#      (default ~/.prometheus/prometheus.yaml — pip installs; this is
#       what `prometheus setup --fast` writes)
#
# SECRETS never belong in this file — put them in the env file the daemon
# and the systemd unit both load: ~/.config/prometheus/env
# (PROMETHEUS_API_TOKEN, PROMETHEUS_TELEGRAM_TOKEN, ANTHROPIC_API_KEY, …).

If you installed with uv tool install or pip — which is almost everyone — yours is ~/.prometheus/prometheus.yaml, and entry 2 never applies. The repo-local path exists for people running from a checkout, and it wins over your home directory when both are present. That is the one surprise in the list: a checkout you forgot you were standing in will quietly take precedence.

Which file am I actually using oara doctor prints it on its first line — ✓ Config: loaded ~/.prometheus/prometheus.yaml, or a ✗ naming every path it searched. That is the reliable answer; see Verify it works.

Secrets go in the env file

~/.config/prometheus/env is a plain KEY=value file, mode 0600. Both the daemon and the systemd unit load it, which is why it is the env file and not your shell profile — a service started at boot never sees your shell.

VariableWhat it is
PROMETHEUS_API_TOKENBearer token for the REST/WS API that Beacon and the iOS app authenticate with. See Tokens and the open web API.
PROMETHEUS_TELEGRAM_TOKENBot token, if you use the Telegram gateway.
ANTHROPIC_API_KEY and friendsCloud provider keys, when the model is not local.

The YAML does have a model.api_key field that accepts a key inline, and the template documents it while telling you not to use it. The reasoning is worth repeating, because it is the reason the split exists: a prometheus.yaml gets copied between machines and pasted into issues. An undocumented key that works is worse than a documented one you are told to avoid.

Reading the defaults

There are 46 top-level sections. Rather than reproduce them here — where they would start going stale the day this page was written — read them from the binary you have installed:

oara config --show-defaults1229 lines
oara config --show-defaults > reference.yaml
grep -n '^[a-z_]*:' reference.yaml
16:system:
21:bootstrap:
25:model:
135:compaction:
153:checkpoints:
…
1170:vault:
1184:doctor:
1189:tasks:
1197:heartbeat:
1216:documents:
1224:escalation:

It is worth actually reading rather than grepping. The comments carry the reasons — several of them record the incident that produced the setting, including dates. That is the closest thing to a design rationale the project has.

Known gap oara config with no flags prints its own help and exits 0. There is currently no command that shows you the merged, loaded configuration — --show-defaults prints the shipped template, which is not the same thing as what your daemon is running. Until there is one, oara doctor is how you confirm which file loaded, and reading that file is how you see what is in it.

The handful you are likely to change

Defaults below are the shipped values, read from the template.

KeyShips asWhy you might touch it
model.provider
model.base_url
llama_cpp
http://localhost:8080
Point at a different backend. oara setup writes these for you.
model.modelemptyA hint, not an assertion — the backend is authoritative. Leave it blank unless your server cannot be asked what it is serving.
web.enabledtrueThe REST/WS control plane Beacon talks to. On by default, but not open by default — the daemon mints an API token on first start if none is set.
web.api_port / ws_port8005 / 8010Change if something else owns those ports.
security.workspace_root~/.prometheus/workspaceWhere the file tools may write without asking. Widen deliberately — and read the next section before you do.
coding.enabledfalseCoding mode runs model-authored commands against a clone of your repo, so it is opt-in at both entry points.
gateway.telegram_enabledfalseTurn on the Telegram gateway. The token itself goes in the env file.

What actually constrains the agent, in order

This is the part worth reading slowly, because the setting with the most reassuring name is the weakest of the three and none of the first two covers bash. The template states all of this in its own comments; it is collected here because it is spread across a hundred and fifty lines and the order matters.

LayerShips asWhat it actually does
security.workspace_root~/.prometheus/workspaceA prompt, on write_file and edit_file only. An accidental write outside your working area asks first. Nothing more.
security.denied_paths/etc, /sys, /boot, /*/.ssh, /*/.gnupg, /*/.config/*/*envA refusal — but still only on calls that pass a file path. The globs span / deliberately, and the daemon's own config file is denied automatically from wherever it loaded.
security.bash_confinement"off"The kernel read floor for bash, via AppArmor. Off by default because most hosts have no AppArmor, where required would refuse every bash call.
security.bash_write_confinement"auto"The kernel write floor for bash, via bubblewrap. auto means "if bwrap is installed" — and on a machine without it, bash runs with no write floor at all.
Neither list covers bash denied_paths is consulted only when a call passes a file_path, and bash is handed a command string — so at both origins cat ~/.ssh/id_* is allowed. The template records this as measured, not inferred. Checking the command string instead does not work either: ordinary shell defeats it (cd ~/.ssh && cat id_*, $HOME indirection, globs, sh -c), which is why the floor for bash is a kernel mechanism or nothing. On a stock machine with neither AppArmor nor bubblewrap, it is nothing.

oara doctor reports both floors and their live state, including ! Bash write floor: mode 'auto' but UNAVAILABLE when bwrap is missing. If you are about to expose this daemon to anything, that line is the one to read first — and Tokens and the open web API is the other half of the question.

Credit where it is due: the required setting for the read floor refuses to run bash at all if the AppArmor profile is missing or the transition does not happen, rather than silently falling back to an unconfined shell. Being handed a weaker sandbox than you asked for is the failure you would not notice, and it is refused by design in several places here — coding.sandbox_type raises for the same reason.

Where everything else lives

PathWhat is in it
~/.prometheus/The data root. Everything below is under it.
~/.prometheus/prometheus.yamlYour config, for a pip or uv install.
~/.prometheus/memory.dbExtracted facts. Fails open — a missing or broken file never blocks a turn.
~/.prometheus/data/Other databases, including training.db.
~/.prometheus/logs/Logs. cli.log always gets INFO even when the console does not.
~/.prometheus/workspace/The default write area for the file tools.
~/.prometheus/skills/Recorded skills; generated ones land in skills/auto/.
~/.prometheus/wiki/The hand- and machine-maintained knowledge tree.
~/.prometheus/coding/sandboxes/Clones that coding runs work in. Never your original repo.
~/.prometheus/trajectories/Where oara export-traces writes.
~/.prometheus/SOUL.md
~/.prometheus/AGENTS.md
Identity files loaded into every system prompt. Managed with oara identity.
~/.config/prometheus/envSecrets. Mode 0600, loaded by the daemon and the service unit.

Two commands wipe things deliberately and are worth knowing before you need them: oara --reset-telemetry deletes telemetry.db and exits, and oara --reset-data deletes all user data — telemetry, memory, LCM, audit, evals, wiki, sentinel and generated skills. Neither asks twice.