[bug][otel]: Plugin Skills injected by SkillsExtension do not emit codex.skill.injected
What version of Codex CLI is running?
codex-cli 0.145.0
The CLI update check reports 0.146.0 as the latest release. The runtime reproduction below is from 0.145.0; I also inspected the rust-v0.146.0 source and the same missing-emission path is still present there.
What subscription do you have?
ChatGPT subscription (exact tier omitted for privacy)
Which model were you using?
gpt-5.6-sol
What platform is your computer?
Darwin 23.6.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
Warp Terminal v0.2026.07.01.09.21.stable_01
Codex doctor report
Relevant redacted excerpt (unrelated local paths, proxy diagnostics, and state-database checks omitted):
{
"schemaVersion": 1,
"codexVersion": "0.145.0",
"checks": {
"auth.credentials": {
"status": "ok",
"details": {
"stored auth mode": "chatgpt"
}
},
"config.load": {
"status": "ok",
"details": {
"model": "gpt-5.6-sol",
"model provider": "openai",
"relevant enabled feature flags": [
"plugins",
"remote_plugin",
"mentions_v2"
]
}
},
"runtime.provenance": {
"status": "ok",
"details": {
"platform": "macos-aarch64",
"version": "0.145.0",
"install method": "standalone"
}
},
"updates.status": {
"status": "ok",
"details": {
"latest version": "0.146.0",
"latest version status": "newer version is available"
}
}
}
}
What issue are you seeing?
Plugin-provided Skills are successfully selected and injected into the turn, but the OTLP metrics pipeline does not receive a corresponding codex.skill.injected data point.
This creates a silent telemetry blind spot for plugin Skills. In the same Codex session, ordinary host/system Skills do emit codex.skill.injected, so the metrics exporter and OTLP receiver are working.
Observed session evidence:
2026-07-29T01:32:21.452Z
<skill>
<name>mattpocock-skills:ask-matt</name>
<path>.../plugins/cache/mattpocock/mattpocock-skills/1.2.0/skills/engineering/ask-matt/SKILL.md</path>
...
</skill>
The same day's rollout also records plugin Skill document reads for:
diagnosing-bugs 5
tdd 1
code-review 1
After allowing exporter batching/flush, the received codex.skill.injected aggregation was:
openai-docs 3
golang-patterns 1
mattpocock-skills:* 0
All received rows had status=ok; the host/system Skill rows used invoke_type=implicit. No plugin Skill data point was present, including the explicitly injected mattpocock-skills:ask-matt.
There is no receiver-side prefix filtering: arbitrary skill attribute values are accepted. Other Codex metrics and the two non-plugin Skill counters arrived through the same OTLP/gRPC endpoint.
This appears to be a missing counter call in the newer Skills Extension path:
- In
rust-v0.146.0,SkillsExtensioncollects explicit mentions, reads each selected entry's main prompt, buildsSkillInstructions, and pushes the fragment: - https://github.com/openai/codex/blob/rust-v0.146.0/codex-rs/ext/skills/src/extension.rs#L386
- https://github.com/openai/codex/blob/rust-v0.146.0/codex-rs/ext/skills/src/extension.rs#L435-L476
- That file contains no
codex.skill.injectedemission. - The legacy/core explicit path does emit the counter:
- https://github.com/openai/codex/blob/rust-v0.146.0/codex-rs/core-skills/src/injection.rs#L140-L146
- The core implicit path also emits it:
- https://github.com/openai/codex/blob/rust-v0.146.0/codex-rs/core/src/skills.rs#L92-L114
This is related to, but distinct from, #27659. That issue covers namespaced Skill names being rejected because : was not sanitized. Commit 6c00dc087e4c01312017389483573500001e9fe9 / #34601 added sanitization to the core explicit and implicit paths. The problem here remains after that source-level fix: the Plugin Skills Extension success path does not call the counter at all.
What steps can reproduce the bug?
- Configure the Codex metrics exporter:
``toml``
[otel]
environment = "dev"
metrics_exporter = { otlp-grpc = { endpoint = "http://127.0.0.1:4317" } }
- Install or enable a plugin that contributes a namespaced Skill, for example
example-plugin:example-skill. - Start a new Codex CLI session and explicitly select/mention that plugin Skill.
- Confirm in the rollout JSONL that Codex injected a structured fragment containing:
``xml``
<skill>
<name>example-plugin:example-skill</name>
...
</skill>
- Inspect exported OTLP metrics after the batch interval or process shutdown.
- Observe that no
codex.skill.injectedpoint exists for the plugin Skill. - In the same session, implicitly invoke a regular host/system Skill by reading its
SKILL.md; itscodex.skill.injectedpoint is exported normally.
What is the expected behavior?
Every successful Skill injection should increment the documented codex.skill.injected counter, regardless of whether the Skill came from the legacy/core loader or the Plugin Skills Extension.
For a successful explicitly selected plugin Skill, the exported point should include at least:
status=ok
skill=<sanitized namespaced skill name>
invoke_type=explicit
A focused regression test around the SkillsExtension selected-entry/read-main-prompt success path would prevent the extension implementation from bypassing the existing Skill telemetry contract.
Additional information
- Official metrics documentation describes
skill.injectedas “Skill injection outcomes by skill”:
https://learn.chatgpt.com/docs/config-file/config-advanced
- Related but not duplicate:
- #27659 — invalid-character sanitization for namespaced Skill tags
- #17132 — proposed PreSkillUse/PostSkillUse lifecycle hooks
- #35650 — request for additional plugin/marketplace attributes
- No prompts, tokens, account identifiers, conversation IDs, or absolute local paths are included in this report.