Preserve the managed block's interior; keep root keys at the document root
Builds onaedbf8a, which fixed the discard-everything-after-the-block bug. Two related faults remained, both reproducible on a config that has drifted: 1. The block's interior was still dropped. Where an older kit let the end marker drift below content Codex had written, real [plugins.*] and [projects.*] sections ended up *inside* the block, so discarding it deleted them. This was the live state on the macOS machine: the markers spanned lines 15-88 with plugins, marketplaces, projects and mcp_servers.graphiti between them. The interior is now filtered like the rest, which also heals the layout in a single run. 2. Bare root keys were still landing under a table. With the block emitted after `before`, and `before` ending in [sandbox_workspace_write], TOML bound model/web_search/project_doc_max_bytes to that table rather than to the document root. Output is now ordered: root keys, managed block, then tables. Against a fixture with a plugin inside the block and an mcp_server after it,aedbf8ayields: swallowed plugin kept: False sandbox keys: [network_access, model, model_reasoning_effort, project_doc_max_bytes, web_search] root keys: [approval_policy] and this commit yields: swallowed plugin kept: True after-block mcp kept: True sandbox keys: [network_access] root keys: [approval_policy, model, model_reasoning_effort, project_doc_max_bytes, web_search] BOM handling, profile file layout and model choices fromaedbf8aare unchanged. Verified on macOS: repeated runs are byte-identical, all 13 plugins / 3 projects / 6 mcp_servers survive, and `codex exec --profile deep` works. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
aedbf8a515
commit
9d177e1f74
@@ -78,22 +78,48 @@ def strip_managed(chunk):
|
||||
return "\n".join(filtered_lines).strip()
|
||||
|
||||
|
||||
def split_root(chunk):
|
||||
"""Separate bare root keys from [table] sections, preserving order within each."""
|
||||
root, tables, seen_table = [], [], False
|
||||
for line in chunk.splitlines():
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("[") and stripped.endswith("]"):
|
||||
seen_table = True
|
||||
(tables if seen_table else root).append(line)
|
||||
return "\n".join(root).strip(), "\n".join(tables).strip()
|
||||
|
||||
|
||||
# Settings may sit on either side of the managed block -- notably `codex mcp add`
|
||||
# appends [mcp_servers.*] to the end of the file. Keep both sides; rewriting only
|
||||
# what precedes the block silently discards everything after it.
|
||||
#
|
||||
# The block's *interior* is filtered too, never dropped. Where an older kit let the
|
||||
# end marker drift below content Codex had written, real [plugins.*]/[projects.*]
|
||||
# sections ended up inside the block; discarding it wholesale would delete them.
|
||||
# Filtering keeps whatever the kit does not own and heals the layout in one run.
|
||||
if managed_start in text and managed_end in text:
|
||||
before = text.split(managed_start, 1)[0]
|
||||
after = text.split(managed_end, 1)[1]
|
||||
before, rest = text.split(managed_start, 1)
|
||||
interior, after = rest.split(managed_end, 1)
|
||||
else:
|
||||
before = text
|
||||
interior = ""
|
||||
after = ""
|
||||
|
||||
before = strip_managed(before)
|
||||
after = strip_managed(after)
|
||||
preserved = "\n\n".join(
|
||||
part
|
||||
for part in (strip_managed(before), strip_managed(interior), strip_managed(after))
|
||||
if part
|
||||
)
|
||||
preserved_root, preserved_tables = split_root(preserved)
|
||||
|
||||
block = f"{managed_start}\n{managed}\n{managed_end}\n"
|
||||
|
||||
parts = [part for part in (before, block.rstrip(), after) if part]
|
||||
# Bare root keys must precede every [table] header, or TOML binds them to the table
|
||||
# above them rather than to the document root -- appending the block last quietly
|
||||
# filed model/web_search under whichever table happened to come before it.
|
||||
parts = [
|
||||
part for part in (preserved_root, block.rstrip(), preserved_tables) if part
|
||||
]
|
||||
config_path.write_text("\n\n".join(parts) + "\n", encoding="utf-8")
|
||||
PY
|
||||
|
||||
|
||||
Reference in New Issue
Block a user