Cache plugin namespace during executor skill discovery - #29831
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 472b5ece5f
ℹ️ 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 |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. 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". |
Why
Executor skill discovery runs before the remote skills catalog is available. For a remote environment, each
ExecutorFileSystemoperation becomes an exec-server RPC.Previously, every discovered
SKILL.mdindependently resolved its plugin namespace by walking its ancestors and probing both supported manifest locations. In the commonplugin/skills/<skill>/SKILL.mdlayout, that repeats 8 RPCs per skill even though every skill under the plugin root uses the same namespace. These lookups happen while skills are parsed, so their cost grows linearly with the skill count and adds directly to first-turn latency.A selected capability root can also contain standalone skills, multiple sibling plugins, nested plugins, or symlinked directories. The optimization therefore needs to retain the nearest-ancestor namespace for each skill rather than assuming the selected root represents exactly one plugin.
What changed
SKILL.mdbefore reading manifestsNo additional directory traversal is required. Namespace work now scales with the number of plugin roots that contain discovered skills, rather than the total number of skills or unrelated sibling plugins. Standalone and nested-plugin names keep their previous behavior.
Benchmarks
I used a temporary counting
ExecutorFileSystemaround the real local filesystem. Each filesystem operation was counted as one remote RPC and given 1 ms of injected latency. Each variant ran three times; times below are medians.One plugin with 100 skills
get_metadataread_fileread_directoryThe namespace-specific work drops from 800 RPCs to 2 in this layout.
Multiple plugins under one selected root
These runs compare the correct pre-optimization implementation with the final nearest-plugin-root cache. The total plugin skill count stays at 100 while the number of plugin roots changes.
The remaining cost grows with the number of relevant plugin manifests. Each relevant manifest is read once instead of once per skill, while sibling plugins with no discovered skills are not read. Absolute latency savings depend on the executor's real RPC latency.
Tests
just test -p codex-core-skills(109 passed across the library and integration-test binaries)