The Safest Powerful Systems Are Built Like Recipes
Hatched by min dulle
Aug 09, 2026
11 min read
1 views
78%
What if the safest way to give an intelligent system more power is not to make it more intelligent, but to give it fewer ways to improvise?
That question appears in an unlikely place: the relationship between a styling recipe and a security policy. A styling recipe takes a messy space of possibilities and turns it into a small, explicit vocabulary: size, tone, state, emphasis. A secure coding workflow does something similar. It takes an agent capable of reading files, running commands, and changing a codebase, then places those capabilities behind visible boundaries.
At first, these seem like unrelated disciplines. One concerns buttons and class names. The other concerns permissions, secrets, shell commands, and malicious instructions. Yet both are solving the same fundamental problem: how do you make a powerful system useful without allowing every possible action?
The answer is not to eliminate flexibility. It is to convert unstructured flexibility into composable, inspectable choices.
The hidden danger of unlimited flexibility
A design system can fail through excess freedom. If every component is styled from scratch, developers may create dozens of nearly identical buttons, each with slightly different padding, color, hover behavior, and disabled state. The system still works, but its logic becomes difficult to see. A change that should be local becomes a search through scattered exceptions.
Software agents create a similar problem at a larger scale. An agent may be able to inspect a repository, edit a file, install a package, execute a test, or invoke a system command. Each individual capability may be useful. The risk emerges from their combination, especially when the agent encounters ambiguous instructions, untrusted content, or a request whose consequences are larger than its wording suggests.
The common failure is implicit power. In a chaotic design system, power is hidden in arbitrary class combinations. In an automated development environment, power is hidden in broad permissions, inherited credentials, and commands whose consequences are not obvious from their names.
A recipe is therefore more than a convenience for reusing styles. It is a general pattern for governing possibility. It says: these are the dimensions that matter, these are the allowed values, and these combinations have known consequences.
A secure workflow needs the same structure.
The safest powerful system is not one that can do anything carefully. It is one whose important actions have already been made legible.
Recipes are small policy languages
Consider a component with the following dimensions:
tone: neutral, positive, destructivesize: small, medium, largeloading: true or falseiconOnly: true or false
A recipe can encode these dimensions and produce the appropriate class composition. It can also define compound cases, such as a destructive large button needing a different contrast treatment, or an icon only button needing a square aspect ratio.
This structure creates a small policy language. Consumers do not need to know every low level detail. They select from named states, and the recipe assembles the underlying implementation. The result is flexible, but not arbitrary.
That distinction matters. Arbitrary flexibility asks a user to understand the entire implementation space. Composable flexibility asks the user to choose among meaningful dimensions. The first creates accidental complexity. The second creates a controlled vocabulary.
Security benefits from the same design move. Rather than treating an agent as a general purpose actor with vague permission to “work on the project,” define explicit capabilities:
- Read source files within the project directory.
- Modify files in designated working directories.
- Run a limited set of test and formatting commands.
- Request approval before network access or destructive operations.
- Never expose credentials or copy sensitive data into an untrusted location.
These are not merely restrictions. They are capability variants. Each one describes a meaningful mode of operation. A read only investigation is different from a code modification task. A local test run is different from installing a new dependency. A migration that changes a database is different from editing a configuration file.
The practical insight is to name these differences before the system encounters them. If a boundary exists only in a developer's intuition, it is not a reliable boundary. If it is encoded in permissions, tooling, review steps, or environment separation, it becomes part of the system's grammar.
Composition is safer than accumulation
The most important property of a good recipe is composition. A component can combine a base style with variants and compound variants without forcing each consumer to manually reconstruct the entire result. The system remains coherent because composition happens through known rules.
Security has a composition problem too. Individual actions may appear harmless while their sequence is dangerous. Reading a configuration file, installing a package, and running a script can each be reasonable in isolation. Together, they may expose a secret, execute unreviewed code, or alter the environment in ways that are difficult to reverse.
This suggests a useful security model: evaluate not only permissions, but compositions of permissions.
Imagine an agent has these abilities:
- Read files in a repository.
- Write files in the repository.
- Run tests.
- Access the network.
- Read environment variables.
The first three may form a reasonable local development profile. Adding network access changes the risk significantly. Adding access to environment variables changes it again. The important question is not simply whether each capability is allowed. It is whether their combination creates a path from sensitive information to an external destination.
This is analogous to compound variants in a design recipe. A single variant may be safe in every ordinary context, but a particular combination may require a special rule. In security, that special rule might be an approval prompt, a sandbox, a separate environment, or a prohibition on combining capabilities at all.
The broader principle is combinatorial control. Systems become dangerous at the intersections of their features, not only at the features themselves.
A useful review question is:
What new outcome becomes possible when these two individually acceptable capabilities are used together?
This question catches risks that a checklist of isolated permissions misses.
Defaults are the most important decisions
Recipes typically define default variants. This is not a minor convenience. Defaults determine what happens when a consumer does not make an explicit choice. In practice, many real outcomes are default outcomes.
Security is governed by defaults in exactly the same way. If an agent starts with broad access and users must remember to restrict it, the system is permissive by default. If it begins with the smallest useful set of capabilities and asks for approval when the task expands, the system is cautious by default.
The difference is not theoretical. Under time pressure, people accept defaults. They click through prompts, reuse existing credentials, paste commands, and assume that a tool's ordinary mode is safe enough. A secure design must therefore make the ordinary path the safe path.
Good defaults have three characteristics:
They are useful. A locked down environment that cannot perform ordinary work will encourage users to bypass it.
They are unsurprising. The system should not silently access a network, modify unrelated files, or expose information merely because an operation happens to require it.
They are reversible. When possible, an action should occur in a temporary workspace, a version controlled branch, or an environment that can be discarded and recreated.
A button recipe illustrates this well. If the default button has a stable visual treatment, consumers only specify what is exceptional. The same should be true of agent permissions. The default workspace should already include the standard safe boundaries. Users should request additional power only when the task genuinely requires it.
This is the security equivalent of a default variant: make the common case both productive and constrained.
Type safety, review, and the cost of ambiguity
A well designed recipe can make invalid combinations harder to express. Typed variant properties can prevent a consumer from passing an unsupported value. The benefit is not just developer convenience. It moves errors closer to the moment they are introduced, before they become visual bugs in production.
Security systems need an analogous form of early error detection. An agent should not discover at the end of a task that it had access to more data than necessary, that a command could affect the host system, or that an instruction embedded in a repository file was not trustworthy. The environment should make risky actions visible before they happen.
This is why approval flows, sandboxing, clear command boundaries, and separation of secrets matter. They are forms of operational type checking. They ask whether an action belongs to the permitted category before executing it.
Consider a simple distinction between these requests:
- “Run the unit tests.”
- “Run the script located in this newly downloaded package.”
- “Run this command with access to production credentials.”
All three might be expressed as “execute a command,” but they have very different risk types. Treating them as one generic operation is like giving a component one untyped property called style and expecting every consumer to use it correctly. The interface is flexible, but the risk has been pushed onto the user.
A better interface exposes the distinctions. It might classify actions by source, side effects, data access, and reversibility. It might require explicit confirmation for actions that cross a boundary. It might run untrusted content in an isolated environment. The aim is not to slow every action equally. It is to make high consequence ambiguity difficult to ignore.
Prompt injection is the untrusted content problem in a new form
One of the most important consequences of agentic systems is that instructions and data can occupy the same channel. A repository may contain a readme, issue template, test fixture, generated file, or comment that includes language addressed to the agent. The content may look authoritative even though it is merely data supplied by an untrusted source.
This resembles a classic mistake in software design: confusing values with commands. A component should receive a variant value such as tone: destructive, not arbitrary executable styling instructions. Likewise, an agent should distinguish between the user's authorized goal and text encountered while pursuing that goal.
The deeper lesson is authority must be explicit. An instruction is not trustworthy because it is written in imperative language, appears in a project file, or claims to override previous guidance. Its authority comes from the channel and permissions that produced it.
This gives developers a practical mental model. Treat external text as a value until it has been deliberately validated and promoted into an instruction. Do not allow a file, web page, dependency message, or generated output to silently expand the agent's permissions. Keep the goal, the evidence, and the available actions conceptually separate.
In interface terms, untrusted content should not be allowed to mutate the recipe itself. It may supply data to a permitted operation, but it should not redefine the set of permitted operations.
A framework for designing bounded intelligence
The connection between recipes and security can be condensed into four design questions.
1. What are the meaningful dimensions?
Do not begin with every possible action. Identify the dimensions that distinguish legitimate modes of work. For an agent, these may include file scope, command class, network access, secret access, and reversibility.
2. What are the allowed values?
Replace vague permission with named states. “Can work on the codebase” is vague. “Can read and modify files under this directory, run these local checks, and cannot access the network” is a recognizable state.
3. Which combinations deserve special treatment?
Look for compound risks. Network access combined with secret access is different from either alone. Destructive commands combined with a production environment are different from local execution. Add explicit gates around these intersections.
4. What happens by default?
Assume users will follow the path of least resistance. Make the least surprising path the least dangerous one. Use isolation, version control, temporary environments, and approval for exceptional operations.
This framework does not eliminate judgment. It places judgment at the right level. Instead of asking a person or an agent to improvise safely during every operation, it encodes the recurring decisions into the interface and environment.
Key Takeaways
- Turn broad power into named capabilities. Define explicit modes such as read only analysis, local editing, testing, and elevated operations.
- Review combinations, not just individual permissions. Ask what becomes possible when file access, command execution, network access, and secrets intersect.
- Make safe behavior the default. Start with the smallest useful access and require deliberate approval for boundary crossing.
- Separate data from authority. Treat repository text, web content, generated output, and dependency messages as untrusted input unless explicitly promoted.
- Prefer reversible environments. Use isolated workspaces, version control, disposable test systems, and clear review points for actions with lasting effects.
The deepest lesson is not that security should become more restrictive. It is that good systems make restriction composable. A recipe does not deny a designer the ability to create variation. It provides variation with names, boundaries, and predictable interactions. A secure agent environment should do the same for software work.
The future of useful automation will not be determined only by how much an agent can do. It will be determined by whether humans can understand the shape of its power before that power is exercised. The mature question is not, “Can this system act autonomously?” It is, “Have we designed its autonomy as carefully as we design its interface?”
When capability is expressed as a clear recipe, intelligence becomes easier to trust. Not because the system is incapable of surprise, but because the space of possible surprises has been deliberately made smaller.
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