JSON clients read the last of repeated object members, and parsing keeps
only that one, so the uninstall ownership rule could not see what removal
would reveal. #4957 therefore made the serializer refuse every repeated
deletion regardless of ownership. Three cases from #4952 still failed:
- Repeated REA-owned rea members could not be uninstalled (exit 1).
- The refusal came from the serializer while removing one client, after
preflight, so an earlier client in iteration order was already changed.
- OpenCode setup replaced a single V1 mcp.rea beside a native V2 table but
refused when that V1 member was repeated.
ClientConfigurationDocument now reports the earlier repeats of one name in
the table a client reads (shadowedClientServers), building a syntax tree
only when that name's JSON string token occurs more than once, so parsing,
setup and doctor keep their cost. The shared uninstall ownership decision
covers every repeat: it removes them all when REA owns each one and fails
in preflight, before any client or backup changes, when an earlier repeat
is not REA-owned. Serialization keeps refusing repeated deletions by
default and removes every repeat only with explicit caller authority,
granted by uninstall after that decision and by setup for its existing
OpenCode V1 replacement rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>