exarch’s config home: trusted because it is not the working tree
exarch keeps its user-authored, trusted configuration in the XDG config home
— $XDG_CONFIG_HOME/exarch/ — structurally outside the working tree the
sandboxed agent can write, and distinct from the per-project state and cache
homes. Where a file lives is its trust level: the config home is the one place
no grant makes writable, so what sits there is exactly what the
agent must not be able to forge.
The XDG split
Every exarch directory resolves through app::App::xdg_dir(kind)
(exarch/src/app.rs), with app::EXARCH supplying the exarch
component — $XDG_<kind>_HOME/exarch/, spelled by core’s
path::app_dir_or_temp, the convention ral’s own directories share, over the shared
xdg-resolver-consolidation
resolver (core/src/path/basedir.rs, XdgKind). Three roles, three relationships
to trust:
- config home —
$XDG_CONFIG_HOME/exarch/— hand-authored, trusted files. The one directory the operator writes and the agent never can. - state home —
$XDG_STATE_HOME/exarch/<project-slug>/viaapp::EXARCH.project_dir(cwd)— the persisted choice of provider, model and via (state.json) and the per-run session logs, keyed by a slug of the launchcwdso a project’s exarch state is one findable directory, never scattered into the working tree. - cache home —
$XDG_CACHE_HOME/exarch/— the model catalog cache, a refetchable snapshot with a TTL.
What lives in the config home
config.ral— the only declaration exarch cannot infer: a custom provider’s base URL, key env var, and wire protocol (provider-config-ral-script). A famous provider auto-populates from its env key and needs no entry; the file exists for the self-hosted or non-famous endpoint. Its authority argument is that a redirected endpoint is an exfiltration channel, so the declaration belongs at the trusted home, never in cwd.AGENTS.md— the operator’s global agent instructions, the outermost link of the Workspace chain injected into the system prompt.
The trust model
The config home is trusted precisely because it is never the working tree.
The sandboxed agent’s grant admits writes to cwd and the
per-session scratch dir alone, so no profile can make $XDG_CONFIG_HOME
writable — the protection is structural, not a deny-list entry an oversight
could omit (policy).
-
Structural covers write, and only write. Most bases read
`xdg-configand`xdg-statewhole, so tools find their own configuration — which is why the files holding our credentials are denied by name, in composition, on the same footing as a restrict file (a-grant-never-reaches-its-own-key). Everything else here the agent may read, and some of it it is meant to: the globalAGENTS.mdand the skill roots are addressed to it. -
A trusted location still gets a no-authority evaluation.
config.ralis source, so it is evaluated, not parsed (exarch/src/config.rs) — under a no-authority grant (Capabilities::deny_all:exec,net, andfsall denied), in a throwaway shell. It can compute a value, cause no effect. The asymmetry is deliberate: even a file the agent cannot write is evaluated as if it might be hostile, because a redirected endpoint is an exfiltration channel and the in-process guard suffices to close it (two enforcers: withexecdenied there is no route to the network).
See also agents-md-injection, exarch-architecture, grant, provider-config-ral-script, xdg-resolver-consolidation.