Apply to my task
arXiv:2610.14216 ★ 94 Oct 9, 2026

Cortex: testing a coding agent's rules and skills by measurement, not by eyeballing

Key result

The trick: how an instruction is delivered matters more than its text. Skills (short instructions the agent decides on its own whether to open) that were available at every step were never once opened by the agent in the measurements. The Cortex method lets you test rules and skills for Claude Code by measurement, not by eyeballing. It turns your corrections into tasks with a check script. Then it runs the agent several times with the new text and several times without it. The text stays only if it helped, reached the context and broke nothing. One successful run proves nothing: on the same task the agent sometimes passes and sometimes falls over.

01

TL;DR

Cortex is a set of three commands for Claude Code. It turns the corrections you make after the agent into testable tasks. Then it writes one new rule or skill at a time (a skill is a short instruction the agent decides on its own whether to open) and runs the agent on the tasks several times with the new text and several times without it. The text stays only if it helped, the agent actually used it, and no task got noticeably worse. Old rules are tested the same way: remove them one at a time and see what changes.

The main pain point: one successful run proves nothing. On the very same task, the agent sometimes passes and sometimes fails. The author measured the same configuration twice and got a difference that, with a single measurement, you'd easily mistake for an effect. The second finding matters more for practitioners. How an instruction is delivered matters more than what it says. Rules tied to files are loaded by Claude Code itself when the agent opens a matching file. Skills have to be chosen by the agent, and skills available at every step were never opened (0 of 198 chances, with Claude Haiku 4.5 as the agent). When a skill was tied to the task's files, it got opened noticeably more often.

The method runs as a chain of three commands. /harvest at the end of a session saves the task and logs your corrections. /evolve finds a recurring problem, writes one candidate and tests it against three conditions: it helped, it fired, it broke nothing. /prune periodically throws out whatever the agent manages fine without. The through-line: credit an item with help or harm only where it actually landed in the agent's context.

Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.

02

Method Blueprint

/harvest (end of session, never runs the agent):
  STEP 1: Did something go from "broken" to "working"? → save a TASK
         (broken commit + the request verbatim + a check script)
  STEP 2: Did the developer correct the agent? → one LESSON line per correction
  STEP 3: Check the check itself: fails on the broken version, passes on the fixed one,
         passes without the tests from the fix

/evolve (one cycle = one candidate):
  STEP 1: Find a recurring theme in the lessons
  STEP 2: Write ONE skill/rule + choose how it loads
         (tied to a folder / at every step)
  STEP 3: Cheap run: k times without the candidate, k times with it
  STEP 4: Strict run on all tasks
  STEP 5: A script decides, not the model: KEEP only if
         it helped + it fired (rule loaded / skill opened) + no task got worse

/prune (once a month and after a model switch):
  STEP 1: Remove items one at a time, run the tasks
  STEP 2: Delete only if things are no worse without the item
  STEP 3: An item that never fired — don't delete it (nothing to test with)

The commands are prompts the model follows. The exact steps (running, counting, recording) are handled by a small program called cortex.

03

Example in Practice

