[codex-core-plugins] Remote Plugin ID Persisted to File#27669
Merged
Conversation
alexsong-oai
approved these changes
Jun 15, 2026
jameswt-oai
added a commit
that referenced
this pull request
Jun 22, 2026
This PR moves construction of `PluginTelemetryMetadata` from loader and
model helpers into `PluginsManager`, which already owns installed plugin
state and will eventually perform remote identity enrichment. The
metadata type remains in `codex-plugin`, and serialized analytics events
remain unchanged.
## Before
```mermaid
flowchart LR
subgraph Events["Analytics event paths"]
direction TB
Lifecycle["Local install / uninstall"]
Config["Enable / disable"]
Remote["Remote install"]
Used["Plugin used"]
end
subgraph Construction["Metadata construction"]
direction TB
Loader["Loader telemetry helpers"]
Summary["PluginCapabilitySummary::telemetry_metadata"]
Override["Caller adds remote_plugin_id"]
end
Metadata["PluginTelemetryMetadata"]
Lifecycle --> Loader
Config --> Loader
Remote --> Loader
Loader -->|"local events"| Metadata
Loader -->|"remote install"| Override
Override --> Metadata
Used --> Summary
Summary --> Metadata
```
Telemetry metadata was constructed through loader helpers, a
capability-summary method, and a remote-install call-site override.
## After
```mermaid
flowchart LR
subgraph Events["Analytics event paths"]
direction TB
Lifecycle["Local install / uninstall"]
Config["Enable / disable"]
Remote["Remote install"]
Used["Plugin used"]
end
Manager["PluginsManager — single construction owner"]
Metadata["PluginTelemetryMetadata"]
Lifecycle --> Manager
Config --> Manager
Remote -->|"authoritative remote ID"| Manager
Used -->|"capability summary"| Manager
Manager --> Metadata
```
Every analytics path delegates metadata construction to
`PluginsManager`. Remote install still supplies its authoritative
backend ID explicitly.
## What Changes
- Make loader code return a focused plugin capability summary instead of
constructing analytics metadata.
- Centralize immutable plugin telemetry metadata construction in
`PluginsManager`.
- Route local install/uninstall, remote install, enable/disable, and
plugin-used emitters through the manager.
- Preserve the current serialized analytics contract exactly.
Normal metadata still has no remote override. Remote install continues
to provide its authoritative backend ID explicitly, so the existing
serializer continues reporting that ID through `plugin_id`.
Snapshot-based enrichment is intentionally deferred to the final PR.
## Testing
- `just test -p codex-core-plugins` (238 tests passed)
- `just test -p codex-plugin` (3 tests passed)
- Scoped Clippy/compile checks passed for `codex-plugin`,
`codex-core-plugins`, `codex-app-server`, and `codex-core`.
## Split Overview
```text
main
├── #27093 Debug analytics capture (merged)
├── #27099 Non-mutating plugin smoke (merged)
├── #27100 Remote install/uninstall smoke (merged)
└── #27102 Plugin telemetry metadata refactor ← you are here
└── #27669 Persist remote plugin identity
After #27102 and #27669 merge:
└── Final PR: add explicit local and remote IDs to plugin analytics
```
Review order and dependencies:
1. [#27093 Add debug-only analytics event
capture](#27093) (merged)
2. [#27099 Add a plugin analytics smoke
workflow](#27099) (merged)
3. [#27100 Add a remote plugin analytics mutation smoke
workflow](#27100) (merged)
4. This metadata refactor, independent and based on `main`
5. [#27669 Persist remote plugin
identity](#27669), stacked on this
PR
6. Final remote-ID behavior PR, created after the prerequisites merge
The original [#26281](#26281)
remains open as the aggregate reference until the final replacement PR
is published.
Base automatically changed from
jameswt/plugin-telemetry-metadata-refactor
to
main
June 22, 2026 17:27
ce0b03e to
bcc3551
Compare
bcc3551 to
14a18bd
Compare
Contributor
Author
|
/merge |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR
Remote plugin analytics cannot rely only on the in-memory installed-plugin snapshot because that snapshot is refreshed asynchronously after startup. This PR persists the authoritative backend identity alongside each cached remote plugin bundle so later consumers can resolve it without a network request.
Behavior
Store Codex-owned remote installation metadata in an atomic
.codex-remote-plugin-install.jsonsidecar under the plugin cache root.Use a versioned, snake_case schema:
{ "schema_version": 1, "remote_plugin_id": "plugins~Plugin_..." }Write the metadata during remote bundle installation.
Backfill it when bundle sync finds an already-current cached bundle.
Clear it when a generic/local install replaces the cache.
Let existing uninstall and stale-cache removal delete it with the plugin cache root.
Reject unsupported schema versions rather than silently misreading future formats.
This PR does not change analytics serialization or event behavior.
Review surface
The implementation is limited to four
codex-core-pluginsfiles:store.rs: owns the versioned sidecar read/write/remove lifecycle.remote_bundle.rs: persists the backend ID after a remote bundle install.remote/remote_installed_plugin_sync.rs: backfills metadata for an already-current cached bundle.Testing / Validation
Automated
just test -p codex-core-plugins(268 tests passed)just fix -p codex-core-pluginspasses with one pre-existinglarge_enum_variantwarning inmanifest.rs.Live manual validation
Validated the production app-server RPC path with an isolated temporary
CODEX_HOMEand the PR-built Codex binary. The app-server communicated over stdio and did not bind a port.Test plugin:
plugins~Plugin_b80dd84519148191a409cde181c9b3d6(build-macos-apps@openai-curated-remote).Confirmed
plugin/readinitially reported the plugin uninstalled.Installed it through
plugin/installand confirmed version0.1.4was cached.Verified
$CODEX_HOME/plugins/cache/openai-curated-remote/build-macos-apps/.codex-remote-plugin-install.jsonwas created beside the0.1.4/bundle directory with mode0600and the expected contents:{ "schema_version": 1, "remote_plugin_id": "plugins~Plugin_b80dd84519148191a409cde181c9b3d6" }Deleted only the sidecar, restarted the app-server, and confirmed installed-plugin startup sync recreated it with the same contents.
Uninstalled through
plugin/uninstall, confirmedplugin/readreturnedinstalled: false, and verified the local plugin cache root was removed.Restored the account's original uninstalled state and removed the isolated home and copied credentials.
Split Overview
This PR is based directly on
main; prerequisite #27102 has merged. The original combined #26281 remains the aggregate reference until the final replacement PR is published.