← All writing

Before the Arm Acts

Two event types — PAUSE_SURFACED, HUMAN_DECIDED — sat unused in a twelve-item vocabulary for a month before either fired for real. A tool that writes automation scripts started refusing to save one without a declared execution mode. A tool that runs them started refusing to run anything consequential without a second, explicit confirmation call. Verified with a single-purpose test arm and a file that either exists or doesn't: unconfirmed, nothing happened; confirmed, it did. The same governance-as-infrastructure move that shaped a content pipeline, applied to whether code gets to act at all.

Michael Shatny··6 min read

A Vocabulary That Waited

TRACE's event vocabulary was published closed — twelve event types, fixed at the outset, meant to describe everything that could happen to an automated arm reaching into a live system. Two of the twelve were written for a moment that hadn't happened yet. PAUSE_SURFACED: a decision surfaced to a human. HUMAN_DECIDED: the human's answer, recorded. Both existed in the spec from day one. Neither had ever actually fired.

A month passed. Arms ran, correctly, and wrote the other ten event types — ARM_START, ARM_COMPLETE, ARTIFACT_WRITTEN — many times over. PAUSE_SURFACED and HUMAN_DECIDED sat in the vocabulary the way an unused clause sits in a contract: real, binding, waiting for a case nobody had triggered yet.

Then an arm tried to run without permission, and both fired for the first time, in the right order, moments apart.

The Default Failure Mode of Confirmation

Most systems that touch something consequential handle confirmation the same way: a step in the process where someone is supposed to ask first. The step is real. It's also optional in exactly the way any convention is optional — it depends on whoever is calling the code remembering it's there, every time, forever. Nothing about the architecture prevents the call from going straight to execution. The safety is a habit, not a wall.

This is the same shape as a validator holding its own copy of the rules: a good idea, sitting one step away from wherever the real decision gets made, hoping someone routes through it on the way. It works until someone doesn't — not from carelessness, but from the same ordinary way any optional step gets skipped when nothing structural requires it.

Where the Opinion Actually Lives

Every arm — REACH's term for a single-file script that reaches into something local: git, a filesystem, an HTTP endpoint — now declares its own mode in its own header, one line, before anything else: MODE: READ or MODE: ACT. READ means the arm only observes. ACT means it changes something. The declaration isn't optional either — the tool that writes an arm to disk checks for it and refuses to write anything without a valid line:

write_arm — refuses to persist an undeclared arm
const mode = parseArmMode(args.cs_source)
if (!mode) {
  return {
    content: [{
      type: 'text',
      text: `Refusing to write ${args.arm} — cs_source must include a
"// MODE: READ" or "// MODE: ACT" line.`,
    }],
  }
}

That's the smaller half. The consequential half is what the tool that actually executes an arm does with the declaration:

run_arm — the gate
const declaredMode = parseArmMode(fs.readFileSync(armPath, 'utf8'))
const mode = declaredMode ?? 'ACT'

if (mode === 'ACT' && !args.confirmed) {
  appendEvent(tracePath, { event_type: 'PAUSE_SURFACED', /* ... */ })
  return { content: [{ type: 'text', text: 'This arm was not executed.' }] }
}

if (mode === 'ACT' && args.confirmed) {
  appendEvent(tracePath, { event_type: 'HUMAN_DECIDED', /* ... */ })
}

// reached only for READ arms, or ACT arms just confirmed
appendEvent(tracePath, { event_type: 'ARM_START', /* ... */ })
const result = await spawnArm(armPath, /* ... */)
!

An arm with no declared mode doesn't default to trusted. It defaults to ACT.

The assumption that costs more friction, not less — because the alternative is a system that quietly trusts anything it can't classify.

An ACT arm called without confirmed: true never reaches the line that would actually run it. The function is never called. PAUSE_SURFACED is written, and the arm hasn't moved.

The Two Calls

Trusting that logic and testing it are different exercises. The test built a single-purpose arm whose entire job was to write one file to disk — nothing else, so there'd be no ambiguity about whether it had actually run. Declared MODE: ACT. Called once, without confirmed. TRACE wrote PAUSE_SURFACED. The marker file did not appear.

Called a second time, same run, confirmed: true added. TRACE wrote HUMAN_DECIDED, then ARM_START, then ARM_COMPLETE. The marker file was there.

Four events, two calls, one file that either exists or doesn't — about as unambiguous as a test gets. The sequence landed in the log exactly the way the gate was supposed to produce it: PAUSE_SURFACED → HUMAN_DECIDED → ARM_START → ARM_COMPLETE, in that order, nothing skipped, nothing reordered.

The General Shape

This is the same move as the governed constraint sets that gate whether a generated artifact should exist at all — a different domain, the same architecture. The check isn't a policy a careful process happens to follow. It's a structural fact the process can't get around, because the function that would skip it is never reached in the first place.

The two events that waited a month for their first real use weren't decoration in the spec. They were a bet that this moment would eventually be worth recording precisely — worth more than a log line saying “approved,” worth an entire named event with its own place in a fixed, twelve-item vocabulary. The bet paid off the first time anything actually needed to pause and ask. Which is, itself, the quiet argument for writing the event before there's a use for it: the vocabulary should be honest about what could happen, not just about what already has.

Related

Michael Shatny is a software developer and methodology engineer and founding contributor to .netTiers (2005–2010), one of the earliest schema-driven code generation frameworks for .NET. His work spans 28 years of the same architectural pattern: structured input, generated output, auditable artifacts. reef-mcp is the same instinct pointed at a different question — what it means for automation to structurally refuse to act without permission, rather than simply being asked nicely to check first.

ORCID: 0009-0006-2011-3258