pub const CX_PARITY_TOML: &str = r#"# built-in preset: cx-parity — Codex's default surface, composed.
schema_version = 1
[core]
effort = "medium" # model_reasoning_effort default tier (cx§6, cx§9)
env_context = true # <environment_context> block: cwd/sandbox/approval (cx§2) — BP-4 supplies the approval/sandbox line this comment already claims, and re-emits the block on change (cx§2 "re-emitted on change")
context_injections = true # BP-4 (catalog:91): Codex's whole `context/` library (~25 block types) is spliced at assembly time (cx§2) — arms `crate::context_injection`'s built-in blocks + the runtime splice seam
project_context = true # AGENTS.md hierarchy, root-down concat, 32KiB cap (cx§2)
project_root_markers = [".git"] # BP-4: cx's own `project_root_markers` default (cx§6 config census) — the git root the AGENTS.md walk climbs to before descending root→cwd (cx§2)
project_doc_max_bytes = 32768 # BP-4 (catalog:87): cx's documented `project_doc_max_bytes` default, 32 KiB (cx§2, cx§6 "project_doc_max_bytes (default 32768)") — the cap the `project_context` line above already claims but nothing enforced
project_doc_excludes = [] # BP-4: Codex has no exclude list (that is CC's `claudeMdExcludes`); stated empty so the preset's hygiene posture is complete rather than defaulted
project_doc_strip_comments = false # BP-4: Codex strips nothing from AGENTS.md — the HTML-comment strip is CC-only (catalog:87)
# P2 placement fix: §4.3's own TOML block places `shell_env_snapshot` under
# `[core.tools]`, but §3.1's schema (the "annotated, exhaustive" canonical
# definition, line ~598) defines it as a direct `[core]` scalar, not a
# `core.tools.*` key — `CoreToolsConfig` has no such field, so a literal
# under-`[core.tools]` placement would silently parse-and-drop it. Moved
# here to match §3.1 (the schema doc doesn't have this key twice with two
# different homes; §4.3 is corrected to agree with it).
shell_env_snapshot = true # S6/S12 home: shell-env snapshotting, cx stable-on feature (catalog:338) — closes a gap-ledger row
parallel_tool_calls = true # BP-2: Codex runs sibling tool calls concurrently behind its RwLock gate (cx§1, catalog:59) — the same batch path, armed
tool_output_spill = true # BP-2: Codex token-caps a tool result with no spill file of its own (catalog:58 `✓*`); supercode's capped result names a per-session spill file the model reads back with `cat` (cx's own read pathway), so the truncation is recoverable rather than lossy
file_mentions = true # BP-5 (catalog D2 "@-file mentions / attachments"): Codex's `@`-mention popup and `/mention` insert a path into the prompt (cx§2 "`@`-mentions (files)"); the path then has to become CONTEXT, which is what this key does. Same permissions-engine read check the cc side gets — cx's `.codex/**` protected paths refuse in place.
output_style = "none" # BP-5 (catalog D2 "Output style / personality module"): Codex's `personality` key at its neutral value (cx§6 `personality (none|friendly|pragmatic)`, cx§2 "Personality layer", `/personality`). `friendly`/`pragmatic` are the swaps; `none` is the selection Codex makes when nobody has chosen, and it appends nothing.
# C4 (catalog §5 conflict 4): Codex's base prompt VARIES BY APPROVAL MODE (cx§2: "proactively run
# tests only under never"). This preset pins prompt + approval together; when CONTINUING an
# imported rollout, the emulate path replays the rollout's own persisted base_instructions
# verbatim (session_meta carries them — cx§2:101; supercode SessionMeta.system_prompt), which is
# exact prompt parity by construction rather than imitation.
[core.tools]
# BP-3: five more optional default-tool names (the `view_image` precedent),
# each closing a gap-ledger row the catalog scores `✓` for Codex:
# `request_user_input` — cx's own experimental spelling of the question
# tool, registered as an ALIAS of the same tool object `ask_user` is, so
# a continued Codex session's calls keep resolving (catalog:45).
# `current_time` + `sleep` — cx's clock/sleep features (catalog:53).
# `get_context_remaining` + `new_context` — cx's token_budget feature
# (catalog:54).
# `image_gen` — cx's image feature (catalog:52); the tool posts to the
# SESSION's own provider `/v1/images/generations` and reports
# unsupported_action when that provider has no image route.
enabled = ["bash", "view_image", "request_user_input", "current_time", "sleep", "get_context_remaining", "new_context", "image_gen"]
# Codex has NO read/write/edit/glob/grep function tools:
# reads via shell (cat, rg), writes via apply_patch (cx§1 "File reads/writes"; D1 footnote ¹).
# Disabling edit/write advertising is ALSO the C1 resolution.
# `view_image` (S6/S12 home, catalog:28) closes the gap-ledger row: with `read_file` off, cx-parity
# would otherwise have NO image-input pathway at all, unlike stock Codex's dedicated tool.
schema_tier = "full"
[core.skills]
enabled = true # SKILL.md discovery, $skill mentions (cx§7 Skills).
harness = "codex" # BP-6: the loop discovers SKILL.md from Codex's own documented roots — admin `/etc/codex/skills`, the bundled `$CODEX_HOME/skills/.system` cache, user `~/.agents/skills` + `$CODEX_HOME/skills`, repo `.agents/skills` from cwd to the repo root (cx§7) — invoked by `$slug` mention or the `skill` tool
implicit_match = false # cx§7 also matches a skill IMPLICITLY from its description; off here, so only an explicit `$slug`/`/skill:` invocation or a `skill` tool call ever spends a body's tokens
# D-7 (S3-amended, no longer a judgment call): the read pathway is bash (`cat`) in the codex
# shape — §2.1's D-7 now names read_file|bash explicitly; the resolver warns, doesn't error.
[core.compaction]
enabled = true
summarize = true # /compact + auto-compaction at model_auto_compact_token_limit (cx§2). BP-4: also arms the CORE span-summary side-call (design §1.5 obligation 5; §3.1 "SpanSummary side-call")
focus_instructions = "" # BP-4 (catalog:98): Codex has no standing compaction focus either — `/compact [instructions]` steers per invocation (cx§2). Empty states that explicitly.
reserve_tokens = 16384 # BP-1: §4.3's own TOML block armed NEITHER trigger, so `Agent::maybe_compact`
# returned false on its `threshold.is_none() && reserve_tokens.is_none()` guard
# and cx-parity could never compact at all — contradicting the `summarize` line's
# own comment ("auto-compaction at model_auto_compact_token_limit"). That limit is
# an absolute TOKEN limit, i.e. §1.5's context-window-pressure trigger, not a
# message count — so the pressure knob is the one to arm (pi-core's `after_messages
# = 0` comment states the same reading: "the trigger is token pressure, never
# message count"). Value transcribed from cc-parity/pi-core's own 16384, the §1.5
# `reserve_tokens` equivalent this schema expresses a foreign auto-compact
# threshold as.
[core.model_switch]
allow_switch = true # BP-13 (catalog D9 "Mid-session model switching"): Codex's `/model` changes the model without losing the thread (cx§9). Arms the governed switch — dep-8 reasoning-artifact filtering plus a persisted `model_change` record in the session journal.
notice = true # BP-13: Codex additionally INJECTS switch instructions into the conversation on a mid-session change (cx§9), so the incoming model reads the handoff instead of inferring it. CC does not, which is why cc-parity leaves this unset.
[core.session]
append_only = true # BP-8 (catalog:150): Codex appends every rollout line and flushes per line, with a retry (cx§5) — a crash mid-turn keeps the turn. Arms `crate::session_journal`.
# `queue_persist` is deliberately NOT set: catalog:154 is `—` for Codex (no queue-operation records), and a cx-parity session must not gain an input-durability guarantee stock Codex does not have.
auto_title = true # BP-7 (catalog:150, cx `✓*`): Codex derives a title/preview for every rollout into its SQLite index and offers `/title` for a manual override (cx§5). supercode's equivalent is the same small-model titler cc-parity uses; the VARIANT the catalog footnotes is that cx derives its default from the first message rather than a model call, which is why this row is `✓*` for cx and not `✓`.
[core.prompts]
# BP-7 (catalog §4a "Review mode"): Codex ships `/review` AND a `codex review`
# subcommand with a `review_model` of its own (cx§3). The template below is the
# report format; the model choice stays this session's model, since cx-parity
# pins no `review_model` (upstream leaves it unset by default too).
code-review = """Review the current code changes as a dedicated review turn. {args}
Read the diff and the files it touches with the shell before judging anything.
Report in exactly these sections, omitting a section only when it is genuinely empty:
1. Correctness — defects, in severity order (blocker / major / minor), each with file:line and the failing case.
2. Security — untrusted input reaching a trust boundary, secrets, injection, permission widening.
3. Reuse and simplification — existing code the change should have used; code the change makes dead.
4. Verdict — one line: SHIP, SHIP WITH FIXES, or DO NOT SHIP, and why."""
# ---- modules ON ----
[capabilities.tools_persistent_shell]
enabled = true
# exec_command/write_stdin PTY unified exec (cx§1); supercode has it (builtins.rs:981-984)
[capabilities.tools_apply_patch]
enabled = true
per_model = true
# freeform envelope, default write path (cx§1); per_model honors C1 via model_catalog bits (cx§9)
[capabilities.todos]
enabled = true
persist = true
goals = true
# update_plan is ALWAYS registered (cx§1); goals (S6/S12 home, catalog:138, cx `/goal`) is the persistent-objective variant of this same module — closes a gap-ledger row
# BP-7: the `goals` key above is that variant, armed. Codex keeps its goal in `goals_1.sqlite`; supercode keeps the same single record in `<session>.goal.json`, restated at the tail of every request while it stands.
[capabilities.tools_web]
enabled = true
fetch = false
search = true
# Codex has hosted web_search but NO web-fetch tool (cx§1); cached mode default
[capabilities.tools_background]
enabled = true
# background terminals, /ps //stop (cx§1); C6 (S8-corrected defense): under `model_requested`, tools run sandboxed WITHOUT prompting unless the model itself escalates — from a background task's perspective that's an auto-run default, satisfying C6's auto-policy requirement without needing a separate allow-list
[capabilities.subagents]
enabled = true
max_depth = 1
background = true
background_prompts = "auto_policy"
# multi_agent default-on, agents.max_depth default 1 (cx§1, cx§6)
# BP-7 (catalog:135 "Background subagents + resume", cx `✓ v2 mailbox
# (send_message/wait/interrupt)`): §4.3's own line read
# `background = false`, which contradicted the very column it was
# transcribing — Codex's multi-agent v2 detaches children and talks to
# them through a mailbox. On, with `background_prompts = "auto_policy"`
# (C6's required companion, and the honest one for cx: under
# `approval = "model_requested"` tools run sandboxed without prompting
# unless the MODEL escalates, so a detached child has no interactive
# prompt to surface to a parent — the same reasoning
# `capabilities.tools_background`'s own C6 comment above already gives).
[capabilities.tools_question]
enabled = true
# BP-3 (flipped from `false`): the catalog scores cx `✓*` for the structured
# user-question tool — `request_user_input` EXISTS at the pin, behind an
# experimental flag — and the parity ledger's denominator is that column, so
# cx-parity has to supply the capability rather than the footnote. The module
# registers the tool; `[core.tools] enabled` above additionally registers
# Codex's own spelling as an alias. §2.1's `tools_question → tui|server` dep is
# met by `[capabilities.tui]` below.
[capabilities.deferred_tools]
enabled = true
core = ["bash", "shell", "apply_patch", "update_plan", "ask_user", "request_user_input", "current_time", "sleep", "get_context_remaining", "new_context", "image_gen"]
# ToolExposure::Deferred + native tool_search is Codex's own mechanism (cx§1)
# BP-3: the new built-ins stay eager — a feature tool the model must tool_search for first is not the same capability Codex ships
[capabilities.structured_output]
enabled = true
# --output-schema final-response contract (cx§8); module 33, Config.response_format
[capabilities.permissions]
enabled = true
approval = "model_requested" # S8 fix: Codex `on-request` default is "the MODEL decides when to ask" (cx§4, protocol.rs:921-924) — NOT supercode's `OnRequest` (client-side allowlist check, config.rs:39-40, 299-302); using the wrong enum value would prompt on every non-allowlisted tool call where stock Codex prompts almost never. `model_requested` is the NEW distinct mode (§3.2) the module must re-implement escalation-initiated-by-the-model for.
[capabilities.permissions.sandbox]
tier = "workspace_write" # writes in cwd + tmp, no network (cx§4); RECOMMENDED POSTURE (S16 fix), not upstream's labeled default — codex.md names no sandbox mode "(default)" (unlike approval); this is upstream's own steered guidance ("prefer --sandbox workspace-write", the deprecated --full-auto warning)
# BP-10: the TABLE form of the same key (§3.1 defines `sandbox = "X"` as identical to `sandbox = { tier = "X" }`), so the three knobs below can be stated. `enabled` is deliberately left UNSET, exactly as the bare form left it — `crate::sandbox::os_sandbox_active` then keeps the tier-driven trigger this preset already had.
env_policy = "filtered" # BP-10 (catalog "Child-process env sanitization", cx ✓): Codex's `shell_environment_policy` filters secrets from a spawned shell BY DEFAULT (cx§4). Until this line, cx-parity resolved to `Inherit` and no sanitization happened under the preset at all — the mechanism existed and nothing armed it.
escalation = "ask" # BP-10 (catalog "Sandbox-escalation path", cx ✓): when a confining tier cannot be enforced on this host, Codex does not silently run unconfined — the user is asked. No handler installed still denies (fail-closed, `crate::sandbox::resolve_escalation`).
[capabilities.permissions.sandbox.network]
enabled = true # BP-10 (catalog "Network sandbox / domain rules", cx ✓): `workspace_write` cuts subprocess network (cx§4). Real on this host: macOS seatbelt `(deny network*)`, Linux a fresh network namespace. Per-DOMAIN filtering of arbitrary subprocess traffic is the remaining gap — see the ledger row's note.
[capabilities.permissions.rules]
enabled = true # execpolicy .rules allow/prompt/forbidden → translated into deny→ask→allow (C5)
deny = []
ask = []
allow = []
[capabilities.permissions.protected_paths]
enabled = true
# Rule-layer floor (file-tools + bash redirect targets + apply_patch + known
# argv-writers; opaque/dynamic bash writes forced to Ask) — NOT the same as
# cx's `workspace_write` OS sandbox read-only mount above; see
# `crate::permissions` module doc for exactly what is/isn't covered here.
paths = [".git/**", ".codex/**"] # read-only even inside writable roots (cx§4 workspace-write)
[capabilities.permissions.approvals]
persist = true # BP-10: cx's `with_cached_approval` grants are saved as prefix rules that outlive the process (cx§4). Same per-project store and the same one-file reversibility as cc-parity.
# BP-10 (catalog "Named permission profiles", cx §4 `[permissions.<name>]`
# Beta: "extends, fs+net rules"). Reusable, INHERITABLE bundles, selectable
# per run without editing config — `supercode --permission-profile <name>`
# (sugar for `-c capabilities.permissions.profile=<name>`, so the selection
# goes through the same resolver every other key does). The three bundles
# below are Codex's own three postures expressed in this schema; no
# `profile` key is set, so cx-parity's own top-level permission keys stand
# until a run names one.
# Each bundle carries the SANDBOX TIER + RULES cx§4 names ("extends, fs+net
# rules"), deliberately not `approval`: the approval mode is coupled to the
# base prompt (C4) and to §2.2 C6's background-prompt dependency, so a
# bundle that silently changed it would make a permission switch a
# loop-shape switch. The mechanism accepts `approval` from a user's own
# bundle; these shipped three do not use it.
[capabilities.permissions.profiles.read-only]
sandbox = "read_only"
[capabilities.permissions.profiles.workspace-write]
sandbox = "workspace_write"
[capabilities.permissions.profiles.locked-down]
extends = "read-only" # the inheritance half of the row: this bundle IS read-only, plus a shell floor
rules = { deny = ["bash", "shell", "background_exec"] }
[capabilities.trust]
enabled = true
default = "ask"
# [projects] trust_level gate + hook hash-trust (cx§4:153, cx§7)
[capabilities.mcp]
enabled = true
serve = true
# full client stack (cx§7); serve = codex mcp-server analog (module 16)
[capabilities.hooks]
enabled = true
# CC-compatible 10-event shape, hash-trusted (cx§7 "Lifecycle hooks")
[capabilities.model_catalog]
enabled = true
provider = "openai" # BP-13: the alias scope in force for this session (cx§9)
service_tier = "auto" # BP-13 (catalog D9 "Fast mode / service tiers"): cx's `model_service_tier` default; `/fast` moves the session to `priority` (cx§9)
allowed_models = [] # BP-13 (catalog D9): Codex pins features/profiles by requirements, not by a model allowlist — stated empty so the preset says so
denied_models = []
# capability bits (apply_patch_tool_type, supports_search_tool) drive
# per-model tool swaps — the C1 resolution machinery (cx§9 "Model catalog")
# BP-5 (catalog D2 "Per-model-family base-prompt selection", cx§2 "Per-model
# base instructions"): Codex selects its system prompt PER MODEL FAMILY from
# bundled markdown — gpt_5_codex_prompt.md, gpt-5.1-codex-max_prompt.md,
# gpt-5.2-codex_prompt.md, gpt_5_1_prompt.md, gpt_5_2_prompt.md, and
# prompt_with_apply_patch_instructions.md, the variant that appends the full
# apply_patch tutorial. The FUNCTIONAL split across that set is exactly that
# tutorial: a codex-tuned family is taught the patch envelope, a general
# family is not. These two entries are that split, in supercode own words —
# never a copy of upstream prompt text. A model matching neither keeps
# core.system_prompt, so this table narrows nothing.
# Keys are model-id globs and the MOST SPECIFIC (longest) match wins:
# openai/gpt-5.2-codex takes *codex*, openai/gpt-5.1 takes *gpt-5*.
[capabilities.model_catalog.base_prompts]
"*gpt-5*" = """
You are a coding agent running in a terminal. Work through the shell: read
with cat/rg, change files by writing them out, and verify with the project own
commands before reporting anything as done. Prefer the smallest change that
fixes the problem, and say plainly what you did and what you did not check.
"""
"*codex*" = """
You are a coding agent running in a terminal. Work through the shell: read
with cat/rg, change files by writing them out, and verify with the project own
commands before reporting anything as done. Prefer the smallest change that
fixes the problem, and say plainly what you did and what you did not check.
File edits go through the apply_patch envelope. One envelope may carry several
operations, and every path is relative to the working directory:
*** Begin Patch
*** Add File: path/to/new.rs
+the whole new file, one + per line
*** Update File: path/to/existing.rs
@@ context line locating the hunk
-the exact line being replaced
+its replacement
*** Delete File: path/to/gone.rs
*** End Patch
Context lines carry a leading space, removals a -, additions a +. An update
whose context does not appear verbatim in the file is rejected whole, so read
the file first and quote it exactly.
"""
[capabilities.model_catalog.models."openai/gpt-5*"]
apply_patch = true # BP-13: the freeform apply_patch envelope IS this family's write path (cx§1) — so `edit_file`/`write_file` are never co-advertised to it
search_tool = true
[capabilities.model_catalog.models."openai/gpt-4*"]
apply_patch = false # BP-13: a family the catalog marks as NOT taking the envelope gets `edit_file`/`write_file` instead — the tool SURFACE adapts to the model, inside `ToolRegistry::from_config`'s own selection
[capabilities.tui]
enabled = true
# ---- notable OFFs ----
[capabilities.tools_search]
enabled = false
# no glob/grep tools; "prefer rg" via shell is prompt guidance (cx§2)
[capabilities.plan_mode]
enabled = false
# /plan is effort-tier steering, not a CC/OC restriction mode (cx§6; catalog D1 CC+OC)
[capabilities.memory]
enabled = false
# [features].memories = false default (cx§6, cx§7)
[capabilities.checkpoint]
enabled = true
restore = false
# BP-7 (catalog:112 "Turn diff tracking", cx `✓ turn_diff_tracker`): §4.3's own
# line read `enabled = false` with the reason "no shadow-git; ghost_snapshot is a
# legacy no-op (cx§6)". That reason is about the RESTORE half, and it still
# stands — `restore = false` states it as a key rather than as prose, and
# `CheckpointObserver::restore` refuses under it. But Codex genuinely DOES track
# each turn's cumulative file diff (cx§3 `turn_diff_tracker`), and this module is
# where supercode captures per-turn pre-images, so leaving the whole table off
# meant cx-parity captured no turn-diff data at all — the gap the ledger row
# named. On: tracking without restoring, which is exactly Codex's shape.
# `file-checkpointing-code-restore` is `—` for cx and stays a cc-only row.
[capabilities.session_tree]
enabled = false
# rollout is STRICTLY LINEAR (C7); fork = truncate+copy (D5 footnote ¹³)
[capabilities.session_share]
enabled = false
[capabilities.lsp]
enabled = false
[capabilities.formatters]
enabled = false
[capabilities.server]
enabled = false
# app-server parity is out of preset scope — see gaps
[capabilities.reduction]
enabled = false
[capabilities.cache]
enabled = false
[capabilities.model_oauth]
enabled = false
# ChatGPT-subscription login (cx§9) — module 27 deferred
"#;Expand description
cx-parity — design §4.3.