szpak

Put The Rules Where The Assistant Starts

A practical tutorial about moving architecture rules out of review folklore and into the repository path a coding agent must read before editing.


Peter did not approve the pull request.

The CSV export worked, but the path through the code was wrong. Reports reached into customer internals, audit data was treated like a helper, and the UI knew more than a UI should know. Peter wrote the comment he had written many times before:

Please do not bypass the application service.

It was a good comment. It was also too late. The assistant had already made the wrong decision, the team had already spent time reviewing it, and now someone had to untangle a feature which looked correct from the outside.

This is how architecture folklore becomes expensive.

Act I. The Comment That Comes Back

The next morning, Peter made coffee and opened the same pull request again. He was not angry with the assistant. That would be too easy, and not very useful. The assistant did what a fast developer without local memory often does: it used the shortest visible path through the repository.

The problem was not that the rule did not exist. The team knew the rule. Reports should ask application services for work. Customers should expose public queries. Audit data should go through audit. The problem was that this knowledge lived in review comments, conversations, and small looks people gave each other when someone imported from an internal folder.

Humans can sometimes survive that. New people struggle with it. Agents cannot cooperate with it at all.

The assistant did not know that Peter had already explained this rule in three other pull requests. It did not know that the customer module had one public seam which was considered stable. It did not know that audit was sensitive because compliance people cared about boring, predictable access. It only saw files and imports.

So Peter decided to move the rule to the place where the assistant starts.

Act II. The Small Room In The Repository

The first version did not need to be big. In fact, Peter wanted it to be small, because large instruction files tend to become polite wallpaper. Everyone agrees with them, nobody reads them, and the next shortcut still happens.

He created a small operating room for the repository:

.enclosure/
  enclosure.yaml
  rules/
  recipes/
AGENTS.md

This is the basic idea behind enclosure. It gives the repository a place to explain itself before work starts. Not after the review, not after the wrong import, not after the assistant has already guessed the architecture from nearby files.

The folder has a few jobs.

  • enclosure.yaml describes roots, tags, boundaries, dependency flow, and checks.
  • rules/ contains reading routes, so the assistant knows which guidance is relevant for the work.
  • recipes/ contains known-good starting points for repeated work.
  • AGENTS.md tells the assistant how to enter the repository before editing.

This is not about writing a constitution for the codebase. It is about giving the assistant a first door.

The Entry Rule

Peter started with the smallest useful instruction:

Start in the .enclosure/ folder and stay anchored there while discovering
project-specific operating guidance.
Before editing code, confirm the rule route you read: files read, reason, stop
point, and checks to run.

This instruction is not clever. That is why it is useful. It tells the assistant where to start and what proof of reading it must provide before touching code.

Without this, the assistant begins inside its own imagination. It searches files, finds examples, and starts implementing. Sometimes that works. Sometimes it imports from the wrong module with perfect confidence.

With the entry rule, Peter can ask for a route before the change:

Route read:
- Files:
- Reason:
- Stop point:
- Checks to run:

The assistant now has to say what it read and why it stopped there. This matters because reading everything is not the same as understanding anything. A good route is small enough to be useful and specific enough to guide the change.

Progressive Rule Reading

The trick is to avoid one giant document called something like ARCHITECTURE_RULES_FINAL_REALLY_FINAL.md.

Peter had seen those files before. They start with good intentions, grow for two years, and become a museum of decisions from five different versions of the system. An assistant can paste parts of such a document into a plan, but that does not mean it has found the rule that matters today.

enclosure works better when rules are routed progressively.

The assistant should first read the entry point. Then it should read the shallowest rule branch that matches the task. Then it should stop and report the route. If the task is about reports, read the reports rule. If the task is about module structure, read the structure rule. If the task is about a refactor, read the change rule. Do not make the assistant drink the whole lake for one glass of water.

For the CSV export, the route could look like this:

Route read:
- Files:
  - .enclosure/rules/INDEX.md
  - .enclosure/rules/shared/INDEX.md
  - .enclosure/rules/local/reports.md
- Reason: customer risk export changes reporting behavior and reads customer
  and audit data.
- Stop point: reports rule names the owner, public seams, and dependency
  direction.
- Checks to run: boundary check and affected report tests.

Now Peter has something concrete to review before the assistant edits. If the route is wrong, the code will probably be wrong too. That is a cheap moment to correct the work.

Turning The Comment Into A Rule

Peter took the review comment and wrote it as a pre-edit rule:

When changing reports:
- Reports own report orchestration and export formatting.
- Reports do not own customer risk rules.
- Reports do not own audit access rules.
- Use public customer and audit seams from the application layer.
- Stop and ask if the public seam is missing.

This is still plain language. That is fine. The first job of a rule is not to impress a tool. The first job is to make the expectation visible before someone starts work.

Later, Peter can turn part of this into deterministic checks. For example, imports from customers/internal into reports can probably be detected. But even before that check exists, the rule is useful because the assistant has to account for it in the route receipt.

This is how the cooperation changes.

Before, Peter reviewed a finished mistake. After, Peter reviews the assistant’s understanding of the rule before the mistake is made.

A Small First Setup

If you want to try this in your repository, do not start by modeling the whole system. Start with the one comment that keeps coming back.

Create the entry instruction first:

Start in the .enclosure/ folder and stay anchored there while discovering
project-specific operating guidance.
Before editing code, confirm the rule route you read: files read, reason, stop
point, and checks to run.

Then create one local rule. Keep it short:

When changing:
Owner:
Allowed public seam:
Forbidden dependency:
Checks:
Stop and ask when:

This is enough to change the conversation. The assistant can still make mistakes, but it no longer gets to pretend that the repository had no rules.

What The Assistant Should Report

Peter now expects a receipt before architecture-sensitive work. For the next CSV attempt, the assistant should say something like this:

Route read:
- Files: .enclosure/rules/INDEX.md, .enclosure/rules/shared/INDEX.md,
  .enclosure/rules/local/reports.md
- Reason: the change adds a report export and needs customer risk data.
- Stop point: reports rule covers ownership and public seams.
- Owner: reports owns export orchestration.
- Public seam: customers risk query and audit query.
- Dependency direction: UI calls reports application code; reports application
  code calls public module seams.
- Checks to run: boundary check, report export tests.

If the assistant cannot fill this in, Peter should not let it edit yet. The missing answer is not a formality. It is the place where the wrong architecture usually begins.

Exercise

Take one review comment you have written more than once. Do not choose a grand architecture principle. Choose something annoying and specific, because that is where useful rules often start.

Write it in this shape:

Start here:
Read this before editing:
Owner:
Allowed public seam:
Forbidden dependency:
Checks:
Stop and ask when:

Then ask an assistant to solve a small task and report the route before editing. Do not judge the first answer by whether it sounds professional. Judge it by whether it names the owner, the seam, and the check. If it cannot do that, the repository has not explained itself clearly enough yet.

Summary

Architecture folklore is expensive because it appears after the work is already done. A coding agent cannot cooperate with rules that only live in review comments and team memory.

The first useful step is small: put the entry rule where the assistant starts, make it report what it read, and turn one repeated review comment into a local rule. This does not replace Peter’s judgment. It gives that judgment a place in the repository before the next change begins.

In the next tutorial, Peter will add evidence to the rule. It is one thing to say that reports should not import customer internals. It is another thing to make the repository show when that line has been crossed.