Demo · infrastructure

An ops agent that asks before it acts

An operator gives orders in chat. An operations agent reads the target, asks a gate that holds a policy file, and makes the one call the gate admits, on a live Kubernetes cluster that it reaches only as a scoped service account. Every order ends with the cluster read back, so the last word is what the cluster shows, not what the agent believes.

136 seconds, captions only. Recorded against a live k3s cluster; every result caption quotes the recorded read-back. Archived on Zenodo: doi:10.5281/zenodo.23006181.
The seven orders

Allowed, escalated, refused, and always read back

OrderOutcomeWhat the record shows
Which pods are not running in the demo namespace?read Answered from the cluster, not from memory.
Scale an ordinary workload to 2allowed Made, then read back at once: two replicas asked for, the new pod still starting.
Scale the critical freezer to 3escalated actuated: false. The read-back shows the freezer unchanged at 1.
Create a workloadallowed Labeled with how it got there. It runs a command, so it stays up.
Create a workload labeled tier=critical, in plain languagerefused The model passed the label through; the gate refused it as a claim by the order. Nothing was created.
Apply a manifest from a public repository1 applied, 2 refused Decided object by object. A Service is refused by kind before the gate: three objects, two decisions.
Is the cluster what the repository says?true Both sides answered and agree. If either is silent, the answer is null, never a quiet "in sync".
The gate

Three rules, each with its reason written down

For an existing workload, the gate decides against labels read off the live object, so an order cannot choose its own answer. A create has no live object: its labels can only come from the order, and the gate is told so. Deny outranks escalation, escalation outranks allow, and anything no rule admits is refused.

policies/gate.policy.json

escalate-scale-critical → require_approval
  when tier = critical and mutation = scale
  "A tier=critical workload carries capacity commitments
   an agent cannot see. Scaling it is a human decision."

no-create-claiming-critical → deny
  when tier = critical, mutation = create, labels proposed
  "The object does not exist yet, so tier=critical is a
   claim by the order rather than a fact about a workload.
   An agent may not grant itself the tier that would
   exempt it from review."

allow-known-mutations → allow
  when mutation is scale, restart, annotate or create
  "Scale, restart, annotate and create are the verbs this
   agent may use."
  1. Two enforcement points. The gateway's own policy file limits where it may write, and the cluster applies the service account's permissions on top. Loosen one and the other still refuses.
  2. Plain language, same gate. With plain language on, a model turns a sentence into one order. The model call is a record, the order cites it, and the gate decides exactly as it does for a typed order.
  3. A ledger that survives a restart. Every record is appended to a hash-chained ledger. A restart reads it back; an edited or dropped line is caught when it loads.
What it does not claim

The limits, stated

  • An escalation is not an approval. The pull-request path to a human is not built in this demo: an escalated order is recorded as needing approval, and nothing changes.
  • Admission is not validation. The gate decides whether an order may proceed, not whether the workload will run well.
  • The gate decides Deployments only. Other kinds are refused rather than applied ungoverned.
  • One cluster, one demo namespace and one critical namespace owned by Argo CD. Not a production rollout.

The manifest comes from a public repository, ok-admission-gate-demo, read without a credential. The Decision Trace view is the published @agent-scope-ca/graph-canvas component.