You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ocx sync overwrites user edits in ~/.codex/config.toml (default subagent, context windows, effort defaults) #7425
ocx sync overwrites user edits in ~/.codex/config.toml. After setting a default subagent model, per-target context-window declarations (modelContextWindows = 1000000 for the combo targets in the Codex catalog) and combo effort defaults, running ocx sync reverts or removes those user settings. We expected sync to preserve user-owned keys it does not manage (merge instead of overwrite). Current workaround: a systemd ExecStartPost hook that re-applies our settings after every OpenCodex service start. Reported by RHODIZ IT LLC (production homelab: VM instance + laptop install).
Reproduction
Point Codex at OpenCodex and set user preferences: default subagent model and modelContextWindows declarations in the Codex config/catalog, plus defaultEffort on the combos in the OpenCodex config.
Run ocx sync.
Observe: the default subagent and the context-window declaration in ~/.codex/config.toml are reverted/removed; combo effort defaults revert as well.
Re-apply the settings by hand; the next ocx sync removes them again.
Version
2.84.0 (VM instance). The config clobbering was also observed on a 2.86.0 laptop install.
Operating system
Linux (Ubuntu Server VM); also observed on a Windows laptop install.
Provider and model
Not provider-specific: affects combo routes generally (for example routes fronting Antigravity accounts).
Logs or error output
No error is emitted; sync completes successfully. The observable evidence is the before/after diff of ~/.codex/config.toml: user-set keys present before ocx sync are absent or reverted after it. Our production mitigation (a systemd ExecStartPost hook re-applying the settings on every start) exists solely because of this behavior.
Screenshots and supporting files
None — this is CLI/config behavior; full detail is in Summary, Reproduction and Redacted configuration.
Redacted configuration
{
"~/.codex/config.toml (user-owned keys reverted by sync)": [
"default subagent model = <user choice>",
"modelContextWindows for combo targets = 1000000"
],
"~/.opencodex/config.json (combo defaults reverted by sync)": [
"defaultEffort = <user choice>"
]
}
Checks
I searched existing issues and documentation.
I removed secrets, tokens, account details, request credentials, and personal data.
changed the title [-]ocx sync overwrites user config in ~/.codex/config.toml; plus 429 account rotation and missing-usage synthesis[/-][+]ocx sync overwrites user edits in ~/.codex/config.toml (default subagent, context windows, effort defaults)[/+]on Oct 20, 2026
Checked against trusted dev 12025981e5a304cdb6b1b54f525ba8554f623977. The report uses conceptual names rather than exact serialized keys: provider modelContextWindows, generated Codex catalog context_window and Codex TOML settings have different owners. Please attach a minimal redacted before/after diff with the exact table/key paths and operation order for each file, plus the effective integration/ownership state. A narrow fixture can then prove preservation of foreign keys and deliberate replacement of managed keys. No need for full configs or credentials, and no live sync should be used as a reproduction here. This remains open rather than assuming all three reported settings share one writer.
Investigation against dev at fdc6dd82d, using isolated fixture homes only (no live sync).
Result: no remaining overwrite of a key that ocx sync does not own was reproduced. #7659 (e9df82cb5, on dev) already fixed the two cases this report describes: per-target context windows and an edited native subagent default. Eleven fixture scenarios ran the real injector and the local sync/catalog writer repeatedly, with LF and CRLF configs.
What sync owns in ~/.codex/config.toml (edits are source-span edits, so foreign keys and comments survive):
Area
Behaviour
Root routing
Refreshes its own openai_base_url / experimental_realtime_ws_base_url and preserves unmarked user overrides. Removes root model_provider, or sets it to opencodex in provider-table mode.
Reserved tables
Regenerates [profiles.opencodex] and [model_providers.opencodex]; other profile and provider tables are untouched.
Catalog pointer
Manages model_catalog_json only when it points at opencodex-catalog.json.
Only with syncCodexSubagentDefaults on, and only marker-tagged [agents].default_subagent_model / default_subagent_reasoning_effort. An unmarked value is never touched. A marked value you edited is adopted as yours while the journal still records the original write (src/codex/subagent-defaults.ts:24).
Everything else
Root model, model_context_window, model_auto_compact_token_limit, unknown keys and tables, other [agents] settings and role config_files were preserved in every fixture.
Where each reported setting actually lives:
Per-target context windows belong in ~/.opencodex/config.json at providers.<provider>.modelContextWindows.<model-id> (src/codex/catalog/model-hints.ts:174). A combo's window is the minimum of its members' windows, written into the generated catalog's context_window. Hand edits to the generated catalog are regenerated on the next sync by design; a modelContextWindows key in TOML is not read as this setting.
combos.<id>.defaultEffort is read, never written, by sync (src/codex/catalog/aggregation.ts:179). In the fixtures its JSON bytes were unchanged. Sync can still save config.json for model-discovery bookkeeping (modelDiscovery / disabledModels, src/codex/catalog/retained-sync.ts:690), so the claim is narrower than "sync never writes JSON".
One open edge: if a marked subagent default was edited and the journal is missing, the marker alone decides and the value is replaced. That is current policy, and it is the case to look at if the report still reproduces after #7659.
To take this further we need a minimal redacted before/after diff (exact table/key paths; no tokens or full config files):
Which subagent field changed: [agents].default_subagent_model, a role's config_filemodel, a profile, or another path? Did the value carry an OpenCodex marker comment?
Where were the windows set: provider JSON, a TOML key, or the generated catalog (which file and row)?
Which combos.<id>.defaultEffort values changed on disk, and was anything else (GUI, CLI, the reapply hook) writing config.json around the sync?
OpenCodex and Codex versions, standalone vs connected client vs Link/Home, and whether syncCodexSubagentDefaults is on.
Root model_context_window in ~/.codex/config.toml is preserved across sync and restore. See src/codex/inject/plan.ts and the regression in tests/codex-integration/codex-sync-user-edits.test.ts.
A marked default_subagent_model / default_subagent_reasoning_effort value that differs from the value recorded in the injection journal is adopted as user-owned instead of reverted. This holds on update and on removal, including multiline strings. Unmarked values were already user-owned.
Still possible, by design today: when the journal has no recorded value for a marked default, the marker alone decides. For example, an install whose journal predates #7659, or one whose journal was removed. A hand-edited value that kept its # Managed by opencodex marker is then replaced on the next sync. src/codex/subagent-defaults.ts documents this ("Absent means no evidence, and the marker alone decides"), and the test "without a journaled record the marker alone decides, as before" pins it. Changing it is a product decision: treating unrecorded marked values as user-owned would also stop updating legacy defaults OpenCodex really did write. Workaround: delete the marker line above your edited value, which makes it user-owned on every later sync.
Not reproduced on dev:
Per-target context windows: combo rows in the generated Codex catalog are managed output and are regenerated by design. Provider modelContextWindows in ~/.opencodex/config.json is read during sync, and no sync writer that changes it was found.
Combo defaultEffort in ~/.opencodex/config.json: sync only reads it (src/codex/catalog/aggregation.ts), and no writer that reverts it was found.
If either of the last two still happens on a current version, please attach the redacted before/after of the exact key path, the command order, and whether another writer (the dashboard, a second host) was running. This stays open for the maintainer decision on legacy marker-only ownership.
Activity
github-actions commentedon Oct 20, 2026
Automated translation bookkeeping — detected language: English.
github-actions commentedon Oct 20, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
[-]ocx sync overwrites user config in ~/.codex/config.toml; plus 429 account rotation and missing-usage synthesis[/-][+]ocx sync overwrites user edits in ~/.codex/config.toml (default subagent, context windows, effort defaults)[/+]Ingwannu commentedon Oct 20, 2026
Checked against trusted dev
12025981e5a304cdb6b1b54f525ba8554f623977. The report uses conceptual names rather than exact serialized keys: provider modelContextWindows, generated Codex catalog context_window and Codex TOML settings have different owners. Please attach a minimal redacted before/after diff with the exact table/key paths and operation order for each file, plus the effective integration/ownership state. A narrow fixture can then prove preservation of foreign keys and deliberate replacement of managed keys. No need for full configs or credentials, and no live sync should be used as a reproduction here. This remains open rather than assuming all three reported settings share one writer.fix(codex): decode multiline managed-default edits; qualify context-w…
docs(structure): drop stale root context-window strip claim
fix(codex): preserve sync edits with canonical sandbox checks (#7659)
lidge-jun commentedon Oct 28, 2026
Investigation against
devatfdc6dd82d, using isolated fixture homes only (no live sync).Result: no remaining overwrite of a key that
ocx syncdoes not own was reproduced. #7659 (e9df82cb5, ondev) already fixed the two cases this report describes: per-target context windows and an edited native subagent default. Eleven fixture scenarios ran the real injector and the local sync/catalog writer repeatedly, with LF and CRLF configs.What sync owns in
~/.codex/config.toml(edits are source-span edits, so foreign keys and comments survive):openai_base_url/experimental_realtime_ws_base_urland preserves unmarked user overrides. Removes rootmodel_provider, or sets it toopencodexin provider-table mode.[profiles.opencodex]and[model_providers.opencodex]; other profile and provider tables are untouched.model_catalog_jsononly when it points atopencodex-catalog.json.service_tier,[features].fast_mode,web_search(sidecar off) and[features].multi_agent_v2(explicit V1) follow OpenCodex settings.syncCodexSubagentDefaultson, and only marker-tagged[agents].default_subagent_model/default_subagent_reasoning_effort. An unmarked value is never touched. A marked value you edited is adopted as yours while the journal still records the original write (src/codex/subagent-defaults.ts:24).model,model_context_window,model_auto_compact_token_limit, unknown keys and tables, other[agents]settings and roleconfig_files were preserved in every fixture.Where each reported setting actually lives:
~/.opencodex/config.jsonatproviders.<provider>.modelContextWindows.<model-id>(src/codex/catalog/model-hints.ts:174). A combo's window is the minimum of its members' windows, written into the generated catalog'scontext_window. Hand edits to the generated catalog are regenerated on the next sync by design; amodelContextWindowskey in TOML is not read as this setting.combos.<id>.defaultEffortis read, never written, by sync (src/codex/catalog/aggregation.ts:179). In the fixtures its JSON bytes were unchanged. Sync can still saveconfig.jsonfor model-discovery bookkeeping (modelDiscovery/disabledModels, src/codex/catalog/retained-sync.ts:690), so the claim is narrower than "sync never writes JSON".One open edge: if a marked subagent default was edited and the journal is missing, the marker alone decides and the value is replaced. That is current policy, and it is the case to look at if the report still reproduces after #7659.
To take this further we need a minimal redacted before/after diff (exact table/key paths; no tokens or full config files):
[agents].default_subagent_model, a role'sconfig_filemodel, a profile, or another path? Did the value carry an OpenCodex marker comment?combos.<id>.defaultEffortvalues changed on disk, and was anything else (GUI, CLI, the reapply hook) writingconfig.jsonaround the sync?syncCodexSubagentDefaultsis on.ExecStartPostreapply hook disabled?With a fragment that reproduces, the next step is an isolated failing regression before any ownership change.
lidge-jun commentedon Oct 30, 2026
Triage against current
dev(4fc870074), from source and the existing regressions. No live sync was run against a reporter config.Fixed by #7659 (
e9df82cb5):model_context_windowin~/.codex/config.tomlis preserved across sync and restore. Seesrc/codex/inject/plan.tsand the regression intests/codex-integration/codex-sync-user-edits.test.ts.default_subagent_model/default_subagent_reasoning_effortvalue that differs from the value recorded in the injection journal is adopted as user-owned instead of reverted. This holds on update and on removal, including multiline strings. Unmarked values were already user-owned.Still possible, by design today: when the journal has no recorded value for a marked default, the marker alone decides. For example, an install whose journal predates #7659, or one whose journal was removed. A hand-edited value that kept its
# Managed by opencodexmarker is then replaced on the next sync.src/codex/subagent-defaults.tsdocuments this ("Absent means no evidence, and the marker alone decides"), and the test "without a journaled record the marker alone decides, as before" pins it. Changing it is a product decision: treating unrecorded marked values as user-owned would also stop updating legacy defaults OpenCodex really did write. Workaround: delete the marker line above your edited value, which makes it user-owned on every later sync.Not reproduced on
dev:modelContextWindowsin~/.opencodex/config.jsonis read during sync, and no sync writer that changes it was found.defaultEffortin~/.opencodex/config.json: sync only reads it (src/codex/catalog/aggregation.ts), and no writer that reverts it was found.If either of the last two still happens on a current version, please attach the redacted before/after of the exact key path, the command order, and whether another writer (the dashboard, a second host) was running. This stays open for the maintainer decision on legacy marker-only ownership.