supercode-harness 0.5.45

The optional native Volter Harness agent and tool harness
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
//! §4 "Presets" (`docs/composable-harness/COMPOSABLE-HARNESS-DESIGN.md`) —
//! P2 of the composable-harness migration (design §5.2, phase **P2**).
//!
//! The six reserved built-in presets, compiled in as TOML consts, transcribed
//! faithfully from the design doc's §4.1-§4.5 TOML blocks (and §4's intro
//! paragraph for the sixth, `supercode-default`, which the doc defines by
//! prose rather than a TOML block — S10 fix: "`pi-core` MINUS `{trust,
//! session_tree, session_share, server, plugins}`", not "`pi-core` plus
//! extras").
//!
//! **Syntax fix (P2 judgment call).** The design doc's `[capabilities.X]
//! { enabled = true, ... }` lines combine a TOML table-HEADER and an
//! inline-table VALUE on one line, which is not valid TOML (verified
//! empirically against the `toml` crate: `invalid table header, expected
//! newline`). Naively rewriting them as dotted-key assignments
//! (`capabilities.X = { ... }`) is also unsafe wherever such a line appears
//! *after* an already-open `[capabilities.permissions]` table (cc-parity,
//! cx-parity, oc-parity all have this): a dotted key inside an open table is
//! relative to the CURRENT table, so `capabilities.permissions.sandbox = {..}`
//! written while inside `[capabilities.permissions]` nests as
//! `capabilities.permissions.capabilities.permissions.sandbox`, silently
//! corrupting the structure. The transcription below instead expands every
//! `[capabilities.X] { k = v, ... }` shorthand into the equivalent explicit
//! form — a real `[capabilities.X]` table header (always root-absolute,
//! never context-relative) followed by `k = v` lines — which is safe
//! regardless of surrounding context and preserves the exact same resolved
//! structure. Every block below is verified to parse into `HarnessConfig`
//! in this module's tests, and each preset's resolved shape is golden-tested
//! against §4.6's per-preset verdicts in
//! `crates/harness/tests/composable_presets.rs`.
//!
//! Comments from the design doc are preserved verbatim inside each TOML
//! block for traceability back to the source section.

/// `pi-core` — design §4.1.
pub const PI_CORE_TOML: &str = r#"# built-in preset: pi-core — the §1 core with pi's exact defaults, plus pi's four kept extras.
schema_version = 1

[core]
effort = "medium"                       # pi default thinking level (pi§3, src:core/defaults.ts:3)
max_tool_output_bytes = 51200           # pi's shared truncation policy: 50KB / 2000 lines (pi§1, truncate.ts)
project_context = true                  # AGENTS.md/CLAUDE.md global + ancestor walk (pi§2 "Context files")
env_context = true                      # pi appends Current date + cwd to the prompt (pi§2, system-prompt.ts:88-170)

[core.retry]                            # pi agent-level auto-retry (pi§3)
enabled = true
max_retries = 3
base_delay_ms = 2000

[core.tools]
enabled = ["read_file", "bash", "edit_file", "write_file"]  # pi's default-ACTIVE four (pi§1, src:core/sdk.ts:245)
schema_tier = "full"
[core.tools.read_file]
multimodal = true                       # pi read returns images as attachments (pi§1, read.ts)

[core.skills]
enabled = true                          # agentskills.io discovery + progressive disclosure (pi§2; D-7 met by read_file)
                                        # No `harness` here: `supercode-default` extends this preset and is DEFINED as
                                        # today's unfiltered default stack (§4 intro), which discovers no SKILL.md
                                        # package and offers no `skill` tool. Naming a root table here would change what
                                        # `supercode` with no config file at all does.

[core.compaction]
enabled = true
after_messages = 0                      # pi's trigger is token pressure, never message count (pi§2)
reserve_tokens = 16384                  # compaction.reserveTokens default (pi§2, pi§6)
keep_recent_tokens = 20000              # compaction.keepRecentTokens default (pi§2)
summarize = true                        # structured Goal/Constraints/Progress/… summary (pi§2, compaction.md)

[core.steering]
steering_mode = "one-at-a-time"         # pi delivery-mode defaults (pi§3 "Message queue", pi§6)
follow_up_mode = "one-at-a-time"

# ---- modules ON (each is on pi's kept-list, pi§10 closing) ----
[capabilities.trust]
enabled = true
default = "ask"
# pi's ONE built-in gate (pi§4, trust-manager.ts; defaultProjectTrust "ask")
[capabilities.session_tree]
enabled = true
branch_summaries = true
labels = true
# THE core pi feature (pi§10; D5)
[capabilities.session_share]
enabled = true
# /share gist public link (pi§8); human /export HTML is core now (§1.6, S6) and on regardless
[capabilities.server]
enabled = true
# --mode json / --mode rpc embedding ladder (pi§8, pi§10)
[capabilities.plugins]
enabled = true
# everything-is-an-extension (pi§7; D-10 dep satisfied by trust above)
[capabilities.tui]
enabled = true
# §1.9 recorded deviation, default-on in parity presets

