Atomic, content-addressed personal-plugin update transaction with exact rollback
Codex variant
Codex App for Windows 26.727.6591.0 and Codex CLI 0.142.4.
Feature request
Please add a product-owned transaction API for updating a local/personal-marketplace plugin as one content-addressed operation. The transaction should atomically coordinate the authoritative source, installed cache, and plugin configuration; quiesce the old MCP server; verify the new server read-only; and restore the exact predecessor state on any pre-commit failure.
The current CLI exposes plugin add/list/remove and marketplace add/list/upgrade/remove, but no operation can atomically switch all three state domains or restore distinct source and cache preimages. Marketplace Refresh/reinstall is therefore not an equivalent primitive.
An illustrative closed operation is:
transact_content_addressed_plugin_install_once(request)
The name is not important; the ownership and semantics are.
Required semantics
- Accept only a content-addressed request that fixes the plugin namespace, predecessor preimages, candidate package, schemas, product build identity, maximum use count of one, and retry count of zero.
- Discover the complete installed configuration graph inside Plugin Manager; callers must not select filesystem, configuration, command, shell, or process paths.
- Acquire one durable per-plugin lock and monotonic epoch before assigning transaction identity, snapshotting, or quiescing. A competing request is rejected before transaction admission.
- Snapshot and fsync the exact source, cache, and product-discovered configuration preimages, including realpath, type/reparse, owner/ACL, length, and SHA-256.
- Quiesce the old MCP server using product-owned process identity, not PID-only termination.
- Stage the candidate in private, non-routable generations; rehash source/cache/config; start it read-only; and prove the expected sole MCP identity and zero target/native actions.
- Use a durable write-ahead state machine.
PREPAREDis not a terminal receipt. A read-back-verifiedCOMMIT_DECIDEDmarker is the irrevocable point. - Before
COMMIT_DECIDED, failure deterministically restores the exact predecessor source, cache, and configuration. After it, rollback is forbidden: recovery must finish the exact candidate commit or leave the route disabled in a closed recovery/quarantine state. - Admit public MCP calls only after exact post-switch verification and one immutable terminal receipt are durable.
- Keep pending recovery states at terminal-receipt count zero; each terminal state has exactly one state-specific receipt. A second terminal receipt for the same request/epoch is rejected.
- If ownership is stale or ambiguous, admit no transaction, disable the route, forbid lock stealing/TTL takeover, and require a separately reviewed product repair path.
Acceptance tests
At minimum, please cover:
- Two different requests race for one plugin namespace.
- Crash after
PREPAREDbut beforeCOMMIT_DECIDED. - Crash after
COMMIT_DECIDEDbut before the internal switch. - Crash after the internal switch but before final verification/receipt.
- Source-only, cache-only, or configuration-only partial switch.
- Exact rollback when source and cache predecessor bytes intentionally differ.
- Rollback failure with both candidate and predecessor routes disabled.
- Terminal-receipt fsync failure and recovery without action replay.
- Stale/mismatched lock ownership and attempted lock stealing.
- Candidate startup writes state, calls a native execution surface, or admits MCP traffic before commit.
- Caller injection of a path, command, shell, environment, or alternate marketplace.
- Second use or second terminal-receipt attempt.
Why this belongs in Plugin Manager
Implementing this with remove+add, source-tree copying, a second marketplace, a sidecar installer, or plugin self-update splits lifecycle authority and cannot atomically restore the product's configuration and cache state. Plugin Manager is the only component that owns the source/cache/config route and MCP lifecycle together.
Related reports
- #21138 documents stale source/cache provenance when plugin contents change.
- #22114 documents Windows active-cache corruption during forced refresh and recommends staged atomic switching.
I can provide a machine-readable request contract and negative-state matrix if maintainers want it. Public contract identity: 21135/b349155c647c44b8e04d502728fa7fbf39c3d7379fbbb3fd8d1e0e26110ffc24 (the hash identifies the specification only; no private source or executable artifact is attached).
1 Comment
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action