Repository navigation
🤖 fix: drop remote plugin snapshots when project trust changes outside the app - #7640
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Perf clearance (perf owner, workspace 8e18f4aada): CLEARED at head What I checked:
Conditions:
Generated with |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 563069192a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
🟢 e2e stories (Haiku): 14 passed22 agent steps · 7 replayed from cache · 15 model calls · 46.3k tokens (28% cached) All 14 tests in 9 files
e2e 0.20.0 · 1m 16s · web · run artifacts 🟢 e2e Electron stories (Haiku): 3 passed3 agent steps · 3 model calls · 8.0k tokens (32% cached) All 3 tests in 3 files
e2e 0.20.0 · 23.0s · electron · run artifacts 🟢 e2e agent repros (Haiku): no tests selectedSpend: $0.00 of the $1.00 cap (proxy ledger) e2e 0.20.0 · 5.3s · 2 targets (web, phone) · run artifacts |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
Readiness record for
Generated with |
Summary
A project trust change made outside the app, by
xum trustor any other writer ofconfig.json, now drops the cached remote project plugin snapshots, asProjectService.setTrustalready does. Before this change, a revoke followed by a re-grant through the CLI could keep serving a snapshot from before the revoke until it was evicted or the backend restarted.Background
Follow-up from the final check of #7592. Only
setTrustcalledclearRemoteProjectPluginSnapshots. A trust change from another writer reaches the running backend only as aconfig.jsonchange. A revoke always failed closed, because each turn computes trust per call and then gets no plugin containers. This PR fixes freshness, not security.Implementation
ProjectService.watchProjectTrust()subscribes toConfig.onConfigChanged. On each change it builds the sorted set of effectively trusted project paths (isProjectTrustedIn, so a project inherits itsparentProjectPathowner's trust). When that set differs from the last one, it callsclearRemoteProjectPluginSnapshots(). A flip, a trusted project added and a trusted project removed all count. Edits that leave trust alone clear nothing.Config's file watch merges a revoke and a re-grant into one notification. Then the trusted set looks unchanged, and the snapshot of that same checkout stays. A read that ran between the two writes did see the revoke. It failed closed, because turns compute trust on every call. The only cost is freshness: the coalesced re-grant does not refresh the snapshot. Clearing on every config change would drop all remote snapshots on each config save, which is frequent.config.loadConfigOrDefault(). That is the config snapshot every config-change listener shares: one stat, plus one parse when the file changed. It runs no other I/O.ServiceContainerstarts the watch as a new best-effort core startup step,projectService.watchProjectTrust.ProjectService.beginShutdown()unsubscribes it, andServiceContainer.dispose()already calls that. The method never throws: it catches and logs both at start and in the handler. An own save's notification can pass a listener's throw to the saving caller, so the handler must not throw.config.jsondirectory watch open for the whole backend life.Configopens that watch only while it has a listener. In a full backend, other services already subscribe (ContextManagementService,MemoryService,AgentResourceLimitsService), so the watch is normally open already.remoteProjectPlugins.tsis unchanged. The hook sits inprojectService.ts, next to the existingsetTrustclear.Validation
projectService.test.ts: a trusted remote checkout's snapshot is read once. A secondConfiginstance on the same root then writesconfig.json, as the CLI does.Expected: 2, Received: 1).serviceContainer.test.ts: the list of core step names includes the new step.Out of scope
The same out-of-app trust change also skips
mcpServerManager.applyProjectTrust: #7639.Fixes #7621
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:high• Cost:$295.90