# ---- notable OFFs (each a pi FIRST-PARTY omission, pi§10 / catalog §3) ----
[capabilities.tools_search]
enabled = false
# grep/find/ls exist but are OPT-IN even in pi (pi§1 "--tools"); one line re-enables
[capabilities.mcp]
enabled = false
# "intentionally does not include built-in MCP" (pi§7)
[capabilities.subagents]
enabled = false
# example extension only (pi§3 "NO subagents")
[capabilities.permissions]
enabled = false
approval = "never"
sandbox = "danger_full_access"
                                # pi has NO popups/rules/sandbox (pi§4; README "Permissions & containerization").
                                # C3 fires its MANDATORY warning here BY DESIGN — pi's own docs say containers, not trust in the harness.
[capabilities.plan_mode]
enabled = false
# example ext only (pi§10)
[capabilities.todos]
enabled = false
# example ext only (pi§10)
[capabilities.tools_background]
enabled = false
# "tmux instead" (pi§10)
[capabilities.tools_web]
enabled = false
# web search ships as a SKILL in pi (pi§10)
[capabilities.checkpoint]
enabled = false
# git-checkpoint example ext only (pi§5)
[capabilities.memory]
enabled = false
# no memory subsystem (pi§2)
[capabilities.hooks]
enabled = false
# pi's "hooks" are code extensions, not config-registered commands
[capabilities.deferred_tools]
enabled = false
[capabilities.cache]
enabled = false
[capabilities.reduction]
enabled = false
# supercode-only OPTIONAL policies off; A7 truncation + rehydrate stay always-on core regardless (§1.13, S1/S7 — no longer a D-8/D-8-error risk)
[capabilities.model_catalog]
enabled = false
[capabilities.model_oauth]
enabled = false
# pi HAS /login OAuth (pi§9) — deferred module 27, recorded gap
"#;

/// `cc-parity` — design §4.2.
pub const CC_PARITY_TOML: &str = r#"# built-in preset: cc-parity — Claude Code's default surface, composed.
schema_version = 1

[core]
model = "anthropic/claude-opus-4-8"     # CC account-default Opus 4.8 (cc§9 "Account-type defaults")
effort = "medium"
env_context = true                      # CC startup context: cwd/git status (cc§2 "Startup context"); BP-4 adds the approval/sandbox policy line the catalog:90 semantics name, re-emitted per turn on change
context_injections = true               # BP-4 (catalog:91): CC splices ambient reminder blocks into every session (hook `additionalContext`, `<system-reminder>` blocks, cc§2) — arms `crate::context_injection`'s built-in blocks + the runtime splice seam
project_context = true                  # CLAUDE.md tiers + directory walk (cc§2); global tier included (§1.4)
nested_instructions = true               # S6/S12 home: subdir CLAUDE.md loaded on demand, CC default (catalog:84) — closes a gap-ledger row
instruction_imports  = true              # S6/S12 home: `@path` imports, depth 4, CC default (catalog:85) — closes a gap-ledger row
project_root_markers = [".git"]          # BP-4: bounds the ANCESTOR walk (catalog:81) — CC walks UP from cwd and concatenates root→cwd, closest read last (cc§2 "Directory-walk loading")
project_doc_max_bytes = 0                # BP-4 (catalog:87): CC documents NO byte cap on CLAUDE.md — its hygiene levers are the two below — and §3.1 spells "uncapped" as 0. Stated explicitly rather than left absent so the preset says what CC does instead of leaving it to a default.
project_doc_excludes = []                # BP-4 (catalog:87): CC's `claudeMdExcludes` (cc§2) — glob/absolute-path list of CLAUDE.md files to skip; CC ships it EMPTY, same as the rule sets below
project_doc_strip_comments = true        # BP-4 (catalog:87): CC strips block-level `<!-- … -->` from CLAUDE.md before injection so maintainer notes cost no tokens (cc§2 "HTML comment stripping")
parallel_tool_calls = true               # BP-2: CC runs an assistant turn's independent sibling calls as a concurrent batch (cc§1, catalog:59) — the gated batch path in `Agent::run_tools_concurrently`, armed
tool_output_spill = true                 # BP-2: CC's Bash-overflow → session file recovery door (catalog:58): a capped tool result keeps its full bytes in a per-session spill file the notice names, readable with `read_file` — no `capabilities.reduction` required
file_mentions = true                    # BP-5 (catalog D2 "@-file mentions / attachments"): `@` in the prompt injects that file's context (cc§2 "`@`-file mentions"). Deny-rule aware, as CC documents it — a mention resolving to a protected path (see `permissions.protected_paths` below) inlines the refusal, never the bytes.
output_style = "default"                # BP-5 (catalog D2 "Output style / personality module"): CC's `outputStyle` setting at the value CC itself ships — the Default style, which appends nothing to the base prompt (cc§7 "Output styles"). The LAYER is what this arms: naming any other style (`explanatory`, `learning`, or a `~/.claude/output-styles/<name>.md` of the user's own) swaps the response-style instructions without touching `system_prompt`.
path_rules = true                       # BP-5 (catalog D2 "Path-scoped rules"): CC's `.claude/rules/*.md` (cc§2). A rule with no `paths:` joins the instruction blob at startup; a rule WITH `paths:` waits and is injected the first time a tool touches a matching file — CC's own "loads only when Claude touches matching files".

