Skip to content
GL
All posts

#AI agents#Engineering

Agents that follow the rules

What changed when I stopped prompting coding agents and started giving them a contract: an AGENTS.md index plus skills.

Most of my early work with coding agents was prompting. I would write a long message, list what I wanted, and hope it held. It held for one task. The next session started from zero, and the agent made the same mistakes again.

So I stopped writing prompts and started writing a contract. It lives in a public repo called Skills. This post is about what is in it and why it works better than asking nicely.

What the pack is

Skills has two parts.

  • An AGENTS.md file that every harness loads on every turn. It is short, and it works as an index.
  • A set of skills, each a folder with a SKILL.md: build, review, verify, write a ticket, investigate, and a few more.

It installs as a plugin for Claude Code, Cursor, and Codex, and the same skill folders serve all three. There is no Cursor-only ruleset and no Claude-only ruleset. One copy of the rules, three places that read it.

Why a contract beats a prompt

A prompt is a one-time request. A contract is standing context. It outranks the agent's generic habits, and it applies even when I never mention it.

The second difference is size. A prompt that tries to hold every preference becomes a wall of text the agent skims. The contract holds almost no detail. It holds pointers, and each pointer says when to follow it.

Mechanisms that matter

Routing by request

The skills table in AGENTS.md maps what I ask to the one skill that owns it. Asking for a feature opens the build skill. Asking for a review opens the review skill. Asking for a ticket opens the ticket skill. The agent does not improvise a weaker version of a workflow that already exists.

When the agent is unsure which one applies, there is a router skill, ask-gabriel, that acts as a map.

Rules opened at the moment they matter

Every rule in the contract is one bold line plus a trigger. The trigger names the moment to open the file. This is the line for tests:

3. **No tests unless the user accepted that test.** About to create or extend a test? Open `rules/no-unrequested-tests.md`. Skip it and you add tests the user has to delete.

The agent does not need to hold the full testing policy in mind all session. It needs to notice the moment, open the file, and read the detail then. The same pattern covers code quality, code structure, planning, shipping, and writing style. A table in the contract lists each moment next to the file to open.

Tests only with consent

Agents love writing tests nobody asked for. They restate the code, they pad the diff, and I end up deleting them. In this pack the default build skill proposes tests after the plan is settled and writes only the ones I accept. I can refuse every one, and the work continues without them. Running existing tests is always fine. Creating new ones needs my yes.

Plain-language replies

The pack has a writing style rule for chat replies. Ordinary words, no acronym-only labels, and no asking me questions the repo already answers. It sounds small, but it changes how reviewable the output is. If I cannot tell what the agent did, I cannot catch what it got wrong.

Verification matched to risk

Verification follows what changed. A small bug fix gets a reproduction check and the relevant tests. Shared infrastructure or authentication can warrant broader checks. The final report says what actually ran and what did not. Planned checks do not count as evidence.

What I learned

Three things.

  1. Short beats complete. The contract is an index. The detail lives in files the agent opens on demand.
  2. Name the trigger. A rule that says "write good code" does nothing. A rule that says "about to add a file, open this" gets followed.
  3. One source of truth. I once pasted standards into several tools. They drifted. Now there is one AGENTS.md, and the pack tells you to delete the old pastes.

The contract is not perfect. Agents still skip a step now and then. The difference is that a skipped step is now a visible breach of a written rule, not a vague disappointment. I can point at the line, and I can fix the line.

If you want to try it, the install steps are in the repo README. Start with the router skill if you are not sure where to begin.