Skip to main content

Config

Struct Config 

Source
#[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 + Send + Sync>>, pub pre_tool_hook: Option<Box<dyn Fn(&str, &Value) -> PreToolOutcome + Send + Sync>>, pub post_tool_hook: Option<Box<dyn Fn(&str, &str, bool) + Send + Sync>>, pub lifecycle_hook: Option<Box<dyn Fn(&LifecycleEvent) + 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<Box<dyn Fn(AgentEvent) + Send + Sync>>, 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> + Send + Sync>>, 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
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§model: String

Model identifier as understood by the endpoint, e.g. anthropic/claude-opus-4-8 or openai/gpt-5 on OpenRouter.

§base_url: String

Base 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: String

Environment 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: bool

BP-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: String

System prompt prepended to every conversation.

§temperature: Option<f32>

Optional sampling temperature.

§max_tokens: Option<u32>

Optional output token cap.

§max_iterations: usize

Maximum 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: bool

BP-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: PathBuf

Working 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: bool

Whether to auto-load CLAUDE.md / AGENTS.md into the system prompt.

§sandbox: SandboxPolicy

Filesystem confinement applied to write-capable tools.

§approval: ApprovalPolicy

When 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) -> PreToolOutcome + 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).

§lifecycle_hook: Option<Box<dyn Fn(&LifecycleEvent) + Send + Sync>>

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: ToolAdvertising

How 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) + Send + Sync>>

Optional sink for streaming crate::AgentEvents.

§cache_plan: CachePlan

Prompt-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: ReductionPolicySettings

Resolved 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: bool

Whether 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: SchemaTier

Global 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: bool

UX-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: bool

P3 (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: ModuleActivation

P3: 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: bool

P3: [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: bool

BP-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: bool

BP-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: bool

BP-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: String

BP-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: bool

BP-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: Routing

BP-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: bool

P4b (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: bool

BP-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: bool

P4b (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: bool

P4b (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: bool

P4b (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: SteeringMode

P4b (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: SteeringMode

P4b (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> + Send + Sync>>

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: bool

P4c (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: bool

BP-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: bool

P4c (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: bool

P4c (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: bool

P4c (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: bool

P4c (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: bool

P4c (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: bool

BP-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: bool

P4e (§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: bool

P4e (§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: bool

BP-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: bool

P4e (§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: bool

P4e (§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: bool

P4e (§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: HumanExportFormat

P4e (§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: bool

BP-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: bool

BP-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: bool

BP-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: bool

P5-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: bool

BP-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: SandboxEscalation

P5-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: SandboxEnvPolicy

P5-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: bool

P5-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: bool

BP-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: usize

P5-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: usize

P5-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: bool

P5-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: bool

Claude 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: bool

Claude 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: usize

P5-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: bool

P5-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: String

P5-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: bool

P5-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: bool

P5-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: bool

P5-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: bool

P5-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: bool

P5-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: usize

P5-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: usize

P5-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: bool

P5-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: usize

P5-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: bool

BP-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: bool

P5-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: usize

P5-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: u64

P5-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: bool

P5-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: bool

P5-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: u64

P5-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: bool

P5-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: TrustDecision

P5-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: bool

P5-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

Source

pub fn builder() -> ConfigBuilder

Start building a Config from defaults.

Source

pub fn tool_enabled(&self, name: &str) -> bool

Whether a tool is enabled given the overrides (defaults to enabled).

Source

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.

Source

pub fn tool_description<'a>(&'a self, name: &str, builtin: &'a str) -> &'a str

The effective description for a tool, applying any override.

Source

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

Source

pub fn from_profile_file( path: impl AsRef<Path>, profile: &str, ) -> Result<ConfigBuilder, Error>

Load a named profile from a JSON config file into a builder. Layered: start from defaults, then apply the named profile’s set fields.

Trait Implementations§

Source§

impl Default for Config

Source§

fn default() -> Config

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more