openai / openai/codex

Explicit $skill mention injects SKILL.md, then the model reads the file again because of the read-completely rule

Open Beginner friendly
#43,188 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI skills
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

codex-cli 0.153.4

What subscription do you have?

Pro

Which model were you using?

gpt-5.6-sol (reasoning effort high)

What platform is your computer?

macOS 26.6.2 (Darwin 25.6.0), arm64

What terminal emulator and version are you using (if applicable)?

Not terminal-specific. Reproduced from the session rollout jsonl.

Codex doctor report

Not included; the report is about deterministic prompt text and is reproducible from the rollout file.

What issue are you seeing?

When a skill is invoked by explicit $skill-name mention, the CLI injects the full SKILL.md into the user turn as a <skill> block (codex-rs/ext/skills/src/fragments.rs, SkillInstructions::body: <name>, <path>, then the complete file contents). The skills section of the system prompt (codex-rs/ext/skills/src/catalog_prompt.rs) then says:

  1. After deciding to use a skill, the main agent must read its SKILL.md completely before taking task actions. ... For a filesystem path, open the file.

Nothing tells the model that the injected block satisfies that requirement. The model's first tool call is therefore a shell read of the same file from the <path> shown in the block, returning byte-identical text.

Observed in thread 01a075e4-7a77-7f51-80ce-89cc522ef21d:

  • User turn: $bmad-build inspector story 1 from ~/src/obeya, followed by the injected <skill> block containing the full 1.5 kB SKILL.md.
  • First model action: sed -n '1,240p' <path>/.agents/skills/bmad-build/SKILL.md.
  • The skill's own first line says to run one render command "exactly once", so the extra read is pure overhead: one round trip (about 6 s on this connection) and about 4K uncached input tokens per agent.
  • A sub-agent spawned from that thread (no <skill> block in its prompt at all) selected the same skill and made the same read, so the rule fires for every agent that decides to use a skill.

Asked afterwards why it re-read the file, the model answered:

Because the harness instructions explicitly say: "When a skill is triggered, the main agent must read its SKILL.md completely." I treated the injected copy as metadata/context, not proof that I had performed that required file read, so I re-read the file from its declared path.

That is a reasonable reading of the prompt as written. The two mechanisms (mention injection and the read-completely rule from #16479 / commit 56554904) were introduced independently and are not reconciled.

What steps can reproduce the bug?
  1. Create any repository skill, e.g. .agents/skills/demo/SKILL.md with a short body (a few lines is enough).
  2. Start codex in that repository.
  3. Send $demo do the thing.
  4. Inspect the rollout jsonl in ~/.codex/sessions/: the user turn contains the full <skill> block, and the first exec_command is a sed/cat of the same SKILL.md path.
What is the expected behavior?

When the selected skill's SKILL.md has already been injected into the conversation by the mention path, the model should proceed directly with the skill's instructions and not open the file again. Either:

  • amend step 1 in catalog_prompt.rs with one sentence such as "If the complete SKILL.md is already present in the conversation inside a <skill> block, treat it as read and do not open the file again", or
  • have the <skill> block itself state that it is the complete file and satisfies the read requirement.
Additional information

Related: #16479 (introduced the read-completely wording), #35853 (re-reads across turns on implicit selection, closed by the reporter). This report is the explicit-mention case, where the file is already in the prompt.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codex-rs/ext/skills/src/catalog_prompt.rs and codex-rs/ext/skills/src/fragments.rs to trace the read-completely wording and the injected block. Reproduce the explicit $demo flow and inspect the rollout JSONL; done means a complete injected SKILL.md no longer causes a duplicate file read.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
ai, cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
87/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.