[core.model_switch]
allow_switch = true                     # BP-13 (catalog D9 "Mid-session model switching"): CC's `/model` + Alt+P change the model without losing the session (cc§9). Arms the governed switch — reasoning-artifact filtering (dep 8) plus a persisted `model_change` record in the session journal.
                                        # `notice` is deliberately NOT set: CC switches SILENTLY (no injected switch instructions); that is Codex's behaviour, and cx-parity sets it there.

[core.tools]
# BP-3: `current_time`/`sleep` join the optional default-tool names (the
# `view_image` precedent, §1.2's "fifth optional default-tool name, not a new
# module"). The catalog's clock/sleep row is `✓*` for CC — ScheduleWakeup
# paces the loop but neither reports the time nor pauses it — so cc-parity
# supplies the capability itself rather than the footnote.
enabled = ["read_file", "bash", "edit_file", "write_file", "current_time", "sleep"]
schema_tier = "full"
[core.tools.read_file]
multimodal = true                       # CC Read renders images/PDFs/notebooks (cc§1 Read)
line_numbers = true                     # BP-2: CC Read's `cat -n` gutter, numbered from `offset` (cc§1 Read, catalog:26)
[core.tools.edit_file]
require_read_before_edit = true         # S6/S12 home: CC Edit refuses unless the file was read this conversation (catalog:32) — closes the cc-parity gap-ledger row
notebook_aware = true                   # S6/S12 home: NotebookEdit cell-level replace/insert/delete (catalog:40) — closes the cc-parity gap-ledger row
[core.tools.bash]
timeout_secs = 120                      # CC default 2 min, model-raisable (cc§1 Bash)

[core.skills]
enabled = true                          # SKILL.md dirs + commands, descriptions-only until invoked (cc§7 Skills)
harness = "claude-code"                 # BP-6: the loop discovers SKILL.md from CC's own documented roots and precedence — enterprise/managed > `~/.claude/skills` > plugin bundles (`plugin:skill`) > project `.claude/skills`, plus nested subdirectory skills as `dir:skill` (cc§7 "Skill locations & precedence")
shell_injection = true                  # BP-5 (catalog D2 "Shell-output injection in templates/skills"): CC executes `` !`cmd` `` inline and ```` ```! ```` blocks inside a skill/command body AT LOAD TIME (cc§7 "Dynamic context injection"), disabled org-wide with `disableSkillShellExecution` — this key is that switch stated positively. Every extracted command is decided by the one permissions engine with THIS preset's rules and protected paths; under `approval = "untrusted"` a bare `bash` is `Ask`, so a body that wants its own command run declares it in `allowed-tools`, exactly as CC requires.

[core.compaction]
enabled = true
summarize = true                        # CC auto-compaction near limit + /compact [instructions] (cc§2). BP-4: this key now arms the CORE span-summary side-call too — design §1.5 makes "an LLM summary of the compacted span" part of obligation 5, and §3.1 annotates this very key "SpanSummary side-call … D-9 small-model fallback"
reserve_tokens = 16384                  # CC's threshold is pct-based (CLAUDE_CODE_AUTOCOMPACT_PCT_OVERRIDE, cc§2); reserve is our §1.5 equivalent
focus_instructions = ""                 # BP-4 (catalog:98): CC has NO standing compaction focus — steering is per invocation, `/compact [instructions]` (cc§2). Stated empty so the preset says that, rather than leaving the knob to a default, and so the mechanism is armed at the one place it belongs: `Agent::compact_now(focus)`.

[core.session]
append_only = true                      # BP-8 (catalog:150): CC flushes every event to its session JSONL as the turn runs (cc§5), so a crash mid-turn keeps the turn. Arms `crate::session_journal` — supercode's own store otherwise rewrites `<name>.jsonl` only at end-of-turn.
queue_persist = true                    # BP-8 (catalog:154): CC writes QUEUE-OPERATION records for prompts typed while it is busy (cc§5), so a pending input survives a restart. The journal armed above is where those records go.
auto_title = true                       # BP-7 (catalog:150): CC writes `ai-title` records — a cheap-model title for every session (cc§5). The titler, its small-model routing and its `SessionStore::set_title` write were all built and CLI-wired at P4b; this preset never set the gate, so under cc-parity no title was ever generated. `small_model` is pinned below (`capabilities.model_catalog`), so this runs on Haiku, not Opus.

