A repository set up for agents
An AI agent writes much of the code in this product repository. What makes that work isn't a clever prompt. It's a set of layers, each catching what the one before can't: instructions that give their reasons, a skill for the house style, scripts that check what prose can't enforce, a hook that runs on every commit, and people who approve every release. This case walks through each layer and the rule for choosing between them.
1. The situation
One product, several stacks: Kotlin, Flutter and a web frontend tested with pnpm. A coding agent (Claude Code) does much of the implementation. Every session starts fresh: whatever the agent learned yesterday is gone unless it's written down somewhere it reads.
The failure that shaped the setup was small and typical. Asked to run the tests, the agent ran a bare pnpm test, saw green, and reported success. That command runs 7 of the 135 tests. Nothing in the repository said so, so the agent couldn't have known.
2. What mattered
- The agent forgets between sessions. Anything it must know every time has to live in a file it loads every time (Module 09).
- Prose is a suggestion. An instruction can be skipped or misread under a long context. Rules that must never break need something that runs (Module 12).
- Context is limited. The house style is long and only matters for UI work; loading it into every session wastes context (Module 02).
- Checks must apply to whoever commits. A person, the agent, or a CI job: the same fast checks every time.
- Shortcuts must be visible. When the agent cuts a corner on purpose (a stub, a skipped edge case), it must be recorded, not buried.
- People stay accountable. The agent prepares; a person approves merges and releases.
3. The options
Every rule in the repository could live in one of five places. They differ in when they load and whether anything enforces them.
| Layer | When it applies | Good for | Weak at |
|---|---|---|---|
| A. Instructions | Loaded at the start of every session (CLAUDE.md, AGENTS.md) | Commands, layout, rules with their reasons | Enforcement: the agent can still skip a line |
| B. A skill | Loaded only when the task matches its description | Long procedures for one kind of work | Anything needed on every task |
| C. A checker script | When the agent (or CI) runs it, before saying "done" | Anything a program can decide: unstyled classes, contrast, test counts | Judgement calls |
| D. A git hook | On every commit, whoever commits | Fast checks that must never be skipped | Slow suites; it's skipped with --no-verify |
| E. A human gate | Pull-request review, the pre-ship runbook | Accountability, product judgement, releases | Speed; it doesn't scale to every small rule |
4. The decision
Use all five, and put each rule in the cheapest layer that reliably holds it. The repository today:
| Practice | Where it lives | Lesson |
|---|---|---|
| Project instructions with reasons | CLAUDE.md | Every rule carries its why, and many record a past failure ("a bare pnpm test runs 7 of 135 tests") |
| Docs as the source of truth | A "Keeping docs in sync" table in CLAUDE.md | The agent knows which document to update for each kind of change |
| A skill for the house style | .claude/skills/frontend-styling/SKILL.md | Procedure, shared classes, and checker scripts to run before "done" |
| Deterministic checks the agent runs | tools/check_unstyled_classes.py, check_theme_contrast.py, tools/preflight.sh | Scripts enforce what prose cannot |
| A pre-commit hook | .husky/pre-commit | Fast checks on every commit, whoever (or whatever) commits |
| Rules files per language | .claude/rules/kotlin/*, .claude/rules/flutter/* | Language conventions loaded as instructions |
| Shortcuts recorded, not hidden | docs/pre-production-checklist.md | An agent's deliberate shortcut gets a row in the same pull request |
| Memory for preferences | Claude Code auto memory | "Batch features into one PR", "verify with real hardware" |
| Human gates | Pull-request review, a pre-ship testing runbook | The agent prepares; a person approves releases |
5. How it works
One illustrative change, a new settings screen in the web frontend, passing through every layer.
6. What decides it
Where should a rule live? Pick a rule, or answer the questions for one of your own. The questions run from cheapest to most expensive layer.
Order matters: if a program can decide it and it must never break, a hook or a script beats a sentence, because the sentence can be skipped. Instructions carry what the agent needs every time; skills carry what it needs sometimes; people carry what needs accountability.
7. How it played out
The test-count failure became a line in CLAUDE.md that keeps its reason: the bare command runs 7 of 135 tests. That reason is what protects the rule. A future reader, human or agent, who sees only "use the full-suite command" might "simplify" it back; one who sees the 7-of-135 note won't.
The rest of the repository follows the same idea: each rule sits in the layer that can hold it. The house style is a skill with its own checker scripts, fast checks run in the pre-commit hook whoever commits, deliberate shortcuts get a row in the pre-production checklist, and a person approves every release.
No before-and-after numbers were recorded, so this case doesn't claim any. Section 9 is the experiment to measure it on your own repositories.
8. Lessons
- Write the reason, and the failure, with the rule. "Run the full suite (a bare
pnpm testruns 7 of 135)" survives refactoring; "run the full suite" gets simplified away (Module 09). - Scripts enforce what prose can't. If a program can check it, write the program and tell the agent to run it before saying "done".
- Load long know-how only when needed. A skill keeps the house style out of every unrelated session (Module 11).
- Hooks don't care who commits. The pre-commit hook treats the agent, a person and a CI job the same (Module 12).
- Make shortcuts visible. A deliberate shortcut is fine; a hidden one is a bug waiting for production.
- Keep a person on the release. The agent prepares the change and the evidence; a person decides (Module 21).
9. Your turn
- Inventory (15 min). List the last five things you corrected an agent on in one repository. For each, use section 6 to decide which layer should hold it.
- Copy the pattern (an afternoon). In a second repository add: instructions with reasons, one skill, one checker script the agent must run, a pre-commit hook, and a shortcuts checklist.
- Measure (one week). Count how often you correct the agent in each repository over the next week. Compare.
- "How do you make an AI agent reliable on a real codebase?" Layers. Instructions with reasons for what it needs every session, skills for long procedures, scripts and hooks for anything a program can check, and a human gate on merges and releases. Each rule goes in the cheapest layer that reliably holds it.
10. Check yourself
Why did the agent report "tests pass" when most tests hadn't run?
A rule a program can check, which must never break, belongs in…
Why is the house style a skill rather than part of CLAUDE.md?
What happens when the agent takes a deliberate shortcut?
11. Sources and further reading
| Source | Why |
|---|---|
| agents.md | The open format for project instructions that all five tools read. |
| agentskills.io | The Agent Skills format behind the house-style skill. |
| githooks (Git documentation) and Husky | How pre-commit hooks run, and the tool this repository uses to share them. |
| Module 09, 11 and 12 | Instructions and memory, skills, and hooks in depth. |