What's wrong
skills/plugins/context/converge.md Step 5 says claude plugin uninstall -s project
"can remove an enabledPlugins entry" from a project's committed .claude/settings.json.
That phrasing licenses a run to predict "no enabledPlugins key, therefore no write" and skip the
diff check. The prediction is wrong: the call always writes that file.
Hit live while running /claude-ops:plugins converge over 18 project-scope pins. The skill reported
the mutations as machine-local, then both affected checkouts turned out to have a dirty tracked
.claude/settings.json.
Verified behavior (Claude Code 2.1.228)
Single calls, against a clean tracked .claude/settings.json, git-diffed after every step:
| Call |
Writes committed settings? |
Effect |
install -s project |
yes |
adds the id to enabledPlugins (true) |
update -s project |
no |
the existing documented exemption still holds |
uninstall -s project |
yes |
removes the entry, leaves "enabledPlugins": {} |
Both writing calls rewrite the whole file in Claude Code's key order, so unrelated sibling keys move.
uninstall writes the enabledPlugins key even into a file that never had one, which is what
produces a diff that changes no behavior — an empty map plus a key reorder.
Also missing
- Project scope keys on the working directory, not the repository. Verified by uninstalling one
id in a repo's main checkout and watching its git worktree's record for the same id survive. Two
checkouts sharing one .git and one tracked .claude/settings.json pin independently.
converge.md Step 2 already mandates a per-projectPath cd, but justifies it as "a different
repo" — understating the worktree case.
sync.md write-timing uncertainty. The "Version capture" section notes the skill has not
established when the CLI writes installed_plugins.json relative to the "restart to apply"
message. One observation is now available and worth recording without retiring the fallback.
Expected
Step 5 should check every touched project unconditionally and classify the diff — inert (empty map
plus reorder) versus substantive (an entry actually removed) — because the two warrant opposite
advice. scope-semantics.md should carry install/uninstall as verified facts beside the update
exemption.
Notes
Upstream anthropics/claude-code#81058 reports a related but more destructive variant on 2.1.220
(the key deleted from user settings, disabling a surviving user-scope install). That did not
reproduce on 2.1.228 — the user-scope enabledPlugins entries survived the converge run intact.
What's wrong
skills/plugins/context/converge.mdStep 5 saysclaude plugin uninstall -s project"can remove an
enabledPluginsentry" from a project's committed.claude/settings.json.That phrasing licenses a run to predict "no
enabledPluginskey, therefore no write" and skip thediff check. The prediction is wrong: the call always writes that file.
Hit live while running
/claude-ops:plugins convergeover 18 project-scope pins. The skill reportedthe mutations as machine-local, then both affected checkouts turned out to have a dirty tracked
.claude/settings.json.Verified behavior (Claude Code 2.1.228)
Single calls, against a clean tracked
.claude/settings.json, git-diffed after every step:install -s projectenabledPlugins(true)update -s projectuninstall -s project"enabledPlugins": {}Both writing calls rewrite the whole file in Claude Code's key order, so unrelated sibling keys move.
uninstallwrites theenabledPluginskey even into a file that never had one, which is whatproduces a diff that changes no behavior — an empty map plus a key reorder.
Also missing
id in a repo's main checkout and watching its
git worktree's record for the same id survive. Twocheckouts sharing one
.gitand one tracked.claude/settings.jsonpin independently.converge.mdStep 2 already mandates a per-projectPathcd, but justifies it as "a differentrepo" — understating the worktree case.
sync.mdwrite-timing uncertainty. The "Version capture" section notes the skill has notestablished when the CLI writes
installed_plugins.jsonrelative to the "restart to apply"message. One observation is now available and worth recording without retiring the fallback.
Expected
Step 5 should check every touched project unconditionally and classify the diff — inert (empty map
plus reorder) versus substantive (an entry actually removed) — because the two warrant opposite
advice.
scope-semantics.mdshould carry install/uninstall as verified facts beside the updateexemption.
Notes
Upstream
anthropics/claude-code#81058reports a related but more destructive variant on 2.1.220(the key deleted from user settings, disabling a surviving user-scope install). That did not
reproduce on 2.1.228 — the user-scope
enabledPluginsentries survived the converge run intact.