Auth configuration parsed from auth.* keys. Controls whether this client
resolves provider tokens from the local auth.json (default) or from a
remote credential broker. See task #157 / auth::credential_source.
Subagent fan-out limits (subagent.* keys). They apply to the whole
delegation tree of one session: workers started by workers count against
the same limits as workers started by the foreground. A prompt manifest
with an explicit delegation policy sets its own concurrency and total
limits; max_depth applies either way.
Typed per-role turn-budget overrides (Task 23, spec §8.1). Every field
is optional: unset fields keep the role’s compiled default. Values are
parsed from turn_budget.<role>.<field> config keys.
gzip Content-Encoding for Anthropic request bodies
(request_compression). Every request re-uploads the whole
conversation, and the JSON compresses about 2x.
Default for cache_keepwarm_auto_max_hours: the longest an auto idle
period may run. Without it the ski-rental bound alone lets a 0.05×
cache-read model (Opus 5.5, Sonnet 5.5) ping ~39 times over ~36h and a
0.025× model (Fable 5.1, Mythos 5.1) ~79 times over ~72h under a 1h TTL,
keeping an abandoned session unparked for days. 24h: a user who steps
away for a working day or overnight still comes back to a warm cache; a
session left over a weekend parks. (Owner decision, task #444.)
Default for subagent_cold_resume_compact_tokens. Below ~100k tokens a
cold full replay costs well under $1 on the priciest model and keeps every
detail; above it (measured resumes reached 250k–715k tokens, up to ~$3.50
each) the compact context is the cheaper trade.
Default for subagent_rollover_tokens: the footprint at which a worker’s
context rolls over (to a successor of about 100k on a 1m window). Workers
are long 5-minute-TTL loops with no human pauses, so every round re-reads
the whole context; a 100k -> 200k cycle repays the ~100k successor write
(about 17 rounds on Opus 5.5) well before the next rollover.
Default for tool_output_spill_bytes: a tool result bigger than this is
stored whole in a spill file and model history gets a head + tail
preview pointing at it. 12 KiB is about 3k tokens. Below it the preview
(head + tail + pointer, ~7.3 KiB) saves too little to be worth a second
look when the model does need the middle; above it every result saves at
least ~4.5 KiB on every later request, and the 22-26 KB results that
were re-read hundreds of times shrink by ~70%.
Every key accepted by the namespaced family parsers that is NOT in
KNOWN_CONFIG_KEYS (shell.*, events.*, turn_budget.*,
memory.*, server.*, bridge.*, auth.*). Open-ended families whose
suffix is user-chosen are listed as prefix.*. Keep this in sync when a
parser learns a key: the /settings coverage test requires each entry to
have a settings row or an explicit exclusion.
Known top-level config keys — used for unknown-key warnings + did-you-mean.
Public so the /settings coverage test can require a settings row (or an
explicit exclusion) for every key here.
Upper bound for the <N>h form of cache_keepwarm. The ski-rental bound
already caps an abandoned session’s spend at about one prefix rewrite; the
hour cap is an extra, user-chosen wall on top of it.
Highest gzip level. Levels 3-6 pay off on slow uplinks, where the extra
CPU time is tens of milliseconds and the upload saved is seconds; above
6 the body barely shrinks further.
Smallest accepted subagent_rollover_tokens. Below it the derived
successor target is smaller than a typical brief plus last round, so
rollovers could not shrink the context and would only churn the cache.
Every problem the parser reports for content: the warnings surfaced
at startup plus the stderr-only diagnostics of the shell.*, events.*,
turn_budget.* and memory.* families. Pure — prints nothing and
touches no process state.
Returns the configured identity string for the system prompt preamble.
Falls back to DEFAULT_IDENTITY (the SynapsCLI identity above) if not set
in config. Initialized by load_config() — safe to call anytime after boot.
Provider API keys parsed from provider.<name> = ... lines in config.
Empty if load_config() hasn’t been called. The registry falls back to
env vars, so e.g. GROQ_API_KEY works even with an empty map.
Whether an env VALUE carries a credential regardless of its key name:
any URL with userinfo (scheme://user:pass@host, scheme://key@host),
anywhere in the value — DATABASE_URL, HTTPS_PROXY, a Sentry DSN or a
JDBC option string all qualify. The key-name denylist alone missed these,
so their credentials reached the daemon and the session files on disk.
A username-only URL (ssh://git@host/…) is treated as a secret too:
rare in an environment, and failing safe beats a guess.
Whether a key matches the secret denylist (case-insensitive).
Used by the journal save path to ensure secret values never reach disk,
and by the client env capture to strip secrets before Hello.
Why name can’t be a tool_scope_slice / daemon_scope_slice value, or
None if it can. A slice unit name: at most 255 bytes, ending in
.slice, only [A-Za-z0-9:_.-] (so no /), not starting with - and
not the root slice -.slice; as in systemd’s own check, the part before
.slice is not empty, has no -- and doesn’t end in - (a - separates
the parent slices: synaps-tools.slice nests under synaps.slice). The
config file is not TOML, so a quoted value keeps its quotes and gets its
own hint. An empty value never reaches this check: the parser takes it
as “unset”.
Sets the active profile name. Must be called before any get_profile() call
(i.e., before config resolution begins). Uses OnceLock — first write wins,
subsequent calls are no-ops. No env var mutation (unsafe under tokio).
Write a single key = value pair to ~/.synaps-cli/config (or profile config).
Replaces the first existing line that matches the key, or appends if absent.
Preserves comments and unknown keys. Writes atomically via temp file + rename.