#[non_exhaustive]pub struct Config {Show 147 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 api_key_command: Option<Vec<String>>,
pub update_check: bool,
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_budget_usd: Option<f64>,
pub max_steps: Option<usize>,
pub price_input_per_mtok: Option<f64>,
pub price_output_per_mtok: Option<f64>,
pub max_tool_output_bytes: Option<usize>,
pub tool_output_spill: bool,
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 + Sync + Send>>,
pub pre_tool_hook: Option<Box<dyn Fn(&str, &Value) -> PreToolOutcome + Sync + Send>>,
pub post_tool_hook: Option<Box<dyn Fn(&str, &str, bool) + Sync + Send>>,
pub lifecycle_hook: Option<Box<dyn Fn(&LifecycleEvent) + Sync + Send>>,
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<Box<dyn Fn(AgentEvent) + Sync + Send>>,
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 skills_harness: Option<String>,
pub skills_dirs: Vec<PathBuf>,
pub skills_implicit_match: bool,
pub skills_shell_injection: bool,
pub file_mentions: bool,
pub output_style: String,
pub path_rules: bool,
pub model_family_prompts: BTreeMap<String, String>,
pub small_model: Option<String>,
pub model_fallback: Vec<String>,
pub model_routing: Routing,
pub service_tier: Option<String>,
pub env_context: bool,
pub project_root_markers: Vec<String>,
pub project_doc_max_bytes: Option<usize>,
pub project_doc_excludes: Vec<String>,
pub project_doc_strip_comments: bool,
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<Box<dyn Fn(&str) -> Option<String> + Sync + Send>>,
pub read_file_multimodal: bool,
pub read_file_line_numbers: 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 model_switch_notice: bool,
pub plan_mode_effort: Option<String>,
pub context_injections: bool,
pub context_injection_blocks: Vec<ContextInjectionBlock>,
pub compaction_enabled: bool,
pub compaction_summarize: 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 session_append_only: bool,
pub session_queue_persist: bool,
pub todos_persist: bool,
pub permissions_enabled: bool,
pub permissions_ask_patterns: Vec<String>,
pub permissions_protected_paths: Vec<String>,
pub network_policy: Option<NetworkPolicy>,
pub permissions_approvals_persist: bool,
pub trust_handler: Option<Arc<dyn PermissionsApprovalHandler>>,
pub trust_store: Option<PathBuf>,
pub permissions_approval_store: Option<PathBuf>,
pub sandbox_os_enabled: Option<bool>,
pub sandbox_escalation: SandboxEscalation,
pub sandbox_env_policy: SandboxEnvPolicy,
pub subagents_enabled: bool,
pub goals_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 checkpoint_restore: bool,
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.
api_key_command: Option<Vec<String>>BP-9 (§3.1 core.api_key_command, D6 row “Credential helpers /
keyring”, cc§6 apiKeyHelper, cx§6 auth{command}): an ARGV
credential helper, exec’d directly (no shell), whose trimmed stdout
becomes the key. Consulted by Agent::new BEFORE
Self::api_key_cmd — it is the safer of the two forms (no
word-splitting, no $(…)), so a config that sets both gets the one
with fewer ways to surprise its author. Same fall-through posture as
api_key_cmd: a failing/empty helper moves on to the next source
rather than erroring. None (the default) is never consulted.
[project-forbidden] (§3.3).
update_check: boolBP-9 (§3.1 core.update_check, D6 row “Auto-update + channels”,
cx§10): whether a startup release check is performed. false (the
default) means no startup network access at all — see
CoreSection::update_check for why opt-in is the only defensible
default here.
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_budget_usd: Option<f64>BP-7 (catalog §4a “Turn/budget caps”, cc’s --max-budget-usd): cap
on the cumulative DOLLAR cost of one crate::Agent::send loop.
The loop stops spawning further model turns once the accumulated
per-turn cost reaches this figure.
Arming this against a model crate::pricing::resolve cannot price
is refused at crate::Agent::new rather than accepted and
silently ignored — a spend cap that cannot bite is worse than none,
because the caller believes they are protected. Set
Self::price_input_per_mtok/Self::price_output_per_mtok to
price an unknown model.
max_steps: Option<usize>BP-7 (catalog §4a “Turn/budget caps” — the STEP cap the semantics
name alongside turns, spend and output tokens): cap on the number of
TOOL CALLS executed across one crate::Agent::send loop.
Distinct from Self::max_iterations, which bounds model
round-trips: one round-trip can carry a whole batch of parallel
tool calls, so a step cap and a turn cap bound different things.
price_input_per_mtok: Option<f64>BP-7: dollars per million INPUT tokens for Self::model,
overriding crate::pricing’s built-in table. Only takes effect
together with Self::price_output_per_mtok — half an override
would bill completions at zero.
price_output_per_mtok: Option<f64>BP-7: dollars per million OUTPUT tokens for Self::model.
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.
tool_output_spill: boolBP-2 (§3.1 core.tool_output_spill, catalog:58 “Oversized output
truncated; full content kept reachable”): when true, an output
capped by Self::max_tool_output_bytes is first written IN FULL
to a per-session spill file, and the cap notice names that path so
the model can read it back with an ordinary read (read_file, or
cat under a shell-only preset) — CC’s own “Bash overflow → session
file” recovery door, available without capabilities.reduction.
false (the default) protects an embedder that never asked for
disk writes: the cap notice stays exactly as it is today and no
spill file is created. Both parity presets turn it on.
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 + Sync + Send>>Consulted when a tool call needs approval; None denies by default.
pre_tool_hook: Option<Box<dyn Fn(&str, &Value) -> PreToolOutcome + Sync + Send>>Runs before each tool executes; may block the call.
post_tool_hook: Option<Box<dyn Fn(&str, &str, bool) + Sync + Send>>Runs after each tool executes (observational).
lifecycle_hook: Option<Box<dyn Fn(&LifecycleEvent) + Sync + Send>>Observes compaction and subagent lifecycle moments (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<Box<dyn Fn(AgentEvent) + Sync + Send>>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.
skills_harness: Option<String>BP-6 ([core.skills].harness, catalog D7 “Skill discovery from
multiple roots”): whose documented skill-root table the LOOP reads
SKILL.md packages from — a crate::HarnessId spelling
(claude-code, codex, opencode, pi, …), resolved by
crate::skills::skill_roots. None (the default) means the loop
discovers no packages at all and Self::skills_enabled can only
index [core.prompts] templates, exactly as before BP-6. Only
consulted when Self::module_registry is true.
skills_dirs: Vec<PathBuf>BP-6 ([core.skills].dirs): extra skill roots, merged OVER the
harness’s own defaults — i.e. they win a name collision, since a
root a config names explicitly is more specific than a discovered
one. Scanned as project scope.
skills_implicit_match: boolBP-6 ([core.skills].implicit_match, cx§7 “implicit
(description-matched) invocation”): whether a user message that
merely DESCRIBES a skill loads its body, in addition to the explicit
$slug mention. false (the default) is the safe posture: only an
explicit mention, /name, or a skill tool call ever spends a
body’s tokens.
skills_shell_injection: boolBP-5 ([core.skills].shell_injection, cc§7 “Dynamic context
injection”, docs:skills#inject-dynamic-context): whether
!`cmd` (and the ```! block form) inside a skill or
command body is EXECUTED when the body is loaded, its stdout
replacing the token. false (the default) leaves the token as
literal text — Claude Code’s own disableSkillShellExecution
posture, stated positively.
Never an unconditional shell: every extracted command is evaluated
through the ONE permissions engine (crate::permissions) with
this config’s own rules, protected paths and approval default, plus
whatever the body’s allowed-tools frontmatter pre-approves for
itself (cc§7 “pre-approved tools while active”). Anything short of
crate::permissions::Decision::Allow is refused in place, with
the reason inlined where the output would have gone.
file_mentions: boolBP-5 ([core.file_mentions], catalog D2 “@-file mentions /
attachments”, cc§2 “@-file mentions”, cx§2 “@-mentions
(files)”): whether an @path token in a user prompt is expanded
into that file’s contents before the turn is sent. false (the
default) leaves @path as literal text.
Deny-rule aware (cc§2: “Read deny rules best-effort apply to
@file mentions”): each mention is resolved through the same
permissions engine a read_file call goes through, so a mention of
a protected path is refused in place rather than silently inlined.
output_style: StringBP-5 ([core.output_style], catalog D2 “Output style / personality
module”, cc§7 “Output styles”, cx§2 “Personality layer”): the NAME
of the response-style layer this session runs under — a built-in
(crate::output_style::BUILTIN_STYLES) or a markdown file
discovered from the style roots of the harness
Self::skills_harness names. Empty (the default) appends
nothing.
A style is a prompt-assembly INPUT, not a module with state: it contributes one section to the system prompt at construction, and nothing else in the loop consults it.
path_rules: boolBP-5 ([core.path_rules], catalog D2 “Path-scoped rules”, cc§2
“.claude/rules/*.md”): whether <root>/.claude/rules/*.md rule
files are loaded. A rule file with no paths: frontmatter joins the
instruction blob at construction; one WITH paths: is held back and
injected only when a tool touches a file matching one of its globs
(the same on-demand door core.nested_instructions uses).
false (the default) reads no rule directory at all.
model_family_prompts: BTreeMap<String, String>BP-5 ([capabilities.model_catalog].base_prompts, catalog D2
“Per-model-family base-prompt selection”, cx§2 “Per-model base
instructions”): model-id GLOB → the base system prompt that family
gets, replacing Self::system_prompt when it matches.
The most SPECIFIC match wins (longest pattern), so the table is
order-independent — a TOML table has no order to rely on. No match
(and an empty table, the default) leaves system_prompt exactly as
it was, so this is a no-op for every config that doesn’t set it.
Re-selected on crate::Agent::set_model, the way cx re-selects
base_instructions when the model changes.
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 (BP-13’s
Agent::run_loop fallback pass, which consumes exactly this list).
model_routing: RoutingBP-13 (catalog Domain 9): the resolved MODEL-ROUTING table —
aliases (including patterns and provider/account scopes), per-model
effort levels, thinking budgets, service tiers, tool-shape
capability bits, and the config-layer allow/deny lists. Every
routing decision in the product asks this one value:
crate::Agent’s request build (effort, budget, tier), its
fallback pass, crate::tools::ToolRegistry::from_config’s
write-surface selection, and the CLI’s --model//model alias
expansion. Default-empty, which resolves exactly like the built-in
alias table alone did before this field existed.
service_tier: Option<String>BP-13 (catalog D9 “Fast mode / service tiers”): a session-level
service-tier override — what /fast sets. It WINS over the
per-model [capabilities.model_catalog] service_tier rule, because
it is the live toggle the user just pulled; None (the default)
leaves the configured rule in force, and if there is no rule either
the request carries no service_tier field at all.
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
(or directory names) that mark a directory as the project root.
Defaults to [".git"].
BP-9 gave this knob its reader: project_root_for is the single
shared ancestor walk every consumer goes through — the
Self::env_context git-status probe (which now reports the ROOT’s
branch, not a subdirectory’s), the CLI’s .supercode.toml
discovery walk (which stops at the root instead of climbing to /),
and (BP-4) prompt assembly’s instruction walk, whose climb from
Self::cwd ends at the first directory carrying one of these
(agent::instruction_walk_roots) — cx’s own project_root_markers
semantics (cx§2). Adding a marker
(project_root_markers = [".git", ".hg", "package.json"]) therefore
changes where all of them stop, which is the catalog’s semantics
(“configurable markers defining the project root”).
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
instruction-file content (Self::load_project_context’s global +
project tiers) appended to the system prompt. None (the default) is
uncapped – byte-identical to today’s behavior; only an explicit
Some(n) truncates (with a trailing notice), mirroring
Self::max_tool_output_bytes’s cap-with-notice shape. BP-4: the cap
binds TWICE – per FILE (no single instruction file may consume the
whole budget and starve the nearer files that win precedence by
coming after it) and then over the assembled AGGREGATE, which is the
total-bytes reading cx documents (default 32 KiB).
project_doc_excludes: Vec<String>BP-4 (catalog:87 “Instruction-file hygiene controls”, cc2
claudeMdExcludes): glob/absolute-path patterns naming instruction
files to SKIP (monorepo hygiene). A pattern is matched against the
file’s bare name, its full path, and its path relative to the tier
root it was discovered under. Empty (the default) excludes nothing.
project_doc_strip_comments: boolBP-4 (catalog:87, cc2 “HTML comment stripping”): when true,
block-level <!-- ... --> spans are dropped from every instruction
file before injection, so maintainer notes cost no tokens. false
(the default, and what cx does – Codex strips nothing) is
byte-identical to today’s behavior.
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<Box<dyn Fn(&str) -> Option<String> + Sync + Send>>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.
read_file_line_numbers: boolBP-2 (S1.2/S3.1 core.tools.read_file.line_numbers, catalog:26
“Dedicated read with offset/limit, cat -n style output”): when
true, every line read_file returns carries a right-aligned
1-based line number and a tab, numbered from the requested offset
so the model can cite real file line numbers. false (the default)
is byte-identical to today’s raw-slice behavior – the harnesses
whose presets do NOT number lines (Codex reads through cat) must
keep the unnumbered output their models were trained on.
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).
model_switch_notice: boolBP-13 (§3.1 core.model_switch.notice, D9 “Mid-session model
switching”): when the model changes mid-session, splice a short
user-role notice naming the old and new model (and, for an automatic
fallback hop, the failure that caused it) into the live
conversation, so the incoming model reads the handoff rather than
inferring it from a style break. This is Codex’s behavior (cx§9
“switch instructions injected”); Claude Code switches silently, so
false (the default) is byte-identical to pre-BP-13 behavior and
each preset states which harness it imitates.
plan_mode_effort: Option<String>BP-13 (§3.1 capabilities.plan_mode.effort, catalog D9 “Reasoning
effort / thinking budgets” — the plan-mode half): the reasoning
effort to send WHILE plan mode is active. Codex’s /plan is
effort-tier steering (cx§6), so planning and executing are not
obliged to think at the same level. None (the default) leaves plan
mode with no effort of its own, byte-identical to pre-BP-13
behaviour. Applied by Agent::apply_routing, which asks the live
PlanModeState — so it turns itself on and off with the mode, and
is still clamped by whatever effort cap applies.
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.
compaction_summarize: boolBP-1 (§1.5/§3.1 core.compaction.summarize): whether a compacted
span is replaced by a marker that states it was SUMMARIZED, or by
one that only states it was cleared. true (the default, and what
every built-in preset sets) is today’s marker text, byte-identical.
Scope note, so this key cannot be over-read: the model-written
summary side-call itself is capabilities.reduction.span_summaries’
installed SpanSummarizer (D-9, Agent::set_span_summarizer) and
is NOT armed by this key – core.compaction.summarize is the
core-compaction statement about what the compaction marker claims,
which is exactly what Agent::maybe_compact writes.
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.
session_append_only: boolBP-8 (§3.1 core.session.append_only, catalog:150 “Append-only
durable transcript”): whether the caller arms a
crate::session_journal::SessionJournal on this agent, so every
message is written and FLUSHED the instant it exists rather than at
the end of the turn. A caller-read gate, the same “mechanism vs.
gate” split Self::session_persist established — Agent owns the
journal once one is installed (Agent::set_journal), but never
opens a store itself. false (the default) is byte-identical to
pre-BP-8 behavior: no journal file is ever created.
session_queue_persist: boolBP-8 (§3.1 core.session.queue_persist, catalog:154
“Queued-prompt persistence”): whether pending steering / follow-up
inputs are recorded in the journal as queue operations, so a
prompt typed while the agent was busy survives a crash or restart.
Meaningless without Self::session_append_only (the journal is
the only place a queue operation is written). false (the default)
is byte-identical to pre-BP-8 behavior: both queues stay purely
in-memory.
todos_persist: boolBP-8 (§2 module todos persist, catalog:156 “Todos/plan persisted
per session”): whether the update_plan checklist is written to the
session store (and restored on resume) rather than living only in
the tool’s own mutex for the lifetime of the process. false (the
default) is byte-identical to pre-BP-8 behavior.
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.
permissions_approvals_persist: boolBP-10 (capabilities.permissions.approvals.persist, catalog row
“Session approval caching”): whether an AllowForSession grant is
remembered ACROSS processes, in a per-project store beside the
session’s other records (crate::permissions::default_approval_store).
false (the default, and every config that never sets the key)
keeps the pre-BP-10 in-memory cache: nothing is written, nothing is
read, a new process re-asks.
trust_handler: Option<Arc<dyn PermissionsApprovalHandler>>BP-10 (§2 module 14 trust, catalog row “Project/workspace trust
gate”): the door the workspace-trust question is asked on — the
SAME crate::permissions::PermissionsApprovalHandler every other
Ask in this crate uses. None (the default) means no interactive
trust door is attached, which crate::trust::is_trusted resolves
per surface: config-declared CODE is refused, project instruction
TEXT is loaded (see that module’s doc comment).
Lives on Config rather than on Agent because every surface trust
gates is decided before or during Agent construction — a handler
installed afterwards could never be asked.
trust_store: Option<PathBuf>BP-10 (embedder/test override): where this project’s recorded trust
decision lives. None (the default) uses
crate::trust::default_trust_store — the same
$SUPERCODE_HOME/project-tag layout the checkpoint store and the
persisted approval cache use.
permissions_approval_store: Option<PathBuf>BP-10 (embedder/test override): where the persisted approval cache
lives, when Self::permissions_approvals_persist is on. None
(the default) uses crate::permissions::default_approval_store —
the same $SUPERCODE_HOME-derived, per-project-tag layout
Self::checkpoint_dir falls back to.
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.
goals_enabled: boolBP-7 (§2 module 7 todos, §3.1 capabilities.todos.goals, catalog
§4a “Goals (persistent objective across turns)”): whether the
session carries a standing objective — /goal, persisted as
<session>.goal.json, restated at the tail of every request while
it stands. Default false: an agent that never turns the knob on
behaves exactly as before.
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.
checkpoint_restore: boolBP-7 (§3.1 capabilities.checkpoint.restore, catalog §4a “Turn diff
tracking”): whether this harness may RESTORE from a checkpoint, as
opposed to only tracking each turn’s diff. true (the default, and
cc-parity’s posture) is CC’s /rewind. false is Codex’s shape: a
real turn_diff_tracker with no code restore behind it.
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.