## What changed
- Allocate 2% of the resolved model context window to skill metadata without
imposing the previous 4,000-token ceiling.
- Keep the 8,000-character fallback when no context window is available.
- Extend catalog rendering coverage to verify that a 400,000-token context
window receives an 8,000-token metadata budget and includes more skills.
GitOrigin-RevId: 5120d462de22fbfe5f9c4ab0d1bb97e51950d4b2
## Why
Rendering host and executor skill catalogs independently allows their combined
metadata to exceed the skills context budget.
## What changed
- Allocate one budget across both catalogs when both contain model-visible
skills.
- Prefer retaining executor skills when budget pressure requires omissions,
while preserving an executor omission marker and reporting when all host
skills were omitted.
- Evaluate absolute and aliased host paths under the shared budget and select
the rendering that best preserves executor entries, total entries, and
descriptions, in that order.
## Testing
Added renderer and production-turn coverage for shared-budget description
shortening, host-first omission, executor omission markers, and alias selection.
GitOrigin-RevId: 30041736a76aa173cb641aa98a876a306cb437d2
## Why
Host skill catalogs supplied through extension world state should report budget warnings only when their catalog update is actually rendered.
## What changed
- Stop rebuilding an extension-owned host catalog in core.
- Emit host catalog budget warnings when the corresponding world-state fragment is rendered, and deduplicate them with executor catalog warnings.
- Cover full, shortened, and omitted host and executor catalogs, including repeated turns and resumed persisted snapshots.
GitOrigin-RevId: ba28b6e337281b49ed4da2175c193fd4a6898ab7
## What changed
- Add a character n-gram shadow selector that combines skill descriptions with host interface metadata and tool dependency names and descriptions.
- Bound routing fields, dependency records, and candidate counts before ranking.
- Exclude explicitly selected skills from shadow candidates and only record invocations for skills eligible for the experiment.
## Testing
- Add unit coverage for host interface metadata, connector dependencies, baseline description matches, and long routing metadata.
GitOrigin-RevId: 36ef0cb4a68601f2d9d41c3344c88f7927c32bf4
## Why
Empty rendered skill catalogs skipped catalog telemetry instead of reporting
zero-valued counts.
## What changed
- Record a default render report when thread, turn-input, or executor catalog
rendering produces no fragment.
- Record zero-valued host world-state metrics when skill instructions are
enabled but no host skills are available.
- Preserve the `catalog_surface` tag so empty host and executor catalogs remain
distinguishable.
## Testing
Add coverage for empty catalog rendering and mixed nonempty-executor,
empty-host world state.
GitOrigin-RevId: f68d65806703c0ded1ece1e5ae1ffaf6d6045126
## What changed
- Add an optional `ExtensionMetrics` capability to thread, turn-input, and world-state contributors, backed by session telemetry in the host.
- Record skill counts, omissions, and truncated description characters for extension-rendered catalogs, tagged by the catalog surface.
- Preserve host session attribution on extension metrics, including the effective model for each turn, and prevent extension tags from overriding host metadata.
- Avoid duplicate host-catalog samples by recording world-state metrics only when the section is published or changes.
## Testing
- Cover metric values and surface tags, session metadata preservation, turn-level model changes, and host world-state publication behavior.
GitOrigin-RevId: 9059e521943a8f81df25a38b03692eddbc1d990d
## What changed
- Carry a plugin's local and remote identities together from plugin loading into
`SkillMetadata`.
- Resolve remote IDs from the installed-plugin snapshot when available, falling
back to persisted install metadata only when no snapshot exists.
- Include plugin identity in skill cache keys so identity changes refresh cached
skill metadata.
## Testing
- Cover snapshot and persisted identity resolution, local marketplace isolation,
cached skill refreshes, and propagation through plugin skill snapshots.
GitOrigin-RevId: aabeeb631a43361fe817358ace7f1ea8ba5db708
## Why
Executor skills that disallow implicit invocation are omitted from `skills.list`, so an explicitly selected skill did not provide the authority and package identifiers needed to read its referenced resources.
## What changed
- Add `resource_access` metadata to injected instructions for explicit-only executor skills.
- Teach the `skills.read` description to accept that metadata as well as values returned by `skills.list`.
- Keep discoverable executor skill instructions unchanged.
## Testing
Add an app-server integration scenario that selects an explicit-only executor skill, confirms it remains absent from `skills.list`, and reads a referenced file through `skills.read`.
GitOrigin-RevId: 97d3b93d1618c013363788452303c8a31e32cc56
## What changed
- Add executor authority support to `skills.list` and `skills.read` for skills from selected capability roots.
- Allow `skills.read` to load package-relative resources referenced by an executor skill while keeping reads within the selected package.
- Paginate skill listings and resource contents with bounded response sizes and stale-cursor validation.
- Resolve executor filesystems per sampling step so skill tools use the active selected capability roots.
## Testing
- Extend the app-server executor skill test to list an executor skill, read its main `SKILL.md`, and read a paginated reference resource.
- Cover visibility filtering, metadata bounds, pagination, invalid cursors, package boundaries, and resource size limits.
GitOrigin-RevId: 1b5de95d5d1b9f79c34d2879d6e67f24401e9c29
## Why
Repeated absolute path prefixes consume the bounded skill catalog and can leave
less room for descriptions or later skills.
## What changed
- Track the discovery root for host skills and render shared roots as `r0`,
`r1`, and similar aliases when doing so improves the bounded catalog.
- Include a skill-roots table and alias-aware usage instructions whenever
compact paths are selected.
- Keep absolute, authority-aware locators when aliases provide no benefit or
the catalog contains non-host skills.
## Testing
Added unit and extension coverage for unpressured catalogs, constrained shared
paths, mixed-source catalogs, and plugin-cache root selection.
GitOrigin-RevId: 4196df2c52be27338796065cb2e6434efcfac6d5
## Why
Extension warnings need a stable thread target even when they are emitted outside an active turn.
## What changed
- Add `ExtensionWarning` and a dedicated `ExtensionEventSink::emit_warning` path with an explicit thread ID and optional turn ID.
- Deliver extension warnings as thread-scoped app-server `warning` notifications, preserving listener ordering and waiting briefly for a subscriber when no listener is active.
- Move skills warnings to the new path, limiting provider catalog warnings to four messages of 256 bytes each.
## Testing
- Cover warning routing, ordering, UTF-8-safe truncation, subscriber fallback, and invalid thread IDs.
- Verify skills warning bounds and app-server delivery of executor catalog budget warnings.
GitOrigin-RevId: 4dcb1ba7f17c0edb1a9d548f9568e0c734bffc15
## What changed
- Recognize root `plugin.json` files using the Agent Plugins 1.0 schema and map their portable metadata, `skills/`, and `mcp.json` into Codex plugin manifests.
- Apply Codex-specific apps, hooks, and interface settings from the inline `com.openai` extension, with `.codex-plugin/plugin.json` as a fallback overlay.
- Preserve legacy manifest precedence when a root `plugin.json` is unrelated, and reject unsupported Agent Plugins schema versions.
- Add a direct-child skill discovery mode that excludes nested skills and paths resolving outside the plugin root.
## Testing
- Cover manifest metadata, validation, extension precedence, legacy fallback, and direct-child skill path boundaries.
GitOrigin-RevId: eab24139f13a5cc5cb3ad3fb444d8e904511aca6
## Why
Skill catalog rendering can shorten descriptions or omit enabled skills to fit
the model context budget. Surface these reductions so users know when the
model-visible catalog has lost detail.
## What changed
- Emit a warning with the omitted skill count whenever entries do not fit.
- Warn when description shortening averages more than 100 characters per skill.
- Deduplicate executor catalog warnings across repeated world-state builds in a
turn.
## Testing
- Cover the description-shortening threshold and omission warning text.
- Verify warnings through extension and production-turn catalogs, including
per-turn deduplication.
GitOrigin-RevId: bd7fc3482e5dfd8c79072f772a2f54aa502478d9
## What changed
- Make `McpRuntime` own the published MCP configuration, connections, elicitation routing, and selected capability roots for a thread.
- Capture immutable MCP bindings for model steps and tool calls so in-flight work keeps a consistent connection set and approval authority while refreshed state is published atomically.
- Mark MCP state dirty when relevant configuration, plugins, environments, authentication, or elicitation capabilities change, then rebuild it before the next sampling request or out-of-band MCP operation.
- Separate config reloads from server invalidation: `ReloadMcpConfig` applies resolved MCP inputs, while `RefreshMcpServers` requests reinitialization from the thread's latest state.
## Testing
- Cover refreshed state visibility for existing turns, stable step bindings, current approval authority, cancelled refresh retries, resource-client reconciliation, and Apps recovery between sampling requests.
GitOrigin-RevId: 59eabb1aa8dc083426bd18ef4d3630508f376401
## Why
Core-compatible skill catalog output should match the core renderer when the
metadata budget omits entries.
## What changed
- Emit the bounded-catalog omission notice only for `ExtensionCompatible`
rendering.
- Continue tracking omitted entries in `SkillRenderReport` for both policies,
even when `CoreCompatible` produces no fragment because every entry is
omitted.
## Testing
Cover policy-specific omission notices and the case where no minimum skill line
fits within the metadata budget.
GitOrigin-RevId: 79883c15a49c02ff83444ddc272030cb4ddb53c0
## What changed
- Return a `SkillRenderReport` with total, included, and omitted skill counts,
plus truncated description counts and character totals.
- Keep fragment construction separate from rendering so callers can inspect the
report even when the metadata budget is too small to emit a fragment.
## Testing
- Cover partial description truncation, fully omitted entries, and catalogs
whose omission marker does not fit the budget.
GitOrigin-RevId: e73fdbcf77ac73c7209100ff6c9b5862b6a59a54
## Why
Core-compatible catalog rendering needs to preserve the core renderer's skill
priority, including when metadata budgets omit lower-priority entries.
## What changed
- Carry each host skill's `SkillScope` into its catalog entry.
- Under `CoreCompatible`, order visible skills by system, admin, repo, and user
scope, then by name and prompt resource ID.
- Preserve insertion order under `ExtensionCompatible`.
## Testing
Add coverage for propagating host skill scope and for both rendering policies.
GitOrigin-RevId: 9594a177edb2166abf1b5719c51a46fcee000600
## What changed
- Initialize the thread lifecycle input without an MCP resource client.
- Call `contribute_thread_context` without the removed step-scoped data argument.
GitOrigin-RevId: 689a982ba49c2788dde6bc2cbe0d6d7cae6c0a73
## What changed
When even the minimum skill catalog exceeds its metadata budget, render each
included entry without its description. This allows more skill names and
locators to fit before the remaining entries are omitted.
## Testing
Add coverage for extreme budget pressure and verify both the extension and
production-turn catalogs omit descriptions while staying within budget.
GitOrigin-RevId: 72cec10e9587beabbd3d8c6d53b931deb76824e6
## What changed
- Remove the step-scoped `ExtensionData` argument from context, turn-input, and tool contributors.
- Pass the host's optional `McpResourceClient` through `ThreadStartInput` so extensions can retain session capabilities explicitly.
- Keep the MCP resource client in skills-owned session state for catalog loading and skill tools.
GitOrigin-RevId: bafa77bcd998aff408d6a396c5fd9ac268c4cce4
## Why
Long skill descriptions can consume the catalog's metadata budget before later
skills are listed, hiding otherwise usable skills from the model.
## What changed
- Reserve space for every skill's name and locator when those minimum lines fit.
- Distribute the remaining token or character budget across descriptions in
round-robin order.
- Fall back to omitting entries only when the minimum catalog cannot fit.
## Testing
Added extension and production-turn coverage that verifies moderate budget
pressure keeps every catalog entry, shortens descriptions evenly, and avoids an
omission marker.
GitOrigin-RevId: 41971e4b47a86863b3839707b5cffcd8d83b888c
## Why
A fixed character limit does not account for the different context-window sizes supported by models.
## What changed
- Budget extension-rendered skill metadata at 2% of the resolved model context window, capped at 4,000 tokens.
- Keep the existing 8,000-character fallback when model context metadata is unavailable.
- Include the omission marker in the budget and still emit it when no skill entry fits.
- Apply the same resolved budget to executor and host skill catalogs assembled for a turn.
## Testing
- Cover proportional and capped budgets, multibyte fallback accounting, and omission-marker behavior.
- Verify through the production turn path that larger model context windows include more catalog entries without exceeding the computed budget.
GitOrigin-RevId: 4667293f1594de4dd605b32b9fa4255d26772c0f
## What changed
- Parameterize skill catalog rendering with explicit core- and extension-compatible description policies.
- Use full skill descriptions for core-compatible output, while extension-compatible output prefers `short_description` and falls back to the full description.
- Keep extension prompt and world-state rendering on the extension-compatible policy.
## Testing
- Add a renderer test covering description selection and fallback for both policies.
GitOrigin-RevId: 5382075f88c25a49a715feb0702a9ab888ec0123
## What changed
- Add a bounded `routing_card_exact_v1` selector that ranks normalized exact
matches across skill names, tool dependencies, short descriptions, and full
descriptions, with stronger weights for routing-specific fields.
- Run the selector in the shadow selection experiment and include catalog entry
dependencies in selection documents.
- Report a selection as `selected` when an exact-name match succeeds even if
the query contains no searchable terms.
## Testing
- Cover dependency ranking, stop-word skill names, exact-term matching, and
input bounds.
GitOrigin-RevId: dfb0b668d726f64ae5da3b3ce2d8c9b23a664ac0
## What changed
- Add a skill selector that uses reciprocal rank fusion to combine the top 50 results from the weighted lexical and character n-gram selectors.
- Prefer candidates supported by both rankings, with deterministic rank and identifier tie-breakers, and propagate truncation metadata from both selectors.
- Include the fused selector in the shadow-selection experiment under `rrf_lexical_char_v1`.
## Testing
- Add unit coverage for cross-ranking support, deterministic tie-breaking, and combined input-bound reporting.
GitOrigin-RevId: 3165136b8729ea3a9484f25c7f2ce0f91fb8aaa9
## What changed
- Add an `ExtensionData` store to each `StepContext`.
- Pass the step store to context, world-state, turn-input, and tool contributors so extensions can use capabilities bound to the current sampling step.
- Preserve the captured step context when rebuilding initial context during compaction.
GitOrigin-RevId: 51f3105d3a793f60534f122f9be8247c131c2ca5
## What changed
- Define and export skill metadata, policy, dependency, interface, and configuration rule types from `codex-skills`.
- Update core, plugin, and extension consumers to use the shared models while retaining compatibility re-exports from `codex-core-skills`.
- Share product-restriction handling between host and environment skill metadata.
## Testing
- Add unit coverage for default and explicit implicit-invocation and product policies.
GitOrigin-RevId: 9093469f8fff8e2d902dc9781235f64709827a87
## What changed
- Add remote and local audio variants to core and app-server user inputs, including generated JSON and TypeScript schemas.
- Preserve audio fields when converting app-server inputs and response content into thread items.
- Keep unsupported audio out of model requests, TUI rendering, text extraction, and truncated tool output, using explicit text placeholders where audio is submitted as a model input.
## Testing
- Cover app-server media conversion, unsupported-input placeholders, TUI omission, and tool-output truncation.
GitOrigin-RevId: 16152bf3af674575ce569764a8b472e032e7569d
## Why
Selected capability roots can contribute plugins, MCP servers, connectors, and
skills. Discovering each contribution separately requires repeated access to the
executor filesystem.
## What changed
- Add the `capabilityRoots/discoverV1` exec-server RPC to scan selected roots and
materialize recognized plugin manifests, configuration files, skill
instructions, and skill metadata in one bounded request.
- Add the opt-in `executor_capability_discovery` feature, with a thread-scoped
cache and per-step snapshot shared by MCP and skill discovery.
- Parse MCP, connector, and skill contributions from the materialized snapshot,
including serving cached skill instructions without another filesystem read.
## Testing
- Cover discovery limits, manifest precedence, root-local failures, cache reuse,
plugin contributions, and parity with the existing environment skill loader.
GitOrigin-RevId: f98fd2321cafb58c596db02da1f83c09d8eb375d
## What changed
- Add a lexical selector that splits compound queries into sentence and connector-delimited views.
- Merge candidates across the full query and its component views, prioritizing their best rank while using full-query rank, view coverage, and stable identifiers as tie-breakers.
- Bound query decomposition and result counts, propagate truncation signals, and include the selector in the shadow-selection experiment.
## Testing
- Add unit coverage for compound-query ranking, single-query compatibility, query splitting, and bounded-input signals.
GitOrigin-RevId: 2442bf7198fc24295cbc270b9d222275ae8a7cc3
## What changed
- Add a character n-gram selector that scores matches across skill names, short descriptions, and descriptions using field weights and inverse document frequency.
- Include the selector in the shadow selection experiment alongside the existing lexical selectors.
- Bound query, document, candidate, and result processing, and report query or candidate truncation through the existing selection metadata.
## Testing
Add unit coverage for related word forms, typos, CJK text without word boundaries, and bounded inputs.
GitOrigin-RevId: 4df60cc661338050eeb7741c716bc1c9f730fedd
## What changed
- Add a bounded BM25 selector that ranks skills across name, short-description,
and description fields, weighting names most heavily and rare terms more highly.
- Run the selector alongside the weighted lexical method in the shadow-selection
experiment, with deterministic tie-breaking and existing per-method metrics.
- Add unit coverage for field weighting, rare-term ranking, unmatched queries,
and input limits.
- Remove the implicit-invocation integration test and its telemetry development
dependency.
GitOrigin-RevId: e5ac6a1f0d6a1f68b194467ef7da48adf4a88d7c
## Why
Host skills can change after a thread starts. Subsequent turns need the updated
catalog without reinjecting an unchanged catalog on every turn.
## What changed
- Register the host skill provider in app-server and project its catalog through
a dedicated World State section.
- Render host skills with the existing metadata budget and usage instructions,
including skill-root aliases when available.
- Suppress the legacy host catalog and contextual fragment when World State owns
the catalog, while preserving host skills for explicit and shadow selection.
## Testing
Added an app-server test that installs a host skill at runtime and verifies the
catalog updates once and remains stable on the following turn.
GitOrigin-RevId: 4cacc6b2258fc3cab8499fbdf9aa6ab0324ec10d
## What changed
- Scan up to eight skill roots concurrently instead of loading them one at a time.
- Share scan capacity across host-skill and plugin-skill loads to bound aggregate filesystem work.
- Merge completed scans in input order so root precedence and error ordering remain deterministic.
- Skip canonicalization and parsing work for empty roots.
## Testing
- Add coverage for out-of-order scan completion and shared-capacity blocking.
GitOrigin-RevId: 33a47aaa02aee7fe31a050bb04d51c1e2043d6ae
## Why
Multi-environment turns can run against different filesystems, so a single
thread-wide workspace-root list cannot accurately describe every selected
environment.
## What changed
- Add optional `runtimeWorkspaceRoots` to each app-server environment selection.
Omitted roots default to that environment's `cwd`, while an empty list selects
no roots.
- Carry environment-native roots through turn selection, model-visible context,
permission materialization, and tool sandboxing.
- Keep the top-level `runtimeWorkspaceRoots` field as a compatibility input when
constructing default environment selections; explicit selections use their
own roots.
## Testing
- Cover thread and turn API defaults, overrides, empty roots, and schema
round-tripping.
- Verify foreign roots remain model-visible and remote execution applies the
target environment's roots before sandbox selection.
GitOrigin-RevId: c6e7a62883c45c676c153055f46a55ee15a323a4
## What changed
Remove the image generation instruction that prohibited any response after an
image was generated.
GitOrigin-RevId: c779055da3142ba84cdbb9312e5f66b132f24b29
## What changed
- Add optional serialized Codex turn metadata to extension tool calls.
- Populate it from the current turn context and send it as the
`x-codex-turn-metadata` header on standalone web search requests.
## Testing
- Extend the app-server web search integration test to verify that client
metadata, including the model ID, reaches the standalone search request.
GitOrigin-RevId: c0950108d89a1d317ac94ccd23efcee72fffc6f0
## Why
Shadow selection can observe invocations from host and orchestrator skills, but
including executor skills in its candidates can skew the resulting metrics.
## What changed
Limit eligible shadow-selection candidates to enabled, prompt-visible skills
from host or orchestrator sources.
## Testing
Extend the implicit-invocation test to add matching executor candidates and
verify that the host skill remains the selected invocation hit.
GitOrigin-RevId: fd444fe27254b5a880ef5c03c29b5e195127cd97
## What changed
- Add an opt-in `skill_search` feature that ranks prompt-visible skills against each turn's user input with a bounded weighted lexical selector.
- Keep the ranked selection out of model-visible context and record metrics for selection cost, catalog reduction, and whether later implicit or `skills.read` invocations matched the ranked candidates.
- Include host-provided skills in the experiment catalog without changing the rendered skill catalog.
## Testing
- Add selector unit tests covering ranking, limits, truncation, stop words, and deterministic tie-breaking.
- Add extension tests covering turn-local invocation recording and host-skill shadow selection.
GitOrigin-RevId: 4d00a1c805ea8b391d6c6ac6a8450afa88ca3e25
## Why
Make it easier to measure the performance of different parts of skill
loading.
## What
- Add spans for step-context capture, world-state construction, executor
catalog snapshot/root loading, and environment skill loading.
- Record the discovered environment skill count.
- Trace outbound exec-server requests with client kind and RPC method
fields.
- Update trace propagation tests to assert that requests keep the parent
trace id while creating their own child span.
## Summary
- add a false-by-default `include_skills_usage_instructions` model
metadata field
- enable the field for the bundled `gpt-5.5` model metadata
- consume the metadata in both core and extension skill rendering
- remove hardcoded legacy-model matching and its marker plumbing
## Why
World State restores its structured snapshot on resume so unchanged
sections do not have to be rendered again. That is safe only when the
model-visible fragment represented by the snapshot is still present in
retained history.
For selected executor skills, the failing selected-capability scenario
exposed this state:
```text
persisted World State: selected skill catalog is known
retained model history: selected skill catalog message is missing
next diff: unchanged, so emit nothing
```
The model resumes without being told about the selected skill catalog.
## What changed
World State contributions may now optionally describe the concrete
model-visible fragment that must remain in retained history.
When a persisted snapshot is present:
```text
matching retained fragment exists -> trust snapshot, emit nothing
matching retained fragment missing -> treat section as absent, render current state once
```
The skills extension uses this for non-empty selected-environment
catalogs by matching its exact rendered catalog body. Empty or hidden
catalogs do not require a fragment.
## Scope
This does not clear or rebuild the whole World State baseline. It does
not change skill discovery, cache invalidation, environment
availability, or MCP runtime behavior. It only keeps a persisted section
snapshot and its retained model context consistent across resume/history
reconstruction.
## Coverage
A focused World State regression test verifies both sides:
- a missing retained fragment is rendered again
- a matching retained fragment avoids duplicate injection
## Why
A selected executor environment can be unavailable in one model step and
ready in the next. The model should see its skills only while that
environment is ready, without rescanning stable files on every sample.
The product assumption is simple:
- an environment ID names one stable logical environment;
- the selected root contents do not change during the thread.
## Behavior
```text
E1 unavailable -> do not show E1 skills
E1 ready -> discover once, cache, show through World State
E1 unavailable -> hide skills, keep cache
E1 ready again -> reuse cache, show skills again
resume -> create a new thread cache and discover again
```
The cache key is the full `SelectedCapabilityRoot`. Availability does
not invalidate it; dropping the extension's thread state does.
The step supplies the ready selected roots directly. They do not have to
be turn environments:
```text
turn environment: laptop
selected root: worker:/plugins/lint-fix
worker ready -> lint-fix skills are visible
```
## What changes
- Keeps executor skill catalogs in the existing skills extension.
- Passes the roots resolved as ready for the step into World State
contributors.
- Loads each ready selected root at most once per thread.
- Contributes the executor catalog as the `skills` World State section.
- Uses the exact step catalog for explicit skill selection and body
reads.
- Leaves host and orchestrator skill behavior where it already lives.
Taking a step snapshot itself does not add an RPC. Executor filesystem
calls happen only on the first discovery of a stable root for that
thread.
## What does not change
- No filesystem watcher or content-based invalidation.
- No retry/generation framework.
- No skill runtime migration into core.
- No general rewrite of the skills extension.
## Stack
1. Extension-owned World State sections.
2. **This PR:** project cached executor skills through World State.
3. Pin one MCP runtime to each model step.
4. Project selected MCP/app/connector metadata by environment
availability.
5. One end-to-end integration scenario.
## Why
After #28918, selected skill roots are `PathUri`, but the executor skill
provider still converts them to the app-server host's `AbsolutePathBuf`.
A foreign Windows root therefore cannot be discovered by a Unix host,
and the inverse has the same problem.
This PR keeps executor skill discovery and reads on the filesystem that
owns the selected root while reusing the existing skill rules.
## What changed
- Generalize the existing skill traversal to operate on `PathUri`
through `ExecutorFileSystem`, preserving its depth, directory, symlink,
and sibling-metadata concurrency behavior.
- Add a small environment skill loader that reuses the shared discovery,
frontmatter validation, dependency parsing, product policy, and
prompt-visibility rules.
- Keep the environment id and entrypoint `PathUri` in the skill catalog,
then route `skills.read` back through the same environment filesystem.
- Preserve the executor's path convention when deriving catalog handles,
including literal backslashes in POSIX filenames.
- Resolve plugin namespaces from nearby manifests through URI-native
filesystem reads.
- Cover foreign Windows roots, executor-owned reads, namespaces,
metadata, policy, and path identity.
```text
selected root (PathUri)
|
v
shared discovery over ExecutorFileSystem
|
v
environment-bound catalog entry --skills.read--> same ExecutorFileSystem
```
No second filesystem abstraction or duplicate traversal implementation
is introduced.
## Stack
1. #29614 — add lexical `PathUri` containment.
2. #29620 — share URI-native manifest path resolution.
3. #28918 — keep selected plugin roots and resources URI-native.
4. **This PR** — load executor skills without host path conversion.
5. #29628 — resolve executor MCP working directories without host path
conversion.
## Why
Selected capability roots belong to the executor filesystem, not the
app-server host. Converting their path strings into the host's native
`Path` breaks whenever the two machines use different path conventions,
such as a Windows executor behind a Unix app-server.
This PR establishes `PathUri` as the selected-plugin boundary so the
executor remains authoritative for its paths.
## What changed
- Require `selectedCapabilityRoots[].location.path` to be a canonical
`file:` URI and deserialize it directly as `PathUri`; native path
strings are rejected.
- Update the app-server schema, generated TypeScript, examples, and
request coverage for the URI contract.
- Keep selected roots, resolved plugin locations, manifest paths, and
manifest resources as `PathUri`.
- Inspect and read plugin roots and manifests only through the selected
environment's `ExecutorFileSystem`.
- Parse executor manifests with the shared URI-native parser from #29620
instead of projecting them onto the host filesystem.
- Enforce resource containment lexically and preserve the root URI's
POSIX or Windows path convention.
- Cover foreign Windows plugin roots and URI-native manifest resources.
```text
thread/start
selectedCapabilityRoots[].location.path = "file:///C:/plugins/demo"
| PathUri
v
ExecutorFileSystem
|
+--> plugin.json
+--> manifest resources
```
This PR stops at the shared selected-plugin representation. The next two
PRs remove the remaining host-path projections in the skill and MCP
consumers.
## Stack
1. #29614 — add lexical `PathUri` containment.
2. #29620 — share URI-native manifest path resolution.
3. **This PR** — keep selected plugin roots and resources URI-native.
4. #29626 — load executor skills without host path conversion.
5. #29628 — resolve executor MCP working directories without host path
conversion.
## Why
Skill descriptions are used in model-visible lists: the default
available-skills catalog that supports implicit selection, and the
on-demand `skills.list` tool response used to discover orchestrator
skills. A single overlong description should not consume a
disproportionate share of either list.
Enforcing the 1024-character limit while loading or migrating skills is
the wrong boundary: it rejects otherwise-valid skills and discards
metadata that non-model consumers and full skill reads may need. Skill
metadata and `SKILL.md` content should remain intact; the cap belongs at
model-visible list rendering boundaries.
## What changed
- Preserve full `description` and `metadata.short-description` values
when loading skills.
- Preserve full external-agent command descriptions during
`source-command-*` migration instead of skipping commands solely because
their descriptions exceed 1024 characters.
- Preserve full normalized orchestrator descriptions in the underlying
skills catalog.
- Cap each description at 1024 Unicode characters when rendering the
default available-skills context in `codex-core-skills` and
`codex-skills-extension`.
- Apply the same cap when serializing descriptions in the model-visible
`skills.list` response.
- Render truncated descriptions as 1021 original characters plus `...`.
- Leave explicit `$skill` injection, `skills.read`, underlying metadata,
and on-disk `SKILL.md` files unchanged and full-fidelity.
## Implicit skill selection
Codex injects a bounded catalog containing each implicitly allowed
skill's name, description, and source locator, together with
instructions to use a skill when the task clearly matches its
description. The model makes that semantic choice; after selecting a
skill, it reads the full `SKILL.md` from its filesystem or provider
resource. Explicit `$skill` mentions remain a separate path that injects
the full skill instructions. For orchestrator skills, `skills.list`
provides bounded discovery metadata before `skills.read` returns the
full selected resource.
## Test plan
- `just test -p codex-core-skills`
- `just test -p codex-skills-extension`
- `just test -p codex-external-agent-migration`
The focused regressions verify that overlong metadata is preserved at
load and migration boundaries while default available-skills rendering
and `skills.list` output produce the 1021-character prefix plus `...`.
## Why
Orchestrator-provided skills and Codex Apps MCP tools add model-visible
instructions, resources, and tools beyond the local workspace. Hosts
need config-level switches to disable those orchestrator-owned surfaces
independently, without disabling regular skills or regular MCP servers.
## What changed
- Adds `[orchestrator.skills].enabled` and `[orchestrator.mcp].enabled`
config entries, both defaulting to `true`.
- Includes the new settings in `config.schema.json` and in the config
lock so resolved thread configuration preserves the same orchestrator
exposure decisions.
- Threads `orchestrator.skills.enabled` through the app-server skills
extension so disabled orchestrator skills do not expose the `skills`
namespace or inject orchestrator skill context.
- Gates Codex Apps MCP exposure, app instructions, and app auth
eligibility on `orchestrator.mcp.enabled` while leaving non-Codex-Apps
MCP tools available.
- Updates the thread-manager sample config to disable both
orchestrator-owned surfaces.
## Verification
- Added config parsing, loading, defaulting, and schema coverage for the
new settings.
- Added MCP exposure coverage that `orchestrator.mcp.enabled = false`
removes Codex Apps tools while preserving regular MCP tools.
- Added app-server coverage that `orchestrator.skills.enabled = false`
prevents orchestrator skill tools, prompts, and resource reads from
reaching the model turn.
## Summary
- Preserve raw plugin skill-root snapshots in the matching loaded-plugin
cache entry, keyed by the effective plugin root identity including
namespace.
- Pass those snapshots through `SkillsLoadInput` as an optional preload,
so session startup reuses plugin parsing while ordinary skill loads pass
`None`.
- Keep plugin skill loading cohesive: the existing loaders accept the
optional snapshots directly, and uncached or marketplace-detail paths do
not create a cache.
## Why
Plugin discovery already parses plugin skills to determine available
capabilities. Cold session startup then scanned and parsed the same
roots again while building the skills snapshot.
This solves the same duplicate-work problem as #28623 while keeping
ownership narrow: `PluginsManager` creates and owns
`PluginSkillSnapshots` only for its loaded-plugin cache entry;
`SkillsService` consumes an optional clone. Entry replacement or
clearing naturally drops the snapshots, with no separate generation,
capacity policy, or watcher coupling.
## Validation
- `cargo clippy -p codex-core-skills --all-targets -- -D warnings`
- `just test -p codex-core-plugins
skills_service_reuses_skills_parsed_during_plugin_load`
- `just test -p codex-core-skills
namespaces_plugin_skills_using_provided_namespace`
- `just fmt`
## Summary
- keep context injection on a single ContextContributor trait
- split context injection into thread-scoped and turn-scoped
contribution methods
- wire turn-scoped fragments into initial context assembly so extensions
can contribute context from turn-local state