#[non_exhaustive]pub struct Config {Show 114 fields
pub model: String,
pub base_url: String,
pub api_key: Option<String>,
pub api_key_env: String,
pub api_key_cmd: Option<String>,
pub system_prompt: String,
pub temperature: Option<f32>,
pub max_tokens: Option<u32>,
pub max_iterations: usize,
pub effort: Option<String>,
pub response_format: Option<Value>,
pub extra_body: Map<String, Value>,
pub max_total_output_tokens: Option<u64>,
pub max_tool_output_bytes: Option<usize>,
pub cwd: PathBuf,
pub additional_dirs: Vec<PathBuf>,
pub load_project_context: bool,
pub sandbox: SandboxPolicy,
pub approval: ApprovalPolicy,
pub auto_approved_tools: HashSet<String>,
pub tool_deny_patterns: Vec<String>,
pub tool_allow_patterns: Vec<String>,
pub approval_handler: Option<Box<dyn Fn(&ToolCall) -> bool + Send + Sync>>,
pub pre_tool_hook: Option<Box<dyn Fn(&str, &Value) -> Option<String> + Send + Sync>>,
pub post_tool_hook: Option<Box<dyn Fn(&str, &str, bool) + Send + Sync>>,
pub prompts: HashMap<String, String>,
pub compact_after_messages: Option<usize>,
pub tool_overrides: HashMap<String, ToolOverride>,
pub tool_advertising: ToolAdvertising,
pub extra_headers: HashMap<String, String>,
pub event_sink: Option<EventSink>,
pub cache_plan: CachePlan,
pub reduction_policy: ReductionPolicySettings,
pub handoff_enabled: bool,
pub tool_schema_tier: SchemaTier,
pub cache_warnings: bool,
pub module_registry: bool,
pub module_activation: ModuleActivation,
pub core_tools_enabled: Vec<String>,
pub skills_enabled: bool,
pub small_model: Option<String>,
pub model_fallback: Vec<String>,
pub env_context: bool,
pub project_root_markers: Vec<String>,
pub project_doc_max_bytes: Option<usize>,
pub instruction_imports: bool,
pub retry_enabled: bool,
pub retry_max_retries: Option<u32>,
pub retry_base_delay_ms: Option<u64>,
pub compaction_reserve_tokens: Option<u64>,
pub compaction_keep_recent_tokens: Option<u64>,
pub compaction_focus_instructions: Option<String>,
pub auto_title: bool,
pub steering_mode: SteeringMode,
pub follow_up_mode: SteeringMode,
pub stop_gate: Option<StopGateHook>,
pub read_file_multimodal: bool,
pub edit_file_require_read_before_edit: bool,
pub edit_file_notebook_aware: bool,
pub shell_env_snapshot: bool,
pub doom_loop_threshold: Option<u32>,
pub nested_instructions: bool,
pub model_switch_allow_switch: bool,
pub context_injections: bool,
pub context_injection_blocks: Vec<ContextInjectionBlock>,
pub compaction_enabled: bool,
pub parallel_tool_calls: bool,
pub session_git_metadata: bool,
pub session_dir: Option<String>,
pub session_persist: bool,
pub session_name: Option<String>,
pub session_retention_days: Option<u32>,
pub session_export_format: HumanExportFormat,
pub permissions_enabled: bool,
pub permissions_ask_patterns: Vec<String>,
pub permissions_protected_paths: Vec<String>,
pub network_policy: Option<NetworkPolicy>,
pub sandbox_os_enabled: Option<bool>,
pub sandbox_escalation: SandboxEscalation,
pub sandbox_env_policy: SandboxEnvPolicy,
pub subagents_enabled: bool,
pub subagents_max_depth: usize,
pub subagents_max_concurrent: usize,
pub subagents_background: bool,
pub subagents_background_prompts: Option<BackgroundPromptsPolicy>,
pub subagents_claude_agent_alias: bool,
pub claude_runtime_tools_enabled: bool,
pub subagents_definitions: HashMap<String, NamedAgentDefinition>,
pub subagent_depth: usize,
pub tui_enabled: bool,
pub tui_theme: String,
pub tui_vim_mode: bool,
pub tui_keymap: HashMap<String, String>,
pub session_tree_enabled: bool,
pub session_tree_branch_summaries: bool,
pub session_tree_labels: bool,
pub tools_background_enabled: bool,
pub tools_background_max_concurrent: usize,
pub tools_background_max_output_bytes: usize,
pub checkpoint_enabled: bool,
pub checkpoint_retain: usize,
pub checkpoint_dir: Option<PathBuf>,
pub lsp_enabled: bool,
pub lsp_servers: Vec<(String, LspServerSpec)>,
pub lsp_max_diagnostics: usize,
pub lsp_timeout_secs: u64,
pub formatters_enabled: bool,
pub formatters: Vec<(String, FormatterSpec)>,
pub formatters_diff_back: bool,
pub formatters_timeout_secs: u64,
pub trust_enabled: bool,
pub trust_default: TrustDecision,
pub plugins_enabled: bool,
pub plugins_dirs: Vec<PathBuf>,
}Expand description
Everything that shapes an crate::Agent: the model and endpoint, the
credentials, sampling parameters, the system prompt, and per-tool overrides.
Build one with Config::builder.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.model: StringModel identifier as understood by the endpoint, e.g.
anthropic/claude-opus-4-8 or openai/gpt-5 on OpenRouter.
base_url: StringBase URL of the OpenAI-compatible endpoint (no trailing /chat/...).
api_key: Option<String>Explicit API key. If None, Self::api_key_env is consulted.
api_key_env: StringEnvironment variable to read the API key from when Self::api_key is unset.
api_key_cmd: Option<String>P4 (COMPOSABLE-HARNESS-DESIGN.md §5.2 “P4”, §1.8/§3.1
core.api_key_cmd, D6 row): a credential-helper command (pi§6
!command form). Consulted by Agent::new when Self::api_key
is unset: the command is run through the shell, its trimmed stdout
becomes the key, and a non-zero exit or empty output falls through to
Self::api_key_env rather than failing outright. None (the
default) means this is never consulted — byte-identical to today’s
behavior. SECURITY: this is a command string, never a secret value —
Self::api_key itself must never be file-plaintext (§3.2 S13);
api_key_cmd is [project-forbidden] at every config-file layer
(§3.3), same trust boundary as base_url/api_key_env.
system_prompt: StringSystem prompt prepended to every conversation.
temperature: Option<f32>Optional sampling temperature.
max_tokens: Option<u32>Optional output token cap.
max_iterations: usizeMaximum number of model/tool iterations per crate::Agent::send call.
effort: Option<String>Reasoning/effort level sent to the model (reasoning_effort).
response_format: Option<Value>Structured-output constraint (response_format), e.g. a json_schema.
extra_body: Map<String, Value>Extra request-body fields merged in (provider-native passthrough: prompt-cache controls, provider-specific knobs).
max_total_output_tokens: Option<u64>Optional cap on cumulative output tokens across one crate::Agent::send
loop; the loop stops once exceeded. Output tokens only; input/prompt
tokens are not counted, so this is not a cost cap.
max_tool_output_bytes: Option<usize>Max bytes of a single tool result fed back into the conversation. Output
beyond this is truncated with a notice, so one runaway command (a huge
log, a binary dump) can’t explode the context window. None disables the
cap. Defaults to 100 KB.
cwd: PathBufWorking directory tools operate within.
additional_dirs: Vec<PathBuf>Additional roots beyond cwd (the analog of --add-dir / multi-root):
searched for project-context files and available to tools.
load_project_context: boolWhether to auto-load CLAUDE.md / AGENTS.md into the system prompt.
sandbox: SandboxPolicyFilesystem confinement applied to write-capable tools.
approval: ApprovalPolicyWhen the agent must seek approval before running a tool.
auto_approved_tools: HashSet<String>Tools that never require approval under ApprovalPolicy::OnRequest.
tool_deny_patterns: Vec<String>P4 (design §5.2 “P4”: “deny-rule patterns generalizing
auto_approved_tools” — the S-sized generalization, NOT the full P5
capabilities.permissions.rules deny→ask→allow engine, §2.1
dependency 3’s command-canonicalization prerequisite is P5-only).
Glob patterns (* wildcard, see glob_match) matched against a
tool’s NAME — no argument/command-level matching. Any match forces
Config::needs_approval to true UNCONDITIONALLY, even under
ApprovalPolicy::Never — the entire point of a deny rule is a
hard floor --yes/Never can’t bypass. Sourced from
capabilities.permissions.rules.deny (§3.1 module 11); empty by
default (today’s behavior, byte-identical).
tool_allow_patterns: Vec<String>P4: the ALLOW-pattern generalization of Self::auto_approved_tools
— glob patterns matched against a tool’s NAME, exempting a match from
approval under ApprovalPolicy::OnRequest exactly like an exact
auto_approved_tools entry does (never consulted under Untrusted,
same as auto_approved_tools). Sourced from
capabilities.permissions.rules.allow; empty by default.
approval_handler: Option<Box<dyn Fn(&ToolCall) -> bool + Send + Sync>>Consulted when a tool call needs approval; None denies by default.
pre_tool_hook: Option<Box<dyn Fn(&str, &Value) -> Option<String> + Send + Sync>>Runs before each tool executes; may block the call.
post_tool_hook: Option<Box<dyn Fn(&str, &str, bool) + Send + Sync>>Runs after each tool executes (observational).
prompts: HashMap<String, String>Named prompt templates (skills / slash commands). A user message of the
form /<name> <args> is expanded to the template with {args} filled.
compact_after_messages: Option<usize>If set, the conversation is compacted once it grows beyond this many messages (older middle turns are summarized into one marker), keeping the system prompt and the most recent turns.
tool_overrides: HashMap<String, ToolOverride>Per-tool enable/disable + description overrides, keyed by tool name.
tool_advertising: ToolAdvertisingHow tools are advertised to the model (B6). Defaults to ToolAdvertising::Full.
extra_headers: HashMap<String, String>Extra HTTP headers sent with every request (e.g. OpenRouter’s
HTTP-Referer / X-Title attribution headers).
event_sink: Option<EventSink>Optional sink for streaming crate::AgentEvents.
cache_plan: CachePlanPrompt-caching plan (B7). Defaults to CachePlan::Off; reduced mode
(--reduced, D5/D14) defaults it to CachePlan::ImportedPrefix
(wired at the CLI’s reduced-mode assembly point, crates/cli/src/main.rs).
reduction_policy: ReductionPolicySettingsResolved optional reduction gates. These are kept separate from the live policy because freshness probes and prepared summaries are per-request data, not configuration.
handoff_enabled: boolWhether the explicit reversible handoff projection is available.
This is separate from Self::reduction_policy because handoff is
an offline command over an existing sidecar, not a per-request
projection pass. Defaults to true; only an explicit composable
capabilities.reduction.handoff = false disables it.
tool_schema_tier: SchemaTierGlobal tool-schema tier (TR-8/T5): how verbose ADVERTISED tool
schemas are. Defaults to crate::tools::SchemaTier::Full (today’s
behavior — byte-identical schemas). A per-tool override in
ToolOverride::schema_tier wins over this for that tool. Tool
definitions are config, never session content, so this never affects
what’s stored or exported — only what’s advertised on the wire.
cache_warnings: boolUX-26 (B7-warn): whether crate::Agent emits
crate::AgentEvent::CacheWarning when a turn under
CachePlan::ImportedPrefix likely paid a full-price prompt-cache
miss despite reuse being expected (idle past the provider’s TTL, or
usage reporting a near-zero cache-read ratio). Defaults to true
(on-brand token-economics feedback, on by default like the savings
figures inspect stats already surfaces); the CLI’s
--no-cache-warnings flag / cache_warnings = false config / the
SUPERCODE_CACHE_WARNINGS=0 env var turn it off. A no-op — never
checked — for any caller not using CachePlan::ImportedPrefix, so
this changes nothing under CachePlan::Off (today’s default outside
reduced mode).
module_registry: boolP3 (COMPOSABLE-HARNESS-DESIGN.md §5.2 phase P3, mandatory risk-2
mitigation, §5.3 risk 2): the [experimental] module_registry flag.
false (the default) means crate::tools::ToolRegistry::from_config
returns EXACTLY crate::tools::ToolRegistry::with_builtins — the
runtime path is byte-for-byte today’s behavior. Only when explicitly
turned on does Self::module_activation start shaping the
registry/prompt assembly.
module_activation: ModuleActivationP3: the resolved §2 module-activation set (pure config → set,
computed by crate::configfile::resolve/crate::modules::ModuleActivation::from_harness
with no agent loop required). Only consulted when
Self::module_registry is true.
core_tools_enabled: Vec<String>P3: the effective [core.tools] enabled list (§3.1) — which of the
core four (read_file/bash/edit_file/write_file, plus any
future core tool name) are present at all. Defaults to the §1.2
default-active four, matching crate::tools::ToolRegistry::with_builtins’s
unconditional registration. Only consulted when
Self::module_registry is true.
skills_enabled: boolP3: [core.skills].enabled (§1.4 obligation 4, D-7) — whether the
skills prompt section may appear at all. Still gated by D-7’s read
pathway (read_file or bash present in Self::core_tools_enabled)
at the assembly site. Only consulted when Self::module_registry
is true.
small_model: Option<String>P4 (COMPOSABLE-HARNESS-DESIGN.md §5.2 “P4”, §3.1
capabilities.model_catalog.small_model, catalog §4a “Small/utility
model routing knob”): a cheaper/faster model id a caller (e.g. a
crate::reduce::summarize::SpanSummarizer implementation, or an
auto-title side-call) MAY use instead of Self::model for
low-stakes side-calls. None (the default) means every such
consumer falls back to the main model — the exact §2.1 D-9 fallback
behavior — since nothing in this crate resolves this field on its
own; it is a knob a caller reads, not a routing loop this crate runs.
model_fallback: Vec<String>P4 (§3.1 capabilities.model_catalog.fallback, catalog §4a “Model
aliases + failure fallback chain”): an ordered list of full model
slugs a caller MAY retry against, in order, if Self::model fails.
Empty (the default) means no fallback chain is configured. Like
Self::small_model, this is the resolved TABLE only — see
crate::model_catalog’s module doc for the scope boundary between
“a resolved list of slugs” (this field, S-sized) and an actual
retry/failover loop that consumes it (a separate, larger change).
env_context: boolP4b (COMPOSABLE-HARNESS-DESIGN.md design doc S5.2 “P4”, S1.4/S3.1
core.env_context, catalog S4a “Environment context block
injection”): when true, Agent::with_parts appends a short
# Environment block (cwd, platform, date, best-effort git branch)
to the system prompt, alongside Self::load_project_context’s
instruction files. false (the default) is byte-identical to
today’s behavior.
project_root_markers: Vec<String>P4b (S1.4/S3.1 core.project_root_markers, catalog:232): filenames
that mark a directory as the project root for Self::env_context’s
git-status probe. Defaults to [".git"].
project_doc_max_bytes: Option<usize>P4b (S1.4/S3.1 core.project_doc_max_bytes, cx2 “project_doc_max_bytes”
analog, S5.2 P4 “instruction-walk nuances”): a hygiene cap on the
TOTAL bytes of instruction-file content (Self::load_project_context’s
global + project tiers combined) appended to the system prompt. None
(the default) is uncapped – byte-identical to today’s behavior; only
an explicit Some(n) truncates the assembled block (with a trailing
notice), mirroring Self::max_tool_output_bytes’s cap-with-notice
shape.
instruction_imports: boolP4b (S1.4/S3.1 core.instruction_imports, catalog:85): when true,
an instruction file may reference another file via an @relative/path
token (CC’s import syntax) – the referenced file’s contents are
inlined in its place, resolved relative to the IMPORTING file’s own
directory, to a max depth of 4 (CC’s own default) to bound cycles.
false (the default) leaves @ tokens as plain literal text –
byte-identical to today’s behavior.
retry_enabled: boolP4b (S1.1/S3.1 core.retry, pi3 shape): whether a transient
(connection failure / 5xx) provider error is retried at all. This
EXTENDS a pre-existing, always-on transport-layer mechanism
(provider::OpenAiProvider’s internal HttpOptions retry — 2
attempts / 500ms base backoff, hardcoded, not previously
config-file-settable) rather than adding a second one: true (the
default, matching today’s always-on behavior byte-for-byte when
Self::retry_max_retries/Self::retry_base_delay_ms are also both
unset) keeps retrying; an explicit false is a NEW capability —
disabling the transport retry entirely.
retry_max_retries: Option<u32>Override the transport retry’s attempt count. None (the default)
keeps the pre-existing built-in default (2).
retry_base_delay_ms: Option<u64>Override the transport retry’s base backoff delay in milliseconds
(doubles per attempt). None (the default) keeps the pre-existing
built-in default (500ms).
compaction_reserve_tokens: Option<u64>P4b (S1.5/S3.1 core.compaction.reserve_tokens, pi2 shape): once
set, Agent::maybe_compact ALSO triggers when the estimated token
size of the live history is within reserve_tokens of the model’s
context window – in addition to (not instead of)
Self::compact_after_messages’s message-count trigger. None (the
default) leaves the pressure trigger off – byte-identical to today’s
message-count-only behavior.
compaction_keep_recent_tokens: Option<u64>P4b (S1.5/S3.1 core.compaction.keep_recent_tokens): when the
PRESSURE trigger (not the message-count one) fires, how many of the
most recent tokens (estimated) to keep verbatim instead of a fixed
message count. Only consulted when Self::compaction_reserve_tokens
is Some and the pressure trigger is what fired.
compaction_focus_instructions: Option<String>P4b (S1.5/S3.1 core.compaction.focus_instructions, catalog D2 “no
instruction steering” gap): free text appended to the synthetic
compaction marker message every time compaction fires (either
trigger), steering the model on what to keep focusing on
post-compaction (CC’s manual-compact /compact <focus> analog).
None (the default) leaves the marker text byte-identical to
today’s.
auto_title: boolP4b (S1.6/S3.1 core.session.auto_title, catalog:150, D-9): whether
crate::session_title::auto_title may be invoked at all by a caller
(the caller still supplies the SessionTitler side-call itself –
this is only the gate, mirroring Self::small_model’s “a knob a
caller reads” framing). false (the default): callers should treat
auto-title as off.
steering_mode: SteeringModeP4b (S1.7/S3.1 core.steering, pi3 semantics): how queued mid-turn
steering messages (Agent::queue_steer) are drained – All
delivers every queued message at once, OneAtATime (the default)
delivers one per drain point.
follow_up_mode: SteeringModeP4b (S1.7/S3.1 core.steering.follow_up_mode): how queued follow-up
messages (Agent::queue_follow_up) are drained once the loop is
otherwise idle (no more tool calls pending).
stop_gate: Option<StopGateHook>P4b (S1.9/S3.1 [core] stop_gate, D3 “stop/completion gating”, CC
Stop-hook semantics cc3): consulted exactly once per run_loop
iteration that would otherwise return a final answer (no more tool
calls pending, and the follow-up queue is empty). Receives the
would-be-final assistant message; Some(reason) VETOES termination
– reason is injected as a new user message and the loop continues
(still bounded by Self::max_iterations); None allows the stop.
Code-only, like Self::pre_tool_hook/Self::post_tool_hook –
the CLI’s declarative [hooks] stop = "cmd" form (module 17)
populates this SAME single slot rather than adding a second call
site, so the two can never double-fire (S2 module 17’s “hooks layer
on core’s gate” note). None (the default) is byte-identical to
today’s behavior.
read_file_multimodal: boolP4c (COMPOSABLE-HARNESS-DESIGN.md S1.2/S3.1 core.tools.read_file multimodal, catalog S4a “Multimodal read (image passthrough on
read_file)”): when true, read_file returns a recognized image
file (.png/.jpg/.jpeg/.gif/.webp/.bmp) as a model-visible
image content block instead of decoding it as (garbled) UTF-8 text.
false (the default) is byte-identical to today’s behavior.
edit_file_require_read_before_edit: boolP4c (S1.2/S3.1 core.tools.edit_file.require_read_before_edit,
UNIQUE CC row, catalog:32): when true, edit_file refuses unless
the target path was read (via read_file) earlier in this same
conversation – tracked in ToolContext. false (the default) is
byte-identical to today’s behavior.
edit_file_notebook_aware: boolP4c (S1.2/S3.1 core.tools.edit_file.notebook_aware, UNIQUE CC row
“NotebookEdit”, catalog:40): when true, edit_file additionally
accepts Jupyter cell replace/insert/delete operations against a
.ipynb target (see tools::builtins::EditFileTool’s cell-op args)
instead of only the exact-string replace it always supports. false
(the default) is byte-identical to today’s behavior.
shell_env_snapshot: boolP4c (S1.2/S3.1 core.shell_env_snapshot, SPLIT CC+CX row,
catalog:338): when true, Agent::new/with_parts captures the
user’s interactive login-shell environment ONCE at construction
($SHELL -lc env, best-effort) and every bash call inherits it
directly instead of needing to re-source shell rc files per call.
false (the default) is byte-identical to today’s behavior – no
snapshot is captured, and bash sees only the ambient process
environment, exactly as before this landed.
doom_loop_threshold: Option<u32>P4c (S5.2 P4 “doom-loop breaker”, oc doom_loop UNIQUE row,
catalog D3): when Some(n) with n >= 2, a tool call whose name AND
arguments are byte-identical to the previous n - 1 consecutive
calls is refused (fed back to the model as an error) instead of
executed – the counter resets the moment a call differs. None
(the default) is byte-identical to today’s behavior: no repetition
tracking, no call is ever refused on this basis.
nested_instructions: boolP4c (S1.4/S3.1 core.nested_instructions, catalog:84, deferred from
P4b): when true, a read_file/edit_file call that touches a path
inside a subdirectory carrying its OWN CLAUDE.md/AGENTS.md (a
directory other than Config.cwd itself, which
Self::load_project_context already loads once at session start)
appends that subdirectory’s instructions to the tool’s OWN result the
FIRST time a path under it is touched this conversation (deduped
thereafter – tracked in ToolContext, mirrors CC/OC’s “auto-attach
on read, deduped” semantics, catalog:84). Reuses the same
canonicalize+containment safety check P4b’s @-import expansion
uses (agent::import_target_is_contained) so a symlink cannot walk
the injection outside Config.cwd. false (the default) is
byte-identical to today’s behavior.
model_switch_allow_switch: boolP4c (S1.10/S3.1 core.model_switch.allow_switch, D9 row, dep 8):
gates whether Agent::switch_model does more than the pre-existing
Agent::set_model mechanics (design’s “UX-30 dev/02” – swap
Config.model for the next request, nothing else touched). false
(the default) makes switch_model byte-identical to calling
set_model directly: no persisted model_change record, no
reasoning-artifact filtering. true additionally (1) appends a
typed model_change::ModelChangeRecord to
Agent::model_change_records, and (2) runs
reduce::rehydrate::filter_reasoning_artifacts over Agent::history
so model-A’s reasoning/thinking artifacts (ChatMessage::metadata
keys and any content_parts reasoning blocks) never reach
model-B’s context (S1.13, dep 8).
context_injections: boolP4e (§1.4/§3.1 core.context_injections, catalog:91 “Synthetic
context-injection blocks”): the master gate for
Self::context_injection_blocks – when false (the default),
Agent::with_parts never appends any of them, byte-identical to
today’s behavior. true splices in whatever named blocks are set,
at the same assembly site P4b’s env_context block uses, right
after it.
context_injection_blocks: Vec<ContextInjectionBlock>P4e: named ambient context blocks a caller/embedder populates
programmatically (mirrors Self::prompts/Self::stop_gate’s
code-extensible shape) – there is no [core.context_injections.*]
FILE table because the §3.1 schema’s core.context_injections key
is already a scalar boolean gate, and TOML forbids a key being both
scalar and table (the same S-fix documented on
[core.model_switch]). Consulted only when
Self::context_injections is true; empty (the default) is a
no-op even then. Each block is appended verbatim as \n\n# {name}\n{content},
in list order.
compaction_enabled: boolP4e (§1.5/§3.1 core.compaction.enabled, “no master gate exists
yet”): the master on/off switch for ALL auto-compaction
(Agent::maybe_compact), composing with – not replacing – the
existing Self::compact_after_messages/Self::compaction_reserve_tokens/
Self::compaction_keep_recent_tokens triggers: false disables
every trigger unconditionally; true (the default, matching
today’s behavior, where nothing has ever gated compaction) changes
nothing – whichever triggers are configured still fire exactly as
before.
parallel_tool_calls: boolP4e (§3.1 core.parallel_tool_calls, catalog:59 “Independent
sibling calls run concurrently”): when true and an assistant turn
requests more than one tool call, Agent::run_loop runs their
Tool::execute futures CONCURRENTLY via Self::run_tools_concurrently
instead of one at a time – see that method’s doc comment for
exactly which part of dispatch stays strictly sequential (approval /
doom-loop / pre-tool-hook checks, and every record/history
append, which the lossless sidecar’s append-order invariant, S1.13,
requires to stay deterministic). false (the default) is
byte-identical to today’s sequential-await-per-call loop.
session_git_metadata: boolP4e (§1.6/§3.1 core.session.git_metadata, catalog:331 “Git branch/
sha captured … closes the loop” – the WRITE half; supercode already
preserves a foreign session’s own gitBranch-shaped fields
verbatim on IMPORT via Session::raw’s byte-for-byte capture).
When true, Agent::with_parts captures a
git_metadata::GitMetadataRecord (best-effort branch/sha/dirty,
like Self::env_context’s git probe) once at construction, readable
via Agent::git_metadata and persistable via
Agent::save_git_metadata. false (the default) is byte-identical
to today’s behavior: no capture, Agent::git_metadata() is always
None.
session_dir: Option<String>P4e (§1.6/§3.1 core.session.dir): overrides the session store’s
root directory. A caller-read knob (like Self::small_model) –
the CLI’s session_store() (main.rs) is the consumer. None (the
default) leaves the CLI’s own default ($SUPERCODE_HOME/sessions)
untouched.
session_persist: boolP4e (§1.6/§3.1 core.session.persist, D5 row): whether a caller
should persist this session to the store at all. A caller-read gate
only – Agent/Config never call SessionStore directly (no
SessionStore handle lives on Config); a caller checks this
field directly before calling store.save(...), the same
“mechanism vs. gate” split Self::auto_title established. true
(the default) matches today’s behavior: every caller that already
calls store.save(...) keeps doing so unconditionally.
session_name: Option<String>P4e (§1.6/§3.1 core.session.name): an explicit session name a
caller should use instead of auto-minting one (the CLI’s
mint_session_name). A caller-read knob, same posture as
Self::session_dir. None (the default) leaves auto-naming
untouched.
session_retention_days: Option<u32>P4e (§1.6/§3.1 core.session.retention_days): the archive-pruning
window store::SessionStore::prune_expired consults. None (the
default) means “never prune” – byte-identical to today’s behavior
(nothing ever prunes automatically).
session_export_format: HumanExportFormatP4e (§1.6/§3.1 core.session.export_format, catalog:283 “transcript
export for humans”): text | html, consumed by
human_export::render_transcript. Defaults to
crate::human_export::HumanExportFormat::Text.
permissions_enabled: boolP5-1 (§3.1 capabilities.permissions.enabled, module 10/11
activation): the master gate for crate::permissions — when false
(the default), Agent::prepare_tool_call’s tool-dispatch gate uses
EXACTLY the pre-P5-1 Self::needs_approval path, byte-for-byte —
no behavior change. true switches the gate to the richer
canonicalized-command-aware crate::permissions::rules engine
(deny→ask→allow first-match, C5), consulting
Self::permissions_ask_patterns (together with the pre-existing
Self::tool_deny_patterns/Self::tool_allow_patterns as the
engine’s deny/allow tiers) and Self::permissions_protected_paths.
permissions_ask_patterns: Vec<String>P5-1 (§3.1 capabilities.permissions.rules.ask, module 11): the
engine’s ask tier — the sibling of the pre-existing
Self::tool_deny_patterns/Self::tool_allow_patterns (P4),
which become the engine’s deny/allow tiers respectively when
Self::permissions_enabled is on (see
crate::permissions::rules::RuleSet). Empty by default. Only
consulted when Self::permissions_enabled is true.
permissions_protected_paths: Vec<String>P5-1 (§3.1 capabilities.permissions.protected_paths.paths, module
13): glob patterns that are an unconditional DENY floor for both
read and write access (cc§4 “never auto-approved… .git/**,
.env*, …”), expanded via
crate::permissions::rules::protected_path_deny_rules into the
engine’s deny tier. Empty by default. Only consulted when
Self::permissions_enabled is true.
Honesty note on coverage (F4, Fable-5 adversarial review): at
the rule-engine layer this floor is enforced for (a) read_file/
write_file/edit_file-shaped path calls, (b) a bash/shell
command’s direct output/input redirect targets (>, >>, &>,
>|, &>>, <), (c) apply_patch’s target path(s), and (d) a
best-effort set of known argv-writers (tee, dd of=, cp/mv/
install, sed -i, truncate, ln) — see
crate::permissions::canon::known_writer_targets’s doc comment for
that heuristic’s named gaps. A write this rule layer genuinely
cannot statically resolve (an opaque wrapper — eval, sh -c, …
— or a dynamic $VAR/`cmd` target) is forced to at least
Ask, never silently Allow. What this layer does NOT provide is
COMPLETE OS-level write confinement of arbitrary bash — that is
capabilities.permissions.sandbox’s job (P5 module 10, a later
unit), not this one’s.
network_policy: Option<NetworkPolicy>P5-1 (§3.1 capabilities.permissions.sandbox.network.*, module 12
carry-forward): the domain allow/deny policy crate::tools::WebFetchTool/
WebSearchTool enforce via crate::tools::ToolContext::check_network
— the enforcement POINT already existed (P4c); this is its real
config source (crate::configfile::materialize_config). None (the
default) is byte-identical to today’s behavior: no policy is
enforced, exactly the honest gap NetworkPolicy’s own doc comment
(crate::tools) already names.
sandbox_os_enabled: Option<bool>P5-10 (§3.1 capabilities.permissions.sandbox.enabled, module 12):
whether the OS-level backstop (Landlock on Linux, seatbelt on
macOS) is engaged for the bash/shell subprocess. None (the
default — unset by the bare sandbox = "<tier>" shorthand, or a
CLI --sandbox flag, neither of which touch this table key) keeps
the PRE-P5-10 trigger byte-identical: crate::sandbox:: os_sandbox_active falls back to “confine whenever the tier isn’t
DangerFullAccess”, exactly what the macOS seatbelt path already
did off Self::sandbox alone. Some(false) (the table form’s
explicit opt-out — cc-parity’s posture) turns the OS backstop off
even for a confining tier; Some(true) forces it on.
sandbox_escalation: SandboxEscalationP5-10 (§3.1 capabilities.permissions.sandbox.escalation, module
12): what happens when a confining fs tier is requested but this
platform/kernel can’t enforce it — see
crate::sandbox::SandboxEscalation. Defaults to Deny
(fail-closed), matching capabilities.permissions.sandbox’s own
escalation = "deny" config default.
sandbox_env_policy: SandboxEnvPolicyP5-10 (§3.1 capabilities.permissions.sandbox.env_policy, module
12): child-process environment sanitization for the spawned
bash/shell subprocess — see
crate::sandbox::SandboxEnvPolicy. Defaults to Inherit
(byte-identical to pre-P5-10 behavior: the full environment passes
through unchanged).
subagents_enabled: boolP5-3 (§3.1 capabilities.subagents.enabled, module 9 activation):
the master gate for the spawn_subagent/subagent_status agent
the master gate for the spawn_subagent/subagent_status agent
intrinsics — when false (the default), Agent::tool_schemas never
advertises them and Agent::run_tool’s interception is a pure
pass-through to the pre-P5-3 dispatch, byte-for-byte unchanged.
subagents_max_depth: usizeP5-3 (§3.1 capabilities.subagents.max_depth, resource bound): the
maximum spawn-tree depth — a depth-max_depth agent may not spawn
(its child would land at max_depth + 1). Only consulted when
Self::subagents_enabled is true.
subagents_max_concurrent: usizeP5-3 (resource bound, NOT in the §3.1 illustrative schema snippet —
added per the build brief’s explicit “max concurrent subagents…
cap, fail-closed… configurable”): the maximum number of subagents
in flight anywhere in one spawn tree at once (root-to-leaf, shared
via crate::agent::Agent’s concurrency gauge). Only consulted
when Self::subagents_enabled is true.
subagents_background: boolP5-3 (§3.1 capabilities.subagents.background): whether
spawn_subagent’s background: true argument is honored at all —
false (the default) refuses every background spawn regardless of
Self::subagents_background_prompts.
subagents_background_prompts: Option<BackgroundPromptsPolicy>P5-3 (§2.2 C6, §3.1 capabilities.subagents.background_prompts):
the auto-policy a background child’s tool approvals route through.
None (the default) means a background spawn is refused
(Error::SubagentBackgroundPolicyMissing) — a detached child must
never reach an interactive prompt it can’t answer.
subagents_claude_agent_alias: boolClaude Code emulation: advertise and accept its Agent tool name and
argument vocabulary in addition to Supercode’s native
spawn_subagent intrinsic. Default false; enabled only for an
explicitly imported Claude continuation.
claude_runtime_tools_enabled: boolClaude Code resume compatibility for the scheduler-shaped
CronCreate/CronDelete/CronList/ScheduleWakeup intrinsics.
The imported manifest is always paused and these tools only mutate
that inert state; no timer is started. Default false so ordinary
agents do not gain a harness-specific tool surface.
subagents_definitions: HashMap<String, NamedAgentDefinition>P5-3 (§3.1 capabilities.subagents.agents.<name>, D3 “named-defs”):
named subagent types, keyed by the name the model passes as
spawn_subagent’s agent_type argument.
subagent_depth: usizeP5-3 (runtime-only, NEVER set from a config file — only
Agent::run_spawn_subagent sets it on a freshly-built CHILD
Config before constructing that child): how deep in the spawn
tree the agent built from this Config is. 0 is a top-level
agent; a config file / ConfigBuilder caller that never spawns
leaves this at its 0 default.
tui_enabled: boolP5-4 (§3.1 capabilities.tui.enabled, module 30 activation, §1.9
recorded deviation): the master gate for the full-screen TUI —
when false (the default), crates/cli’s chat() runs the
pre-P5-4 rustyline REPL loop byte-for-byte, and every P5-4 seam
below (Agent::set_permissions_approval_handler/
Agent::set_child_approval_handler_factory/
crate::mcp::McpClient::set_elicitation_handler) is simply never
invoked with a TUI-backed implementation. crates/cli’s TUI runner
additionally requires stdin/stdout/stderr all be a real tty before
activating even when this is true — see that crate’s
tui::should_activate doc comment.
tui_theme: StringP5-4 (§3.1 capabilities.tui.theme): "dark" | "light" — which
built-in crate::tui::Theme the renderer starts with. Unknown or
unset values fall back to "dark" (crate::tui::Theme::default()).
tui_vim_mode: boolP5-4 (§3.1 capabilities.tui.vim_mode, D8 “vim”): whether the
input buffer starts in vim-style modal editing (normal/insert)
rather than plain single-mode editing. See
crate::tui::InputMode’s doc comment for the (deliberately
basic — hjkl/i/a/o/dd/x) scope of what’s implemented.
tui_keymap: HashMap<String, String>P5-4 (§3.1 capabilities.tui.keymap.<action> = "<key>",
“configurable keybindings”): per-action key overrides layered on
top of crate::tui::Keymap::default() — see that type’s doc
comment for the action names and key-spec syntax understood.
session_tree_enabled: boolP5-5 (§3.1 capabilities.session_tree.enabled, design §2 module 21
activation): the master gate for the native in-place session tree
(crate::session_tree) — a pure “does the harness advertise/prefer
tree-mode session semantics” signal for a caller (CLI/TUI) to consult.
false (the default, matching every HarnessConfig that never sets
this table) changes nothing about crate::session_tree::SessionTree
itself, which has no runtime dependency on this flag (a caller can
always construct/use one directly, exactly like
crate::store::SessionStore::fork isn’t gated on any capability
either) — this field exists purely so a future integration point has
a resolved config signal to read, matching every other P5 module’s
“carried on Config, pure config → set” convention.
session_tree_branch_summaries: boolP5-5 (§3.1 capabilities.session_tree.branch_summaries, module 21
“branch summaries”): whether a caller wiring
crate::session_tree::SessionTree::splice_for_linear_export into a
C7 linear-export path should generate/attach summaries for off-path
branches at all, vs. leaving them unsummarized (still fully present
in the sidecar either way — this only controls the human-readable
digest, never the underlying lossless data). Defaults true (the
§3.1 schema’s own default) when Self::session_tree_enabled is
true and this key is unset.
session_tree_labels: boolP5-5 (§3.1 capabilities.session_tree.labels, module 21 “entry
labels”): whether a caller’s UI/CLI surface should expose
crate::session_tree::SessionTree::label/clear_label at all.
Defaults true (the §3.1 schema’s own default) when
Self::session_tree_enabled is true and this key is unset. Like
Self::session_tree_branch_summaries, this is advisory — the
underlying SessionTree API always supports labeling regardless.
tools_background_enabled: boolP5-6 (§3.1 capabilities.tools_background.enabled, module 4
activation): the master gate for the background_exec/
background_status/background_list/background_kill agent
intrinsics — when false (the default), Agent::tool_schemas
never advertises them and Agent::prepare_tool_call’s interception
is a pure pass-through to the pre-P5-6 dispatch, byte-for-byte
unchanged (a hallucinated call falls through to the ordinary
unknown-tool error, exactly like spawn_subagent’s own disabled
posture).
tools_background_max_concurrent: usizeP5-6 (resource bound, NOT in the §3.1 illustrative schema snippet —
added per the build brief’s explicit “max-concurrent cap,
fail-closed”, mirroring Self::subagents_max_concurrent’s own
precedent): the maximum number of background jobs this agent may
have running at once. Only consulted when
Self::tools_background_enabled is true.
tools_background_max_output_bytes: usizeP5-6 (resource bound, “must not OOM” — mirrors
crate::mcp::MCP_MAX_RESPONSE_BYTES’s hardening-cap precedent): the
maximum number of bytes of combined stdout/stderr retained per
background job — output beyond this is truncated-with-marker, never
buffered further (crate::background::CapturedOutput::append).
Only consulted when Self::tools_background_enabled is true.
checkpoint_enabled: boolP5-9 (§3.1 capabilities.checkpoint.enabled, module 20 activation):
the master gate for file checkpointing — when false (the
default), crate::agent::build_tool_context never touches disk for
this at all: no crate::checkpoint::CheckpointStore is opened, no
shadow directory is created, ToolContext::write_observer stays
None, and every write-tool call site’s observer branch is a
pure no-op — byte-identical to before this module existed. See
crate::checkpoint’s module doc comment for the full design.
checkpoint_retain: usizeP5-9 (bounded-disk requirement, NOT in the §3.1 illustrative schema
snippet — added per the build brief’s explicit “bounded… no
unbounded disk growth”, mirroring Self::tools_background_max_concurrent’s
own precedent): the maximum number of checkpoints retained per
project before the oldest are pruned. Only consulted when
Self::checkpoint_enabled is true.
checkpoint_dir: Option<PathBuf>P5-9 (embedder/test override, NOT a [capabilities.checkpoint]
schema key — this is a Rust-only knob, the same class as
Self::pre_tool_hook/Self::post_tool_hook): where the shadow
store lives. None (the default) means
crate::checkpoint::observer_for_config derives the location from
crate::agent::global_instructions_dir() + a hash of Self::cwd
(mirroring the CLI’s own cwd_tag precedent) — set this to make the
location hermetic/deterministic (tests; embedders that want a
specific on-disk layout) without touching process-global env vars.
lsp_enabled: boolP5-11 (§3.1 capabilities.lsp.enabled, module 28 activation): the
master gate for LSP server lifecycle + edit-path diagnostics (D1).
false (the default) means crate::agent::build_tool_context never
touches crate::lsp::manager_for_config at all — no child process
is ever spawned, ToolContext::write_observer’s chain never gains
an LSP entry — byte-identical to before this module existed. See
crate::lsp’s module doc comment for the accepted gaps (no
auto-provisioned server fleet, no symbol-indexing query tool).
lsp_servers: Vec<(String, LspServerSpec)>P5-11 (capabilities.lsp.servers.<name>): the configured language
servers, in alphabetical order by server name (a TOML table has no
inherent ordering — configfile::materialize_config sorts
explicitly for reproducibility) — first extension match wins. Only
consulted when Self::lsp_enabled is true. An empty Vec with
lsp_enabled = true is legal but warns once
(crate::lsp::manager_for_config) — very likely a config mistake.
lsp_max_diagnostics: usizeP5-11 (bounded-context requirement, NOT in the §3.1 illustrative
schema snippet — added per the build brief’s explicit “a flood
mustn’t blow context”, mirroring Self::tools_background_max_output_bytes’s
own precedent): the maximum number of diagnostics rendered into a
single tool result. Only consulted when Self::lsp_enabled is
true.
lsp_timeout_secs: u64P5-11 (bounded-latency requirement): how long to wait for a
configured server to publish diagnostics after a
didOpen/didChange before giving up gracefully. Only consulted
when Self::lsp_enabled is true.
formatters_enabled: boolP5-11 (§3.1 capabilities.formatters.enabled, module 29
activation): the master gate for format-on-write. false (the
default) means the shared D-5 write-observer chain never gains a
crate::formatters::FormatObserver entry — byte-identical to
before this module existed.
formatters: Vec<(String, FormatterSpec)>P5-11 (capabilities.formatters.<name>): the configured formatter
commands, in alphabetical order by formatter name (same “TOML has
no inherent ordering” rationale as Self::lsp_servers) — first
extension match wins. Only consulted when
Self::formatters_enabled is true.
formatters_diff_back: boolP5-11 (§3.1 capabilities.formatters.diff_back, C10): whether a
formatter’s rewrite is diffed back into the calling tool’s result
so the model’s file-memory stays truthful (design line 534, “must
diff-back into the result”). true is the C10-SAFE default; false
still runs the formatter but withholds the annotation — legal, but
the model then has a stale belief about the file’s exact bytes
until it re-reads it.
formatters_timeout_secs: u64P5-11 (bounded-latency requirement, “a hanging formatter can’t hang
the loop — timeout + kill like hooks”): how long a single formatter
invocation may run before it’s treated as failed (the file is left
untouched). Only consulted when Self::formatters_enabled is
true.
trust_enabled: boolP5-12 (§2 module 14 trust, D-10): the master gate for the
project/workspace trust concept — false (the default) means
Self::trust_default is never consulted and crate::plugins
treats every plugin as untrusted (see
crate::plugins::is_trusted’s doc comment). [capabilities.trust]
is project-forbidden (configfile::PROJECT_FORBIDDEN_CAPABILITY_TABLES
/ userconfig’s own copy): only the user/global layer — or a
preset extended from it — may ever set this, exactly like
hooks/plugins/server (a project asserting its OWN trust would
defeat the entire point of the gate).
trust_default: TrustDecisionP5-12 (capabilities.trust.default): the workspace-trust decision —
see crate::plugins::TrustDecision’s doc comment for why, absent a
wired interactive upgrade flow, only crate::plugins::TrustDecision::Always
actually unlocks plugin loading in this build (an honest,
documented gap — not a silent no-op: ask/never both cleanly
refuse, they don’t pretend to prompt). Only consulted when
Self::trust_enabled is true.
plugins_enabled: boolP5-12 (§2 module 18 plugins, §3.1 capabilities.plugins.enabled):
the master gate for out-of-process, manifest-declared plugins (see
crate::plugins’s module doc comment for the ABI). false (the
default) means crate::agent’s tool-registration path never touches
crate::plugins::discover_and_load at all — no directory read, no
manifest parse, no subprocess — byte-identical to before this module
existed.
plugins_dirs: Vec<PathBuf>P5-12 (capabilities.plugins.dirs): EXTRA directories to scan for
<plugin-name>/plugin.toml manifests, on top of the always-scanned
$SUPERCODE_HOME/plugins (see crate::plugins::discover_manifests).
[capabilities.plugins] (this field included) is project-forbidden,
so this can only ever come from the trusted user/global layer or a
preset. Only consulted when Self::plugins_enabled is true AND
the workspace is trusted (see crate::plugins::is_trusted).
Implementations§
Source§impl Config
impl Config
Sourcepub fn builder() -> ConfigBuilder
pub fn builder() -> ConfigBuilder
Start building a Config from defaults.
Sourcepub fn tool_enabled(&self, name: &str) -> bool
pub fn tool_enabled(&self, name: &str) -> bool
Whether a tool is enabled given the overrides (defaults to enabled).
Sourcepub fn needs_approval(&self, tool: &str) -> bool
pub fn needs_approval(&self, tool: &str) -> bool
Whether a tool call requires approval before it runs, given the
policy, the auto-approve allowlist, and (P4) the deny/allow glob
PATTERN lists — see Self::tool_deny_patterns/
Self::tool_allow_patterns’s doc comments for the exact
semantics. Both are empty by default, so this is byte-identical to
pre-P4 behavior for any Config that doesn’t set them.
Sourcepub fn tool_description<'a>(&'a self, name: &str, builtin: &'a str) -> &'a str
pub fn tool_description<'a>(&'a self, name: &str, builtin: &'a str) -> &'a str
The effective description for a tool, applying any override.
Sourcepub fn schema_tier_for(&self, name: &str) -> SchemaTier
pub fn schema_tier_for(&self, name: &str) -> SchemaTier
The effective schema tier for a tool (TR-8/T5): a per-tool override if
set, else the global Self::tool_schema_tier.
Source§impl Config
impl Config
Sourcepub fn from_profile_file(
path: impl AsRef<Path>,
profile: &str,
) -> Result<ConfigBuilder>
pub fn from_profile_file( path: impl AsRef<Path>, profile: &str, ) -> Result<ConfigBuilder>
Load a named profile from a JSON config file into a builder. Layered: start from defaults, then apply the named profile’s set fields.