My AGENTS.md kept growing. Every time the agent did something dumb, I added a paragraph: how to review a PR, how to cut a release, "please don't fix flaky tests with retries". Eventually it was 400 lines that got loaded into every single session, including the ones where I just wanted a typo fixed.

That's the problem skills solve. Short version:

  • Rules (AGENTS.md, CLAUDE.md, Cursor rules) load every time. Put project facts and conventions there.
  • Skills are folders with a SKILL.md. The agent only sees each skill's name and description up front, and reads the body when the task actually calls for it.

So "how we review PRs" moves out of your always-on file and only costs context when you're reviewing a PR.

Where each tool looks

The nice part is that the format is now shared (the Agent Skills spec), so one folder works in all three tools. As of their docs this month:

Tool Project folder Invoke
Claude Code .claude/skills/<name>/ /<name>
Cursor 2.4+ .agents/skills/, .cursor/skills/, also reads .claude/skills/ and .codex/skills/ type / in Agent chat
Codex .agents/skills/ (current folder, parents, repo root) $ mention or /skills

If you use Cursor plus one other tool, one folder is enough, since Cursor reads both .claude/skills and .agents/skills.

Docs: Claude Code skills, Cursor skills, Codex skills, spec.

The format

name: fix-flaky-test # lowercase, hyphens, must match the folder name description: What it does AND when to use it # Instructions... 

The description is the only thing the agent sees when deciding whether to use the skill, so write it like a trigger: "Use when a test is flaky, fails only in CI, or passes locally but not in the pipeline." A vague description means the skill never gets picked.

A skill you can copy right now: fix-flaky-test

This is the one I would start with. Without it, agents tend to reach for retry(3) or a bigger sleep. Drop this into .claude/skills/fix-flaky-test/SKILL.md (or .agents/skills/...):

name: fix-flaky-test description: Diagnoses and fixes a test that passes and fails intermittently by reproducing the flake with repeated runs, identifying the nondeterminism (timing, ordering, shared state, randomness, time zones, network), and fixing the cause instead of adding retries. Use when a test is flaky, fails only in CI, fails randomly, or passes locally but not in the pipeline. # Fix a flaky test  A flaky test is a bug in the test or the code. Find the source of nondeterminism and remove it. ## Steps 1. Reproduce. Run the single test many times (e.g. 50) to measure the failure rate. If it never fails alone, run it with its neighbors, in random order, in parallel, or under CPU load. 2. Read the failure output of a failing run in full: which assertion, what value, any timing in the logs. 3. Check the usual causes in this order: - Async/timing: sleeps, missing awaits, polling without a deadline, asserting before render. - Shared state: globals, singletons, module caches, DB rows or files left by other tests, env vars. - Order dependence: passes only after (or before) another test. - Time: now(), dates near midnight or month end, time zones, DST, tight timeouts. - Randomness: unseeded random, UUID ordering, hash/set iteration order, queries without ORDER BY. - External: real network, ports in use, third-party sandboxes. - Resource limits: parallel workers sharing a DB, temp dir, or port. 4. Form one hypothesis and test it: make the condition deterministic (freeze the clock, seed the RNG, force the order) and show the failure becomes 100% or 0%. 5. Fix the cause: await the right condition, isolate state per test, inject the clock, sort before comparing, unique temp dirs and ports, stub the network. 6. Verify with the same repeat command and report before/after failure counts. ## Not acceptable as the fix - Adding retries, longer sleeps, or bigger timeouts without a reason tied to the cause. - Skipping or deleting the test. If quarantine is truly needed, ask the user and link an issue. ## Output format **Test:** <id> **Before:** x/50 failures **After:** 0/50 **Cause:** ... **Fix:** ... ## Stop and ask when - The cause is in production code and fixing it changes behavior users see. - You can't reproduce it after trying isolation, order, parallelism, and load: report what you tried. 

The "Not acceptable" section matters more than the steps. Agents are good at the steps; they just need to be told that the shortcut doesn't count.

Gotchas I hit

  • Broken YAML fails quietly in Claude Code. The skill still loads, but with no description, so it never gets auto-selected. If a skill "doesn't work", check the frontmatter parses first.
  • Name clashes are silent. A project skill named like a bundled one (e.g. code-review) replaces it. I use pr-review and security-audit to stay out of the way.
  • Codex caps the initial skills list (around 2% of context by default) and shortens descriptions first, so put the key use case at the start of the description.
  • Cursor subagents couldn't use skills at the 2.4 launch; the workaround was telling the subagent to read the skill file directly.
  • Cloud sessions (Claude Code cloud, Cursor Cloud Agents) don't read your home-folder skills. Commit the ones you need to the repo.

What I'd put in skills vs rules

Rules: stack, commands to run tests, folder layout, "never touch X". Skills: anything that's a procedure — plan before coding, PR review with severity levels, release checklist that stops before publishing, a handoff note at the end of a session, splitting work across git worktrees when you run several agents.

I ended up writing 24 of these (planning, review, testing, debugging, releases, git, docs) plus an installer that never overwrites existing files and a small linter that catches the YAML/name problems above. They're packaged as Agent Skill Pack ($17) if you'd rather not write them yourself: https://payhip.com/b/S3RJk. The flaky-test one above is the full skill, not a teaser, so take it either way.

If you only want the always-on half, the free AGENTS.md starter is here: https://github.com/hwu121380-afk/agents-md-starter

Not affiliated with Anthropic, Cursor or OpenAI.