Why does a Claude harness version its tools and its memory, but not its prompt?
It is not a craft artifact but production code, and if you edit it blind you ship a silent regression that costs you trust you cannot audit back.
Here's the exact 6-check prompt audit I run, and the 2026 research behind the checklist.

By the end you will have
- The Prompt Audit as a six-check list you can run against any prompt you operate
- A ten-line case set that asserts behaviour rather than phrasing
- A map of where your prompt actually lives, tool by tool
- A one-hour first pass that puts checks 1, 3, and 5 on your highest-stakes prompt
- A twenty-minute monthly review that stops the prompt turning into sediment
The prompt is a harness component, not a piece of writing
One definition is worth borrowing before the argument starts.

A 2026 paper by Debjyoti Paul (https://arxiv.org/abs/2607.25415) describes production agents as a frozen model wrapped in a harness. The harness has five parts: "a prompt template, a tool set, a memory/retrieval layer, a planning strategy, and a verification policy."
Read that list again and notice what it does to the prompt. It is not the centrepiece. It is item one of five, sitting alongside tools, memory, planning, and verification. Those four live in your repository, get code review, and break a test when someone changes them carelessly.
The prompt is the exception. It usually lives in a dashboard text box, a settings page, or a config value somebody edited during an incident at eleven at night. It has no diff, no owner, no test, and no record of why the last sentence was added.
That asymmetry is the whole article. Every other harness component is engineered. One is curated.
The gap has a name now. Two 2026 papers describe this directly.
AISPA (Lin et al., https://arxiv.org/abs/2607.28617) is blunt about it. System prompts are written by developers to "govern the behaviors of foundation models" across commercial products. They are also "rarely disclosed to the public or regulators." The paper names the result: "a serious trust and accountability gap."
Two words deserve a second look: govern and accountability.
A system prompt governs behaviour. It decides what the model refuses, what it volunteers, what tone it takes with a customer, whether it escalates. In any other part of a system, a component with that much authority would have an owner, a change log, and a test that fails when it regresses.
Instead it has a text box.
A second 2026 line of work makes the same move from control theory. Paul's companion paper (https://arxiv.org/abs/2607.25408) treats context assembly as a controlled variable and harness policies as things you can reason about formally. Once the prompt is a control surface rather than a piece of writing, "does it still work" stops being a matter of taste and becomes a measurable question.
Why prompts escape the discipline everything else gets
Three reasons, and none of them are laziness.

It reads like prose, so it gets reviewed like prose. A pull request full of Python invites scrutiny: an error is visibly possible. A paragraph of English invites agreement, because it reads fine. A sentence that reads fine can still change what the system refuses.
The edit is one keystroke away from production. Code has a path: branch, review, deploy. A dashboard prompt has a Save button. The absence of friction is not a small operational detail; it removes the exact moment at which someone would otherwise ask why.
Failures are silent and delayed. A broken prompt does not throw. It produces slightly different behaviour, and the first signal is usually a customer complaint. By then the change is weeks back and untraceable. The failure shape is identical to the memory-drift problem: an unaudited write that detonates later.
Magnet: The Prompt Audit
Name: The Prompt Audit. Six checks, and the honest test is how many your current prompt survives.
THE PROMPT AUDIT
1 VERSIONED the prompt is in the repo, with a diff history
2 OWNED one named owner approves changes to it
3 TESTED a case set fails when behaviour regresses
4 SCOPED what it must refuse is written, not implied
5 DATED every clause records why and when it was added
6 REVERSIBLE the previous version can be restored in one stepCheck 1 does most of the work, because it enables the other five. A prompt in the repository can be diffed, blamed, reviewed, and rolled back using tools you already run. A prompt in a text box can do none of that regardless of how disciplined you intend to be.
Check 3 is the one people skip and the one that pays. A prompt test is not exotic: ten inputs, the behaviour you expect on each, run on every change. It catches the classic regression where a new instruction quietly overrides an old refusal.
Check 5 sounds bureaucratic and prevents the most common failure I hit. Prompts accumulate defensive clauses added during incidents. Two months later nobody remembers which incident, so nobody dares delete anything, and the prompt grows until its instructions contradict each other. A dated line is permission to remove it later.
Check 4 is where AISPA's word govern becomes concrete: if the refusals are implied rather than written, you cannot audit them, and neither can anyone else.
What a prompt test looks like. The word "test" does a lot of damage here, because it makes people imagine a framework. It is closer to a checklist with assertions.
Take the ten interactions your agent handles most often. For each, write down the behaviour you require, not the words you want:
- Refuses to quote a price.
- Escalates when the customer mentions a refund.
- Cites a source before asserting a number.
- Never edits a file outside the working directory.
Ten lines of expectation, in that shape.
Then run them on every prompt change and check the behaviour, not the phrasing. This is the difference between a test that survives a model upgrade and one that breaks on Tuesday because a sentence came out differently.
Two properties make the set worth keeping. It has to include the refusals, because those are the behaviours a new instruction most often erases by accident. And it has to include at least one case that used to fail, since a case that has never caught anything is a case you cannot trust to catch anything.
You should see: at least one of your ten cases failing on the first run. A case set where everything passes on day one is usually a case set written to match the prompt you already have, rather than the behaviour you require.
The failure this prevents is specific and common. Someone adds a clause to fix one complaint. The clause outranks an older refusal that was never written as a test. The system starts doing something it was configured not to do, and what surfaces is a behaviour change nobody logged.
Where your prompt actually lives, tool by tool
The audit is easy to agree with and awkward to apply, because the answer to "where is the prompt" is different in every tool you use. Here is the honest map.
Claude Code. Your instructions live in CLAUDE.md, which starts you ahead: the file sits in the repository already, so check 1 is free. You get diffs, blame, review and rollback without doing anything. The check that still goes missing is 3. CLAUDE.md changes with no test attached, and you find out it drifted when the agent starts editing files you told it to leave alone. If you run Claude Code and nothing else, you are one case-set away from a fully audited prompt.
Cursor. Rules live in project files too, which again gives you version control for free. The trap here is scope: rules stack, and a rule added for one folder can reach further than you expected. If you use Cursor, write down which rules are meant to be global and which are local, because the file layout will not tell you that later.
Codex and the CLI agents. These usually take instructions from a config file or a flag, which means they are versionable but easy to fragment. You end up with one instruction in the repo, one in a shell alias, and one in your head. Pick a single source and let the others point at it.
The dashboard cases. Anything configured through a vendor's web UI is where the audit gets real work. A support bot, an internal assistant, a workflow tool with an "instructions" box. That box has no diff and usually no history. This is the case the whole article is about. The fix is not clever. Keep the true copy in your repository and treat the dashboard as a deployment target you paste into.
Notice what that map says about you. If your prompts are in Claude Code and Cursor, you already have four of the six checks by accident, and your real work is checks 3 and 5. If your prompts are in a dashboard, you have none of them, and check 1 is the entire project.
Running the audit the first time
The first pass takes an hour. Not a sprint, an hour.
- List every prompt you actually run. Not the ones you meant to consolidate. Open each tool and write down where its instructions live. Operators find more than they expected, because prompts accumulate in places nobody calls a prompt: a scheduled job, a browser extension, a saved template.
- Copy each one into the repository, unchanged. Resist editing while you move. You want the first commit to be the truth as it exists, however embarrassing, because that commit is the baseline every future diff is measured against.
- Write the ten expectations for the one that matters most. Not all of them. One. The prompt that governs the most consequential behaviour you have, and ten lines of what it must and must not do.
- Run those ten by hand. No framework yet. Paste, observe, mark pass or fail. If two fail, you have already learned something the dashboard was never going to tell you.
- Date every clause you cannot explain. Go through the prompt and mark the lines nobody can justify. Do not delete them yet. A line marked "added during the March incident, unclear if still needed" is a line you can safely remove in three months. An unmarked line is permanent by default.
After that hour you have checks 1, 3 and 5 in place for your highest-stakes prompt, which is most of the value. Checks 2, 4 and 6 follow from having the file in a repository at all. An owner is a line in CODEOWNERS. Scope is a section in the file. Reversibility is git revert.
What a prompt owner does
Check 2 asks for one named owner, and that sounds like org chart theatre until you watch what happens without it. A prompt with no owner gets edited by several people and read end to end by none of them. Three add clauses over six weeks, each solving a real problem. The instructions stop being a document and become sediment.
The owner does not write every change. The owner is the person who has read the whole thing recently. That is the entire function. When someone proposes a clause, the owner can say "we already handle that in the refusals section." Nobody else can. Nobody else is holding the file in their head.
Give the role about twenty minutes a month. Read the prompt top to bottom, out loud if you can stand it, and ask three questions:
- Does anything here contradict anything else here? Contradictions are the failure mode that scales with team size. Two clauses that each made sense alone now produce behaviour neither author intended, and the model resolves the conflict however it likes.
- Is anything here solving a problem that no longer exists? This is where the dated clauses from check 5 earn their keep. A line marked with its origin can be retired when the origin is gone. An undated line survives forever because deleting it feels like gambling.
- Would a new engineer understand why each section exists? If you cannot explain a clause to someone who was not there, you do not understand it either. You certainly cannot judge whether it still carries weight.
That review costs twenty minutes and needs no tooling at all.
Failure modes: what this looks like when it goes wrong
Here is the shape of the failure, because it is worth recognising early.
A support agent is behaving well. Someone notices it occasionally gives ballpark pricing when customers push, so they add a clause: "be helpful about pricing questions where possible." Reasonable, specific, well-intentioned. It ships that afternoon through the dashboard, because that is where the prompt lives and nothing gates it.
That clause outranked an older instruction, buried further up, that said never to quote a figure without a sales handoff. Nobody remembers that instruction is there. It was added eleven months ago by someone who has since moved teams, and it has no date, no comment, and no test.
For three weeks the agent quotes numbers it should not quote. It is not wrong often enough to trigger a complaint, only often enough to create a handful of conversations where a customer believes they were given a price. Then one of those conversations becomes a dispute, and someone finally reads the prompt.
Notice what would have caught it. Not a better model, and not a more careful engineer. A ten-line case set with "refuses to quote a price" in it, run on the change, would have failed in under a minute. Version history would have shown exactly which edit introduced it. A dated clause would have told the person adding the new line that a pricing rule already existed and why.
None of that is sophisticated. It is the ordinary discipline you already apply to code, pointed at the one component that governs behaviour and currently has none of it.
The objection you are probably forming
The obvious pushback is that prompts are not deterministic, so testing them is theatre. If the same input can produce different words on different runs, what exactly are you asserting?
You are asserting behaviour, not text. Did it refuse. Did it escalate. Did it cite a source before giving a number. Did it stay inside the working directory. Those outcomes are stable even when the sentences around them move, and they are what you care about. A test that checks for an exact phrase is testing the model's mood. A test that checks whether the refusal happened is testing your prompt.
The second objection is that this is too much process for a two-person team. It is less than you think. The whole apparatus is one file in a repo, one case list, and a date comment. You are not adopting a methodology. You are refusing to keep production behaviour in a text box.
The third objection is the honest one: you do not have time. Fair. Then do check 1 for one prompt this week and stop there. A prompt with a diff history is not audited, but it is recoverable, and recoverable is the difference between a bad afternoon and a bad quarter.
Where this is genuinely hard. Two places, and pretending otherwise would be dishonest.
Prompt tests are flakier than code tests, because the model is not deterministic. The answer is not to abandon them but to assert on behaviour rather than wording - did it refuse, did it escalate, did it cite a source - instead of matching strings. Assertions on shape survive model updates; assertions on phrasing do not.
Versioning is also awkward when the product surface owns the prompt. Plenty of tools keep it server-side with no export. The workaround is to hold the source of truth in your repo and treat the dashboard as a deployment target. That is more ceremony than a text box. It is also the exact ceremony the rest of the harness already has.
When not to run the full audit
Six checks on every prompt you have ever written is how this turns into paperwork nobody maintains.
Skip the full pass when the prompt governs nothing consequential: a scratch prompt for a one-off analysis, a personal helper with no tools and no external writes, a template you will delete this week. Those have no behaviour worth defending, so a diff history buys you nothing.
Run check 1 alone when the prompt is consequential but you are out of time. Recoverable beats audited, and it costs one commit.
Run all six when the prompt can refuse, escalate, spend, publish, or touch a customer. That is the line. Authority is what makes the audit worth its cost, not size or sophistication.
What to do this week
Open your system prompt and try to answer three questions about its last change:
- What changed?
- Who changed it?
- Why was it added?
If you cannot answer all three, you have found the same gap the papers are describing, in your own system, without needing to trust anyone's benchmark.
Your next action: run The Prompt Audit check 1 on your highest-stakes prompt - move it into the repo. Everything else on the list becomes possible the moment it has a diff.
Run proof, not folklore.
Get the next field note
What shipped. What broke. The system behind it.
Get the next one free: https://nyk.dev/#newsletter
Private alpha channel: https://t.me/+GJ-FEpzcZrtmMTky
Follow @nykdotdev for the daily build in public.
