---
name: context-engineering-audit
description: Audit and cut what an agent loads before the user types — system prompts, CLAUDE.md/AGENTS.md, skill and tool descriptions. Use before trimming any instruction file, or after a model-generation change makes old prompt scaffolding counterproductive.
license: MIT
tags: [context-engineering, prompts, claude-code, agents, audit]
agents: [claude-code, codex, cursor]
category: workflow
metadata:
version: "1.0.0"
capabilities:
network: false
filesystem: readwrite
tools: [Read, Edit, Bash, Grep]
resources:
- path: story.md
type: file
- path: references/measuring.md
type: file
- path: references/coupling-check.md
type: file
- path: references/rewrite-patterns.md
type: file
---Context Engineering Audit
Every agent session pays for its instructions before the user types a word. This
skill is a method for finding out what that costs, what it buys, and what to cut.
The order matters. Measuring before cutting keeps you honest about where the
tokens actually are; the coupling check keeps you from deleting a constraint
something depends on. Skip step 3 and you will eventually delete a rule that a
validator, a parser, or a test was relying on.
1. Measure before you cut
Get real numbers per injection source rather than guessing from file sizes.
Sources usually rank: the imported instruction file, the skill listing (every
skill's frontmatter description, always loaded), the global instruction file,
deferred tool names, the agent listing, MCP server instruction blocks, hook
output.
See references/measuring.md for where each lives and how to count it,
including reading the session transcript's attachment records.
Record the total. A restructure that doesn't move it is a restructure you can
skip.
2. Classify every section into four buckets
- Gotcha — non-obvious, expensive to rediscover, cheap to state. Keep upfront. ("Tags are a hard gate: they filter before scoring." "stdout is reserved for the MCP protocol.")
- Runbook — needed by a minority of sessions, in full when needed. Move to a doc or skill and link it.
- Restates the tree — a table of paths that a directory listing already shows. Delete.
- Duplicate — the same instruction in a second place. Pick one home.
The tell for a runbook is a command sequence. The tell for a duplicate is that
you've read it twice in one file.
3. Coupling-check before deleting anything
This is the step that pays for the skill. Prompt text is often load-bearing in
ways nothing documents.
Before cutting a rule, search for code that depends on it: response validators,
output parsers, harness branches, and tests asserting on prompt strings. Then
give each rule a verdict — load-bearing (keep the substance, change the
framing), format contract (move it into the schema or tool description), or
residue (delete).
Two failure modes worth knowing, both real:
- A prompt asserting something the harness doesn't actually do ("your work will not be delivered unless you call X" — when a fallback path exists). Fix the claim, don't preserve it.
- A prompt whose output is discarded downstream. Reasoning scaffolds are the usual case: check whether a sanitizer strips the very blocks you're asking for.
references/coupling-check.md has the search patterns and the verdict table.
4. Rewrite coercion as product-context facts
On current model generations, exhaustive prohibitions cost quality rather than
buying it. State what the system does and let the model reason.
"CRITICAL: These tools are NOT optional. Your work will not be delivered!"
becomes
"The user sees yourpresent_resultpayload — summary condensed for chat,
content attached as a file. Exit without it and the harness falls back to
condensing your raw final message."
Keep every constraint that survived step 3. Change only the register.
More before/after pairs in references/rewrite-patterns.md.
5. Add drift guards, then verify
Instruction files regrow. A size budget and an imperative-word budget as
ordinary tests will catch it:
assert.ok(composed.length <= BUDGET, `${composed.length} chars, budget ${BUDGET}`);
assert.ok((text.match(/\b(NEVER|ALWAYS|MUST|CRITICAL|MANDATORY)\b/g) || []).length <= N);
Set the ceiling just above where you landed, with a comment on what earned the
headroom. Watch the floor too: cached prompt prefixes have a minimum below
which they silently stop caching, so cutting past it trades a small token saving
for a cache miss on every turn.
Verify with /context in a fresh session before and after, and re-run the
suites that touch prompt assembly.
Notes from practice
- Rule density is often lowest in the files people suspect first. Measure imperatives per 1k chars before assuming an instruction file is the problem — the offender is frequently a plugin or a runtime prompt nobody reads.
- A repo's own history can tell you whether coercion worked. Commits that fix "the model hesitated" or "the model looped" are usually patching damage an earlier absolute rule caused.
- Moving content beats deleting it when a prior finding says a model generation still wants the structure. Progressive disclosure is generation-neutral; rule-density rewrites are not.