Atomic, content-addressed personal-plugin update transaction with exact rollback

Open
#36,540 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
18/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
rust
Domain
devtools

Research direction

Start with the Plugin Manager, its authoritative source/cache/config route, and MCP lifecycle described in the issue. Use the 12 acceptance tests as the completion criteria, including crash recovery, exact rollback, lock ownership, pre-commit isolation, and single terminal receipts.

Written by the indexing model from the issue text.

Description

app CLI enhancement mcp skills

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. PREPARED is not a terminal receipt. A read-back-verified COMMIT_DECIDED marker 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:

  1. Two different requests race for one plugin namespace.
  2. Crash after PREPARED but before COMMIT_DECIDED.
  3. Crash after COMMIT_DECIDED but before the internal switch.
  4. Crash after the internal switch but before final verification/receipt.
  5. Source-only, cache-only, or configuration-only partial switch.
  6. Exact rollback when source and cache predecessor bytes intentionally differ.
  7. Rollback failure with both candidate and predecessor routes disabled.
  8. Terminal-receipt fsync failure and recovery without action replay.
  9. Stale/mismatched lock ownership and attempted lock stealing.
  10. Candidate startup writes state, calls a native execution surface, or admits MCP traffic before commit.
  11. Caller injection of a path, command, shell, environment, or alternate marketplace.
  12. 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).

Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.