Crinaro.AI · horizontal CRINARO.AI

The direction people forget

The front door is public and the work is private, so reports have to cross inward. Outbound is the direction a design guards first. The inbound one carries text an agent will read as instructions.

Part 2 of 2. It starts at Coaching is a file now.

The argument

A report arrives where somebody found the problem. The team that can fix it works somewhere else, and the fix has to arrive back as a release.

Every arrow across that boundary crosses a trust domain, and the two directions are not symmetric. A design that guards only one has guarded the easy one.

Publishing is the easy direction. The harder problem is that the front door is public and the work is private.

Someone who installed a plugin reports a defect where they found it, on the public repository. That is correct, and they should not have to know anything about how the thing is maintained. But the team that can fix it works in the private repository, and the fix has to arrive back on the public side as a release.

Private where the team works The agent team and its roster Architecture decisions Work in flight The source it all comes from Public what leaves the building What a user installs Its documentation A version history and nothing else PUBLISH One commit carrying the current tree. Never a history, so no old blob exists to leak. MIRROR Reads public, writes private, one direction. Nothing in it can push private content out. ACKNOWLEDGE A separate, deliberate step. Posting outward is never a side effect of reading in.

What the inward path has to guarantee

So reports are mirrored across: read public, write private, one direction, with nothing in that path able to push private content outward. That constraint is what makes it safe to run unattended. Acknowledging the reporter on the public thread is a separate, deliberate step, because posting outward is a different act from reading inward and should never be a side effect of a mirror.

Filing runs the same way from the inside. A request against the team that owns a capability is an issue on that team's repository, which is the private one, and the tool that files it refuses outright when the target is public. A public issue is permanent, the scan that would catch a leak is a pattern match, and a pattern match cannot see an employer's name inside a URL slug. It also never files partially: either an issue URL comes back or a refusal does, with a non-zero exit. A printed report is not a filed report.

Inbound is the one that carries instructions

Every arrow crossing that boundary crosses a trust domain, and the two directions are not symmetric. Outbound risks publishing something that should not have left, and that failure is easy to picture. Inbound risks importing text that an agent will read as instructions.

A mirrored issue body is written by anyone with an account, and it lands in a repository where agents read issues and act on them. So it is carried across fenced and labeled as reporter-supplied data. An agent acting on please run X found inside an issue body is executing a stranger's instructions. A design that guards only one direction has guarded the easy one, and outbound is the easy one, because it is the one that is easy to imagine.

Written by John Kelly. If a piece of this does not hold in your architecture, at your size, that is the mail worth sending: john@crinaro.ai. Today I read it myself.
The rest are in the notes.