Add frozen cloud skill snapshots to the app server (#55631)

## What changed

- Add `--cloud-skills-snapshot PATH` to load a cloud skill catalog and resource contents from JSON once at app-server startup, without contacting a live skill service.
- Expose snapshot skills through the native `skills.list` and `skills.read` interface, preserving aliases and prompt visibility. Reads remain available after the snapshot file is removed.
- Validate package boundaries, required resources, duplicate packages, and size limits; fail startup for missing or invalid snapshots.
- Keep frozen cloud catalog and read caches independent of live MCP resource changes.

## Testing

Add provider, cache, app-server, and core scenario tests covering validation, exact resource contents, authority boundaries, startup failures, and listing and reading frozen skills alongside a named executor.

GitOrigin-RevId: d438a5d678121db3e17515fc5edcd00d4e20b900
This commit is contained in:
Francis Chalissery
2026-10-20 17:01:52 +00:00
committed by copyberry
parent 48b6a9d8e0
commit e776b27eb0
22 changed files with 785 additions and 3 deletions
@@ -249,6 +249,7 @@ impl ConnectionSessionState {
}
pub(crate) struct MessageProcessorArgs {
pub(crate) cloud_skill_provider: Option<Arc<dyn codex_skills_extension::SkillProvider>>,
pub(crate) outgoing: Arc<OutgoingMessageSender>,
pub(crate) analytics_events_client: AnalyticsEventsClient,
pub(crate) arg0_paths: Arg0DispatchPaths,
@@ -277,6 +278,7 @@ impl MessageProcessor {
/// `Sender` so handlers can enqueue messages to be written to stdout.
pub(crate) fn new(args: MessageProcessorArgs) -> Self {
let MessageProcessorArgs {
cloud_skill_provider,
outgoing,
analytics_events_client,
arg0_paths,
@@ -358,6 +360,7 @@ impl MessageProcessor {
goal_service: Arc::clone(&goal_service),
environment_manager: Arc::clone(&environment_manager_for_extensions),
executor_skill_provider: Arc::clone(&executor_skill_provider),
cloud_skill_provider: cloud_skill_provider.clone(),
git_attribution_base_url: config.chatgpt_base_url.clone(),
http_client_factory: config.http_client_factory(),
queue_service: queue_service.clone(),