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
After #2393, ZCode still causes the managed provider.opencodex integration to become conflict / foreign-edit after ZCode saves its config.
In this reproduction, the protected provider values remain semantically unchanged, but ZCode reorders JSON object keys such as moving options before enabled / source, and moving per-model limit before modalities. OpenCodex still fingerprints these nested objects through JSON.stringify(fragment.value), so key-order-only rewrites change the protected fingerprint.
I expected JSON object key order to be ignored for ownership classification while real changes to protected fields such as options.baseURL, provider identity, model names/modalities, or authoritative context values continue to produce a hard conflict.
This appears to be a follow-up to #2389 / #2393: the derived metadata paths handled by #2393 are tolerated, but ZCode's object-key normalization still changes the protected contribution fingerprint.
The full diff also contains ZCode-derived reasoning, limit.output, and filled limit.context values that are within the refreshable paths introduced by #2393.
Current canonicalContribution() sorts fragment paths, then serializes each nested fragment.value directly:
protectedContributionFingerprint() removes only the declared refreshable paths and then calls this same canonicalization. Because nested object keys are not recursively canonicalized, JSON key-order normalization changes the protected fingerprint even when protected values are identical.
A full diff -u between ocx export --client zcode --json and the on-disk provider.opencodex shows repeated object-key reordering across provider and model entries. The semantic values of protected fields shown above remain unchanged.
The same diff also shows expected ZCode-derived metadata additions, for example reasoning, limit.output, and default limit.context, which #2393 explicitly intended to tolerate.
Client or integration
Other
Area
CLI
Summary
After #2393, ZCode still causes the managed
provider.opencodexintegration to becomeconflict / foreign-editafter ZCode saves its config.In this reproduction, the protected provider values remain semantically unchanged, but ZCode reorders JSON object keys such as moving
optionsbeforeenabled/source, and moving per-modellimitbeforemodalities. OpenCodex still fingerprints these nested objects throughJSON.stringify(fragment.value), so key-order-only rewrites change the protected fingerprint.I expected JSON object key order to be ignored for ownership classification while real changes to protected fields such as
options.baseURL, provider identity, model names/modalities, or authoritative context values continue to produce a hard conflict.This appears to be a follow-up to #2389 / #2393: the derived metadata paths handled by #2393 are tolerated, but ZCode's object-key normalization still changes the protected contribution fingerprint.
Reproduction
~/.zcode/v2/config.jsonnormally.The integration reports
conflict / foreign-edit.Representative key-order-only diff at the provider level:
{ "name": "OpenCodex", "kind": "openai-compatible", - "enabled": true, - "source": "custom", "options": { "apiKey": "opencodex-loopback", "baseURL": "http://127.0.0.1:10100/v1", "apiKeyRequired": true }, + "enabled": true, + "source": "custom", "models": {Representative per-model reorder with the same authoritative context value:
"gpt-5.6-sol": { "name": "gpt-5.6-sol (native)", + "limit": { + "context": 350000 + }, "modalities": { "input": ["text", "image"], "output": ["text"] - }, - "limit": { - "context": 350000 } }The full diff also contains ZCode-derived
reasoning,limit.output, and filledlimit.contextvalues that are within the refreshable paths introduced by #2393.Current
canonicalContribution()sorts fragment paths, then serializes each nestedfragment.valuedirectly:protectedContributionFingerprint()removes only the declared refreshable paths and then calls this same canonicalization. Because nested object keys are not recursively canonicalized, JSON key-order normalization changes the protected fingerprint even when protected values are identical.Version
2.33.0
Operating system
macOS 27.0, Apple Silicon
Provider and model
Not provider-specific
Logs or error output
$ ocx integration client status --client zcode --json { "clientId": "zcode", "state": "conflict", "installed": true, "configPath": "<HOME>/.zcode/v2/config.json", "reason": "foreign-edit", "appliedAt": "2026-08-27T12:09:59.043Z", "lastOpId": "18f13a13-96c4-49f8-96b5-10b91102e8be", "snapshotCount": 10, "retentionDegraded": false }Screenshots and supporting files
A full
diff -ubetweenocx export --client zcode --jsonand the on-diskprovider.opencodexshows repeated object-key reordering across provider and model entries. The semantic values of protected fields shown above remain unchanged.The same diff also shows expected ZCode-derived metadata additions, for example
reasoning,limit.output, and defaultlimit.context, which #2393 explicitly intended to tolerate.Redacted configuration
{ "provider": { "opencodex": { "name": "OpenCodex", "kind": "openai-compatible", "options": { "apiKey": "opencodex-loopback", "baseURL": "http://127.0.0.1:10100/v1", "apiKeyRequired": true }, "enabled": true, "source": "custom", "models": { "example/model": { "name": "example/model", "limit": { "context": 350000 }, "modalities": { "input": ["text"], "output": ["text"] } } } } } }Checks