← All guides

Harness Tests Explained: Check Your CLAUDE.md and Skills

You edit CLAUDE.md, the agent seems better, and you move on. But you never checked. A 2026 study found that context files written by an LLM made coding agents slightly worse and cost about 20% more. Your instruction files, skills and hooks are code that steers the agent. This guide shows how to test each one, with the tools that exist today.

Bottom Line

  • Instruction files do not help by default. An ETH Zurich study found LLM-written context files made agents slightly worse and about 20% more expensive.
  • Test two things for every skill: does it trigger on the right prompts, and does the result improve when it does?
  • claude plugin eval tests plugins with and without the plugin. It does not load your CLAUDE.md.
  • Hooks are the easiest to test. Pipe saved JSON into the script and check the exit code. No model call needed.
  • OpenClaw has readiness checks (openclaw skills check, openclaw doctor --lint), not behavior tests.

Why Instruction Files Need Tests

The paper “Evaluating AGENTS.md” (Gloaguen and others, arXiv, version 3 from September 2026) tested context files with Claude Code, Codex and Qwen Code:

Context fileChange in task successChange in cost
Written by an LLMAbout -0.5 points (SWE-bench Lite), about -2 points (CTXbench)About +20% to +23%
Written by the developersAbout +2.4 points, not statistically significantUp to +19%

The agents did follow the instructions. The instructions just did not help much, and they made the agent take more steps. Repository overviews did not help at all. The authors found context files useful for practices that are not standard, and say changes “should be rigorously evaluated.”

What this means for you: a rule you add can cost tokens on every task and help on none. You only know if you measure.

What to Test

PartQuestionTest type
CLAUDE.md / AGENTS.mdDo tasks succeed more often, or more cheaply, with it?Golden tasks, with and without the file
Skill triggerDoes the agent pick the skill when it should, and not when it should not?Trigger test
Skill effectIs the result better when the skill runs?Golden tasks, with and without the skill
HookDoes it allow, block or change exactly what it should?Fixture test, no model
PluginAll of the above, in one packageclaude plugin eval

Test 1: Skill Triggers

A skill only helps if the agent loads it. Claude decides from the skill’s description, and Claude Code cuts description plus when_to_use at 1,536 characters in the skill list. Put the main use case first.

Write two lists of prompts:

  • Should trigger: real phrasing a user would type, not the skill’s own name.
  • Should not trigger: close but wrong requests.

Anthropic’s skill-creator plugin uses 20 such queries, splits them 60/40 into train and test sets, runs each 3 times, and tries up to 5 description rewrites. It picks the final description by the test score, so it does not overfit to the prompts it was tuned on. OpenAI’s Codex guide uses the same idea: a CSV with id,should_trigger,prompt and 10 to 20 prompts per skill.

How much this matters: Scott Spence measured Claude Code skill activation on 22 prompts (February 2026). With no help, skills fired 50% to 55% of the time. With a hook that forced an evaluation step, they fired 100%.

