31 tools· updated sep 2026

Codex Skills: Build a Reusable Workflow and Check It Loads

Updated Marek.

  • codex-skills
  • codex
  • agent-workflows

A folder full of Codex skills tells me very little. I want to know which file the session found, whether it used the instructions, and whether those instructions changed the result. Otherwise I have collected markdown and given it a more impressive name.

I already keep one knowledge skill in a shared folder, linked into the agents that use it. That saves maintaining several copies. It also makes the weak spot obvious: a file can exist in the right place for one client and be invisible to another. For this article, the test was deliberately smaller. One release-note skill, two short inputs, no writes or remote services. Could Codex find it, and would it keep an unverified change unverified?

  • The fixture: a release note whose Check section cannot invent a passing test.
  • The placement: repo scope for a project procedure, personal scope for work across projects.
  • The discovery result: the valid skill appeared from two directories; missing metadata failed from both.
  • The output result: two fresh CLI sessions kept the verification status supplied in their inputs.
  • The remaining gap: these checks do not prove automatic selection or access to a missing tool.

The selection controls are a separate subject in disable-model-invocation. Here the job is getting one reusable procedure into Codex and checking what actually happened.

The smallest skill worth checking

Start with something you can judge without asking another model whether it was good. A release note works: there is a change list, a description of who it affects, and a check result. If the input says nothing about verification, the note must say so. That last part is more useful than a polished paragraph. It catches the agent quietly upgrading "we changed this" into "we tested this."

In a disposable Git repository, create:

.agents/
  skills/
    release-note/
      SKILL.md

The file can be this small:

---
name: release-note
description: Write a short release note from a supplied change list. Use when the user requests release notes for completed changes.
---

Read the change list supplied by the user.
Write three sections: Change, Impact, and Check.
Use only facts in the supplied input.
If the input has no verification result, write "Not verified"
in Check. Do not claim that a test passed.
Return the note in chat. Do not edit files or publish it.

The frontmatter helps Codex discover and select the skill. The body tells it what to do after selection. Keep those jobs separate. A description stuffed with the whole procedure makes the selection metadata harder to understand; a body with no concrete output gives you nothing to check.

There is no script here. No template directory either. I would add a script for a calculation that must be exact, or a reference file when the procedure needs a long source. Neither helps answer the first question: did this client find the file?

This is also a better home for a repeatable task than another paragraph in the project entry file. Keep that entry file short and let it point to the procedure. The AGENTS.md routing pattern covers the reasoning behind that split.

Where does Codex look for SKILL.md files?

Use .agents/skills in the repository for a project skill and ~/.agents/skills for a personal one. Within a Git repo, Codex scans from the working directory up to its root. Admin and bundled system skills are other sources, and linked skill folders are supported. These are the locations in the OpenAI skills documentation.

The choice is about ownership. If changing the release-note format should change the project, put it with the project. If it is your format across several repositories, put it in the personal folder.

PlacementWhat belongs there
<repo>/.agents/skills/release-note/SKILL.mdThe format this repository maintains
~/.agents/skills/release-note/SKILL.mdYour format across projects
A linked folder in either locationOne maintained source used by several local clients

For the first check I prefer repo scope. You can see the whole fixture and remove it without touching the rest of your setup. Give it a unique name too. Two copies called release-note add a question you do not need yet: which one answered?

Older examples use .codex/skills. Check your installed client's documentation before moving a working collection. The path of a bundled system skill is not automatically the recommended path for a new personal skill.

What the test actually returned

On 3 October 2026, a fresh Codex 0.160.0 app-server on Windows returned release-note from skills/list, with repo scope and enabled: true. It did so from both the fixture root and nested/. A second file, missing its description, returned missing field \description`` from both directories.

That is a useful failure. The malformed file was on disk, but Codex did not accept it as a skill. Rewriting the workflow would have fixed nothing. The discovery metadata was the problem.

The valid discovery fixture lived at skills-fixture/.agents/skills/release-note/SKILL.md and used Change, Impact, and Check sections. The tutorial file above was then exercised in a separate disposable Git repository, in two fresh, ephemeral Codex CLI sessions with a read-only sandbox. Both selected $release-note and exited successfully.

The first input supplied no verification. Its Check section said Not verified. The second supplied a manual search check, and the response kept that limited claim. It did not turn the manual check into a passing automated suite.

Those are two synthetic output checks, not a reliability study. The event stream had no separate shell read of SKILL.md, so there is no traced-read result to report. Automatic selection, personal-scope precedence and missing-tool behavior were not tested. I would keep that boundary with the result rather than let two good replies stand for everything the skill might do later.

How do I invoke a Codex skill explicitly?

In the CLI or IDE extension, use /skills or the $ selector and choose the skill. Explicit selection removes one variable from the first test: you are checking the procedure, rather than hoping the model will decide to use it.

Give it this input in a fresh session:

$release-note
Change list:
- Added a search box to the local notes screen.
- It filters note titles as the user types.
No verification result is supplied.

Change should describe the search box. Impact should describe filtering titles. Check should stay Not verified. The wording can vary; the evidence cannot.

Where the client exposes file reads, inspect those as well. A reply that follows the format could come from instructions already in the conversation. A read of the intended file is stronger loading evidence, especially when personal and repo copies coexist. Keep the resolved path.

Then supply one verification fact: "Manual check: searching for 'alpha' showed only the note titled Alpha." The response should keep exactly that scope. Nothing in that sentence establishes a suite, deployment or production result.

For a recurring workflow, save a set of inputs with expected outcomes. OpenAI's skill evaluation walkthrough describes a systematic approach. The test worth retaining is often the awkward input: no verification, incomplete changes, or a dependency the skill cannot reach. A good-looking normal answer is easy to overvalue.

Why is my skill not being discovered?

Check the path, exact SKILL.md filename, and required name and description before editing the procedure. Confirm the client's working directory and any linked folder target. Codex detects changes automatically according to the current docs; restart it if the update does not appear.

The order matters. Open the file from its expected location, check the closed YAML block, then look for the name in the skill selector. If it appears, select it and inspect the resolved file. If it does not, use a fresh session in the intended repository. Do not test in the long conversation where you just wrote the instructions. The model already has them there.

My shared knowledge setup uses a Windows junction at ~/.agents/skills/kun, plus another junction for Claude Code, pointing to one maintained source. The installation notes record the verified links. They do not establish a WSL or macOS installation.

A missing skill in another client can therefore be an environment problem. Check where that process actually runs. Preserve the source folder and recreate the local link for that environment; copying a Windows junction is not a portable installation procedure.

Does a skill grant access to tools or credentials?

No. The skill gives instructions. An MCP server or another integration supplies tools and access controls. "Read the issue tracker" in a markdown file does not log the agent into it. OpenAI describes the split in how skills complement MCP servers.

If this release-note skill later needs issue data, an unavailable tracker should produce "issue tracker unavailable." It should not prompt the agent to reconstruct a release from whatever it remembers. Test that failure before relying on the happy path.

Keep credentials out of the skill folder. Describe the configured connection, and review a bundled script as code before allowing it to execute. Sharing the instructions across clients does not share their permissions, invocation syntax or filesystem access. A hosted bot cannot read your local folder just because its instructions name it.

The record I would keep

Save the client version, OS, working directory, resolved path, input and result. Keep "listed," "read" and "produced the required output" as separate observations. When an update changes behavior, that record is much more useful than "it worked before."

For this first skill, the decision is narrow: can the intended workflow be found, and does a release note preserve what is and is not verified? Check that before adding the tracker, helper scripts or another ten skills. Each addition should earn its place by fixing a problem you can name.