## Why
Config layer provenance describes how effective configuration was
assembled, so it belongs with the config loader rather than in
app-server's serialized API types.
## What changed
- Moved `ConfigLayerSource`, `ConfigLayerMetadata`, and `ConfigLayer`
ownership into `codex-config`.
- Kept app-server's wire payloads unchanged and added explicit
conversions at the app boundary.
- Removed lower-level app-server-protocol dependencies from config
consumers.
## Stack
This is PR 3 of 6, stacked on [PR
#29721](https://github.com/openai/codex/pull/29721). Review only the
delta from `codex/split-auth-domain-types`. Next: [PR
#29723](https://github.com/openai/codex/pull/29723).
## Validation
- `codex-config` coverage passed.
- App-server config-manager and config RPC coverage passed.
## Summary
This switches skill discovery to the simpler same-connection scalar
request shape.
After reading a skills directory, discovery now starts the existing
`fs/getMetadata` calls for all visible entries in that directory before
awaiting the results. There is no JSON-RPC batch frame and no new
filesystem API; remote filesystems use the existing request-id
multiplexing on the same exec-server connection.
This is the scoped alternative to the batch-frame approach in #29074 /
#29075.
## What changed
- Collect visible directory entries before processing them.
- Run their existing `fs.get_metadata(...)` calls with `join_all`.
- Process the results in the original directory order, so skill
discovery behavior stays the same.
## Benchmarks
Fresh local benchmark against generated skill trees over a real
exec-server remote filesystem. The benchmark calls the actual
`load_skills_from_roots` path, so this includes directory reads,
metadata stats, `SKILL.md` reads, and parsing.
Times are p50 milliseconds from 5 samples after 1 warmup, using warmed
runs.
| Scenario | Legacy `main` | Batch frame stack (#29074 / #29075) |
Same-connection scalar stack |
| --- | ---: | ---: | ---: |
| 100 flat skills | 377.4 | 389.0 | 378.6 |
| 500 flat skills | 1983.2 | 1856.6 | 1757.5 |
Takeaway: for the actual skill discovery path, same-connection scalar is
tied with legacy at 100 skills and best at 500 skills. The batch-frame
stack does not show enough win here to justify the extra protocol/API
surface.
Benchmark command:
- `just test -p codex-exec-server benchmark_remote_skill_discovery
--run-ignored ignored-only --no-capture`
Checked locally with:
- `just test -p codex-core-skills`
- `just bazel-lock-update`
- `just bazel-lock-check`
## Summary
- reuse the shared shell read parser for implicit skill doc invocation
detection
- add regression coverage for `nl -ba .../SKILL.md`
## Why
Desktop could render `Read User Context skill` for reads recognized by
the shared command parser, while implicit `skill_invocation` analytics
used a separate reader allowlist and missed cases such as `nl`.
## Validation
- `HOME=/private/tmp/codex-core-skills-home-pr
PATH=/Users/alexsong/.cache/cargo-home/bin:$PATH
CARGO_HOME=/Users/alexsong/.cache/cargo-home just test -p
codex-core-skills`
- `git diff --cached --check`
- `just fmt` attempted; Rust formatting completed, but the Python
formatters could not download uncached Ruff wheels because
`files.pythonhosted.org` is blocked in this sandbox.
- `bazel mod deps --lockfile_mode=update/error
--repo_env=ASPECT_TOOLS_TELEMETRY= --repo_env=DO_NOT_TRACK=1` evaluated
the module graph and produced no `MODULE.bazel.lock` diff, but Bazel
crashed on sandboxed `sysctl` during exit.
## Why
We're moving exec-server to use PathUri for its internal path
representations.
## What
Move `ExecutorFileSystem` APIs to use `PathUri` instead of
`AbsolutePathBuf`. Future changes will convert higher-level parts of
exec-server.
## Why
`codex-core` currently owns the generic contextual-fragment trait and
several reusable fragment implementations. That makes it harder for
other crates to share the same host-owned model-input abstraction
without depending on all of `codex-core`.
This change extracts the reusable fragment machinery into a small
`codex-context-fragments` crate so future extension and skills work can
depend on the fragment abstraction directly.
## What Changed
- Added the `codex-context-fragments` crate with:
- `ContextualUserFragment`
- `FragmentRegistration` / `FragmentRegistrationProxy`
- additional-context fragment types
- Moved `SkillInstructions` into `codex-core-skills`, since
skill-specific rendering belongs with skills rather than generic core
context machinery.
- Kept `codex-core` re-exporting the fragment types it still uses
internally, so existing call sites keep the same shape.
- Updated Cargo and Bazel workspace metadata for the new crate.
## Verification
- `cargo metadata --locked --format-version 1 --no-deps`
- `just bazel-lock-update`
- `just bazel-lock-check`
Cap the model-visible skills section to a small share of the context
window, with a fallback character budget, and keep only as many implicit
skills as fit within that budget.
Emit a non-fatal warning when enabled skills are omitted, and add a new
app-server warning notification
Record thread-start skill metrics for total enabled skills, kept skills,
and whether truncation happened
---------
Co-authored-by: Matthew Zeng <mzeng@openai.com>
Co-authored-by: Codex <noreply@openai.com>
## Summary
- move skill loading and management into codex-core-skills
- leave codex-core with the thin integration layer and shared wiring
## Testing
- CI
---------
Co-authored-by: Codex <noreply@openai.com>