[core.prompts]
# BP-7 (catalog §4a "Review mode"): CC's `/code-review` + `/security-review` are
# purpose-built review TURNS with a fixed report format, not a separate agent
# (cc§10). This template IS that format; `Agent::review` sends it as an ordinary
# turn of this same session, so the review inherits the session's tools,
# permissions, transcript and records.
code-review = """Review the current code changes as a dedicated review turn. {args}
Inspect the diff and the files it touches with the available tools 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_search]
enabled = true
glob = true
content_search = true
list_dir = false
                               # Glob + Grep, promptless read-class (cc§1); list_dir OFF (S15 fix) — CC lists dirs via Bash/Glob, Read rejects directories (catalog:33 fn²), so the module's dir-listing sub-tool would be a capability CC users never see
[capabilities.tools_web]
enabled = true
fetch = true
search = true
# WebFetch + WebSearch (cc§1)
[capabilities.tools_question]
enabled = true
# AskUserQuestion (cc§1)
[capabilities.todos]
enabled = true
persist = true
goals = true
# Task*/TodoWrite checklist, persists across compaction (cc§1, cc§3)
# BP-7 (catalog:138): `goals` is this module's persistent-objective variant (design §2 module 7) — CC's `/goal`, a standing condition restated at the tail of every request and persisted as `<session>.goal.json`, distinct from the per-stretch `update_plan` checklist above.
[capabilities.plan_mode]
enabled = true
effort = "high"                         # BP-13 (catalog D9, the plan-mode half of "Reasoning effort / thinking budgets"): planning is the phase that most rewards deeper reasoning, and CC's plan mode is where a session does its thinking (cc§3). While the mode is live the request carries this level instead of `[core] effort`; leaving the mode restores it.
# Shift+Tab / EnterPlanMode read-only mode (cc§3); dep met by permissions.rules below
[capabilities.subagents]
enabled = true
max_depth = 2
background = true
background_prompts = "parent"
                               # Agent tool; background-by-default v2.1.198+, nested allowed (cc§1, cc§3)
                               # C6 resolved via the schema key (S2 fix, not prose): background_prompts = "parent" — background children surface prompts in the parent session (cc§3, claude-code.md:98)
[capabilities.tools_background]
enabled = true
# run_in_background + Ctrl+B (cc§1, cc§8); C6: same parent-surfaced queue as subagents.background_prompts above

[capabilities.permissions]
enabled = true
approval = "untrusted"                  # CC tiered default: read-only never prompts, Bash/edits prompt first-use (cc§4 "Tiered defaults")
                                        # No C3: approval != never.
auto_approved_tools = ["read_file", "glob", "search", "ask_user", "current_time", "sleep", "enter_plan_mode", "exit_plan_mode", "update_plan"]
                                        # CC read-only tier (cc§4); `list_dir` removed (S15 — module tool is off above)
                                        # BP-3: the new no-side-effect tools join that tier — CC never prompts before
                                        # AskUserQuestion/EnterPlanMode/ExitPlanMode, and under `approval = "untrusted"`
                                        # every tool NOT listed here asks first, which would put a permission prompt in
                                        # front of the question prompt (and would refuse both outright in a headless run).
                                        # `exit_plan_mode` carries its own explicit plan approval, so the generic gate in
                                        # front of it is pure double-prompting.
                                        # BP-8 (catalog:156): `update_plan` joins the same tier — CC's TodoWrite is a
                                        # checklist write with no side effect outside the session and never prompts
                                        # (cc§1/cc§3). Under `approval = "untrusted"` it otherwise asks on every plan
                                        # update, which in a headless run refuses the plan outright — i.e. the plan row's
                                        # own behaviour would be unreachable under this preset.
# module 12 in table form (S5): OS sandbox OFF (CC's `/sandbox` is opt-in, cc§4), fs tier unconfined.
# One key `permissions.sandbox` — the table form, not the bare-scalar shorthand, so no collision.
[capabilities.permissions.sandbox]
enabled = false
tier = "danger_full_access"
env_policy = "inherit"                  # BP-10 (catalog "Child-process env sanitization", cc `✓*`): CC's env control is `sandbox.credentials.envVars` — an OPT-IN of the opt-in `/sandbox` (cc§4). With the OS sandbox off above, a CC Bash call inherits the user's environment, so the preset SAYS "inherit" rather than leaving the knob to a default that happens to agree; cx-parity states the other posture on the same key.
escalation = "ask"                      # BP-10 (catalog "Sandbox-escalation path", cc `✓*` allowUnsandboxedCommands): with `enabled = false` nothing is confined, so this never fires under cc-parity today — it is the answer for the `/sandbox` session, where CC asks before running a command outside the sandbox rather than refusing it outright.
[capabilities.permissions.sandbox.network]
enabled = false                         # BP-10: CC's own default. `/sandbox` is opt-in and its network proxy with it (cc§4 `sandbox.network.*`); stated so the preset carries CC's posture on the key instead of defaulting to it silently.
[capabilities.permissions.rules]
enabled = true                          # deny→ask→allow first-match IS the CC algebra — native, no translation (C5 decision; cc§4 "Rule sets & evaluation")
deny  = []
ask   = []
allow = []                              # CC ships empty rule sets; "don't ask again" persists into allow at runtime (cc§4)
[capabilities.permissions.protected_paths]
enabled = true                          # never-auto-approved set (cc§4 "Protected paths")
# Rule-layer floor: file-tools + bash redirect targets + apply_patch + known
# argv-writers (tee/dd/cp/mv/install/sed -i/truncate/ln); an opaque or
# dynamic bash write is forced to Ask. Complete OS-level write confinement
# is `permissions.sandbox`'s job (module 10), not this table's — see
# `crate::permissions` module doc / `Config::permissions_protected_paths`.
paths = [".git/**", ".env*", ".claude/**", ".vscode/**", ".idea/**", "~/.claude/settings*"]
[capabilities.permissions.approvals]
persist = true                          # BP-10 (catalog "Session approval caching"): CC records "don't ask again" PER PROJECT + command, not per process (cc§4) — the grant is still there tomorrow. Stored beside the session's other per-project records ($SUPERCODE_HOME/approvals/<project tag>.json) and reversible: delete it (or `ApprovalCache::clear`) and the next matching call asks again.

[capabilities.trust]
enabled = true
default = "ask"
# workspace trust gates project allow-rules (cc§4)
[capabilities.mcp]
enabled = true
# stdio/HTTP/OAuth, resources, prompts-as-commands (cc§7)
[capabilities.deferred_tools]
enabled = true
core = ["read_file", "bash", "edit_file", "write_file", "glob", "search", "update_plan", "ask_user", "enter_plan_mode", "exit_plan_mode", "current_time", "sleep"]
                               # CC defers MCP tool definitions BY DEFAULT behind ToolSearch (cc§7 "Tool search"); builtins stay eager
                               # BP-3: the new built-ins are eager for the same reason the older ones are — CC advertises AskUserQuestion/EnterPlanMode/ExitPlanMode up front, and a question tool the model must first tool_search for is not the same capability
[capabilities.hooks]
enabled = true
# config-registered lifecycle hooks (cc§7: 30 events; module ships the CC-compatible subset first)
[capabilities.memory]
enabled = true
# auto memory MEMORY.md + topic files (cc§2); D-9 dep → model_catalog below
[capabilities.checkpoint]
enabled = true
# per-prompt file-history-snapshot → /rewind (cc§5)
[capabilities.session_tree]
enabled = true
branch_summaries = false
labels = false
                               # CC has the tree DATA MODEL (uuid/parentUuid, cc§5) + /rewind; summaries/labels are pi-isms
[capabilities.model_catalog]
enabled = true
small_model = "anthropic/claude-haiku-4-5"
fallback = []                           # CC ships NO fallback model; `--fallback-model` (≤3) is per-invocation (cc§9). The chain is EXECUTED by the loop when one is given — see `Agent::complete_with_fallback`.
provider = "anthropic"                  # BP-13: which provider's alias scope is in force — CC's friendly names resolve per provider/account (cc§9)
account = "max"                         # BP-13 (cc§9 "Account-type defaults"): on Max, `default`/`best` mean Opus; another plan's scope would mean something else
service_tier = "auto"                   # BP-13 (catalog D9 "Fast mode / service tiers"): CC's standard tier; `/fast` moves the session to `priority` and warns about the cache churn (cc§9)
allowed_models = []                     # BP-13 (catalog D9 "Org model allowlists"): CC ships availableModels EMPTY — unrestricted. Stated so the preset says CC's posture rather than leaving it defaulted.
denied_models = []
                               # aliases + ANTHROPIC_SMALL_FAST_MODEL + fallback chains (cc§9)
[capabilities.model_catalog.aliases]
"*[1m]" = "{}[1m]"                      # BP-13: CC's 1M-context SUFFIX form (cc§9 `sonnet[1m]`) — a pattern alias whose captured stem is itself alias-resolved, so `sonnet[1m]` lands on `anthropic/claude-sonnet-4-6[1m]`
[capabilities.model_catalog.providers.anthropic.aliases]
fast = "anthropic/claude-haiku-4-5"     # BP-13: provider-scoped — `fast` means Haiku only while this session talks to Anthropic
[capabilities.model_catalog.providers.anthropic.accounts.max.aliases]
default = "anthropic/claude-opus-4-8"   # BP-13 (cc§9): the Max plan's account defaults
best = "anthropic/claude-opus-4-8"
[capabilities.model_catalog.models."anthropic/claude-haiku-4-5"]
max_effort = "low"                      # BP-13: the per-model effort TIER — the small/fast model is not asked for deep reasoning, whatever `[core] effort` says
[capabilities.tui]
enabled = true

# ---- notable OFFs ----
[capabilities.tools_apply_patch]
enabled = false
# CC is edit-only (C1; catalog §5 conflict 1)
[capabilities.tools_persistent_shell]
enabled = false
[capabilities.lsp]
enabled = false
# CC's LSP is inactive until a plugin installs it (cc§1) — off matches default
[capabilities.formatters]
enabled = false
[capabilities.session_share]
enabled = false
# no PUBLIC share links in CC (D5 OC+PI-only row); `/export`+`/copy` are core now (§1.6 `export_format`, S6) and stay on regardless
[capabilities.server]
enabled = false
# CC has no local HTTP server surface; SDK is in-process
[capabilities.reduction]
enabled = false
[capabilities.cache]
enabled = true
plan = "imported_prefix"
warnings = true
# BP-4 deviation from §4.2's own `enabled = false` line, recorded here rather than silently:
# that line's reason ("CC caching is provider-automatic") does not survive the catalog's own
# grading of the same behavior. catalog:110 "Cache-aware context architecture" marks CC ✓ with
# the cache-action matrix, cache-preserving `/cd` and TTL switches (cc§2) — i.e. CC deliberately
# SHAPES the cached prefix and warns when an action would churn it, which is a harness behavior,
# not a provider one (Anthropic prompt caching is driven by explicit breakpoints, and something
# has to place them). supercode's equivalent is exactly `CachePlan::ImportedPrefix` + the
# imported-prefix compaction clamp + `AgentEvent::CacheWarning`, all already implemented and
# wired — with the module off they simply never fired under this preset, which is the gap the
# ledger row named. `warnings = true` is C2's referee, and now reaches `Config::cache_warnings`.
[capabilities.structured_output]
enabled = false
# --json-schema is headless-only surface; enable per-run
[capabilities.model_oauth]
enabled = false
# recorded gap: CC's DEFAULT auth is subscription OAuth (cc§9) — module 27 deferred
"#;

/// `cx-parity` — design §4.3.
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
"#;

/// `oc-parity` — design §4.4.
pub const OC_PARITY_TOML: &str = r#"# built-in preset: oc-parity — opencode's default surface, composed.
schema_version = 1

[core]
env_context = true
project_context = true                  # AGENTS.md + instructions[] concat (oc§6)
nested_instructions = true              # S6/S12 home: nested AGENTS.md auto-attached only for touched-file dirs, oc default (catalog:84; opencode.md:34 "nested-AGENTS.md") — closes an oc-parity gap-ledger row
instruction_imports  = true             # S6/S12 home: `instructions[]` config imports, oc default (catalog:85; opencode.md:367) — closes an oc-parity gap-ledger row
max_tool_output_bytes = 51200           # tool_output.max_bytes default 51200 / 2000 lines (oc§1 Truncate service)

[core.session]
auto_title = true                       # S6/S12 home: hidden title+summary agents (deny-all utility agents) on small_model, oc default (catalog:150; opencode.md:169-170,235) — closes an oc-parity gap-ledger row; small_model is "" below so this falls back to the main model per D-9 until a cheap model is configured

[core.tools]
enabled = ["read_file", "bash", "edit_file", "write_file"]  # oc registry core (oc§1; read subsumes ls)
schema_tier = "full"
[core.tools.read_file]
multimodal = true                       # images/PDFs as attachments (oc§1 read)
[core.tools.bash]
timeout_secs = 120                      # flags.bashDefaultTimeoutMs default 120000 (oc§1 bash)

[core.skills]
enabled = true                          # skill tool + .opencode/skills + remote registries (oc§7)
harness = "opencode"                    # BP-6: the loop reads opencode's own roots — `{skill,skills}` under the global config dir and every `.opencode` dir (oc§7)

[core.compaction]
enabled = true
summarize = true                        # compaction{auto,prune,…} (oc§6)

# ---- modules ON ----
[capabilities.tools_search]
enabled = true
# glob + grep via ripgrep (oc§1)
[capabilities.todos]
enabled = true
persist = true
# todowrite → SQLite todo table (oc§1)
[capabilities.tools_web]
enabled = true
fetch = true
search = false
                               # webfetch is default; websearch only under the Zen provider / exa flags (oc§1 "webSearchEnabled")
[capabilities.subagents]
enabled = true
max_depth = 2
background = false
                               # task tool → child session via parentID, resumable task_id (oc§1); background is env-gated experimental → off
[capabilities.tools_apply_patch]
enabled = true
per_model = true
                               # THE C1 precedent: swapped in (edit/write out) for gpt-* models (oc§1 apply_patch; catalog §5 conflict 1)
[capabilities.plan_mode]
enabled = false
# S18 fix (flipped from `true`): opencode's plan_enter/plan_exit TOOLS — exactly what this module is defined by (§2 module 8) — are DENY-BY-DEFAULT at the pin (opencode.md:251), and this preset's own translated rule set below denies them. What oc actually runs by default is the LEGACY generation: the plan agent is a permission-ruleset agent (edit denied) — already expressible as an agent-scoped `permissions.rules` restriction, not the tool-based `plan_mode` module. Enabling `plan_mode` here would contradict oc's own deny-default; off is the honest reading.

[capabilities.permissions]
enabled = true
approval = "on_request"                 # ask-flow with once|always|reject replies (oc§4 "Ask/approve flow")
sandbox  = "danger_full_access"         # opencode has NO OS sandbox (catalog D4: sandbox is CC+CX only)
[capabilities.permissions.rules]
enabled = true
# opencode's default policy, TRANSLATED per the C5 decision (last-match-wins → deny→ask→allow
# first-match). Source policy (oc§4 "Default policy"): {"*": allow} with carve-outs
# doom_loop: ask, external_directory: ask, question: deny, plan_enter/plan_exit: deny,
# read {*.env: ask, *.env.*: ask, *.env.example: allow}.
#
# S4 fix — this is NOT "the same fixed point" as oc's last-match algebra, and is recorded honestly
# as THREE NAMED DEVIATIONS rather than claimed as exact parity:
#   1. `.env.example` → ASK here, not ALLOW. Under first-match deny→ask→allow, a read of
#      `.env.example` matches the ask-rule `read_file(*.env.*)` (glob matches) BEFORE the allow
#      list is ever consulted, so it asks where stock opencode allows. The engine's rule grammar
#      has no specificity/negation to express "ask unless a more-specific allow" — fixing this
#      would require adding that to the grammar (not done here); the deviation is in the SAFE
#      direction (stricter) and is named, not hidden.
#   2. `doom_loop` is NOT a rule-language pattern at all — it's a repetition TRIGGER (same tool
#      call repeated), not a tool/path match. Routed instead to its actual mechanism: the P4
#      doom-loop breaker (a call-repetition counter + PreToolHook default, §5.2 P4) — no rule
#      entry for it below.
#   3. `external_directory` is an oc PERMISSION CATEGORY (any tool touching paths outside the
#      worktree), not a tool name — routed instead to its actual permission category: `[core]
#      additional_dirs` (Config.additional_dirs, config.rs:169) governs which extra roots are
#      writable at all; paths outside cwd AND outside `additional_dirs` are simply not reachable,
#      which is a stricter (not equivalent) reading of oc's ask-by-default.
deny  = ["plan_enter", "plan_exit"]      # matches module 8's off-by-default above (S18) and oc's own "plan_enter/plan_exit: deny"
ask   = ["read_file(*.env)", "read_file(*.env.*)"]   # includes .env.example per deviation 1 above (glob matches before any allow)
allow = ["*"]
[capabilities.permissions.protected_paths]
enabled = false
# oc does .env protection through rules (above), not a path module

[capabilities.trust]
enabled = true
default = "ask"
# DELIBERATE SAFETY DEVIATION: opencode LACKS a project trust gate (catalog §3 closing) yet loads
# .opencode/ plugins/tools/commands from the repo. Our resolver treats plugins→trust as a HARD dep
# (D-10: "config-borne code execution without a trust gate is an injection hole") — so oc-parity
# ships the gate ON. This only NARROWS behavior (§3.3 monotonic-tightening spirit); recorded, not hidden.

[capabilities.mcp]
enabled = true
# local/remote/OAuth servers (oc§7)
[capabilities.plugins]
enabled = true
# .opencode/plugin + npm specs (oc§7); dep on trust satisfied above
[capabilities.lsp]
enabled = true
# 38 auto-spawned servers; diagnostics into edit/write results (oc§7, oc§10)
[capabilities.formatters]
enabled = true
diff_back = true
# ~27 format-on-write formatters; diff_back honors C10 (oc§7; oc§10; catalog §5 conflict 10)
[capabilities.checkpoint]
enabled = true
# shadow-git snapshots + revert/unrevert (oc§4 "Snapshots"/"Revert")
[capabilities.session_share]
enabled = true
# share manual|auto|disabled, default manual (oc§5, oc§6)
[capabilities.server]
enabled = true
# the client/server split: every frontend is an HTTP client (oc§8)
[capabilities.model_catalog]
enabled = true
small_model = ""
# models.dev catalog + small_model config key (oc§6, oc§9)
[capabilities.tui]
enabled = true

# ---- notable OFFs ----
[capabilities.tools_question]
enabled = false
# question tool is DENY-by-default outside build/plan agents (oc§1, oc§4)
[capabilities.tools_background]
enabled = false
# background subagents are env-gated experimental at the pin (oc§1)
[capabilities.session_tree]
enabled = false
# oc sessions are parent/child linear, no in-place tree (D5; C7)
[capabilities.memory]
enabled = false
[capabilities.hooks]
enabled = false
# no config-registered hooks; the plugin API is the interception layer (oc§7)
[capabilities.deferred_tools]
enabled = false
# opencode advertises eagerly (D1: deferred is CC+CX)
[capabilities.cache]
enabled = false
[capabilities.reduction]
enabled = false
# oc "prune" is the LOSSY analog (catalog §1 UNIQUE OC note); ours stays off to match, mechanism on per §1.13
[capabilities.structured_output]
enabled = false
[capabilities.model_oauth]
enabled = false
# provider /login flows (oc§9) — module 27 deferred
"#;

/// `token-saver` — design §4.5.
pub const TOKEN_SAVER_TOML: &str = r#"# built-in preset: token-saver — the reduction spine over the minimal core.
schema_version = 1
extends = "pi-core"                     # smallest surface = cheapest surface; every knob below overrides it

[core.tools]
schema_tier = "minimal"                 # TR-8/T5 schema tiering (config.rs:219-225)
# C9 (catalog §5 conflict 9): a GLOBAL minimal tier is a footgun for models trained on exact
# schemas. Per-tool override survives the global — pin any load-bearing tool back:
[core.tools.edit_file]
schema_tier = "full"                    # exact-string edit is the least forgiving schema; keep it verbatim

[core.compaction]
enabled = true
reserve_tokens = 24576                  # trigger earlier than pi's 16384 — spend the summary, save the window
keep_recent_tokens = 10000              # aggressive: half of pi's keep budget (recall traded — see caveats)
summarize = true                        # SpanSummary side-call (reduce.rs:274-289) → small_model below (D-9)

[capabilities.reduction]                # module 23 — ALL genuinely-optional passes on (≡ CLI reduce=true, userconfig.rs:33-38)
enabled = true
# NOTE (S7): no `truncation` key here — A7 ToolOutputTruncated (reduce.rs:95-103) is always-on core
# plumbing (§1.13), never a `[capabilities.reduction]` toggle, in token-saver same as every other preset.
stale_reads = true                      # A8 FileReadElided (reduce.rs:104-111)
diff_reads = true                       # TR-3 FileReadDiffed (reduce.rs:202-217)
duplicates = true                       # TR-2 DuplicateOutput (reduce.rs:228-234)
supersede = true                        # TR-6 Superseded (reduce/supersede.rs)
tool_input_elision = true               # TR-10 ToolInputElided (reduce.rs:148-169)
normalize_output = true                 # T30 OutputNormalized (reduce/normalize.rs)
image_redaction = true                  # A9 ImageRedacted (reduce.rs:112-116) — ON here, off everywhere else
span_summaries = true                   # TR-7 (reduce/summarize.rs; D-9)
handoff = true                          # reduce/handoff.rs — smallest-faithful-context model handoff

[capabilities.deferred_tools]           # module 24 — the FLAGSHIP lever (SPEC.md B6)
enabled = true
core = ["read_file", "bash", "edit_file", "write_file"]  # builtins stay eager; everything else behind tool_search

[capabilities.cache]                    # module 25 — the C2 referee
enabled = true
plan = "imported_prefix"                # CachePlan::ImportedPrefix (config.rs:88-96)
warnings = true                         # cache_warnings (config.rs:227-239): every prefix-churning feature must answer to this

[capabilities.model_catalog]            # module 26 — D-9 consumer
enabled = true
small_model = "anthropic/claude-haiku-4-5"  # compaction summaries + span summaries route here, not the main model
"#;

/// `supercode-default` — design §4 intro (S10 fix).
pub const SUPERCODE_DEFAULT_TOML: &str = r#"# built-in preset: supercode-default — pi-core MINUS {trust, session_tree,
# session_share, server, plugins}, PLUS the six extra with_builtins() builtins
# ON, notify available, reduction off (design §4 intro paragraph, S10 fix: NOT
# "pi-core plus extras" — pi-core itself turns those five modules ON to match
# pi's kept-list, so this preset is pi-core's core knobs UNCHANGED with a
# capability delta). This is what `supercode` resolves to with NO config file
# at all — "today's defaults, named and warned" rather than implicit
# (design:958-960).
schema_version = 1
extends = "pi-core"

# core knobs identical to pi-core (§4.1's [core]/[core.retry]/[core.tools]/
# [core.skills]/[core.compaction]/[core.steering] blocks) — unchanged, nothing
# to override here; inherited verbatim via `extends`.

# ---- the S10 delta over pi-core: OFF (today's CLI has none of these — "—"
# across the board in §2's Today column) ----
[capabilities.trust]
enabled = false
[capabilities.session_tree]
enabled = false
[capabilities.session_share]
enabled = false
[capabilities.server]
enabled = false
[capabilities.plugins]
enabled = false

# ---- the six extra with_builtins() builtins (tools/mod.rs:179-192), ON ----
# list_dir/glob/search -> tools_search; apply_patch -> tools_apply_patch;
# persistent_shell -> tools_persistent_shell; update_plan -> todos.
[capabilities.tools_search]
enabled = true
[capabilities.tools_apply_patch]
enabled = true
# NOT per_model: with_builtins() registers every tool struct unconditionally
# with no per-model filtering at all (§4.6 "faithful to today's actual
# unfiltered default stack") — this is what makes C1's warning fire here,
# honestly, rather than suppressing it with a `per_model` bit today's CLI
# doesn't actually have.
[capabilities.tools_persistent_shell]
enabled = true
[capabilities.todos]
enabled = true

# notify available (today's CLI already ships full notify support end to end
# — userconfig.rs:61-71 — unlike pi-core, which doesn't mention it at all).
[capabilities.notify]
enabled = true

# reduction off (policies only; A7 truncation + rehydrate stay always-on core
# regardless, §1.13) — already off by inheritance from pi-core; restated for
# clarity per the design intro's explicit "reduction off" callout.
[capabilities.reduction]
enabled = false

# permissions stays off too (approval = never, sandbox = danger_full_access)
# — identical to pi-core's own values (config.rs:36-38, tools/mod.rs:40-42);
# restated verbatim so the C3 mandatory warning fires here by the same
# mechanism as pi-core's, naming today's actual default stack rather than
# leaving it implicit (design:971-974).
[capabilities.permissions]
enabled = false
approval = "never"
sandbox = "danger_full_access"
"#;

/// The six reserved built-in preset names (design §4, opening paragraph).
pub const RESERVED_PRESET_NAMES: &[&str] = &[
    "pi-core",
    "cc-parity",
    "cx-parity",
    "oc-parity",
    "token-saver",
    "supercode-default",
];

/// Look up a built-in preset's compiled-in TOML text by name. Returns `None`
/// for anything not one of the six [`RESERVED_PRESET_NAMES`] — the resolver
/// (`configfile.rs` §3.5) falls back to treating the name as a file path in
/// that case (user/global layer only, §3.3).
pub fn lookup(name: &str) -> Option<&'static str> {
    match name {
        "pi-core" => Some(PI_CORE_TOML),
        "cc-parity" => Some(CC_PARITY_TOML),
        "cx-parity" => Some(CX_PARITY_TOML),
        "oc-parity" => Some(OC_PARITY_TOML),
        "token-saver" => Some(TOKEN_SAVER_TOML),
        "supercode-default" => Some(SUPERCODE_DEFAULT_TOML),
        _ => None,
    }
}