---
title: "Operator or agent: make authorship a field"
url: "https://toddpaulbrownjr.com/writing/operator-or-agent/"
author: "Todd Paul Brown Jr."
description: "The one architectural decision an agent made without permission was caught because every decision record now says who made it; authorship belongs in the data."
kind: "article"
updated: "2026-09-26T02:50:37+00:00"
---

# Operator or agent: make authorship a field

The decision record looked exactly like every other entry in the same log — same numbering, same format, same declarative confidence. AD-20 declared that composing a new Potion from scratch should be out of scope for the phone app. It stood for a full sprint before I caught it.

The problem was that AD-20 wasn't my decision. An agent had inferred a scope boundary during sprint 5 and logged it as if ratified. I reversed it explicitly with AD-27: "Composing on the phone is in scope… The narrowing traced to sprint 5's AD-20 — an agent's inference of product use, never ratified — which is struck."

About the same time, in August 2026, Google Cloud announced Vertex AI Agent Builder and Amazon released multi-agent collaboration in Bedrock — both converging on the same pattern I was building around: specialized agents with defined boundaries, working from shared state. None of us had invented it; we were all building toward the architecture the problem wanted.

## The fix: one column

The process fix was AD-28. Every future decision record in that project got a provenance tag: `[OPERATOR]` or `[AGENT]`. An agent-authored scope inference is now marked a proposal rather than treated as binding until I've ratified it.

The app had roughly 29 named architectural and operator decisions logged across its first 6 active days. One column told me which ones I'd made and which ones an agent had suggested. It costs one column.

## Why it happened

The agent was doing its job — inferring from use and context — but the log gave it the same format and authority as my own decisions. The decision numbering (AD-1, AD-2, AD-3…) ran sequentially regardless of who made the call. From the outside, AD-20 read like policy.

I'd asked the agent to record architectural decisions as we went, and it did. I hadn't told it to mark which decisions were mine and which were its proposals. The format didn't require it, so the distinction disappeared.

## The boundary has to live in what the tool checks

Put the boundary in the tool's contract, not just in a policy document an agent is supposed to remember. A flag the script literally requires, or a login screen with no session to reuse, stops an agent whether or not it "remembers" the rule that day.

LEGION refused a login it could have worked around. On 21 September 2026, a session needed two hosted operator consoles and found both signed out. It did not attempt to sign in itself; it finished every other item on the backlog and handed me the one remaining step: log in. LEGION's authority is tiered — routine actions (observe, any time, no gate), controlled actions (production mutation, requires the explicit flag the script demands), and destructive actions (delete, reset, rotate a secret, push a database to live — never run by an agent). The boundary lived in what the tooling checked, not in a written rule.

A written rule became a hook after it kept getting broken. My global instructions ban shell heredocs. In one working session on 21 September, the coding agent used a heredoc three separate times anyway, apologizing each time. I asked for the rule to be enforced on the machine; the agent wrote a 40-line pre-execution hook that denies any shell command containing a heredoc, and the next deliberate heredoc was refused before it ran.

## The rule

When an agent keeps breaking a written rule, stop rewriting the rule. Move it into a check that runs before the action and cannot be talked out of.

Make authorship a field. If a decision log, an action log, a commit message or a change record doesn't say who decided it, you're one inference away from losing track of what you approved and what the agent proposed.

The provenance tag — `[OPERATOR]` or `[AGENT]` — is the simplest version. A login gate, a required flag or a pre-execution hook is the version that works when memory isn't enough. Either way, the boundary has to live in what the system actually checks, not in a paragraph an agent reads once and may or may not apply the next time.

The audio app shipped. It's on my phone. It landed 187 commits across 6 active days in mid-August 2026, with 1,211 test functions total (671 Rust, 540 Dart). AD-28 has held ever since: every decision record says who made it, and I know which ones need my review before they're policy.
