Skip to main content
Handbook/Architect/Page 33 · Enforcement

Make the Wrong Thing Impossible

Share

Share this page

Pass it to someone who needs it.

Star on GitHub

Key takeaway: Make the wrong path impossible to take

Your rules file tells the agent what to do, and most days it listens. Then a long session runs down, the context fills, and it quietly does the thing you forbade in writing three weeks ago. This chapter is about the fix that does not depend on it remembering anything.

3.9.1An instruction can be skipped, a required argument cannot

Everything you write in a rules file is advice. It is read, weighted against everything else in the window, and sometimes loses. Nothing enforces it.

Structure is different. If the function that creates a page cannot be called without the thing you require, no amount of tiredness gets around it. Designing so the broken version cannot even be expressed has a name in engineering: make invalid states unrepresentable. You stop writing a better rule and remove the ability to break the rule.

3.9.2Require the thing you would otherwise forget

Say every form on your site must send a confirmation email. You can write that in the rules and hope. Or you can make the form impossible to build without one:

// advisory: the rule lives in a file, and gets forgotten createForm({ fields, onSubmit }) // enforced: there is no form without a confirmation createForm({ fields, onSubmit, confirmationEmail })

The second version does not need you to remember, review, or notice. A form with no confirmation is not a mistake anyone has to catch, because it will not run.

Look for these wherever a step is easy to omit and expensive to omit: the audit line on a sensitive action, the tenant filter on a query, the permission check before a delete.

3.9.3Register a family in one place

The second failure is quieter. You have five side drawers, and the agent adds a sixth somewhere new. It works, it looks fine, and it slowly drifts from the other five because nobody could see them side by side.

Anything you have more than three of belongs in one registry: drawers, forms, background jobs, outbound emails, model calls. One file lists the family, and adding to the family means adding a line there.

// ui/drawers/registry.ts export const drawers = { settings: SettingsDrawer, billing: BillingDrawer, invite: InviteDrawer, }

Now the family is one thing. You can change all of them at once, count them, and see the odd one out. So can your agent, in a single read instead of a search.

3.9.4Add a command that prints each family

Then put a command in front of every registry:

make list-forms # every form, and its confirmation email make list-jobs # every scheduled job, and its cadence make list-models # every model call, and which model it uses

Two things come from this, and the second is the point. You get an honest answer in one second without reading any code, which is how you audit a system you did not type. And the command cannot exist unless the family is genuinely grouped, so writing it keeps the grouping honest.

Rule of thumb: if you cannot list something with one command, your agent cannot see it as one thing either, and it will drift.

3.9.5Turn your rules into structure

Ready prompt
Act as a senior engineer hardening my codebase against its own mistakes. Read my rules file, my conventions, and my module boundaries first. Go through every rule I currently rely on the agent to remember. For each, tell me whether it can be enforced in the code instead: a required argument, a type that will not compile, a single entry point, a check that runs on its own. Convert the ones that can be, and say plainly which ones cannot, so I know what still depends on discipline. Then find anything I have more than three of that is not registered in one place: forms, drawers, jobs, outbound emails, model calls. Give each family one registry file, and add a command that prints that family with the detail I would want to audit. Add nothing speculative. Every registry and command must cover something that already exists in my code. If you need the full reasoning behind this step, read https://zalt.me/guides/vibe-coding/architect/enforcement My project, and the rules I keep having to repeat:

Do this now: paste the prompt, then take the one rule you have repeated most often and turn it into something the code refuses to run without.

Mahmoud Zalt

Mahmoud Zalt

Software engineer, 16+ yrs · built Sistava.com in 3 months, idea to production, using these methods

Resources
Star on GitHubContribute
Donate

Support my work

A small tip keeps the free work coming.

© 2026 Mahmoud Zalt. Free to read, not to republish.
Copyright & license