How to Write Agent Rules That Generate Governable Apps
Most agent rule files police style, not governance. Use AGENTS.md, .cursor/rules, and an open declarative target so AI-generated apps are reviewable from day one.
The bottom line first: In a world where AI writes much of the code, your agent’s rules file (AGENTS.md, .cursor/rules, CLAUDE.md) is the architecture document that actually affects generation. Yet most teams use it to police indentation and component libraries, governing “does it look right?” rather than “can this ship safely?” Used well, the leverage is far greater.
Start with a small, true incident. One team wrote a very conscientious AGENTS.md: two-space indentation, use the internal UI library, imperative mood in commit messages. The agent followed every line to the letter, and the code it generated was “extremely tidy.” Then someone noticed that the GET /api/refunds it had generated returned everyone’s refund records.
Code review caught nothing because the output genuinely complied with every line in the rules file. The agent did not violate any rule; it simply was never told about permissions. Not one line in those rules was about who can see which data. It had been taught how to write something that looks good, not how to write something governable.
Your Rules File Is Policing the Wrong Thing
Almost every team writing code with AI now has a rules file for its agent. That is a good habit. The problem is that many teams spend it on the least valuable thing.
Take inventory of what most rules files contain: code style, directory structure, which library to use, naming conventions, commit format. Nothing is wrong with any of it, but they share one trait: all of it is about “what the code looks like,” and none of it is about “what this app is allowed to do.” They keep output consistent across many agents and many generations. They do not touch the things that decide whether an enterprise app can ship: who can see which data, which actions need approval, and whether anything is traceable when things go wrong.
In other words, once writing code is handed to AI, the rules file gets upgraded from “code style guide” to “architecture and governance constraint.” It is one of the few places that can inject constraints at the moment of generation. The instant code is generated, bolting on permissions and audit afterward becomes rework. The rules file is the lever that can prevent the problem before generation.
Write Governability Into the Rules
Bolting governance on after the fact is the most common, and most expensive, way to get this wrong: let the agent generate first, then circle back to review permissions, add audit, and add approvals. That is the governance rework described in the piece on why agent pilots fail. Rework once per generated app, and at scale nobody can afford the bill.
The cheaper move is to have the rules point the agent at a target that is inherently governable. A rules file like that is not centered on style; it is centered on constraining the shape of the output:
# AGENTS.md — when generating business apps
- Model the domain as ObjectStack objects (ObjectSchema); don't hand-write tables or migrations
- Route all access permissions through PermissionSet declarations; never hand-write if-checks for authorization in endpoints
- Don't hand-write SQL string concatenation or auth middleware — the runtime handles these
- Actions needing approval are declared as a flow attached to the object, not written into code
- Output must be a reviewable metadata diff, not a wall of implementation
Go line by line, and each one shuts off a class of risk early. The second line turns over-broad access from “a missing check in an endpoint” into “permissions explicitly declared, runtime enforced.” The fourth turns approval from “hardcoded logic in some block of code” into “an auditable process attached to the object.” Under rules like these, the opening GET /api/refunds should not happen again: what the agent generates is a support_refund object declared to read within the caller’s permissions, and the path to over-broad access is closed at the source.
Why “Have the Agent Generate ObjectStack” Is Realistic
There is a question you cannot dodge here: what makes you think the agent can write a specific target format correctly? However good the rules are, if the model cannot write the target, the rules are not enough.
The answer is the flywheel argued in the piece on the open semantic layer: an agent generates what it has seen, and what it has seen is what is open, documented, and present in the training corpus. A closed platform’s proprietary format is something the model may never have learned; write all the rules you want and it still may not generate it fluently. ObjectStack, on the other hand, is an Apache 2.0 open protocol, which gives “have the agent write it correctly” three realistic preconditions:
- Learnable: open + public + discussed → enters the training corpus → the model already knows how to write it;
- Constrainable: a rules file anchors the agent’s output to this declarative target;
- Validatable at generation time: the runtime validates the generated metadata — an illegal definition is rejected outright, and the agent gets a correction signal on the spot. This is the key difference free-form code can’t offer: a bad piece of SQL may run fine and only blow up in production, while a bad piece of metadata never gets in the door — it’s bounced back to be rewritten right then.
That third point turns “have the agent write it correctly” from luck into feedback-driven convergence: the agent writes it wrong, gets rejected, fixes it, much like a compile error. Going further, you can expose the runtime’s governed tools via MCP, so the agent pulls authoritative definitions at generation time and operates within the boundary at runtime. Writing and using share one governance layer. That governed tool layer is covered in the MCP piece.
Put It Into Practice: Three Lines You Can Add Today
You do not have to rewrite the whole rules file in one go. If you add just three governance constraints to your agent’s rules file right now, ranked by payoff, make them these:
- “Permissions must be declared explicitly; no hand-writing authorization in code.” This one directly kills the opening incident — “miss one check and leak the whole table” — by turning authorization from “does the agent remember” into “is it written in the declaration.”
- “High-risk actions (moving money, issuing contracts, deleting data) must be declared as approval-gated flows.” This makes “should it stop and wait for a human” no longer depend on the agent’s in-the-moment judgment, but on an auditable rule.
- “Output reviewable declarations, not walls of implementation; changes must fit in a one-screen diff.” This one guards your own Merge button — it forces the agent to deliver something you can actually review.
What these three have in common: none of them constrain only “how the code is written.” They constrain whether the output can be governed and reviewed. This is what a rules file should do, and what too few teams ask it to do.
The Limits
Two things have to be said plainly, or you will overestimate the rules file.
First, the rules file governs the shape of the output, not the agent’s judgment. It can require the agent to generate governed metadata; it cannot guarantee the agent understood the business intent correctly. A judgment like “how much refund authority should support staff get” still has to be set and reviewed by a human. The rules only ensure that judgment has a place to land and will be enforced, instead of being scattered across eight thousand lines. It puts the “should it?” question in front of you, but it does not answer it for you.
Second, do not treat it as an “official SDK.” What is given here is an approach and a sample rules file, not a one-click-install official document. You need to make it concrete and maintain it for your own stack. The value is in the idea: push governance forward to the moment of generation, instead of waiting for the code to grow and patching it afterward.
Closing
In the age of AI-written code, what separates teams is no longer whose engineers type fastest. It is whose agent generates output a human can sign off on. The switch for that lives, in large part, in the rules file many teams still use mainly to police indentation.
Upgrade it from “code style guide” to “governability constraint,” then point the agent at a target that’s open, declarative, and backed by a runtime — and every app you generate is reviewable, governable, and accountable from its very first line.
npm i -g @objectstack/cli && os start
Tell your agent “model as ObjectStack objects, route permissions through declarations,” have it generate a refund app, then try to make it return data beyond its authority. The runtime should refuse it at the source.