A 1972 paper might be one of the most practical tools for building safer AI agents. Make it impossible: Use types, APIs, and module boundaries to prevent invalid states and dependencies. Detect it deterministically: Use tests, linters, ty...
A 1972 paper might be one of the most practical tools for building safer AI agents.
In 1972, David Parnas argued that software modules should hide design decisions that are likely to change.
More than five decades later, that idea has a new job: making codebases safer for AI agents to work in.
Here’s why it matters.
🤖 1. Agents don’t just need context. They need boundaries.
Giving an agent more files, documentation, and instructions doesn’t automatically make its changes safer.
A module with a clear interface and hidden implementation details gives the agent a smaller, more reliable surface to reason about.
But a leaky abstraction changes everything. The interface may look simple while hidden state, locking requirements, retries, or undocumented assumptions determine whether a change is actually safe.
The agent can be confident and still be wrong.
🏗️ 2. Small modules don’t solve every problem.
Limiting module size, interfaces, and dependency fan-out helps contain implementation changes.
But what happens when a widely used interface changes?
Now the agent may need to understand every caller that depends on it.
The cost of a change isn’t determined only by the size of the module being edited. It also depends on how many other parts of the system rely on its contract.
Sometimes, duplication is safer than extracting a shared abstraction—especially when caller relationships are difficult to discover reliably.
🛡️ 3. Make invalid changes impossible, not merely discouraged.
There’s a hierarchy to building agent-harnessable software:
Make it impossible: Use types, APIs, and module boundaries to prevent invalid states and dependencies.
Detect it deterministically: Use tests, linters, type checks, and architectural fitness functions.
Judge it probabilistically: Use AI reviewers where judgment is genuinely needed.
Assert and hope: Rely on prompts, context files, and written principles.
Documentation still matters. But a rule enforced by the build is stronger than a rule an agent must remember.
A practical experiment for this week:
Choose one architectural boundary in your codebase.
For example: The domain layer must not import the database layer.
Turn that principle into a rule that fails the build when violated.
You’ve moved one architectural decision out of the agent’s memory and into the system itself.
That’s the shift: from asking an agent to behave correctly to designing a codebase where correctness is easier to preserve.
One important caveat: this is a structural argument, not yet proof of a causal relationship. The hypothesis deserves to be tested, not treated as settled science.
Question for developers: Which module in your codebase would you least trust an AI agent to modify—and is the problem the code itself, or the boundaries around it?
📖 Read Chapter 10 of The Agentic Development Lifecycle:
https://neam-lang.github.io/The-Agentic-Development-Lifecycle/chapters/10-structural-engineering.html
Next: What happens when an attacker starts testing those boundaries?