Configuration files and merging¶
Configuration file locations, owner identity, merge precedence, and storage layout.
This document is the central reference for all sase configuration: config files, YAML sections, environment variables, and CLI flags.
Config File Location¶
All sase configuration lives under ~/.config/sase/. The base config file is:
~/.config/sase/sase.yml
Overlay files matching the glob ~/.config/sase/sase_*.yml are merged on top of the
base file. In the SASE Admin Center new-overlay prompt, enter a single local overlay
name rather than a path: extra, sase_extra, and sase_extra.yml all resolve to
~/.config/sase/sase_extra.yml. SASE trims surrounding whitespace and rejects empty
names, . / .., or names containing / or \, so the create-overlay flow cannot
escape the user config directory. A project-local sase/sase.yml at the detected
project root usually takes highest priority. A root-level sase.yml remains an
exclusive read fallback during the
layout compatibility window;
if both files exist, SASE reports a collision instead of merging them. sase's TUI
deliberately disables project-local config loading for its own process so opening
sase tui inside a repo does not inherit that repo's agent-run settings. See
Deep-Merge System below.
Owner Identity¶
SASE has one explicit owner identity selected for the current machine. Initialize or migrate it interactively with either equivalent command:
sase config init
sase init config
The selected overlay owns both parts of the identity:
id:
username: alice
machine_name: athena
id.username is a path-safe, dot-free SASE username. It must be globally unique, should
be identical on every machine owned by the same user, and should normally be the user's
GitHub username. SASE validates its syntax and reserved names but cannot prove global
uniqueness. id.machine_name matches ^[a-z_]+$ and is unique among that user's
machines.
The bounded local state file ~/.sase/machine_name (or $SASE_HOME/machine_name) is
only a selector. It contains one machine name and is deliberately not portable
configuration; it is not the owner identity and cannot supply a missing username. SASE
discovers machine overlays by nested id.machine_name first, with top-level
machine_name accepted only as migration input. See
Configuration migration notes. Foreign
machine overlays do not contribute runtime settings, Config inventory layers, or
config-defined macros. Ordinary overlays still participate.
Only the selected raw machine overlay can own provenance. An id value in bundled
defaults, plugins, ~/.config/sase/sase.yml, ordinary overlays, or project-local config
is ignored by runtime merging and cannot change the owner for one project. The selected
raw id object remains visible in merged configuration for inspection.
The initializer lists declared machines, suggests a schema-safe hostname when a machine
must be chosen, and requires an explicit valid username unless exactly one existing
username is clearly confirmed for reuse. It never chooses among conflicting usernames.
Creation and migration minimally set id.username and id.machine_name in the same
overlay, remove its top-level key, preserve unrelated YAML/comments, and then write the
selector. With use_chezmoi: true, the overlay edit is made in the chezmoi source tree.
Direct sase config init uses the normal commit/push/apply deployment; bare sase init
combines the edit with deferred chezmoi deployment. The initializer also adds a hostname
guard to the chezmoi source .chezmoiignore, staging it in the same commit as the new
overlay:
{{ if ne .chezmoi.hostname "<chezmoi-hostname>" }}
.config/sase/sase_<machine>.yml
{{ end }}
The guard uses chezmoi's hostname, which may differ from the SASE machine name, so the
overlay is applied only on the machine where it was initialized. If .chezmoiignore
already contains an entry for that overlay, the existing guard is left unchanged. The
same hostname guards are required when a machine overlay declares memory.h1_title so
sase memory init can emit a per-hostname H1 in the chezmoi AGENTS.md.tmpl source.
Prompting requires a TTY. sase config init --check, bare sase init --check, and
sase doctor report missing usernames, migration input, invalid values, selector
mismatches, duplicate overlays, and identity conflicts without writing. Config
inspection, help, initialization, doctor, and historical run records remain available
while identity is incomplete. Actual agent process creation, new commit provenance, and
agents-sidecar mutations require both identity fields and fail with the actionable
sase config init instruction.
There is intentionally no bundled identity default.
Machine hoods also provide stable ownership for the hidden agents sidecar. See Agent Hood Synchronization for privacy controls, package contents, import/publication commands, and recovery.
Deep-Merge System¶
Sase builds a merged configuration through five layers, each merged on top of the previous:
default_config.yml— bundled package defaults- Plugin
default_config.ymlfiles — from installed plugin packages (viasase_configentry points), sorted by entry-point name; lists concatenate sase.yml— user config (~/.config/sase/sase.yml); lists replace defaults (not concatenate)- Selected
sase_*.ymloverlays — ordinary overlays plus only the machine overlay whose nestedid.machine_name(or top-level compatibility fallback) matches~/.sase/machine_name, sorted alphabetically; lists concatenate - Local
sase/sase.yml— project-level config at the detected project root (or the rootsase.ymlcompatibility fallback); lists concatenate (highest priority)
This allows splitting shared configuration across ordinary files (e.g., sase_work.yml,
sase_personal.yml) without duplication and keeping machine-specific settings in
selector-safe overlays. Plugins can provide sensible defaults that users can override,
and individual projects can customize behavior without changing global config.
Merge semantics:
| Type | Behavior |
|---|---|
| Dicts | Merged recursively (overlay keys override base keys). |
| Lists | Concatenated in layers 2, 4, and 5; replaced in layer 3 (user config). |
| Scalars | Override (overlay value replaces base value). |
For example, given a base file with two mentor profiles and an overlay or local project
config that adds a third, the merged result contains all three profiles. A user
~/.config/sase/sase.yml list replaces earlier defaults instead. If two files define
the same scalar key (e.g., axe.max_hook_runners), the later layer wins.
The axe block is the one exception to plain dictionary merging: after the layers are
combined, SASE recomposes it from the same layer chain so that keyed routine and job
entries merge by identity and AXE compatibility aliases (see
axe) normalize to one effective shape.
Source: src/sase/config/core.py, src/sase/config/loading.py
Directory Sharding¶
High-volume state writers use a YYYYMM/ shard inside each managed artifact directory
(keyed by the current month). Readers merge sharded and unsharded files, so top-level
files remain visible and both layouts support reads and writes.
Prompt history and TUI artifact layout migration are described in Local state migration.
Related¶
- Configuration reference — generated keys and defaults.
- Configure the essentials — common setup values.
_[project]: A sase project is a named unit of work registered with SASE. _[workspace]: A sase workspace is a numbered clone of a project's primary repo, managed by the workspace store and tracked in that project's registry.json. _[agent]: A sase agent is an agent session or a single agent that does not belong to a session. _[prompt]: A prompt is the text SASE hands to a provider to start an agent turn. _[macro]: A macro is a reusable prompt triggered with #name in agent prompts. _[Patch]: A Patch is SASE's local unit of change. _[bead]: A bead is one tracked work item in SASE's git-native issue tracker. _[plan]: A plan is a persisted, approved artifact recording the intent behind agent work. _[TUI]: The TUI is SASE's terminal interface for running agents and reviewing results. _[epic]: An epic is an executable multi-phase plan run with sase bead work. _[gate]: A sase gate is a durable, command-backed request for one user decision, created when work must pause for the user. _[monitor]: A sase monitor is a monitor turn that runs one long command under a detached supervisor, so the command outlives the agent that started it. *[stitch]: A stitch is the lightweight ordered change record inside a Patch's STITCHES: section.