Our illustration, not a case from the paper (the paper's lab does have a similar "money in integer cents" house rule).

Task: You run the backend for a grocery delivery service. In the shop/billing/ folder, money is handled only in cents as integers via the money.py module. Any float breaks rounding on refunds through Stripe. The agent (Claude Code) keeps writing price * 0.87. The tests pass, but the convention is broken, and you're fixing it for the third time. Instead of yet another line in CLAUDE.md, make a rule tied to the folder and test it by measurement.

Prompt (for Claude Code at the repository root):

Task: check whether a rule against float in money calculations helps.

1. Create the rule .claude/rules/money-in-cents.md with the field paths: ["shop/billing/**"].
   The rule text — no longer than 5 lines: store all amounts in cents (int),
   calculate only via shop/billing/money.py, float is forbidden.

2. Take 3 tasks from shop/billing/ (I'll list them below) and make a check script for each:
   exit 0 if the changed code has no float for money and the tests pass.
   Tasks:
   - add a "−13%" promo code to the cart
   - calculate 20% VAT on the receipt
   - implement a partial refund on an order

3. Run each task 5 times IN A CLEAN CLONE of the repository:
   - variant A: without the new rule
   - variant B: with the rule
   For each run, record: did the check pass, did the rule load
   (did the agent read a file from shop/billing/).

4. Output a table: task × variant → share of successful runs, plus a "rule loaded" mark.
   Verdict KEEP only if: B beats A overall, the rule loaded at least once,
   and no task in B got worse than in A.

Result: The agent will create the rule file and the check scripts, then do 30 runs in isolated copies. The response will contain a table of success rates for each task in both variants and marks for whether the rule loaded. At the end comes a KEEP or KILL verdict referencing the three conditions. If the rule never loaded, the honest verdict is: nothing to test, and it can't be kept. That narrows the problem down to checking the pattern in paths.

04

Why It Works

The LLM agent's weakness: the result on any single task is random, because the model samples every time (picks a continuation with some randomness). So "I saw it work" isn't proof. On top of that, the agent doesn't read everything. It opens a skill only if its short description convinces it the skill is needed. An instruction that never reached the context changes nothing, yet takes up space and creates an illusion of control.

The strength: the agent dutifully follows whatever is actually in its context. A rule tied to a folder gets placed in the context by Claude Code itself as soon as the agent touches a matching file. The agent doesn't have to decide whether to read it.

How the method uses this: it repeats runs and compares "task with text / task without text" pairs, so the luck of individual attempts averages out. It counts an effect only where the text reached the context. And the decision is made by a script, not by the model that wrote the candidate and wants to keep it.

Your levers: - Loading method (paths on a rule or skill) → the narrower the binding, the less extra context; for skills, file binding is what got them opened at all (28 of 66 chances vs 0 of 198 for every-step skills). A rule without paths always loads and "pays" at every step. - Number of repeats k → more repeats mean less noise but cost time and tokens. Use more for noisy tasks. - Tolerance for regression → in the original it's zero for a task the agent never failed. Loosen it if your tasks are unstable. - Item type → a rule for what the agent must always know in a given folder; a skill for a rare, large procedure.

05

Prompt Template

The original texts of the /harvest, /evolve and /prune commands live in the repository (link under "Resources"); they aren't in the part of the paper covered here. Below is a reconstruction of the logic of one /evolve cycle based on the paper's description, so you can repeat it by hand in Claude Code.

<Role>
You are a cautious editor of an agent's instructions. You do NOT decide the text's fate yourself:
the decision is made by the strict conditions below, based on run results.
</Role>

<Inputs>
- Corrections log: {corrections_log}
- Saved tasks (request + broken commit + check script): {task_list}
- Current harness (CLAUDE.md, .claude/rules/, .claude/skills/): as-is in the repository
- Number of repeats per task: k = {repeat_count}
</Inputs>

<Procedure>
Step 1. theme = find ONE recurring problem in the log.
        If nothing recurs — answer BARREN and stop. Don't write anything.
Step 2. candidate = write ONE skill or rule against this problem.
        Choose the loading method:
          - the problem lives in one folder → rule/skill with paths: ["{folder}/**"]
          - the problem is everywhere → first ask whether this belongs in CLAUDE.md
Step 3. screen = for tasks related to the theme that don't always pass,
        run k times each: base (without the candidate) and cand (with the candidate),
        each run in a clean clone of the repository.
        For each run, record: did the check pass; did the candidate reach
        the context (rule loaded / skill opened).
Step 4. confirm = if the screen looks promising, run ALL tasks the same way.
</Procedure>

<Gates>
KEEP only if ALL three conditions hold:
  1. cand beats base overall on the tasks the candidate reached
  2. the candidate fired in at least one run (rule loaded or skill opened)
  3. no task got worse beyond the tolerance {tolerance}
     (for a task that base never failed, tolerance = 0)
If it fails only on condition 3 → rerun the failed tasks, then decide.
If the candidate never reached the context → RERUN/"not tested," not KEEP.
If the data can't be trusted (no load marks) → RERUN, decide nothing.
</Gates>

<Output>
Table: task × (base, cand) → share of successful runs + "reached context."
Verdict: KEEP / KILL / RERUN / BARREN — and which condition decided it.
If KEEP — put the file into the harness. If KILL — put it in .graveyard/ with the reason.
</Output>

What to plug in: {corrections_log} — lines like "date, task, what the agent did, what it should have done"; {task_list} — tasks with check scripts; {repeat_count} — the paper used 2 for the screen and 3 for the confirm run; {tolerance} — how much a task is allowed to regress.

🚀 Quick start — paste into a chat (ideally straight into Claude Code in your repository):

Here's a template for a rule-testing cycle for an agent (based on the Cortex method). Adapt it to my project: {describe the project}.
Ask me questions to fill in the fields.

[paste the template above]

The LLM will ask which corrections you keep repeating, which folders the problem lives in, how to automatically check that a task is solved, and how many repeats you're willing to run. That's because the method rests on three things: a recurring theme, a script-based check and file binding. Without them there's nothing to measure.

06

Limitations

⚠️ Strong model — little benefit: on a stronger model that already followed nearly all the conventions, the gain from a harness built in one run was small. On a real open-source project where the agent was hardly ever corrected, Cortex found nothing to learn at all.

⚠️ Harm doesn't get caught: the agent didn't open harmful skills, and harmful rules landed on tasks that mostly failed even without them. The cycle issued no verdict even when a harmful rule broke a task that passed without it. The method guarantees that unused text won't stick around. That it will catch text that damages the work is not proven.

⚠️ You need a script-based check: without a script that unambiguously decides "task solved," the method doesn't work. Writing and creative work have no such check.

⚠️ Every-step skills almost never get opened: in the measurements, the agent never once opened a skill with no file binding. That doesn't mean skills are useless in general, but "drop in a skill and hope" is a weak strategy.

⚠️ Removal checks make mistakes: /prune gave the expected verdict on most items, but on planted items with known answers — only on half. It kept a useless always-on skill (one the agent never opened) because 2 tasks happened to pass less often when it was removed. Better to confirm removal decisions by hand.

⚠️ A narrow test: one small synthetic codebase, one main model (Claude Haiku 4.5), and a script playing the developer. Real teams with live sessions are the next step.

07

How They Studied It

The author built a small synthetic repository with four "house rules." For example, read the time only through a custom clock module. Code that ignores this works but breaks the convention, and the model breaks it on its own. For each rule he made a family of tasks, plus a fifth family of ordinary bugs where there's nothing to learn (the control). A script played the developer: 10 rounds of sessions. Cortex was run from scratch four times, and each resulting harness was tested on 30 new scenarios the cycle had never seen. That way the gain can't be explained by memorizing the tasks.

Result on the new tasks: the Cortex harness beat the empty one (no skills or rules) by 55 points of success rate (confidence interval from +34 to +74; Claude Haiku 4.5 as the agent, averaged over the four runs on the 23 house-rule scenarios), while the control family barely changed. But the most instructive findings aren't about the gain. Of 18 kept items, 16 turned out to be rules. A skill tied to files was opened in 28 of the 66 cases where it was available. An every-step skill was never opened by the agent across 198 cases.

They also planted 20 useless and 5 harmful candidates. None got through, but the test is weaker than it looks: most were simply never opened. The same harness measured twice diverged by −3.3 points. That's a vivid lesson about noise: a single measurement can be mistaken for an effect. When one run's harness was moved from Claude Haiku 4.5 to the stronger Claude Sonnet 5, its gain dropped from +66.7 to +5.6 points (a single harness on a single stronger model).

08

Adaptations and Extrapolations

🔧 Technique: tight folder binding → less context, and skills actually get opened

Any rule that concerns one area of the code should get a paths field. An unbound rule loads at every step and always costs context. A bound one loads only when the agent touches the relevant files. In the study, every kept item was bound, and the harness added nothing "at every step."

---
paths: ["shop/billing/**"]
---
Money — in cents only (int), calculate via money.py. float is forbidden.

Extrapolation: a manual corrections log (the /harvest idea). At the end of a work session, tell the agent:

The session is over. Go through our conversation and find every case where I corrected you.
For each one, output a single line: date | task | what you did | what you should have done.
If there were no corrections — say so, don't make anything up.
Append the lines to lessons.md, even if the same line is already there: repeats are a signal.

After a couple of weeks, the repeats in lessons.md show which rule to write first. It's a safeguard against "fixing from memory."

09

Resources

  • Cortex: Measurement-Gated Evolution and Pruning of Coding-Agent Skills and Rules — Samuele Giampieri, independent researcher.
  • Tool and lab code: https://github.com/samugit83/cortex (tag v1.0-eval — the system as in the paper; v1.0.5 — data and reproduction scripts).
  • Claude Code documentation on rules, skills and CLAUDE.md; the AGENTS.md format.
  • Recommendations on evaluating LLMs as an experiment (Miller): repeated runs and paired comparisons.
  • Related: SWE-bench, SWE-rebench, τ-bench, Meta-Harness, SkillReducer.

Research digest

Key result

The trick: how an instruction is delivered matters more than its text. Skills (short instructions the agent decides on its own whether to open) that were available at every step were never once opened by the agent in the measurements. The Cortex method lets you test rules and skills for Claude Code by measurement, not by eyeballing. It turns your corrections into tasks with a check script. Then it runs the agent several times with the new text and several times without it. The text stays only if it helped, reached the context and broke nothing. One successful run proves nothing: on the same task the agent sometimes passes and sometimes falls over.

Principle

A cycle of three commands. `/harvest` at the end of a session saves the task and logs your corrections. `/evolve` takes one recurring problem, writes ONE candidate and tests it against three conditions. Did it help? Did it fire (rule loaded, skill opened)? Did no task get worse? `/prune` once a month removes items one at a time and sees what changes. Credit an item with help or harm only where it landed in the agent's context. A script decides, not the model. The model that wrote the candidate always wants to keep it. That's like a judge who's also the defendant. Why does the loading method matter so much? A rule bound to a folder (`paths`) gets placed in the context by Claude Code itself when the agent opens a matching file. No decision needed. A skill gets chosen by the agent based on a short description, and most of the time it decides the skill isn't needed.

Why it works

The agent's results are random. The model picks a continuation with some randomness every time. So "it worked for me" isn't proof. Repeats and "with text / without text" pairs average out the luck. The second reason: the agent doesn't read everything. An instruction that never reached the context changes nothing, yet takes up space and creates an illusion of control. The kicker: a skill with no file binding was never opened once. But tie a skill to the task's files and it got opened noticeably more often. A rule without `paths` always loads and "pays" at every step, even when it isn't needed. Another finding: the author measured the same configuration twice and got a difference. With a single measurement you'd easily mistake it for an effect.

When to apply

Coding agents → recurring corrections in a specific folder, like "float instead of cents again," especially when there's a script that unambiguously says "task solved." Also good for cleanup: once a month and after a model switch, check which rules the agent no longer needs. NOT suitable for writing and creative work: there's no check script there. Little benefit on a strong model that already follows conventions, and on a project where you hardly ever correct the agent. The method also isn't guaranteed to catch harmful rules. Confirm removals via `/prune` by hand: it once kept a useless skill the agent never opened, because two tasks happened to pass less often without it.

Mini recipe

1. Find the pain: pick the correction you're making for the third time. Ideally one that lives in a single folder. 2. Make a task: save the broken commit, the request verbatim and a check script. Check the check itself: fails on the broken version, passes on the fixed one. 3. Write one rule: no longer than 5 lines. Bind it to the folder: `paths: ["shop/billing/**"]`. Don't write five rules at once, or you won't know which one worked. 4. Run the pairs: 3-5 times without the rule, 3-5 times with it (our suggestion; the paper used 2 repeats for a quick screen and 3 for the confirm run). Each run in a clean clone of the repository. Record whether the rule loaded. 5. Check the three conditions: helped overall, loaded at least once, no task got worse. For a task the agent never failed, the regression tolerance is zero. 6. Read the verdict: the rule never loaded? That's not a win, it's "not tested." Fix the pattern in `paths`. 7. Clean out the old: once a month, remove items one at a time. Delete only if things are no worse without the item. An item that never fired — don't delete it: there's nothing to test with.

Examples

(Our illustrations, not examples from the paper.) [BAD]: `Add a line to CLAUDE.md: don't use float for money` (the rule loads at every step, and nobody knows whether it helped) [GOOD]: `Create the rule .claude/rules/money-in-cents.md with paths: ["shop/billing/**"], no longer than 5 lines: amounts in cents (int), calculate via shop/billing/money.py, float is forbidden. Take 3 tasks (a −13% promo code, 20% VAT on the receipt, a partial refund) and make a check script for each. Run each 5 times in a clean clone: without the rule and with it. Record whether the check passed and whether the agent read a file from shop/billing/. Output a table and a KEEP verdict only if things are better overall with the rule, it loaded at least once, and no task got worse` [BAD]: `Write a skill about handling money` and drop it into .claude/skills with no file binding. The agent won't even open it. [GOOD]: `Bind the skill to the files shop/billing/** and in every run mark whether the agent opened it. If it never opened it, don't keep it: there's nothing to test`

In plain words

When you clean up after an AI agent and tack another line onto its instructions, you're practicing pure voodoo. Models generate an answer from scratch every time, so a lone success after your edit is an illusion of control. On top of that, the agent often just doesn't open skills if it sees no need. Cortex ends the guessing game and brings in hard measurements: every new instruction is tested with a series of runs and has to prove its worth in cold, hard numbers.

It's like a stuffy boss who rolls out a new five-page policy after every intern screw-up. On paper, order has been restored, but in reality nobody reads that wall of text, and the old processes start glitching. Cortex works like a sane team lead: it figures out whether the agent even opened the instruction, whether it helped, and whether it wrecked neighboring tasks.

All the magic rests on three utilities. The /harvest command takes your fresh fix and turns it into a reproducible test with a lesson for the future. Next, /evolve generates exactly one rule, runs the agent on tasks with and without it, and keeps the text only if there's a proven quality gain. And regular /prune audits switch off old items one by one: if nothing broke without a rule, the junk gets ruthlessly deleted.

The method was tested only with Claude Code on one small synthetic codebase (on a real open-source project it found nothing to learn), so carrying the idea further is our extrapolation. The same thinking may help with configs like .cursorrules, custom instructions and system prompts that tend to degrade into a dump of contradictory rules, wherever there's a script that can check the result. There it makes sense to replace gut feeling with measured selection.

Bottom line: stop believing in the random 'well, it worked just now' — the agent was just shooting in the dark. If a rule's usefulness can't be proven by code on tests, it has no place in the project. Measure the impact, automate the selection and cut the dead weight, or your assistant will drown in its own instructions, and you'll be the one digging it out again.

AI lab assistant

Apply this study to your task

Describe what you're working on. AI takes the method and the measured results from this paper and adapts them to your case, or writes a ready prompt built on them.

Based on Cortex: testing a coding agent's rules and skills by measurement, not by eyeballing arXiv:2610.14216

Sign in to apply this study New accounts get 50 free credits.