Skip to content
Automation Forge

Trinity Architecture

A company practice, applied across every Blackcode project.

Software, human, machine — and every edge intentional.

Software has always had two sides and one connection. A second user has appeared in that relationship, and it is a machine. This is how we build for both of them at once.

Hover an edge to read it.

interfacetoolsinstructionSoftwareone typed surfaceHumana thin client over itMachinea different thin client, same surface

Three relationships, not one shape. Choose an edge to read it.

What changed

The second user is not a script.

With agents, with the Model Context Protocol, and with tool-calling as a first-class model capability rather than a bolt-on, a machine now consumes software directly. Not a script driving a user interface built for somebody else — a genuine consumer, with its own needs, its own failure modes, and its own way of discovering what a system can do.

So we design for a triangle rather than a line. And the distinction that matters is not that the software is accessible to machines. It is that no function is written for a human and adapted for a machine afterwards. Both are first-class citizens of the same surface.

In practice

Six rules. Each one rules something out.

One surface, two thin clients.

Every operation lives on a typed editor subsystem. The editor UI is a thin layer over it; the agent toolset is a different thin layer over the same thing. Neither contains logic, so neither can drift.

If a function needs a widget to work, the design is wrong.

The schema is the documentation, and it is generated from the code.

A machine discovers what a tool does by reflecting over its signature. Parameter types, clamps and doc comments are not internal notes — they are user-facing copy, read by the reader who matters most.

That is why a JSON string in a signature is a design failure, not a shortcut.

Errors are written for a reader who will act on them.

Every failure names the tool to call next. Models recover well from a mistake and badly from not noticing one — and so do people.

A message that only says what went wrong has done half the job.

Prose for the machine, deliberately authored.

A skill document ships beside each toolset carrying what a signature cannot express: the order operations go in, the trap that is not visible from the types, the thing that looks like it should work.

Documentation whose reader is a model, written as carefully as the README whose reader is a person.

Nothing is available only through a panel.

Every capability has a route that does not involve pointing at something. Where a button exists it calls the same function the toolset calls.

An agent cannot read a panel, and a human iterating should not have to.

Boundaries are drawn for both users at once.

No tool writes a credential. No tool deletes an unrecoverable take. Not because agents are untrustworthy, but because those are the two operations where speed turns a small mistake into an irreversible one.

The same limits protect a person working at speed.

The payoff

Building for the machine user produced a better API for the human one — idempotent, non-blocking, typed, and costed before it commits. We did not set out to improve the human experience by serving the machine. That is simply what happened.

Every one of those properties was forced by the machine user. An agent cannot sit through a modal dialog, so operations became non-blocking. An agent will call the same tool twice, so operations became idempotent. An agent should not spend a studio’s money by accident, so a run is costed before it commits and a gate stops it where a person has to decide.

Every one of them is also just good software, which is why we build this way on client work with no agent in it.

See it in the plugin list →