Check one result by hand. A GitHub issue (#79998) reports that the skill-creator trigger eval can read near 0% whatever the description says, because test probes register as slash commands. It was closed as stale, not fixed.

Test 2: Plugins With claude plugin eval

Claude Code v2.1.269 added claude plugin eval. It shipped in the week of 7 to 11 September 2026.

claude plugin eval init     # proposes prompts that should and should not trigger, and graders
claude plugin eval .        # runs the suite from the plugin root

Each case is a folder:

evals/<case>/prompt.md          # the prompt, with options such as max_turns
evals/<case>/graders/*.md       # one file per grader

There are six grader types:

GraderChecksModel call
regexText in the outputNo
tool_usedA tool was called, such as SkillNo
tool_orderTools ran in the right orderNo
file_existsA file was writtenNo
llmA judge model grades the resultYes
baselineA judge compares with the no-plugin runYes

The key feature is the baseline. Each case runs 3 times with the plugin and 3 times without. The table shows WITH, W/OUT and Δ. The docs put it plainly: if a case scores 1.0 with and without the plugin, the plugin is not what made it pass.

The most common first result, per the docs, is a Δ near zero with the Skill grader failing. That means Claude does not choose your skill on natural phrasing. Fix the description and run it again.

For CI, the docs give this pattern:

claude plugin eval . --trust-plugin --json results.json --threshold 0.8 \
  --model claude-sonnet-5 --judge-model claude-haiku-4-5 --no-publish --max-cost-usd 20

Pin the model, so that a model update is not mistaken for a plugin regression. Exit code 0 means the suite passed, 1 means a case fell below the threshold, and 2 means the cost limit stopped the run.

Two limits:

  • It costs money. Every run and every judge grader is a real model call.
  • It loads only the plugin. The docs say your CLAUDE.md files, hooks, MCP servers and other skills are absent.

Test 3: CLAUDE.md and AGENTS.md

Because claude plugin eval leaves CLAUDE.md out, test it with golden tasks:

  1. Pick 5 to 10 real tasks from your repo history, each with a check you can run, such as a test that must pass.
  2. Run each task with and without the file. Use a fresh session each time, with claude -p for Claude Code or codex exec --json for Codex.
  3. Compare success, steps and tokens. Keep a rule only if it moves one of them.

promptfoo can automate this. Its anthropic:claude-agent-sdk provider loads no CLAUDE.md by default. Set setting_sources to project to load it, and compare two configs. It also has a skill-used assertion. Turn caching off when you test config changes, or the cache can hide them.

Anthropic’s skills docs give the reason for fresh sessions: context left from writing the skill “will mask gaps in the written instructions.”

Test 4: Hooks

Hooks are plain scripts with a clear contract, so they are the cheapest part to test.

  • Input: for command hooks, “input arrives on stdin” as JSON, with fields such as hook_event_name, tool_name and tool_input.
  • Output: exit 0 to proceed, exit 2 to block with a reason on stderr. The docs: “If your hook is meant to enforce a policy, use exit 2.”

A fixture test:

# tests/hooks/rm-rf.json holds a saved PreToolUse input for "rm -rf /"
./.claude/hooks/block-dangerous.sh < tests/hooks/rm-rf.json
test $? -eq 2 && echo "PASS: blocked" || echo "FAIL: not blocked"

Save one input that the hook must block and one it must allow. Run them on every commit. They need no model and cost nothing.

Test 5: OpenClaw

OpenClaw’s commands check setup and readiness. None of them score behavior.

CommandWhat it checks
openclaw skills check --agent <id>Which skills are found, ready and visible to that agent
openclaw skills info <name>One skill’s details
openclaw plugins validate / lintPlugin structure and runtime compatibility
openclaw doctor --lintRead-only health checks for CI, including bootstrap file size. Exits 0, 1 or 2

Use skills check first when a skill “does nothing”. It is often not visible to the agent at all. Then test behavior with golden tasks, as for CLAUDE.md.

When to Run Which Test

TriggerRun
Every commitHook fixture tests, openclaw doctor --lint
You change a skill or pluginTrigger test and claude plugin eval
You change CLAUDE.md or AGENTS.mdGolden tasks, with and without
A new model or a new agent versionEverything, because a harness tuned for one model can fail on the next

Honest Caveats

  1. The ETH results are averages. A file with rules your repo really needs can still help a lot. Measure your own.
  2. Small test sets are noisy. With 10 tasks, one task is 10 points. Run each case more than once.
  3. We did not run these tools for this guide. Commands and numbers come from the docs and posts below.
  4. Hook fixture testing is a community method. It follows from the documented stdin contract, but the docs do not describe it.

Sources

See Also

Read next

Agent Loops Explained: Goal, Act, Verify, Stop
Every AI agent is a loop: goal, act, verify, stop. Loop engineering is designing that loop so it checks its own work and ends at the right time. Stop conditions in Claude Code, Codex, the OpenAI Agents SDK and OpenClaw, the verification data, and the runaway costs.
Tool Search Explained: Why 100 Tools Make Agents Worse
Every tool you give an agent costs context and makes the right tool harder to pick. How tool search works (regex, BM25, embeddings), what it does to prompt caching, when code mode is better, and how to set it up in the Claude API, OpenAI and OpenClaw.
AGENTS.md vs CLAUDE.md: Pick One Source of Truth
Use AGENTS.md for portable repository rules. Use CLAUDE.md for Claude-specific behavior. Keep shared rules in one file to prevent drift.
Claude Code Hooks vs Skills: Enforce or Instruct
Use a hook for automatic lifecycle enforcement. Use a skill for a reusable workflow the agent invokes. Here is the exact choice boundary.