Essay record

System Guardrails for Software Factories - Building Pits of Success for Agents and Humans

Record
Essay / / 5 min read / 1,361 words
On this page8 sections / +

DISCLOSURE: Some links may be affiliate links. Details

I've been diving into software factories and how they're built as I believe that's where the industry is heading. AIs can crank out reasonable code much faster than we can and often at same or higher quality if given the right constraints.

But the question remains of how we get there and my current hypothesis is Durable Context, Disposable Code. But for code to be disposable and for humans to no longer need to look at every line we need better guardrails for what shape it takes - and I think System Guardrails helps to fill that gap.

System Guardrails

The goal of System Guardrails is to build a pit of success for agents to fall into.

  • Paved roads for how to do common things
  • Guardrails to prevent common gotchas / classes of problems

We've long sought to build these out for humans and now we move to doing it with agents where it's arguably more important given the increased velocities.

Like many types of guardrails, the idea is to shift them as far left as possible in the dev cycle. The earlier in the cycle we can provide feedback on the direction, the faster and cheaper it is to correct.

So as we look at these System Guardrails, we want to try and move as many checks as we can to be as fast, early, and deterministic as we can. Not all checks will be able to do this but many can and over time I expect more to shift left as technologies improve.

Types of System Guardrails

This list is by no means exhaustive but I do think it's useful to provide buckets of things to look for to help build a mental model around them.

These are listed in most left to least left so we should try to put our guardrails in the earliest bucket we can.

Structural Guardrails

Structural Guardrails provide 1 clear paved road and make invalid routes unrepresentable.

Examples include:

  • A clean codebase - A pristine codebase that leads newcomers into a pit of success. Clear APIs, good examples, good structure. AIs copy what they see and so if the examples and structure is good, it vastly constrains the opportunity space.
  • Types making invalid states unrepresentable - Types have always been a great way to structure code and share context about what a program is supposed to do. This is why I've always been in favor of types. Here that gets even more useful as we move to hands-off AIs coding everything.

Mechanical Guardrails

Mechanical Guardrails are deterministic rules that give clear feedback on rule breaks - think linters, compilers, CI, git hooks, CLI tools.

These rules can catch more things around structure and behavior that Structural Guardrails by themselves may not catch, especially as agents change the structure itself. In general these can be very cheap because they're deterministic and scriptable so we can run them early in the dev cycle and get good feedback from them.

These are particularly good for adding in new constraints to the system - add in a mechanical guardrail to stop the bleeding for some gotcha, then land all the fixes to build in good structural guardrails.

Examples include:

  • Static analysis via type checks / compiler - one reason I've been so bullish on Rust is it gives us more of these guardrails out of the box
  • Linters for code rules - suggest better forms, completely block bad forms
  • Deterministic tests - unit, integration, e2e

Judgement Guardrails

Judgement Guardrails are less deterministic rules where a reviewer interprets the result and determines if the result is valid.

These rules can have a much broader coverage than Mechanical or Structural Guardrails. At this level we can basically cover ~anything that an AI can parse and we have some sort of decision criteria for. The downside is these are less deterministic and typically cost more both in time and money.

Examples include:

  • Automated code review on PRs / in dev cycles - This is table stakes at this point and AIs are quite good at reviewing!
  • CLI tools for common operations like creating/running migrations/refactors, tracing app performance, and verifying app flows - These can help an AI drive a deterministic first step but often still need a parsing and validation step by an AI to determine if the outcome is good or not
  • Comparing the Durable Context (what the system should do) with what the system actually does and making calls on what should change

Guidance Guardrails

Guidance Guardrails are context that an agent or human should follow.

These rules can cover anything you can write down. But the downside is that adherence is sporadic - an agent may not read the context or if it does it may not put as much emphasis on the guidance and ignore it anyway - and it can be costly - poor management can lead to increased token budgets with limited or even negative outcomes.

So this context is extremely flexible and useful but it's much harder (if not impossible) to ensure that it's actually being followed to the letter and 100% of the time.

Examples:

  • Details about how an area of the app should work - note: this is Durable Context! So while I think Durable Context provides a good structure of what a system should do it is a poor standin for actually keeping that system quality and direction on track, thus the need for System Guardrails to actually enforce it.
  • Skills for doing common things like running PRs, formatting docs
  • Change Context for carrying out a given project

Building Software Factories

So my current hypothesis is to build a software factory that balances speed and quality, we need more than just System Guardrails.

Agents travel toward the destination defined by durable context, bounded by system guardrails on both sides of the path.

We need:

  • Durable Context - The DNA of the system, setting what the system should be doing
  • System Guardrails - The enforcement that we're utilizing best practices and avoiding known issues

Together this gives us a clear framework for evolving our system over time and ratcheting up quality as we remove classes of misalignment.

In this vein I think System Guardrails that span multiple types are often some of the most effective.

  • Verification - You can have a deterministic cli an agent can utilize to drive the app (mechanical) that provides results the agent can easily parse and review (judgement)
  • Direction - You can have Durable Context (guidance) to explain how an area of the app is structured / should work which can allow agents to build better behavior-driven tests to enforce it actually does that and stays that way (mechanical)
  • Self Improvement - You can have AI reviewers (judgement) that find common patterns / mistakes in the codebase that then propose updates to prevent those altogether (structural) or go ahead and build out lints to prevent those from being pushed (mechanical)

Sprinkle in some loops and checkpoints to provide feedback on how things are working in prod and taking those bits of feedback to evolve the system further and we approach not only a factory but the beginnings of an almost organically evolving system.

Next

So that's how I'm thinking about building software factories. I'm experimenting more with this at work and in my personal projects. I think this area is early so will likely be much better approaches coming out but I'm very bullish this is where the industry is going.

Special thanks to all my HAMINIONS Members for making free posts like this one possible. If you liked this and want to see more of it or just want to get access to my monthly snapshots of my AI Dotfiles then consider joining today.

If you liked this post you might also like:

Built with CloudSeed Rust