Wiring the command pipeline: the ticker stops being a promise

A few posts ago I drew an honest line: the command pipeline was designed but not actually enforced. The UI showed a status strip, but the send path went straight to the adapter. That strip was indicative, not proof. This post is the follow-through.

In the zero-trust honesty post I put the command pipeline in the "designed, not wired" column and said so plainly: the UI showed a pipeline status strip, but the actual send path was command → adapter. The strip was a promise, not a proof.

This post closes that gap. Every operator command now runs through an ordered chain of gates — RBAC → Safety → ROE → Authorization — before it reaches a vehicle. A veto anywhere short-circuits the rest and comes back as a rejection naming the gate that refused and why.

The interesting part isn't that it works. Ang interesting (what's interesting) is that wiring it was a small change, because the architecture had been holding a seam open for it the whole time.

Why this was the right thing to do first

Everything credible in this system hangs off this spine. Role-based access, the audit trail, per-command re-authorization — none of them mean anything if commands can route around the gates. Wiring the pipeline first turns "we have a security architecture" from a diagram into a property you can point at in the code and watch reject a command.

That's the difference between a story and a system, and it's the one I'd rather be able to demonstrate.

Next up is the recorder — an append-only, replayable log of every input and every decision — so that when a gate refuses a command, there's an immutable record that it did.

The pipeline design and implementation detail

Same password as the other GCS posts — or request access below.

Build log entry. Apache-2.0. Part of the multi-domain GCS build log.