Dallen Pyrah
Software Engineer
I build software for people and agents, but most of the work begins before I write the software.
I start with a premise. Then I question it. What has to be true for this to work? Where does it break when the team, the company, or the scale changes?
When reasoning stops being enough, I prototype. Prototypes introduce failures that are difficult to imagine in advance, and those failures are not interruptions to the design process. They are the design process.
I keep going until the system feels coherent and more of its truth lives in the software than in the memory of the people who built it. This site is where I work through those ideas in public.
New: The Resident Model
→ If something here gives you a new way to think about a problem, send me a message on X.
Work
- BatonFX
A TypeScript framework for building AI agents with Effect.
The idea behind BatonFX is that an agent should still feel like ordinary software. An agent is an Effect value: instructions, typed tools, a policy for how a turn proceeds. Its dependencies are services, so they can be replaced, composed, and tested like the rest of an Effect application.
The seams around the agent have deterministic test implementations, so behavior runs in CI without API keys or live model calls. The model remains probabilistic. The system around it does not have to be.
- RelayFX
Durable orchestration for agents and long-running work.
Processes restart. Machines disappear. Deployments happen halfway through a run. RelayFX begins from the premise that none of those events should erase the work.
Each step of a run is recorded in the database before it executes. If the process dies, the history replays and the work continues. Postgres, MySQL, or SQLite: the database you already operate can carry the execution history too.
- FoldCN
Accessible components for FoldKit, distributed as source.
86 components built on @foldkit/ui and Tailwind. The CLI copies the source into your repository, where it can be themed with CSS variables and changed without waiting for a dependency to expose the right option.
I prefer this model because the component becomes part of the system that uses it. You can inspect it, understand it, and change it when the design changes.
How I think
I start with a premise, but I do not trust it yet
Most design work begins with something that appears to be true. The first thing I do is question it. What evidence supports it? What would make it false?
I keep decomposing until I can see the parts, the boundaries, and the assumptions crossing them. That becomes the model. When its predictions stop matching reality, I change the model.
I use prototypes to discover what reasoning missed
There are failures you cannot predict because they exist outside the model you have built. That is why I prototype.
Sometimes a design feels wrong before I can explain the flaw. I trust that signal, build alternatives, and compare them until one feels coherent. The explanation often arrives after the discovery.
I look for the stable abstraction beneath the current use case
Requirements change. Organizations change. Teams change. A good abstraction captures the part of the problem that remains true while everything around it changes.
I know I am beginning to understand a problem when I can see that stable shape.
I compare models, not conclusions
When another engineer suggests an alternative I already rejected, I want their reasoning, not their conclusion. Maybe they missed a consequence. But maybe their model contains a constraint mine did not. Then the alternative becomes interesting again.
I can change my mind about almost anything when the new reasoning expands the bounds of the problem.
I care about where a design fails
Traffic is scale. But so is complexity, team size, trust, and the amount of context an engineer or agent has to carry. A design can handle a hundred times more traffic and still fail because nobody knows who is responsible for it.
A good design is not one that never fails. It is one whose failure modes are understandable, contained, and recoverable.
I move the model into the system
A system becomes fragile when too much of its meaning lives only in the head of the person who designed it. So when a model becomes stable, I encode it: types carry constraints, schemas reveal the domain, names help the next person form the correct model faster.
The goal is to stop requiring people and agents to rediscover the same truth every time they enter the system.
How I work
I build the smallest thing that can challenge the idea
A spec, a failing test, a thin vertical slice. I am not building the product early. I am building the smallest environment in which the model can fail.
The failure is information.
I use evidence when authority is not enough
You build the prototype. You collect the numbers. You make the alternative concrete enough that the organization can evaluate it as evidence rather than opinion.
A working system changes the discussion.
I treat engineer behavior as feedback about the system
When capable engineers keep skipping a required step, I do not assume they are careless. Maybe the step is too manual. Maybe the incentives reward skipping it.
The system should make the correct action the practical one.
I automate work the system already understands
When a step is necessary, repeatable, and unpleasant, I automate it. If the system already knows what must happen, a person should not have to remember it.
When every deadline is urgent, this foundational work disappears, and the team keeps paying the same cost forever. Slack is not slowness. Speed comes from removing friction, not from pushing people through more of it.
I stay close to the work
You cannot understand why an organization is moving slowly from a dashboard. You have to talk to the engineers and see where their time goes. The engine is where the answers are, not the fuel.
Engineers can usually solve the problems in front of them. What they sometimes lack is permission. I use questions until they see the system clearly enough to feel able and responsible to improve it.
I cut scope before I cut trust
I would rather ship a narrow system whose behavior is clear than a broad system that works inconsistently. A product can grow later.
But once people learn that the system does not keep its promises, every future interaction carries that doubt.
Writing
- The Resident ModelAn actor is usually a process that owns its state. A resident is state that occasionally borrows a process. An introduction to the model behind Relay.
- Interface-Driven DevelopmentCoding agents should not have to memorize a repository before they can work inside it. Give them a surface they can navigate, inspect, and verify.