Add atomic plugin marketplace retarget with rollback
What problem does this solve?
Changing an installed plugin marketplace from one Git repository/ref to another
currently requires a destructive multi-command sequence:
codex plugin remove <plugin>@<marketplace>
codex plugin marketplace remove <marketplace>
codex plugin marketplace add <new-repository> --ref <new-ref>
codex plugin add <plugin>@<marketplace>
There is no atomic boundary or automatic rollback. A failure after either
remove leaves the plugin unavailable; a failure after the marketplace add can
leave source, ref, snapshot, installed cache, and enabled state disagreeing.
Moving a temporary review ref to main after merge requires another manual
normalization pass.
This occurred in a public plugin rollout: the released 0.2.0 metadata looked
current while the active installation remained bound to a stale local/private
marketplace. The symptom and repair evidence are public in
<https://github.com/jim80net/memex-codex/issues/24>. A later canonical-repository
cutover required the same remove/add/reinstall sequence and a separate
branch-to-main normalization after
<https://github.com/jim80net/memex-codex/pull/25>.
Related but distinct: #21138 covers stale cache contents when a source changes
without a version bump, and #19834 covers identifying stale marketplace clones.
This request is for transactional source/ref replacement.
Proposed command
One possible shape:
codex plugin marketplace retarget <marketplace> <repository> \
--ref <ref> --reinstall <plugin> --json
The exact spelling is flexible. The required behavior is:
- preflight the new repository/ref and validate its marketplace manifest;
- stage the new snapshot and requested plugin cache without removing the live
installation;
- verify plugin identity/version and cache completeness;
- atomically swap marketplace source/ref/revision and installed/enabled state;
- roll back all staged/config changes on any failure;
- preserve unrelated plugin and hook-trust state;
- return old/new source, ref, revision, installed path/version, and rollback
disposition in --json output.
The old snapshot/cache should be removed only after the new state is committed.
Why not compose existing commands?
Shell composition cannot provide atomicity across Codex configuration,
marketplace snapshots, plugin caches, and enabled state. It also cannot reliably
restore the previous state if network, manifest validation, cache installation,
or process interruption fails between commands.