DEV Community

Devflow AI
Devflow AI

Posted on

SKILL.md is not a compiler

If you use Cursor long enough, you will watch it ignore a rule you wrote down.

You add a SKILL.md. You tell it "no explicit any". You maybe add a hook. It agrees. Then it ships id: any anyway.

A comment on a thread about skill files put it cleanly: the model can work around hooks too. That is not a Cursor bug. It is what "the instruction is text" means.

What a Skill File Actually Is
A SKILL.md is a document the agent is supposed to read when the task matches. .cursor/rules and hooks are the same family: they change the prompt, not the type system.

Attention is limited. Mid-thread, the ratio of "your rules" to "the last twenty tool results" gets worse. The model locally prefers completing the user's latest sentence over satisfying a file it saw at the start of the turn.

So:

Skills are good at default shape: interfaces, try/catch, test file next to the change.

Skills are bad at guarantees.

If your workflow assumes the markdown file is a compiler, you will keep getting surprised.

The Setup That Survives a Skip
Treat generation and verification as different jobs.

Layer 1 — The Skill
Tell the agent how you want code to look. Keep it short. Long skill files are just more tokens to ignore.

Layer 2 — A Command That Can Fail
After the edit, run whatever this repo already uses:

Bash
npx tsc --noEmit
npm test -- --run path/to/changed-file
Use the scripts in package.json if they exist. Do not invent a parallel toolchain so the agent can look thorough.

The skill's job is to remember to run Layer 2, and to refuse the sentence "this is production-ready" when Layer 2 did not run.

That is the whole product. Not a smarter prompt. A prompt that stops lying when tsc is red.

A Small Example
Layer 1 alone often still emits this:

TypeScript
async function getUser(id: any) {
const res = await fetch('/api/user/' + id)
return res.json()
}
You can write a skill that forbids any. Sometimes it works. Sometimes the chat is long and it does not.

Layer 2 does not care about the chat. tsc --noEmit fails until id is typed and res.ok is handled. Tests fail until a non-200 is covered. The agent then has to edit against a failing command, which is a much stronger signal than a paragraph in SKILL.md.

What to Do in a Live Session
Keep skills tiny: Four rules beat forty.

End requests cleanly: End every "make this production-ready" request with "run typecheck and tests, paste the output."

Reset threads: Start a new chat when the thread is doing two features. Skills do not reset attention math.

Use hooks strictly: If you use hooks, keep them for formatters and secret scans — deterministic tools. Do not expect a hook to be a second personality that the model cannot dodge.

If You Want the File
The SKILL.md I use for this is a two-layer review gate: read the diff, then run the repo's typecheck/lint/test and print the commands. It lives in this studio as two-layer-review-gate. Use it as a template; the valuable part is Layer 2, which you already have if your repo has tsc.

I will put the listing on PromptBase after the current reviews clear. Until then, the article is the whole method.

Subscribe if you want the next one: how to hand a session to a fresh chat without dumping 40k tokens of history into the new thread.

Originally published on Substack: https://apparatusappello861559.substack.com/p/skillmd-is-not-a-compiler

Top comments (1)

Collapse
 
citedy profile image
Dmitry Sergeev

finally someone said it. cursor definitely starts ignoring rules once the context window gets too cluttered lol