Dashboard control plane
One screen where the operator sees everything the agents are doing and makes every decision the system escalates: live sessions, permission slips, approvals, submitted plans, violations, and the global switches.
The enforcement layers run on the host, but the operator runs them from the dashboard. Under an
admin-only “Agent Authority” menu (decided in ADR 0117 — see
decision records) sit six panels, each backed by its own
database table in a dedicated operator_authority schema:
| Panel | What the operator sees / does |
|---|---|
| Active Sessions | Every governed agent currently running — kind, identity, worktree, claimed scopes, last-seen time. Opened and closed by the shims; an agent not listed here is running outside the walls. |
| Scope Manifests | The per-worktree permission slips (see scope manifests): allowed paths, scope tokens, expiry, and which operator issued each one. |
| Approval Queue | Actions the gate has paused, waiting for a yes or no — with agent, kind, target, reason, and an expiry clock. Approve / Deny buttons decide them. |
| Plans Awaiting Approval | Task briefs agents have submitted before starting work (below). |
| Violation Log | The audit log, browsable: time, agent, tool, target, rule, outcome — blocked in red, reverted in orange, approved in green. |
| Global Settings | Three switches: require approval for docker build, require approval for pushes to main, auto-deny edits to engineering-standards/. Every change records who flipped it and when. |
How an approval actually flows
Section titled “How an approval actually flows” agent hits a rule that says "ask first" │ ▼ gate POSTs an approval request ──▶ operator_authority.approval_requests │ │ │ polls for the decision │ dashboard panel refreshes │ every 2 seconds │ every 10 seconds │ (up to 10 minutes, ▼ │ then the request expires) operator clicks Approve / Deny │ │ (who, when, why — recorded) ◀─────────────────────────────────────┘ │ ▼ the action runs, or is refused — either way, loggedThe timing is the design: an agent is never stuck forever (requests expire — default ten minutes, never less than one), and a decision is never anonymous (each row records which operator decided, when, and an optional reason).
Plans before work: the six-section brief
Section titled “Plans before work: the six-section brief”For task-scale work, the unit of approval isn’t a single action but a plan. The agent submits a brief with six fixed sections: what users will see change, what they will not see change, risks and mitigations, how the agent will verify the result, a size estimate, and optional technical detail. The operator reads it in the dashboard and decides.
Approving a plan does two things in one database transaction: it marks the plan approved,
and it issues a scope manifest for that agent’s worktree carrying
the task-approved token (default lifetime: 24 hours). There is no gap where a plan is
approved but the permission slip doesn’t exist, or the reverse — the gate starts honoring the
approval at the same instant the record says it should.
Who can call what
Section titled “Who can call what”The control plane has exactly two kinds of caller, and each endpoint admits only one of them:
- The operator (deciding, viewing, changing settings) — must be signed in through
the identity provider (Authentik) and in the
dashboard-adminsgroup. The browser never talks to the backend directly; a proxy layer attaches the verified identity to each request. On the private loopback deployment, a bypass identity exists — but it only activates for connections genuinely from the local machine. - The gate (filing requests, polling decisions, recording violations) — trusted when calling from localhost or the private network, or, when a shared-secret token is configured, only with that token in a header, compared in constant time. The gate can file and ask; it can never decide. Deciding is reserved to the admin endpoints.

