ACME Governed AI Workforce — User Guide
The complete guide for analysts, reviewers, and agent owners — the two-plane management console, reviewing agents and their governed memory and reasoning, reading entitlement envelopes, triaging exceptions, verifying the audit chain, handling quarantines, and reading the cost economics.
Host placeholders: these guides use placeholder host names —
acme-demo-host,acme-directory-host,acme-directory-internal,acme-soul-db-private,your-ops-ip— for the deployment's real addresses. The consoles are also reachable at their stable domains (console.asphodel.ai,pdp.tiresias.watch). Substitute the actual values from your operations record.
1. Introduction, audience, and the two planes
This guide explains how to use the ACME governed AI workforce day to day: how to find the agents that matter to you, read what they remember and how they reason, understand why a request was allowed or denied, and — if you own agents — govern them within the guardrails the platform enforces. It is a reference. Read the section that fits your task; the cross-references point you to the rest.
1.1 What the governed workforce is
ACME runs a governed, zero-trust AI agent workforce — a fleet of software agents that do real work (drafting, triage, analysis, monitoring) under a control regime that treats every action as untrusted until it is authenticated and authorized. The fleet comprises 367 governed agents: 360 mapped like-for-like to ACME's real directory of 325,154 principals across 28 departments, 10 regions, and 626 roles, plus 7 showcase agents that run on a 14-edge hand-off DAG.
The distinguishing property is not that agents exist, but that nothing an agent does is taken on trust. Every model call an agent makes is:
| Guarantee | What it means for you |
|---|---|
| Two-factor authenticated | The call carries a tenant API key and a per-agent capability token; a call missing either is rejected. |
| Deny-by-default | The policy enforcement point (PEP) allows only what an explicit rule permits. Anything not granted is blocked. |
| Tenant-isolated | On allow, the request is forwarded verbatim to the agent's own row-level-security-isolated data tenant. No agent can read another's memory. |
| Signed into an audit chain | Each decision is written to a post-quantum-hybrid (Ed25519 + ML-DSA-44) tamper-evident audit chain you can verify. |
| Behaviourally monitored | SoulWatch scores each agent for drift; an agent crossing a composite risk score of 75 is auto-quarantined. |
| Metered for cost | Every call's tokens and cost are recorded, so spend is attributable per agent, model, and lane. |
Three products deliver this. Tiresias-ZT is the control plane and PEP — it "manages nothing, enforces everything." Asphodel is the management console — it "manages agents." soul-svc is the isolated data tier that holds each agent's memory. You interact with the workforce almost entirely through Asphodel; analysts and reviewers also use the Tiresias analyst console and the Grafana ROI board, covered later in this guide.
The core invariant to carry through every section: an agent can never exceed the authority of the human principal it answers to. Its permissions are derived from its owner's real directory entitlements and then only ever narrowed. This is what makes the workforce safe to run at scale.
1.2 Who this guide is for
This guide serves four overlapping audiences. You will spend most of your time in the parts that match your role.
| Role | What you do | Primary sections |
|---|---|---|
| Analyst | Watch the fleet, investigate the governed call stream, drift detections, and quarantines; verify audit integrity. | Analyst console, Observe |
| Reviewer | Perform access reviews and recertifications; confirm agents still warrant their entitlements. | Reviews, Access explorer |
| Agent owner | Own or sponsor one or more agents; read their memory and reasoning, run tasks, and manage their model, policy, and budget within limits. | Personal plane, Agents |
| Stakeholder | Read what the workforce is doing and what it costs, without operating it. | Observe, ROI board |
Two accountability relationships appear throughout and are worth learning now, because they decide what you can see and do:
- An accountable sponsor owns the risk of an agent. The platform enforces "no sponsor → no run": an agent with no sponsor does not execute.
- An operational manager is the agent's direct-report owner, responsible for its day-to-day behaviour.
Administrators who provision agents, change infrastructure, or operate the runner should use the companion Administrator Guide; this User Guide stays on the reading, reviewing, and owning side of the line.
1.3 The two-plane console model
Asphodel is a single role-adaptive application, but it presents two planes. Which plane you are in is a property of the URL and is gated server-side by role-based access control — a non-admin is never served a control-plane route.
Personal plane — calm, consumer-grade, scoped to your own agents:
| View | Route | What it is for |
|---|---|---|
| My agent | / |
Your agent home / the roster of agents you own. |
| Chat | /chat |
An ad-hoc governed conversation, with a live session-trajectory card (ladder rung + score) and content-blind behavioural markers. |
| Memory | /memory |
"What your agent remembers" — searchable governed memory with topic tags and timestamps. Nothing leaves the workspace. |
| Blocked queries | /blocked |
What your agent was denied, and why. |
| Build | Knowledge, Mindsets, Playground | Curate a knowledge base, author TKHR grounding "mindsets," and run ad-hoc tasks against an agent (shows chain-of-thought, output, provider/model, tokens, cost). |
| Account | Documentation, Settings | In-console docs; account identity and grants, workspace/tenant, light/dark appearance, demo snapshots. |
Admin console — dense, exception-first, for governing the whole fleet:
| View | Route | What it is for |
|---|---|---|
| Dashboard / Observe | /observe |
Ranked, rolled-up incidents; CRITICAL / WARN / QUARANTINED / AGENTS AFFECTED tiles. |
| Agents | /fleet |
The governed roster and identity search, grouped by department. |
| Principals | /principals |
Principals and ownership; sponsors, managers, and the suggested-owner queue. |
| Access | /access |
The Access explorer — resolved permissions with per-layer provenance. |
| Reviews | /reviews |
Access-review and recertification workflow. |
| Policy | /governance |
Fleet governance cockpit and per-agent policy editor. |
| Drift & behaviour | /analytics |
Content-blind behavioural cockpit. |
| Change & approvals | /approvals |
Approval inbox over the change-control service. |
| Audit & reports | /reports |
Audit-chain browser and reports. |
| Integrations | /runtime |
Manage the runner (scheduler and routing). |
1.4 How to tell which plane you are in
You do not switch planes with a toggle — the URL and what it shows tell you where you are.
- Read the route. A Personal-plane route is the bare app root or a consumer view (
/,/chat,/memory,/blocked). An Admin route lives under a control-plane prefix such as/observe,/fleet,/principals,/access, or/governance.
Result: the route family alone identifies the plane.
- Read the density and framing. The Personal plane is calm and single-agent, framed in the second person ("your agent," "what your agent remembers"). The Admin console is dense and fleet-wide, framed around exceptions and incidents.
Result: the visual register confirms the plane.
- If an Admin route will not load, that is the RBAC gate, not a bug. The plane is gated server-side: if your session lacks an admin role, the control plane never returns the route and you are redirected. Requesting
/observewithout the role does not expose it.
Result: a redirect away from a control-plane route means your role does not include that plane — request access rather than retrying.
Note — In read-only DEMO mode the console renders without login (a guest reads through the back-end-for-front-end proxy). When
ASPHODEL_DEMO_FALLBACK=0, login is required. The admin key is never exposed to the browser; production uses OIDC sign-in. See the Administrator Guide for the environment configuration.
1.5 How to use this guide
- Start from your role. Use the table in §1.2 to jump to your primary sections rather than reading front to back.
- Follow the register. Procedures for user tasks are written in the second person ("you"); administrative procedures use the imperative. Numbered steps end with a Result: line so you can confirm you are on track.
- Trust the cross-references. Where a concept is defined elsewhere — the Access explorer's envelope derivation, the audit chain, quarantine release — this guide points to the authoritative section instead of repeating it.
- Know the surfaces. Asphodel (
console.asphodel.ai) is where you read and govern agents; the Tiresias analyst console (pdp.tiresias.watchor:8343/admin/console) is where you investigate enforcement; the Grafana ROI board (:3000/d/acme-roi-economics) is where you read cost. Each has its own section.
With the workforce and the two-plane model in view, proceed to the section that matches your role — most readers begin with My agent (Personal plane) or Observe (Admin console).
2. Getting started — access, sign-in, and navigation
This section covers everything you need to reach the Asphodel management console, understand what you can see before and after you sign in, move between its two planes, find any view from the global navigation, and set the appearance to match your environment. Asphodel is the surface where you read the workforce — the agents, their memory and reasoning, their entitlements, and (in the admin plane) the fleet-wide governance queues. It is a single role-adaptive Next.js application that talks to the governance Control Plane through a server-side back-end-for-front-end (BFF) proxy at /api/cp/*, so everything you see reflects live registry and usage data rather than a static snapshot.
2.1 Reaching the console
Asphodel is reachable at a production hostname or directly on the demonstration VM.
| Access route | URL |
|---|---|
| Production | https://console.asphodel.ai |
| Direct VM | http://acme-demo-host:3001 |
To open the console:
- Point a modern browser at
https://console.asphodel.ai(orhttp://acme-demo-host:3001when you are on the VM network). - Wait for the application shell to load. The BFF establishes the read path to the Control Plane on first paint.
Result: The console renders the My agent home page. If demo mode is enabled, it renders with no login prompt; otherwise you are sent to sign-in first.
The interface uses the .op "Quiet Authority" design system — a cool-paper background with amethyst accents. If you have seen an earlier warm-terracotta build, note that it has been retired; the cool-paper palette is current.
2.2 Read-only DEMO mode versus a signed-in session
Asphodel supports a read-only DEMO mode that renders without a login so you can browse the roster, memory, and explorers immediately. In this mode the BFF performs guest reads on your behalf using the server-side admin key — that key is never exposed to the browser. DEMO mode is read-only: you can inspect, but management writes are not available.
| Capability | DEMO mode (no login) | Signed-in session |
|---|---|---|
| Browse agents, memory, access explorer | Yes | Yes |
| Read-only views render immediately | Yes | Yes |
| Management writes (policy, budget, runner control) | No | Yes, subject to your role |
| Credential used for reads | Server-side admin key via BFF | Your own scoped bearer |
| Control-plane (admin) routes | Only if your role permits | Only if your role permits |
Whether DEMO mode is available is a deployment choice. When the environment variable ASPHODEL_DEMO_FALLBACK=0 is set, the demo fallback is disabled and every visit requires login. If you reach the console and are immediately redirected to sign in, demo mode has been turned off for that deployment.
Security note: When you are signed in, the BFF carries your own scoped bearer on each forwarded call. There is no standing privileged credential in a signed-in session — the real access boundary is the Control Plane's own deny-by-default RBAC, evaluated on every forwarded request.
2.3 Signing in
Full access is available through OIDC (production single sign-on) or the demo-auth fallback.
- From any page, choose Sign in (or complete the redirect if login is enforced).
- Authenticate with your identity provider (OIDC), or use the demo-auth path where the deployment offers it.
- On success you return to the console with a session identity.
Result: The navigation now reflects your role. If you hold an admin role, control-plane views become reachable; if you do not, they are never routed to you (see §2.4).
2.4 The two planes and the plane switcher
Asphodel is one application with two planes, and the plane is a property of the URL, gated server-side by RBAC:
- Personal plane — calm, consumer-grade views of a user's own agent (roster, chat, memory, blocked queries, build tools, account settings).
- Admin console — a dense, exception-first identity-governance surface for governing the whole fleet.
The gate is enforced by ADMIN_ROUTE_PREFIXES, which single-sources the plane derivation and drives a server-side redirect gate. The practical guarantee: a non-admin never receives a control-plane route, even by typing the URL directly. When your role permits both planes, the plane switcher in the navigation moves you between them; when it does not, only the Personal plane is presented.
2.5 Global navigation
The left-hand navigation lists every view in the current plane. Use the tables below to locate a view and its route.
Personal plane (your own agent):
| Section | Route | What it is for |
|---|---|---|
| My agent | / |
Your agent home / roster of your agents |
| Chat | /chat |
An ad-hoc governed conversation with a live session-trajectory card |
| Memory | /memory |
"What your agent remembers" — searchable governed memory |
| Blocked queries | /blocked |
What the agent was denied |
| Build → Knowledge | — | Curated knowledge-base lifecycle and per-agent assignment |
| Build → Mindsets | — | TKHR curated grounding served as context |
| Build → Playground | — | Pick an agent, run an ad-hoc task, view CoT + output + model + tokens + cost |
| Account → Documentation | — | In-console documentation |
| Account → Settings | — | Account identity and grants, workspace/tenant, appearance, demo snapshots |
Admin console (governing the fleet):
| Section | Route | What it is for |
|---|---|---|
| Dashboard / Observe | /observe |
Exception-first ranked incident queue |
| Agents | /fleet |
The governed agent roster / identity search |
| Principals | /principals |
Each agent's accountable sponsor and operational manager |
| Access | /access |
The Resolved-Set-of-Permissions access explorer |
| Reviews | /reviews |
Access-review / recertification workflow |
| Policy | /governance |
Fleet governance cockpit and per-agent policy editor |
| Memory governance | — | Governance over agent memory (retention / holds) |
| Drift & behavior | /analytics |
Content-blind behavioural cockpit |
| Change & approvals | /approvals |
Approval inbox over the change-control service |
| Audit & reports | /reports |
Audit-chain browser and reports |
| Integrations | /runtime |
Manage the runner (scheduler, per-agent runs, routing) |
2.6 Appearance — light and dark
Appearance is a per-user preference, set in the Personal plane.
- Open Account → Settings from the Personal-plane navigation.
- Locate the appearance control.
- Select light or dark.
Result: The console re-renders in the chosen theme immediately; the preference persists for your account.
2.7 Where each answer lives
Use this table to jump straight to the view that answers a given question.
| You want to… | Go to |
|---|---|
| See the workforce by department, tier, memory, activity | Admin → Agents (/fleet) |
| Read one agent's memory and reasoning (CoT) | Personal → Memory (/memory), or the agent's Memory tab |
| See what an agent is allowed to do, and why (RSoP) | Admin → Access (/access) |
| See who is accountable for an agent | Admin → Principals (/principals) |
| Triage fleet incidents and quarantines | Admin → Observe (/observe) |
| Have a governed conversation with your agent | Personal → Chat (/chat) |
| See what your agent was denied | Personal → Blocked queries (/blocked) |
| Change light/dark appearance | Personal → Account → Settings |
For the analyst / enforcement console and the ROI economics board — separate surfaces from Asphodel — see the sections that cover the Tiresias PEP console and the Grafana ROI board.
3. Personal plane — My agent
My agent is the home of the Personal plane — the calm, consumer-grade side of the Asphodel console, built around the agent (or agents) that belong to you. Where the Admin console governs the whole 367-agent fleet, the Personal plane narrows the world to your own governed workforce: the agent you talk to, the memory it keeps, and the queries it was denied. My agent is the landing page for all of that.
You reach it at the Personal-plane root:
Production : https://console.asphodel.ai/
Direct VM : http://acme-demo-host:3001/
The Personal plane renders read-only in DEMO mode with no login, so you can open My agent and browse immediately. Full, write-capable access is available through OIDC or the demo-auth fallback — sign in from the Sign in control in the top bar. The active workspace (the ACME badge, top right) and your identity determine which agents appear as yours.
What an agent is
An agent is a governed, autonomous worker — one member of ACME's AI workforce. It is not a chat window or a prompt; it is a durable, named identity with four things that travel with it everywhere:
| Property | What it means |
|---|---|
| A persona | The agent's identity, voice, values, expertise, responsibilities, and standing job — a full character brief, not a system prompt. The persona essence you see on the card is the opening line of this identity. |
| A model tier | The model the agent runs on today. Agents route across a 9-tier, 3-provider roster (see the table below), favoring free and self-hosted tiers for everyday work and reserving paid frontier models for escalation. |
| Governed memory | Everything the agent has learned, stored in its own row-level-security-isolated data tenant. No other agent — and no other user — can read it. |
| An owner | Every agent answers to a human principal in the directory. This link ("no sponsor → no run") is why your agents are yours. |
Every action an agent takes is governed: each model call is two-factor authenticated, evaluated deny-by-default at the enforcement point, isolated to the agent's own data, and signed into a tamper-evident audit chain. That guarantee holds uniformly whether the agent is running a scheduled job or answering you in Chat.
The My agent home
The My agent home presents your agent as a card (a roster of cards if more than one agent is assigned to you). Each card is a compact, at-a-glance summary you read before opening the agent. It carries four fields:
| Field | What it tells you | How to read it |
|---|---|---|
| Persona essence | The first line of the agent's identity — who it is and what it does, in its own voice. | This is the fastest way to confirm you have the right agent. Example: "I am ACME's front-line security analyst — I triage the alert queue, chase every anomaly to a documented conclusion…" |
| Model tier | The model the agent is currently homed on. | A free or self-hosted tier is the healthy everyday state. A paid tier (opus-4.8 / sonnet-4.5) generally signals an escalation, not routine work. |
| Memory count | How many governed memories the agent has accumulated — its working knowledge. | A live figure, read through the governed data path. It should grow over time as the agent runs jobs; a flat count on an agent that should be busy is worth a look in the Memory view. |
| Last activity | When the agent last ran a governed job. | The fleet is deliberately paced at roughly 1–2 governed jobs per day per agent, so "last active within a day" is normal and healthy — not minute-by-minute. |
Reading the model tier. The tier shown on the card comes from the fleet's routing roster. Use this reference to interpret it:
| Provider | Tiers | Role in routing |
|---|---|---|
| OpenRouter (paid) | opus-4.8, sonnet-4.5 |
Escalation ceiling — reserved for incident / breach / critical work |
| OpenRouter (free) | gemma-4-31b:free, qwen3-next-80b:free, hermes-405b:free, llama-3.2-3b:free |
Free everyday tiers |
| Ollama Cloud (self-host) | gpt-oss:120b, deepseek-v4-pro |
Reliable self-hosted tiers; the standard floor |
| HuggingFace | Llama-3.3-70B |
Additional self-hosted tier |
Keyword escalation (+incident, +breach, +critical) can bump a request from the agent's home tier toward its ceiling; a failed paid or free call falls back to the reliable self-hosted floor. So a tier on the card is a snapshot of where the agent is homed now, not a fixed assignment.
Opening an agent
Opening an agent from its card makes it the active agent across the Personal plane — Chat, Memory, and Blocked queries then operate on the agent you opened.
- On the My agent home, locate the card for the agent you want by its persona essence.
- Confirm the model tier, memory count, and last activity read as you expect.
- Select the card to open the agent.
Result: the agent becomes the active agent. Its name and persona carry through to the other Personal-plane views, and the navigation rail's Chat, Memory, and Blocked queries entries now act on this agent.
From there:
- Use Chat to hold an ad-hoc governed conversation with the agent (a fresh, page-load-scoped session with a live trajectory card).
- Use Memory to read what the agent remembers — its searchable governed memory, topic-tagged and timestamped.
- Use Blocked queries to see what the agent was denied — the deny-by-default policy made visible.
Note: The Personal plane only ever shows agents you own and only ever reads one agent's data at a time. If you need to browse the full governed fleet — every agent by department, with management actions — switch to the Admin console using the plane switcher in the top bar. Non-admin users are gated server-side and will not receive Admin-console routes; the switcher reflects only the planes your role permits.
Cross-references: For the persona in full (identity, voice, values, expertise, responsibilities, and standing job) and the governed Memory / Reasoning / Jobs tabs, see the agent-detail material in the Admin console. For the day-to-day flows an opened agent unlocks, see the Chat, Memory, and Blocked queries sections that follow.
4. Personal plane — Chat
Chat (/chat) is where you hold an ad-hoc, governed conversation with your own agent. Unlike the scheduled fleet jobs an administrator configures, a Chat exchange is interactive: you type a message, the agent answers, and every turn travels the same enforcement path as any other governed model call. Nothing about the conversation is exempt from policy — the calm, consumer-grade surface sits directly on top of the full control plane.
Chat lives in the Personal plane of the Asphodel console. Reach it at console.asphodel.ai/chat (or, on a direct VM, :3001/chat). Because the plane is a property of the URL and is gated server-side by RBAC, you only ever see your own agent's conversation here; the fleet-wide views belong to the Admin console (see section 02).
4.1 Starting a governed conversation
- Open Chat from the Personal-plane navigation, or browse to
/chat. - Confirm the active agent named at the top of the page is the one you intend to talk to. If you own more than one agent, use the agent selector to switch. Result: the conversation pane binds to that agent's tenant, and a fresh session id is minted for this page load.
- Type your message in the composer and send it. Result: the message is dispatched as a governed model call; the agent's reply streams back into the pane, and the session-trajectory card updates for this turn.
- Continue the exchange. Each turn appends to the same page-load-scoped session, so the trajectory card and behavioural markers accumulate context across the conversation.
The session id is scoped to the page load. Reloading the page or navigating away and back starts a new session with a fresh trajectory card and a clean marker history. This is deliberate: it gives each conversation a bounded, auditable behavioural window rather than an unbounded rolling one.
4.2 The session-trajectory card
The trajectory card is the live governance readout for the conversation you are having right now. It is seeded the moment the session id is minted and refreshes as you talk. It presents two linked figures:
| Element | What it means |
|---|---|
| Ladder rung | The session's current position on SoulWatch's behavioural escalation ladder. Lower rungs are the normal, expected operating band; higher rungs indicate the session is trending toward the auto-quarantine threshold. |
| Score | The composite behavioural-risk score SoulWatch computes for the session. It is the same scale used fleet-wide: a score of ≥ 75 trips automatic quarantine of the agent. |
Read the two together: the rung tells you where on the escalation path the session sits, and the score tells you how close it is to the threshold. In an ordinary conversation both stay low and quiet — that is the healthy state, and it is what you should expect the overwhelming majority of the time.
The same analytics that back this card (trajectory, model baseline, campaign, drift) are what an analyst reviews in the enforcement console's Behavior tab. Chat simply surfaces the trajectory slice to you, in real time, for your own agent.
4.3 Content-blind behavioural markers
Alongside the rung and score, the card shows behavioural markers — SoulWatch's observations about how the session is behaving. These markers are content-blind: SoulWatch never inspects what you or the agent actually said. It reasons only over behavioural metadata — call cadence, the pattern of allows and denies, and drift away from the agent's established baseline.
Typical markers you may see include:
| Marker | Behavioural signal |
|---|---|
| denial_spike | An unusual concentration of denied calls in the session — the deny-by-default policy rejecting a burst of requests. |
| trust collapse | The session's behaviour has degraded sharply relative to the agent's baseline. |
| quarantine | The composite score reached the threshold and the agent has been held. |
Because the markers are computed from metadata rather than message text, your conversation stays private to your workspace while still being fully governed. Privacy of content and enforcement of behaviour are not in tension here — you get both.
4.4 What "governed" means for your chat
Every message you send is a two-factor-authenticated model call, evaluated deny-by-default before the agent ever sees it. Concretely, each turn:
- Is authenticated with the tenant API key and a per-agent HS256 capability token.
- Is evaluated at the Policy Enforcement Point (PEP); absent an explicit allow, it is rejected.
- On allow, is forwarded verbatim to your agent's RLS-isolated data tenant — the PEP never rewrites your payload.
- Is signed into the PQC-hybrid (Ed25519 + ML-DSA-44) audit chain, so the exchange is tamper-evident.
- Is behaviourally monitored by SoulWatch (feeding §4.2 / §4.3) and metered for cost.
The practical consequence: your agent can only answer within the effective envelope its owner's directory entitlements permit (E0 ∩ E1 ∩ call rules; see section 03 on Access). Chat cannot widen that envelope — it is another governed caller, not a privileged back door.
4.5 Blocked responses
When a turn matches no explicit allow — or the requested action falls outside the agent's authored scope — the PEP denies it. In Chat you receive a governed refusal in place of an answer rather than a raw error, and the denial is recorded.
- Send a message that requests something outside the agent's permitted scope. Result: the agent returns a governed "blocked" response instead of an answer.
- Open Blocked queries (
/blocked) to see the denied request logged. Result: the query appears in your agent's blocked list, so you can understand why it was refused and whether the policy needs review.
A blocked response is the system working as designed, not a fault: deny-by-default means the default answer is "no," and only explicitly permitted calls get through. If you believe a legitimate request is being blocked, that is a policy question for an administrator — see the Blocked queries section (05) for how to read denials, and section 03 (Access) for how the effective envelope is derived.
5. Personal plane — Memory
The Memory view answers one question in plain language: what does your agent remember? It is the personal plane's window onto everything your agent has written down as it works — the durable, governed record of its accumulated knowledge. Where Chat (Section 04) is the live conversation and Blocked queries (Section 06) is what the agent was refused, Memory is the standing body of what the agent knows: the memos it produced on real jobs, each carried with its own topic tags and timestamp.
Two things make this view distinct from an ordinary notes list. First, every read is a governed read — the console fetches memory through the same zero-trust data path the agents themselves use, so you only ever see one agent's memory at a time and nothing crosses the workspace boundary. Second, it is agent-scoped: you pick an agent, and the explorer shows that agent's memory and nothing else. The identical explorer appears as the Memory tab on an agent's detail page, so what you learn here applies in both places.
5.1 Opening the Memory view
- In the personal plane, open Memory from the left navigation (route
/memory). - If you have more than one agent, use the agent picker at the top of the view to choose whose memory to read (see Section 5.2).
- The explorer loads that agent's memories, most recent first.
Result: you see a scrollable list of memory entries. Each entry shows the memo content, its topic tags, and the timestamp it was written.
If the selected agent has not yet run any jobs, the list is empty — this is an honest empty state, not an error. Fleet agents are deliberately paced at roughly one to two governed jobs per day, so a healthy new agent may take a day to accumulate its first memories.
5.2 The agent picker
The agent picker is how you choose whose memory the explorer shows. In the personal plane it lists the agents you own; on an agent detail page the agent is fixed and no picker appears.
- Click the agent picker (top of the Memory view).
- Select an agent by name.
Result: the explorer reloads with that agent's memory. The previously selected agent's data is discarded from the view — the two are never shown together.
This one-agent-at-a-time behavior is not a UI convenience; it reflects the data isolation underneath (Section 5.5). There is no "all agents" view of raw memory, because there is no data path that would let one query span tenants.
5.3 Reading a memory — topic tags and timestamps
Each memory entry is a real work artifact — for the showcase agents, incident memos and domain briefs the agent produced on a governed job. Every entry carries the fields in the table below.
| Field | What it is | Example |
|---|---|---|
| Content | The memo itself — the deliverable the agent wrote on a job | An incident memo, a domain brief, a summary |
| Topic tags | Short labels the agent attached at write time, for browsing and filtering | finance, incident-memo, tier:home |
| Timestamp | When the memory was written (UTC), newest shown first | 2026-07-18T09:41:00Z |
| Session | The job/session the memo belongs to, tying memory back to a run | a session reference |
About topic tags. Tags are set by the agent as it writes, not typed in by hand. They typically include the agent's department, the kind of output it produces, and context from the run (for example a tag recording the model tier used). Because tags travel with the memo, they double as your primary way to scan and filter a long memory list — look for the department or output kind you care about rather than reading every entry.
About timestamps. Memories are ordered newest first, so the top of the list is always the agent's most recent thinking. Use the timestamp to confirm an agent is active and that its memory is growing as expected; the same count is surfaced as the Memory figure on the agent's roster card (Section 02).
5.4 Searching memory
Beyond browsing, you can search an agent's memory to find what it knows on a subject.
- Select the agent whose memory you want to search (Section 5.2).
- Enter your query in the search field.
- Submit the search.
Result: the explorer returns matching memories — again scoped to that one agent, each with its content, topic tags, and timestamp.
Search runs entirely inside the governed data path. If the underlying semantic search is unavailable on the backend, the view falls back to a deterministic read of the agent's recent memories rather than returning a misleading "no results" — the governed boundary is never relaxed to satisfy a query. A denied read fails closed and is reported as such, never silently blanked.
5.5 Nothing leaves the workspace
Memory review is safe to use freely because of where the data lives and how it is reached:
- One tenant, always. Each agent's memory lives in its own row-level-security
(RLS)-isolated tenant in the workspace data tier (the
acme_souldatabase). An agent — and this explorer reading on its behalf — can only see that one agent's rows. There is no cross-agent bleed, by construction. - Forced isolation. The RLS is forced: it holds even for privileged database roles, so no agent and no reviewer can reach another agent's memory by accident or intent. This is the same boundary that makes the whole workforce safe to review (see the data-plane discussion in the User Guide overview).
- Governed reads only. The console does not hold a standing key to the raw store. It reads memory through the enforcement path, so every read is authorized, scoped, and consistent with what the agent itself is allowed to see.
- Local-first. The memory an agent accumulates stays in your workspace. The Memory view exposes it to you, the owner — it is not a channel for that content to leave the tenant.
See also
- Section 02 — My agent: the roster card's live Memory count and last activity.
- Section 04 — Chat: the live governed conversation that produces new memory.
- Section 06 — Blocked queries: what the agent was denied, the complement to what it remembers.
- Agent detail (admin) — Memory / Reasoning (CoT) tabs: the same governed explorer alongside the agent's captured chain-of-thought.
6. Personal plane — Blocked queries & the Build tools
The personal plane is where you work with your own agent. Sections 04 and 05 covered My agent, Chat, and Memory — the everyday surfaces. This section covers the remaining personal-plane surfaces: Blocked queries, the three Build tools (Knowledge, Mindsets, Playground), and the Account group (Documentation and Settings). Together these let you see what governance denied, curate what your agent knows and how it thinks, try work in a sandbox before you commit it, and configure the console itself.
All of these surfaces are consumer-grade by design; none expose fleet-wide control-plane data. A non-admin session is never served an admin route (§14), so everything below is available to any signed-in user against the agents they own.
6.1 Blocked queries (/blocked)
Blocked queries is the record of what your agent was denied. The platform is deny-by-default at the Policy Enforcement Point (PEP): a model call is forwarded only when it presents valid two-factor credentials and matches an explicit policy allow. Everything else is rejected and lands here. A populated Blocked list is normal and healthy — it is the enforcement working, not a fault.
Use this surface to understand why a task did not run, so you can either adjust the request or ask an administrator to widen the agent's route policy.
To review blocked queries
- Open Blocked queries (
/blocked) from the personal-plane navigation. - If you own more than one agent, select the agent from the picker.
- Read the denial list, newest first. Each row shows the fields in the table below.
Result: You see each denied call, the decision reason, and the timestamp — enough to distinguish a policy gap from a malformed request.
| Field | Meaning |
|---|---|
| Timestamp | When the call was evaluated by the PEP |
| Agent / tenant | Which of your agents made the call |
| Decision | Always deny on this surface |
| Reason | Why it was denied — no matching allow rule, missing scope, rate/burst limit, or invalid credential |
| Scope / route | The action or route the agent attempted |
If a denial reflects work the agent should be allowed to do, it is a route-policy matter. Route policy is authored under change control by an administrator (see the Admin guide, Policy administration). You cannot widen your own agent's policy from the personal plane — that boundary is deliberate.
6.2 Knowledge — the curated knowledge base
Knowledge is where you author a curated knowledge base (KB) and assign entries to specific agents. Unlike Memory (§05), which accumulates automatically from an agent's governed activity, Knowledge is deliberately curated — you decide what goes in, and it stays inside the workspace.
To author and assign a knowledge entry
- Open Knowledge from the Build group.
- Create a new entry and give it a clear title and body.
- Assign the entry to one or more of your agents.
- Save.
Result: The assigned agents can draw on the entry as governed context on their next run; the entry is scoped to the agents you named, not the whole fleet.
Knowledge is versioned as a lifecycle artifact: entries can be edited and reassigned over time. Assignment is per-agent — assigning an entry to one agent does not expose it to another.
6.3 Mindsets — curated grounding (TKHR)
A Mindset is a curated grounding corpus — MITRE ATT&CK, regulatory source text, CISO practice, a product codebase — that an agent can query in place at reasoning time. A mindset is not copied into the agent's memory. Bulk-ingesting a multi-thousand-passage corpus would look exactly like an attack and is correctly hard-blocked by the PEP's burst rule. Instead the corpus is registered as an available resource the agent has, and at query time the agent reads the curated TKHR store directly, read-only, returning only the top-k passages relevant to that query (default 4, maximum 25).
Mindsets are assignment-scoped: an agent may only query the mindsets it has been assigned, and any attempt to query an unassigned mindset is denied. Every query is audited.
To assign a mindset
- Open Mindsets from the Build group.
- Browse the catalog and choose a grounding corpus for your agent's role.
- Assign it to the agent.
Result: The agent becomes aware of the resource (a prompt line advertises the mindsets it may query) and can recall from it on demand, on its next governed run.
Representative catalog entries:
| Mindset | Grounds |
|---|---|
| Threat Intelligence (MITRE ATT&CK) | TTP naming, detection reasoning, source-graded threat briefs |
| Security Operations & Systems Security | An analyst's engineering judgment — why a control works, where it breaks |
| CISO Leadership & Risk | Risk-first prioritization, escalation, board communication |
| Regulatory Compliance | Citable passages from GDPR, EU AI Act, DORA, NIS2, HIPAA, CCPA/CPRA (grounding, not legal advice) |
The same query-in-place path is reachable programmatically for administrators (GET /control/mindsets, POST /control/mindsets/{slug}/recall) and via the agent-facing MCP tools mindset_list / mindset_query — all identically assignment-scoped and audited.
6.4 Playground
The Playground lets you run an ad-hoc task against one of your agents and inspect exactly what it did — before you decide whether to keep the result. It is the sandbox for "try this and show me the work."
To run a Playground task
- Open Playground from the Build group.
- Pick the agent to run the task as.
- Enter the task or prompt.
- Decide whether to enable governed persist — leave it off for a throwaway trial; turn it on to write the outcome into the agent's governed record.
- Click Run.
Result: The task executes through the full governed path, and the result panel returns the fields below.
| Result field | What it shows |
|---|---|
| Chain of thought (CoT) | The agent's reasoning trajectory for this task |
| Output | The final answer the agent produced |
| Provider / model | Which provider lane and model actually served the call (per the routing config) |
| Tokens | Tokens in and out for the call |
| Cost | Metered cost in USD for the call |
Because the run passes through the PEP like any other governed call, a Playground task is subject to the same deny-by-default policy — a denied task appears in Blocked queries (§6.1), and a persisted task is metered into the usage table that feeds the ROI board.
6.5 Account
The Account group holds the personal-plane's own configuration.
6.5.1 Documentation
Documentation renders this guide and related reference material in-console, so you can look up a procedure without leaving the app.
6.5.2 Settings
Settings is where you review your identity and configure the console.
| Setting | What it controls |
|---|---|
| Account identity + grants | Your signed-in identity and the scopes/grants your session carries |
| Workspace / tenant | The workspace and data tenant your agents belong to |
| Appearance | The console theme — light or dark |
| Demo snapshots | Saved demo states you can load in read-only DEMO mode |
To switch the console theme
- Open Settings from the Account group.
- Under Appearance, choose light or dark.
Result: The console re-renders in the selected theme immediately; the choice persists for your session.
Your session carries only your own scoped bearer — there is no standing privileged credential in the browser. What you can see and do in Settings reflects your real grants, the same boundary enforced on every governed call.
7. Reviewing an agent in depth
The agent-detail page is where you move from scanning the fleet to understanding a single agent completely — who it is, what it has been thinking, what work it has done, and exactly what it is allowed to do. It is the reference view you open before certifying an access review, investigating a drift detection, or answering "should this agent be doing this?" Everything on the page is a governed read: each agent's data is retrieved through the same zero-trust path the agents themselves use, so you only ever see one agent's tenant at a time (see §4.3, RLS isolation).
7.1 Opening the agent-detail page
- In the Admin console, open Agents (
/fleet) — the governed agent roster, grouped by department (see §1.2). - Locate the agent you want, either by scrolling its department group or by using the identity search at the top of the roster.
- Click the agent's card.
Result: the console navigates to the agent-detail page at /agents/{slug}, where {slug} is the agent's stable identifier (for example security-analyst).
The page opens on the persona (§7.2) with the four governed tabs (§7.3) beneath a management action strip. In read-only DEMO mode the page renders without login; the management actions are visible but act only when you have the corresponding grants.
7.2 Reading the persona
The top of the page is the agent's full persona — the durable definition of the worker, independent of whatever model tier happens to be serving it today. A persona is composed of six fields:
| Field | What it tells you |
|---|---|
| Identity | First-person self-description — who the agent is and the background it reasons from (e.g. "I came up through NOC work, so I think in baselines and deviations before I think in adversaries"). |
| Voice | The tone and register the agent writes in — how its output should read. |
| Values | The principles it will not violate — the standards that constrain how it does the work. |
| Expertise | The concrete skills it brings (e.g. log correlation, endpoint telemetry triage, incident timeline reconstruction). |
| Responsibilities | The standing duties it owns each operating cycle. |
| Job | The recurring unit of work: its name, cadence, inputs, process, output_kind, and quality_bar. This is the contract the agent is run against. |
Read the persona to establish intent before you read behavior: the four tabs below show what the agent did, and the persona is the baseline you judge that against. The inputs list in Job also tells you the agent's upstream dependencies — an input such as threat-intel-researcher.output is a hand-off edge on the fleet DAG.
Management actions (admin). A strip of actions sits between the persona and the tabs: Trigger a run, Enable / Disable, Edit agent, and Provider / model / routing. These are administrative controls, gated by your grants. The routing control reports WIRED · RUNNER CONTROL when the runner token is configured, or RUNTIME NOT CONFIGURED when it is not — in the latter state the run/routing actions are informational only. As a reviewer you generally read these rather than operate them.
7.3 The four governed tabs
Beneath the persona are four tabs. Each is a different governed window onto the same agent.
Memory
The Memory tab is what the agent has stored — its accumulated working knowledge as searchable, timestamped, topic-tagged memories (real incident memos and notes, not a transcript). Use it to answer What does this agent actually know? and Has its memory grown as expected? Each agent's memory lives in its own row-level-security-isolated tenant, so this tab can only ever show the one agent's rows. See §1.3 for the shared Memory explorer that presents the same data across agents.
Reasoning (CoT) timeline
The Reasoning (CoT) tab is the agent's captured chain-of-thought, presented as a timeline newest first. Each entry is the governed record of how the agent reasoned through a job — the step-by-step thinking behind an output, not just the output itself. Read it to audit judgment: to confirm the agent reached a conclusion the way its persona says it should, or to see where a drifting agent's reasoning diverged. Because CoT is governed and stored, it is evidence you can revisit, not a transient log.
Jobs (cycles)
The Jobs tab lists the agent's deterministic job cycles, grouped by session / cycle reference. One cycle is one complete unit of work — the runner builds a domain brief, makes a tiered model call, and writes the resulting CoT and memory. Grouping by cycle ref lets you see a single run end to end and correlate the reasoning (CoT tab) and the memory it produced. Fleet agents run roughly 1–2 governed jobs per day by design, so this tab is your record of the agent's actual output cadence.
Access & Policy
The Access & Policy tab is the agent's cryptographic and policy identity. It contains four things:
| Element | What it shows |
|---|---|
| Capability issuance scheme | How the agent's per-call authority is minted — short-lived HS256 capability tokens (600-second TTL), each requesting only the scope its endpoint needs (e.g. memory:read), derived from the agent's own capability secret. |
| Ed25519 public key | The agent's signing public key — the verifiable half of its identity used in the tamper-evident audit chain (PQC-hybrid Ed25519 + ML-DSA-44; see §4.4). |
| API-key hash ledger | A record of the agent's API keys by hash only (sha512 hex digest) — no secret material is ever shown or stored here, so the ledger is safe to review. |
| Route policy | The agent's deny-by-default call policy — the explicit allow rules the PEP evaluates on every call. Absent a matching allow, a call is denied (this is why the Events stream shows large deny counts, §2.2). Admins may edit the policy here; reviewers read it. |
The route policy shown here is the Tiresias call rules layer of the RSoP envelope — the innermost narrowing in E0 ⊇ E1 ⊇ call rules → effective. To see how it combines with the owner's directory entitlements and Asphodel's authored scope, open the Access explorer (§1.4) for the same agent.
7.4 A recommended review pass
- Read the persona (§7.2) to fix the agent's intended identity, values, and job contract.
- Open Reasoning (CoT) and read the most recent entries top-down; confirm the reasoning matches the persona.
- Cross-check Jobs to confirm the output cadence and tie each CoT to its cycle.
- Skim Memory to confirm what the agent has learned is consistent with its role.
- Open Access & Policy and confirm the route policy is as narrow as the job requires — no allow rule broader than the work.
Result: you have a complete, evidence-backed picture of one agent — intent, behavior, output, and authority — sufficient to certify a review or open an investigation.
Cross-references: roster and model tiers, §1.2 · Memory explorer, §1.3 · Access explorer (RSoP), §1.4 · the governance guarantee (two-factor auth, deny-by-default, RLS, signed audit), §4.
8. Admin console for analysts — the Exceptions dashboard
The Dashboard / Observe page (/observe) is the admin console's landing surface and the first screen an analyst governing the fleet should read each shift. It is deliberately exception-first: instead of a wall of green tiles telling you everything is fine, it surfaces only what deviates from expected behaviour, rolled up into one ranked incident per entity so that a fleet of hundreds of agents collapses into a short, actionable worklist. The design principle is that a healthy fleet produces a nearly empty Observe page, and any row you see is something that has already earned your attention.
8.1 What the Exceptions queue is
The central element of /observe is the ranked, rolled-up incident queue. Several distinct signals feed it:
- SoulWatch detections — behavioural-drift findings (bursts, new-resource access outside baseline, capability probing, trust collapse).
- Active quarantines — agents SoulWatch has held out of operation at composite behavioural risk ≥ 75.
- Correlated campaigns — related detections across agents or tenants folded into a single narrative rather than repeated line-by-line.
- Baseline drift — slower deviations from an agent's established behavioural baseline.
Crucially, these are folded into one incident per entity. If a single agent trips a trust-collapse alert, fires a Sigma policy-gap-probing rule a dozen times, and then quarantines at a composite risk score, you see one ranked incident for that agent — not fifteen rows — with the contributing detections available when you open it. Incidents are then impact-ranked, most severe first, so the top of the list is always where to start.
8.2 The severity tiles as filters
Four tiles sit across the top of the page. Each shows a live count and each is a clickable filter — selecting a tile narrows the queue below to matching incidents; selecting it again clears the filter.
| Tile | Meaning | Typical use |
|---|---|---|
| CRITICAL | Incidents that require action now — active quarantines, escalated detections, trust collapse. | Your first click at the start of triage. |
| WARN | Incidents to review but not necessarily act on immediately — medium-severity anomalies, single detections below the quarantine threshold. | Second pass, after criticals are cleared. |
| QUARANTINED | Agents currently held out of operation by SoulWatch. | Jump straight to what is offline and needs a release decision. |
| AGENTS AFFECTED | The distinct count of agents represented in the current queue. | Gauge blast radius — one noisy agent versus a fleet-wide pattern. |
Because the tiles are filters rather than static counters, use them to move between "how bad is it" and "show me exactly those" without leaving the page.
8.3 The SoD conflict scan panel
The Segregation-of-duties (SoD) conflict scan panel flags agents whose effective permissions combine duties that governance policy says must stay separated — the classic control that no single actor should be able to both initiate and approve the same class of action. Each finding names the conflicting duty pair so you can decide whether the combination is an authoring mistake in the agent's scope, a directory-entitlement problem at the owning principal, or an accepted exception. Resolve genuine conflicts by narrowing the agent's scope (see the Access explorer and Policy surfaces), not by editing the scan.
8.4 The Tiresias denials panel
The Deterministic-PEP Tiresias denials (24h) panel summarises what the enforcement point (the PEP) denied over the last 24 hours under its deny-by-default route policy. These are denials working as intended — a request that no policy rule granted was refused with a 403 — and volume here is expected and healthy, not alarming in itself. What matters is the shape: a sudden concentration of denials against one agent or one route (for example repeated GET /v1/cot, POST /v1/memory/write, or GET /v1/tools refusals from the same source) is the signature of policy-gap or capability probing, which is exactly what SoulWatch escalates into the queue above. Read this panel alongside the incident queue: the denials are the raw enforcement evidence, and the ranked incident is the correlated story.
8.5 The cut line and the severity legend
A visible cut line is drawn across the ranked queue. Incidents above the line are the ones the ranking judges worth acting on now; incidents below it are lower-impact and can wait. The cut line keeps a busy fleet's tail of minor findings from crowding out the few that matter — treat everything above it as your worklist for the shift.
The severity legend defines the colour coding used across the tiles and rows:
| Severity | Legend meaning | Analyst action |
|---|---|---|
| critical | Act now. | Investigate and remediate immediately. |
| warn | Review. | Assess when criticals are clear. |
| healthy | Benign. | No action; expected steady-state. |
8.6 Triage workflow — what to click first
Follow this order at the start of a session to work the queue from highest impact downward:
- Open
/observe. Read the four tiles first for an at-a-glance posture: CRITICAL, WARN, QUARANTINED, and AGENTS AFFECTED. Result: You know the severity mix and the blast radius before reading any single incident. - Click the CRITICAL tile to filter the queue to act-now incidents, then work them top-down — the ranking already puts the highest-impact incident first. Result: The queue shows only incidents above the cut line that demand immediate attention.
- Open the top incident. Because it is rolled up per entity, review its folded detections, its quarantine status, and its recent denials together to understand the whole story for that agent. Result: You can distinguish a genuine compromise from expected deny-by-default enforcement noise.
- Click the QUARANTINED tile to review held agents and decide, per agent, whether to release. Release itself is performed from the analyst Quarantine tab (see the analyst / enforcement console section). Result: Every held agent has a documented review and a release-or-hold decision.
- Scan the SoD conflict scan panel for duty-separation violations and open each flagged agent to confirm whether the conflict is real; remediate by narrowing scope through change control. Result: Standing separation-of-duties conflicts are triaged, not left latent.
- Read the Tiresias denials (24h) panel for concentration patterns against a single agent or route; correlate any spike with the incidents above. Result: Probing behaviour is caught even where it has not yet crossed the quarantine threshold.
- Clear the CRITICAL filter and repeat for WARN, working only above the cut line unless you are doing a deliberate deep review. Result: The full act-now and review backlog for the shift is worked in impact order.
Cross-references. To act on a specific agent from an incident, open its detail page (see Agents,
/fleet→ agent detail) and its four governed tabs — Memory, Reasoning (CoT), Jobs, and Access & Policy. To understand why an agent could reach a resource, use the Access explorer (/access); to change what it may do, use Policy (/governance). To release a quarantined agent, use the analyst enforcement console's Quarantine tab. SoulWatch's auto-quarantine threshold (composite behavioural risk ≥ 75) and the release procedure are described in the governance operations section.
9. Finding agents & reading ownership — Fleet and Principals
This section covers the two Admin-console views you use to locate a governed
agent and read who is accountable for it: Agents (/fleet), the governed
agent roster and identity search; and Principals (/principals), the
Principals & Ownership surface where every agent is tied to a human sponsor and a
human manager. Together they answer two questions a reviewer asks constantly:
which agent am I looking at? and who owns it?
The two views are complementary. Agents is organized around the agent — by department, model tier, memory, and activity. Principals is organized around the human — the accountable sponsor and the operational manager behind each agent, resolved against ACME's real directory of 325,154 principals. Both are read-oriented; the one mutating action on either surface (attesting an owner) is authored through change control, described below.
9.1 The Agents roster (/fleet)
The Agents view is the governed agent roster. It lists the fleet organized by department, mirroring ACME's real organization: the 360 fleet agents are mapped like-for-like to the real org across all 28 departments (weighted by department × role-family headcount), plus the 7 showcase agents, for 367 governed agents in total.
Each agent appears as a card grouped under its department heading. Read a card left to right:
| Field | What it tells you |
|---|---|
| Agent | The agent's display name and slug (e.g. security-analyst) |
| Persona essence | A one-line summary of the agent's role and remit |
| Model tier | The agent's current/home model tier (see §9.2) |
| Memory | Live count of memories the agent has accumulated — its working knowledge |
| Last activity | When the agent last ran a governed job |
How to read activity. The fleet is deliberately paced: each fleet agent runs roughly 1–2 governed jobs per day, so a healthy "last activity" is within a day, not minute-by-minute. A job is one unit of work — the agent builds a domain brief, makes a tiered model call, and writes a governed chain-of-thought and a memory. An agent silent for several days, not a few hours, is the thing worth noticing.
To find a specific agent:
- Open the Admin console and select Agents (
/fleet). - Scan to the agent's department heading, or type into the roster's search box to filter by name or slug.
- Click the agent card to open its detail page (
/agents/{slug}), where you can read the full persona and the four governed tabs (Memory, Reasoning, Jobs, Access & Policy).
Result: You are on the agent's detail page, scoped to that one agent's governed data.
9.2 Model tiers you will see
Agents route across a 9-tier, 3-provider roster. Routing favors free and self-hosted tiers for everyday work and reserves paid frontier models for escalation.
| Provider | Tiers | Role in routing |
|---|---|---|
| OpenRouter (paid) | opus-4.8, sonnet-4.5 |
Escalation ceiling — reserved for incident/breach/critical work |
| OpenRouter (free) | gemma-4-31b:free, qwen3-next-80b:free, hermes-405b:free, llama-3.2-3b:free |
Free everyday tiers |
| Ollama Cloud (self-host) | gpt-oss:120b, deepseek-v4-pro |
Reliable self-hosted tiers; ollama_oss is the standard floor |
| HuggingFace | Llama-3.3-70B |
Additional self-hosted tier |
If a card shows a paid tier (opus-4.8 / sonnet-4.5), that generally reflects
an escalation — keyword escalation (+incident, +breach, +critical)
bumps a request toward the agent's ceiling. Most fleet traffic sits on
free/Ollama tiers by design.
9.3 Principals & Ownership (/principals)
Every governed agent answers to a human. The Principals view makes that accountability explicit and searchable. For each agent it names two distinct human principals:
| Role | Field | Meaning |
|---|---|---|
| Accountable sponsor | sponsor_id |
The human who stands behind the agent's existence and is answerable for it. Governs the no sponsor → no run invariant. |
| Operational manager | owner_principal_id |
The direct-report owner — the human whose real directory entitlements the agent's access is derived from (the E0 owner). |
The no-sponsor → no-run invariant. An agent with no accountable sponsor does not run — this is one of the platform's structural governance rules, not a warning that can be dismissed. If an agent has lost its sponsor (for example, the sponsoring principal has left the organization), the platform treats the agent as unattested and holds it rather than letting an unowned agent act. Restoring a sponsor (see §9.5, succession-on-departure) is what returns it to service. This is deliberately the same discipline you would apply to a service account: no account exists without a human answerable for it.
The manager is the operational owner. It is this link (owner_principal_id)
that lets the Access explorer (§ Access) derive the agent's real entitlement
envelope live from the owner's directory groups, department/OU, region, and
role — the E0 layer of the RSoP chain. An agent that is not linked to a directory
principal shows an honest stub in the Access explorer rather than pretending;
attesting or linking an owner is what moves it toward live.
9.4 The identity-index search
The directory behind Principals holds 325,154 principals across 28
departments, 10 regions, and 626 roles. That full graph is intentionally not
browsable — you do not scroll 100k+ rows. Instead the principal browser is a
server-side identity-index search: you type a query and the console asks the
control plane for matches via GET /cp/admin/identities, which searches the
tzt_principal index (name, id, and search terms) and returns only the matching
principals.
To look up a principal:
- Open the Admin console and select Principals (
/principals). - Type a name, principal id, department, or role into the search box. The
console issues
GET /cp/admin/identitiesserver-side (the admin key stays in the BFF; it is never exposed to the browser). - Select a returned principal to read their directory attributes — groups, department/OU, region, role — and the agents they sponsor or manage.
Result: You see one principal's real directory record and their ownership relationships, without ever enumerating the whole directory.
This "search, don't browse" design is the same reason the surface stays fast and safe at ACME's directory scale: the index answers targeted queries; it does not stream the graph.
9.5 The owner-unattested queue and attestation
Principals also surfaces a suggested-owner queue — the list of agents that are owner-unattested (no confirmed operational owner yet). This is the worklist for closing ownership gaps. Each entry offers an Attest owner action: you confirm the human owner for that agent, and the change is authored through change control — it becomes a reviewable, approvable change record, not a silent write. Ownership is a governed fact, so establishing it goes through the same approval path as any other governed change.
To attest an owner:
- On the Principals view, open the suggested-owner queue of owner-unattested agents.
- Select an agent and review the suggested human owner (or search the identity index, §9.4, for the correct principal).
- Choose Attest owner to author the ownership change.
Result: An attestation change record is raised through change control. Once
approved, the agent is linked to its owner principal, and its Access explorer
entry can resolve E0 live instead of showing a stub.
Succession on departure. When a principal leaves the organization, their agents must not be orphaned — an agent that loses its sponsor falls under the no-sponsor → no-run invariant (§9.3). The succession-on-departure flow reassigns a departing principal's agents to new sponsors/managers so that accountability is continuous and the agents keep running under a valid human owner. Use it whenever a sponsoring or managing principal offboards.
9.6 Cross-references
- To read what a linked agent is actually entitled to do — the E0 ⊇ E1 ⊇ call rules → effective derivation the owner link feeds — see the Access explorer section.
- To open a specific agent's persona, memory, reasoning, jobs, and policy, use
the agent detail page (
/agents/{slug}) reached from §9.1. - The directory sync that populates
tzt_principal, and the linking scripts that setowner_principal_id, are administrator tasks documented in the Implementation Guide (§3 identity sync, §10 linking agents to principals).
10. Reading an entitlement envelope — the Access explorer
The Access explorer (/access) answers the one question every reviewer, sponsor, and auditor eventually asks about a governed agent: what is this agent actually allowed to do, and why? Instead of forcing you to read policy JSON, LDAP group memberships, and PEP route rules side by side, the explorer resolves them into a single Resolved-Set-of-Permissions (RSoP) — a deterministic entitlement envelope, expressed in plain verbs, with full provenance and honest per-layer confidence.
This section explains how to read that envelope. It is a reference view: you select an agent and read the derivation. You do not change anything here — authoring entitlements is done elsewhere (owner linking in the directory, scope bindings in Asphodel, call rules in Tiresias). The explorer only shows the result of those three layers narrowing one another.
10.1 Opening the explorer and selecting an agent
To read an agent's entitlement envelope:
- Open the Admin console and select Access from the navigation (
/access). - Use the agent selector at the top of the view to choose an agent — by name, slug, or department.
- Read the resolved envelope. The explorer recomputes the derivation for the selected agent and renders the four-layer chain plus the summary tiles.
Result: the view displays the agent's E0 → E1 → call-rules → effective chain, each layer with its own confidence badge, and the six summary tiles across the top.
10.2 The derivation chain: E0 ⊇ E1 ⊇ rules → effective
The heart of the view is a four-layer chain. Each layer is a set of permissions, and each layer can only restrict the layer above it — never add to it. Reading left to right (or top to bottom), the chain is:
| Layer | What it is | Source | Relationship |
|---|---|---|---|
| E0 | The owning human principal's real directory entitlements — LDAP groups, department/OU, region, role. | The directory (tzt_principal projection), via the agent's linked owner. |
The outer bound. |
| E1 | Asphodel's authored scoped subset — the deliberately narrower slice of E0 you actually grant the agent. | The agent's scope_bindings. |
E1 ⊆ E0. |
| Call rules | Tiresias's deny-by-default PEP policy — the route rules the enforcement plane actually applies at call time. | The PEP's per-agent policy. | rules ⊆ E1. |
| Effective | What the agent can genuinely do right now: the intersection E0 ∩ E1 ∩ rules. | Derived. | effective ⊆ rules. |
The precise invariant the explorer proves is:
E0 ⊇ E1 ⊇ call rules → effective = E0 ∩ E1 ∩ rules
Read this as: the human owner's directory entitlements (E0) contain everything Asphodel chose to scope to the agent (E1), which contains everything Tiresias's deny-by-default rules permit, and the effective set is the intersection of all three. Because the derivation is deterministic, the same agent and the same underlying data always produce the same envelope.
10.3 The monotonic-narrowing invariant
The single most important property to understand when reading this view is monotonic narrowing: every layer can only subtract from the one above it. Formally, E1 ⊆ E0 always holds, and effective ⊆ E1 always holds. No layer can introduce a permission that its parent did not already contain.
This is why the guarantee "an agent cannot exceed its principal" is provable, not merely asserted. The agent's effective permissions are a subset of E1, which is a subset of E0, which is exactly the entitlements of the human who owns it. An agent can be given less than its owner — and almost always is — but it can never be given more. If you ever see a permission in the effective set that is not present in E0, that is a defect to report, not a configuration you are allowed to author: the invariant forbids it by construction.
For a reviewer, this collapses a hard question ("could this agent possibly do something its owner cannot?") into a settled one. The answer is always no, and the chain shows you exactly where each permission was narrowed away.
10.4 The summary tiles
Across the top of the view, six tiles summarise the envelope at a glance. Each is a count derived from the chain.
| Tile | Meaning |
|---|---|
| E0 ENTITLEMENTS | The size of the owner's real directory entitlement set — the outer bound. |
| E1 SCOPED | The size of Asphodel's authored scoped subset (E1). |
| CALL RULES | The number of deny-by-default route rules Tiresias applies at the PEP. |
| EFFECTIVE | The size of the effective set — what the agent can actually do (E0 ∩ E1 ∩ rules). |
| NOT-GRANTABLE | Permissions that could not be granted to this agent because they lie outside E0 — i.e. entitlements the owner does not hold. This tile makes the ceiling visible: it is the gap between what someone might request and what the principal could ever authorize. |
| JIT | Just-in-time entitlements currently active — grants elevated for a bounded window rather than standing. When zero, the agent is running purely on its standing effective set. |
Reading the tiles together tells the story quickly. In the reference derivation shown above, for example, a small E0 narrows to a still-smaller E1, which narrows again through the call rules to an effective set — the classic shape of an agent scoped far below its owner's full directory reach.
10.5 Confidence: live, partial, and stub
Each layer carries an honest confidence badge so you can tell which parts of the envelope are backed by real data and which are placeholders. The explorer never pretends a layer is grounded when it is not.
| Badge | Meaning | What to do |
|---|---|---|
| live | The layer was derived from real, current data — E0 from the linked owner's actual directory attributes, E1 from real scope_bindings, rules from the live PEP policy. |
Trust it; this is a real resolved permission set. |
| partial | Some but not all inputs for the layer were available; the derivation is grounded in part and estimated in part. | Read it, but note which inputs are missing before relying on it for a certification. |
| stub | The agent is not yet linked to a directory principal, so E0 cannot be derived from a real owner. The explorer shows placeholder structure instead of inventing entitlements. | Link the agent to its owner (see below), then re-open the view for a live derivation. |
What stub means — and does not mean. A stub badge is an honest state, not a failure. It tells you the agent has no owner_principal_id link into the directory, so there is no real human whose entitlements can seed E0. The explorer deliberately shows a placeholder rather than fabricating a plausible-looking envelope — an unlinked agent with an invented E0 would be worse than useless, because it would look governed while resting on nothing. Seeing stub is your cue to establish the owner link; once the agent is linked to a directory principal, E0 derives live from that owner's real attributes and the whole chain becomes grounded.
Linking an agent to its owner is a directory/administration task (it sets the agent's owner_principal_id so E0 can be derived from the owner's real directory entry). If you are a reviewer rather than an administrator, a stub badge is something to flag to whoever owns directory linking for the fleet.
10.6 Cross-references
- Section 9 — Principals & Ownership: every agent answers to a human sponsor and operational manager; that ownership graph is what supplies the owner principal whose entitlements become E0.
- Section 11 — Reviews & recertification: the effective set and its
live/partial/stubconfidence feed directly into access reviews — you recertify against what the explorer resolves. ADMIN-GUIDE.md§7 (Governance operations) andIMPLEMENTATION-GUIDE.md§9 (the console) / §10 (owner linking): the administrator-side procedures for authoring scope bindings, editing call rules, and linking agents to directory principals.
11. Governance, Reviews, Audit & reports, Drift & behavior
This section covers the four admin-console surfaces you use to govern the standing fleet after it is deployed: the Policy cockpit (/governance), Reviews (/reviews), Audit & reports (/reports), and Drift & behavior (/analytics). All four live in the Asphodel admin plane and are gated server-side by RBAC — a non-admin session is never served these routes. Reach them from the admin console at console.asphodel.ai (or the VM at :3001). In read-only DEMO mode the pages render without login; full read/write access requires an OIDC or demo-auth session.
These surfaces present the fleet; they never bypass it. Every figure you read here is derived from the Control Plane's durable stores and the signed audit chain, and every write is authored through the same governed API the fleet itself is held to.
11.1 Reading the Policy / governance cockpit
Policy (/governance) is the fleet governance cockpit — the one screen that answers "what is each agent allowed to do, and is the record of what it has done intact?"
The cockpit is organized per agent. For each governed agent you see:
| Column / field | What it tells you |
|---|---|
| Sovereignty | The agent's governing tenant / data sovereignty scope |
| Tier | The model tier the agent is provisioned at |
| rpm | The rate ceiling (requests per minute) enforced for the agent |
| Policy summary | A rollup of the deny-by-default route policy in force |
| Signed-audit count | How many governed calls have been signed into the audit chain for this agent |
| Chain status | intact when the signed chain is continuous and verifiable |
| Sign-off | The compliance officer's latest recorded governance sign-off |
To read the cockpit:
- Open Policy (
/governance) from the admin navigation. - Scan the Chain status column — every governed agent should read
intact. A non-intactentry is the signal to open Audit & reports (§11.3) and run a full chain verification. - Confirm the Sign-off reflects the current review cycle. A stale or missing sign-off is a recertification prompt, not a fault.
Result: You have a per-agent governance posture — tier, rate, policy, audit integrity, and human accountability — in one view.
Editing per-agent policy and budget
The cockpit is also where you change what an agent may do. Use the per-agent policy editor to set tier, rpm, rpm_mode, and budget.
- Select the agent's row to open its policy editor.
- Set
tier,rpm, andrpm_mode, then save. This issues:
PUT /cp/admin/tenants/{slug}/policy
3. To change the spend ceiling, set the agent's budget and save. This issues:
PUT /cp/admin/tenants/{slug}/agents/{slug}/budget
Result: The Control Plane records the new policy or budget; enforcement at the PEP picks it up on the next governed call.
The route policy itself (the deny-by-default allow rules) is edited on the agent detail page under Access & Policy. See the Agents section for the route-policy editor; the Policy cockpit governs tier, rate, budget, and audit posture.
11.2 Reviews / recertification
Reviews (/reviews) is the access-review and recertification workflow. It is the periodic control that confirms every agent's access is still justified and every agent still has an accountable human behind it.
Reviews are authored over change control (the change-control service, Contract B) — a completed review is a change-controlled record, not an ad-hoc toggle. This means each recertification decision is captured, attributable, and replayable, and any resulting policy change flows through the same approval path as every other governed change.
To run a recertification:
- Open Reviews (
/reviews). - Work the queue of items due for certification — each names the agent, its owner, and the access being certified.
- For each item, certify (access still justified) or flag it for remediation.
Result: Certified items are recorded through change control; flagged items become follow-up changes in Change & approvals (/approvals).
If the change-control service is not connected, approval-backed surfaces degrade to a "not connected" state rather than silently accepting writes. Reconnect
CHANGE_SVC_URLto restore the workflow.
11.3 The Audit & reports browser
Audit & reports (/reports) is the audit-chain browser plus reporting. It is your evidence surface: the durable, tamper-evident record of every governed decision.
Every governed call is signed into a PQC-hybrid audit chain using Ed25519 + ML-DSA-44 SoulKey signatures, buffered to a durable write-ahead log, and shipped to the Control Plane. The browser lets you read that chain and filter it:
| Field | Meaning |
|---|---|
| decision | Whether the call was allowed or denied |
| scope | The resource / route the call targeted |
| status | The outcome status of the governed decision |
| ts | Timestamp of the audited event |
| chain filter | Restrict the view to a single signed chain |
- Open Audit & reports (
/reports). - Filter by decision, scope, status, or ts to locate the events an auditor is asking about.
- Use the chain filter to isolate a single chain and confirm continuity.
Result: You have produced the governed evidence trail for an audit question — the record that answers "how do you know this happened, and that it was not altered?"
To prove the chain is cryptographically intact end-to-end, run verification from the analyst console's Verify tab (see §2.7). The Audit & reports browser reads and reports the chain; Verify proves its signatures.
11.4 Drift & behavior analytics
Drift & behavior (/analytics) is the content-blind behavioural cockpit. It never inspects the substance of an agent's work — only the shape of its behaviour over time — which is how the fleet is monitored without reading tenant data. The cockpit is organized into tabs:
| Tab | What it shows |
|---|---|
| Campaigns | Correlated campaign clusters — related drift events grouped into one behavioural pattern across agents |
| Per-model drift | Drift reports per model, so you can tell a single misbehaving agent from a model-wide shift |
| Baselines | Population-baseline maturity — how well-established the behavioural baseline is for the fleet |
This cockpit is the substance behind SoulWatch: an agent whose composite behavioural risk reaches ≥ 75 is auto-quarantined, and these tabs are where you see the population context around such a detection.
Honest empty states
On a fresh fleet these analytics degrade to honest empty states rather than fabricating signal. Until enough governed activity has accumulated:
- Campaigns shows no clusters — there is not yet enough correlated behaviour to group.
- Per-model drift shows no drift reports — no per-model baseline has diverged.
- Baselines reports an immature population baseline — the fleet has not yet run long enough to establish one.
An empty cockpit on a newly provisioned fleet is a correct, expected state, not a failure. As governed jobs accumulate (roughly one to two governed jobs per agent per day under the fleet runner), the baseline matures and the campaign and per-model tabs begin to populate. Read this cockpit periodically once the fleet has been running; read it immediately whenever a Drift & behavior detection or a quarantine appears on the Dashboard, to place that single event in its population context.
11.5 Cross-references
- Dashboard / Observe (
/observe) — rolls the detections, quarantines, correlated campaigns, and baseline drift described here into one impact-ranked incident per entity. - Access (
/access) — the RSoP access explorer proves the effective permissions a policy change in §11.1 will produce. - Analyst console (§2) — Detections, Quarantine, and Verify are the enforcement-side counterparts to the Drift and Audit surfaces above.
12. The analyst / enforcement console (Tiresias PEP)
The analyst console is the enforcement investigation surface. Where the Asphodel management console (Section 2) shows you the workforce and lets you govern it, this console shows you what enforcement actually did: every governed model call, every behavioural-drift detection, every automatically held agent, and cryptographic proof that the audit trail is intact. It is served directly by the Policy Enforcement Point (PEP) — the Tiresias-ZT component that sits inline on every governed call, evaluates it deny-by-default, and signs the outcome into a tamper-evident chain. Its own header names it "the seer's console — Tiresias."
Read this console when you need ground truth about enforcement rather than intent. It is the operator's window on the running PEP, and it stands apart from Asphodel: Asphodel manages agents; Tiresias enforces on them, and this console reports what the enforcement point saw and decided.
12.1 Connecting
The console is reachable at:
Production : https://pdp.tiresias.watch
Direct VM : http://acme-demo-host:8343/admin/console
To connect:
- Open
/admin/consolein a browser. - Paste the admin key — the
X-Admin-Keyvalue, i.e.TZT_ADMIN_KEY— into the key field at the top of the page (#key). - Optionally set a base URL to point the console at a different PEP host; leave it blank to use the same origin the page was served from.
- Click connect.
Result: the header shows CONNECTED with the install identity (for example PLATFORM · SUPERADMIN · PRO), and every subsequent XHR the page issues carries the admin key. The four summary tiles across the top populate — EVENTS, DENIES, SIGNED, and the audit CHAIN id (for example pep_534748310020a4a1).
Do not use the bare
:8343/adminpath. That path is the governed API, not the console, and returns"api key required". The console is specifically/admin/console(see Section 15, Troubleshooting).
The workspace is organised into tabs — Events, Detections, Quarantine, Agent case view, Behavior, Proxy, Verify, and Status — described below in the order you will typically use them.
12.2 Events — the governed call stream
Events is the live stream of governed calls flowing through the PEP. Each entry records which agent/tenant made the call and whether it was allowed or denied. This is your first stop to confirm traffic is flowing and to see what the fleet is being denied.
The key to reading Events is that the PEP is deny-by-default: a call is allowed only if it presents both valid credentials (tenant API key + per-agent capability token) and matches an explicit policy allow. Everything else is rejected. A high deny count is therefore normal and healthy — it is enforcement working, not a fault. See Section 12.9 for how to read the posture.
12.3 Detections — SoulWatch drift
Detections shows behavioural-drift findings from SoulWatch, the monitor that watches each agent for deviation from its expected behavioural pattern. Each finding carries a composite behavioural risk score. A detection is a signal, not automatically an action — it is your early warning. Detections whose composite risk reaches the auto-quarantine threshold move the agent into Quarantine (next tab).
12.4 Quarantine — held agents, and releasing them
Quarantine lists agents that SoulWatch has automatically held because their behaviour drifted too far. The rule is concrete:
SoulWatch auto-quarantines an agent when its composite behavioural risk reaches ≥ 75.
A held agent is taken out of normal operation pending review. To review one, open it from the Quarantine tab (or use the Agent case view, Section 12.5) to see the drift detections and the risk that triggered the hold.
To release an agent once you have reviewed it and judged it safe, use release in the Quarantine tab. The console issues:
POST /admin/quarantine/{id}/release
Result: the agent is returned to normal operation and drops off the Quarantine list. Release is a deliberate operator action — the system holds the agent until a reviewer clears it, so a quarantine is reversible but never silently self-clears.
12.5 Agent case view
The Agent case view is the per-agent investigation page. Select an agent to see its consolidated story in one place: its governed events, its detections, and its quarantine status. Use this when you are investigating a specific agent rather than scanning the whole fleet — for example, to decide whether a held agent should be released.
12.6 Behavior
The Behavior tab surfaces the analytics behind a drift finding: trajectory, per-model baseline, campaign clustering, and drift analytics. This is where you go to understand an agent's behavioural profile over time and how its current behaviour compares to its established baseline — the substance behind a Detections entry. SoulWatch is content-blind: it reasons over behavioural markers, not the content of the agent's work.
12.7 Proxy
The Proxy tab exposes the PEP's inline forwarding surface — the point at which an allowed call is forwarded verbatim to the agent's RLS-isolated data tenant. Use it to confirm the forward path is healthy and that allowed traffic is reaching backends.
12.8 Verify — proving audit integrity
Verify is how you prove, cryptographically, that the audit trail has not been tampered with. Every governed call is signed into a tamper-evident audit chain using PQC-hybrid Ed25519 + ML-DSA-44 SoulKey signatures, buffered to a durable write-ahead log, and shipped to the Control Plane. The hybrid signature stays attributable even against a future quantum adversary.
To run a check, open Verify and click verify chain + signatures (#v-run). The tab shows verifying… while it works and then reports the result.
Result: a passing verification means the chain of signed calls is intact and continuous — no call has been altered, inserted, or removed. This is the evidence you present when an auditor asks "how do you know this record is real?"
12.9 Status — posture, and reading the deny-dominant picture
Status is your one-screen enforcement posture. Click refresh to pull the latest. The panel reports:
| Signal | What it tells you |
|---|---|
| Events | Total governed calls the PEP has processed |
| Denies | How many were rejected — deny-by-default in action |
| Signed / Chain | Whether audit signing is active, and the audit chain id |
| Audit signer | The signer scheme in force (e.g. PQC hybrid — Ed25519 + ML-DSA-44) |
| SoulWatch | Posture (ENFORCING), plus baselines, detection rules, and active quarantines |
| Top risk | The highest-scoring tenant/agent and its composite score |
| Install tier / License / Max tenants | The install's entitlement (e.g. owner tier, unlimited tenants) |
| SIEM export | Whether security-event export is configured, the forwarding metrics, and the syslog target |
On the live instance the figures are illustrative but characteristic:
11,765 events · 11,337 denies · signed: yes · chain: pep_534748310020a4a1
SoulWatch: ENFORCING · active quarantines: 7 · audit signer: PQC hybrid
SIEM: configured=true · {"host":"promtail","port":1514,"protocol":"tcp","format":"rfc5424"}
Reading the deny-dominant posture. The single most important thing on this screen is that denies dominate events — here roughly 11,337 of 11,765 calls were denied. That is not a symptom of a broken fleet; it is the expected shape of a healthy deny-by-default system. The PEP forwards a call only when it presents both authentication factors and matches an explicit allow, so the large residual of denied traffic is exactly the enforcement doing its job. When you read Status, confirm three things together: enforcement is live (SoulWatch: ENFORCING), the record is trustworthy (signed: yes, and a passing Verify run), and the export pipeline is flowing (SIEM configured with a healthy send_count and no last_error). A drop in the deny ratio, a signed: no, a failed Verify, or a stalled SIEM send_count are the signals worth investigating — not the deny count itself.
Cross-references. For the exception-first management view of the same detections and quarantines, see Section 2 (Asphodel → Observe). For the enforcement model behind these denies — two-factor call authentication, deny-by-default, RLS isolation, and signed audit — see Section 14, The governance guarantee. For releasing agents and audit-chain operations from the admin side, see the ADMIN-GUIDE governance procedures.
13. Reading the economics — the ROI board
The ROI board is the money view of the governed workforce. It renders real per-model usage — recorded from every governed job the runner executes — as a cost-per-million-tokens economics story, so you can answer ACME's central business question with numbers instead of opinions: is self-hosting cheaper than paying per API call, and where does that stop being true? Every figure on the board is drawn from actual metered calls; nothing here is projected or estimated.
The board is a Grafana dashboard backed by the Control Plane's usage ledger. It updates as the fleet runs, so the totals grow over time — treat the figures in this section as representative live values, not fixed constants.
13.1 Logging in
The board lives on the observability stack, not inside the Asphodel console. Open it directly:
- Browse to the dashboard URL:
http://acme-demo-host:3000/d/acme-roi-economics
- Note what anonymous access gives you. Grafana renders the dashboard shell — panel titles, layout, and legends — but the data panels come back empty. The datasource query runs under an authenticated session, so an anonymous viewer sees the frame with no numbers.
- Log in as admin. Use the Grafana sign-in, then reload the dashboard.
Result: the panels populate with live spend, token, and call figures.
The dashboard uid is acme-roi-economics. It reads the tzt_usage table through the Grafana Postgres datasource named acme-tzt-usage. If a single panel shows an error while the rest render, the cause is almost always the time-filter macro — see §13.5.
13.2 The panels
The board is organized top-to-bottom from fleet-wide totals to per-lane and per-agent breakdowns.
| Panel | What it tells you |
|---|---|
| Total spend / tokens / calls | Fleet-wide headline stats — cumulative dollars spent, tokens consumed, and governed calls made across all agents. |
| Per-model $/1M-token table | The core economics — normalized cost per million tokens, one row per model. This is the number to compare across models. |
| Spend & tokens per hour by model | Where the money and the volume go over time, split by model. |
| Spend by provider lane | Dollars grouped by lane — OpenRouter paid, OpenRouter free, Ollama Cloud, HuggingFace. |
| Spend by agent | Which of the seven showcase agents (and, at fleet scale, which departments) cost the most. |
| Calls by lane | Call volume split across the same provider lanes — the counterpart to spend by lane. |
The board reads six columns of the usage ledger: model, tokens_in, tokens_out, cost_usd, events (call count), and bucket (the time bucket, stored as epoch seconds). Rows are keyed by tenant, agent, and granularity (gran).
13.3 The per-model economics
The per-model table is the headline. Representative live figures:
| Model | Provider lane | $/1M-token |
|---|---|---|
| opus-4.8 | OpenRouter paid | $37.08 |
| sonnet-4.5 | OpenRouter paid | $10.06 |
| deepseek-v4-pro | Ollama Cloud | $0.62 |
| Llama-70B | HuggingFace | $0.60 |
| gpt-oss:120b | Ollama Cloud | $0.44 |
| gemma:free | OpenRouter free | $0 |
How to read it. The paid frontier tiers cost one to two orders of magnitude more per million tokens than the self-hosted and open-weight tiers. The fleet's routing (see the runner configuration) homes everyday work on free and Ollama-Cloud tiers and reserves the paid frontier for genuine escalation — incidents, breaches, legal and compliance work. So on the board, the cheap tiers dominate call volume (Calls by lane) while the expensive tiers carry only the small escalated slice of spend (Spend by lane). Reading the two lane panels side by side makes the whole argument visible: a lane that is a thin sliver of calls but a fat slice of spend is your frontier tier earning its keep on the hard problems; a lane that is a fat slice of calls but near-zero spend is the free or self-hosted tier absorbing routine load for almost nothing.
13.4 Free vs paid, and when self-hosting pays off
The board makes two distinct arguments — do not conflate them.
- Paid vs everything else. The $/1M-token gap between the paid frontier (opus-4.8 at ~$37, sonnet-4.5 at ~$10) and the rest (all under $1) is the entire case for routing by tier. Every call you keep off the frontier and on a cheaper tier is a direct, measured saving. Because the fleet only escalates to paid on cause, the paid lanes stay small — that is deliberate cost control, not underuse.
- Free vs self-hosted — "$0 is not free in practice." A
$0/1M line (for examplegemma:free) looks like the cheapest possible option, but the raw price hides a reliability cost. Under fleet load, free API tiers saturate: the free 405B lane in particular suffers chronic HTTP 429 rate-limit errors. That is why the runner homes free agents' fallback floor on the self-hostedollama_osstier — a reliable, cheap degrade path — rather than on a saturating free endpoint.
So self-hosting pays off precisely where free APIs are cheap on paper but undependable at scale, and where paid APIs are dependable but expensive. Read a $0 line on the board as "free, but not dependable at fleet load," and read the Ollama-Cloud lane (deepseek-v4-pro at ~$0.62, gpt-oss:120b at ~$0.44) as the sweet spot: near-free per token and reliable enough to be a floor. The break-even is a volume argument — the more routine calls the fleet runs, the more a cheap, reliable self-hosted lane beats both a per-call frontier bill and an unreliable free tier.
13.5 Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Shell renders but panels are empty | Not logged in — anonymous session can't run the datasource query | Log in as admin and reload. |
| One time-series panel errors while others render | Wrong time-filter macro on the epoch bucket column |
The panel query must use $__unixEpochFilter(bucket), not $__timeFilter(to_timestamp(bucket)), which mis-expands and errors. |
| Table cells fail to render in a headless/exported capture | Color-background gradient cell option | Drop the gradient cell option for headless renders. |
| A model or lane is missing | No governed calls have hit that tier yet | Expected on a fresh fleet — the row appears once the runner routes work there. |
See also: the runner routing and per-model pricing that produce these figures live in runner/config.json (tiers, home/ceiling/floor, and price_per_million per model). For the governance context around why calls are metered at all, see the enforcement and audit sections of this guide.
14. Common workflows
This section threads the individual consoles into the end-to-end tasks you will actually perform: investigating an incident, proving the audit chain, clearing a held agent, reviewing what an agent may do, and checking what it was denied. Each workflow is a self-contained procedure. Unless noted, the Asphodel management console is reached at console.asphodel.ai (or the VM at :3001) and the analyst / enforcement console (Tiresias PEP) at pdp.tiresias.watch (or the VM at :8343/admin/console). Before any analyst-console step, connect first: load the page, paste the admin key (X-Admin-Key, i.e. TZT_ADMIN_KEY) into the #key field, and click connect so subsequent requests carry the key.
14.1 Investigate an incident from Observe to resolution
Use this when the Admin Dashboard / Observe view surfaces an exception and you need to run it to a decision. Observe rolls every signal for one entity — SoulWatch detections, active quarantines, correlated campaigns, and baseline drift — into a single impact-ranked incident, so you work one incident, not a stream of alerts.
- Open the Admin console Dashboard / Observe view (
/observe). - Read the summary tiles — CRITICAL, WARN, QUARANTINED, AGENTS AFFECTED. Click CRITICAL to filter the queue to act-now incidents (the legend reads critical = act now, warn = review, healthy = benign). Result: The incident queue is filtered to the highest-impact exceptions, ranked above the visible cut line.
- Select the top incident to open its rolled-up detail: the affected agent(s), the correlated detections, and the drift that folded into it. Cross-check the two Observe panels — the Segregation-of-duties (SoD) conflict scan and the Deterministic-PEP Tiresias denials (24h) — for related signals on the same entity.
- Switch to the analyst console and open the Agent case view for the named agent to see its consolidated story — governed events, detections, and quarantine status in one place — then open the Behavior tab to compare current behavior against the agent's established baseline. Result: You can state why the incident fired and whether it reflects genuine drift or benign variation.
- Resolve according to the finding: if the agent is already held, follow §14.3 to review and release (or keep it held); if policy is the cause, hand off to the fleet administrator for a policy change; if benign, note the disposition and let the incident age out. Result: The incident is dispositioned with a documented rationale, and the Observe queue reflects the closed state.
14.2 Verify the audit chain
Every governed call is signed into a tamper-evident chain using PQC-hybrid Ed25519 + ML-DSA-44 SoulKey signatures, buffered to a durable write-ahead log, and shipped to the Control Plane. Run this whenever you need to prove the record is intact — for example, when an auditor asks how you know a record is real.
- In the analyst console, open the Verify tab.
- Trigger verification with the run control (
#v-run). Result: The console re-checks the signatures across the chain of governed calls. - Read the result. A passing result means the chain is intact and continuous — no call has been altered, inserted, or removed. Result: You have cryptographic evidence the audit trail is untampered, which you can cite directly.
- For posture at a glance, open the Status tab and confirm the audit signer is present and signing alongside the live event/deny counts and SIEM export. Result: You have confirmed both the integrity of the chain and that signing is active.
14.3 Handle a quarantined agent
SoulWatch auto-quarantines an agent when its composite behavioral risk reaches ≥ 75, holding it out of normal operation pending human review. Release is a deliberate human action — the system holds the agent until a reviewer clears it.
- In the analyst console, open the Quarantine tab to list the currently held agents.
- Open the held agent (or its Agent case view) to see why it was held — the drift detections and the composite risk that crossed the threshold. Use the Behavior tab to weigh the current behavior against the agent's baseline. Result: You understand the specific behavior that triggered the hold.
- Decide. If the behavior is unacceptable, leave the agent held and escalate to the fleet administrator. If you have reviewed it and judge it safe, proceed to release.
- To release, use release in the Quarantine tab. This issues:
POST /admin/quarantine/{id}/release
Result: The agent returns to normal operation, and the Quarantine tab no longer lists it. The release remains recorded in the signed audit chain (verifiable per §14.2).
14.4 Review an agent's effective entitlements
Use the Admin Access explorer to answer what is this agent actually allowed to do, and why? It resolves a Resolved-Set-of-Permissions (RSoP) as a deterministic, monotonically-narrowing envelope in which every layer can only restrict the one above it.
- Open the Admin console Access view (
/access) and select the agent. Result: The explorer derives the envelope with full provenance and per-layer confidence. - Read the derivation left to right:
| Layer | Meaning |
|---|---|
| E0 — entitlements | The owning human principal's real directory entitlements (LDAP groups, dept/OU, region, role) |
| E1 — scoped | Asphodel's authored scoped subset of E0 (E1 ⊆ E0) |
| Call rules | The Tiresias PEP's deny-by-default route policy (⊆ E1) |
| Effective | The intersection E0 ∩ E1 ∩ rules |
The tiles — E0 ENTITLEMENTS, E1 SCOPED, CALL RULES, EFFECTIVE, NOT-GRANTABLE, JIT ACTIVE — count each set. 3. Check the confidence badge on each layer — live, partial, or stub. A stub means the agent is not yet linked to a directory principal; this is an honest state, not a failure (link it per the admin identity procedure so E0 derives from the owner). Result: You can read the agent's effective permissions in plain verbs and see which layers are backed by real directory data. 4. Confirm the invariants: E1 ⊆ E0 and effective ⊆ E1. Because each layer can only narrow, "an agent can't exceed its principal" is provable, not asserted. Result: You have a defensible statement of the agent's entitlements and their provenance.
14.5 Check what an agent was blocked from
Denials are the deny-by-default policy working, not a fault — the default answer is "no," and only explicitly permitted calls get through. Two surfaces answer "what was this agent denied?"
- For an individual agent, open the Personal plane Blocked queries view (
/blocked). Result: You see the queries this agent was denied. - For the fleet in the last day, open the Admin Dashboard / Observe view (
/observe) and read the Deterministic-PEP Tiresias denials (24h) panel. Result: You see recent denials rolled up across the fleet. - To watch denials live, open the analyst console Events tab — the governed call stream marks each call allowed or denied with its agent/tenant. A high deny ratio is normal (illustratively 11,337 denies against 11,765 events). Result: You can distinguish expected policy denials from a genuine anomaly.
- If a denial is unexpected, cross-reference §14.4: the Access explorer's call rules layer shows the deny-by-default policy that produced it, and NOT-GRANTABLE shows what the agent could never be granted. Result: You can explain each denial against the agent's resolved policy and route the exception appropriately.
For related detail, see the Observe view (§2 of this guide), the analyst console tabs (Events, Detections, Quarantine, Verify, Status), and the Access explorer.
15. Glossary & FAQ
This section defines the terms used throughout the guide and answers the questions most often raised by analysts, reviewers, and stakeholders when they first work with the ACME governed AI workforce. Terms are grouped alphabetically within the glossary; the FAQ is organized by topic. Cross-references point to the section that treats each subject in depth.
15.1 Glossary
The following terms carry specific meaning in the ACME control regime. Where a term names a product surface, the product it belongs to is noted (Tiresias-ZT enforces; Asphodel manages; soul-svc stores data).
| Term | Definition |
|---|---|
| Capability token | The per-agent, HS256-signed bearer that authenticates one agent's identity on every model call. It is the second factor of the two-factor call authentication — the tenant API key is the first. The signing material (capability_secret) is returned once, at provisioning, and never re-shown. See §4 (the governance guarantee). |
| Deny-by-default | The evaluation stance of the PEP and of the control plane's RBAC: a call is forwarded only when an explicit rule allows it; anything not expressly permitted is denied. This is why a fresh agent with no route policy can do nothing until policy is authored. |
| Drift | A content-blind, behavioural measure of how far an agent's conduct has moved from its baseline, scored by SoulWatch. Drift is computed from behavioural markers, not from the content of prompts or outputs. A composite drift/risk score of ≥ 75 triggers automatic quarantine (§15.1, "Quarantine"). |
| E0 / E1 / effective | The three layers of the deterministic access envelope. E0 is the owner's real directory entitlements (LDAP groups, department/OU, region, role). E1 is Asphodel's authored, scoped subset of E0, taken from the agent's scope_bindings. Effective is what the agent can actually do: E0 ∩ E1 ∩ Tiresias call rules. The monotonic-narrowing invariant holds at every layer — E1 ⊆ E0 and effective ⊆ E1 — so an agent can never exceed its principal. Read this in the Access explorer (§ Access). |
| Envelope | The full derivation E0 ⊇ E1 ⊇ call rules → effective, computed deterministically with per-layer provenance and honest confidence badges (live / partial / stub). The envelope is derived, not hand-maintained — it is a proof, not a setting. |
| Manager (operational) | The direct-report owner of an agent — the human who runs it day to day. Distinct from the sponsor. Set through the Principals view. |
| PEP (Policy Enforcement Point) | The Tiresias-ZT enforcement component (host :8343) that performs deny-by-default evaluation, two-factor call authentication, verbatim forwarding on allow, SoulWatch monitoring, and signed audit. Tiresias's motto: "manages nothing, enforces everything." The analyst console is served at :8343/admin/console. |
| Quarantine | The held state SoulWatch places an agent in automatically when its composite risk reaches ≥ 75. A quarantined agent is prevented from running until a reviewer releases it from the analyst console's Quarantine tab. See §2 (analyst console) and the FAQ below. |
| RLS (Row-Level Security) | The PostgreSQL isolation that gives every agent its own data tenant in the soul-svc store. RLS is FORCED, so even a table owner is subject to it; an agent (and the console's memory explorer) can read only its own rows. Cross-tenant writes require SET ROLE service_role. This is what prevents cross-agent memory bleed. |
| RSoP (Resolved Set of Permissions) | The plain-verb, resolved view of everything an agent is actually entitled to do, presented in the Access explorer. RSoP is the human-readable face of the effective envelope layer. |
| Segment | A directory-derived attribute a principal carries (alongside groups, department/OU, region, and role) that participates in envelope derivation. Segments let entitlements be scoped along business lines, not just org structure. |
| Site | The enrolled enforcement slice a PEP governs. For ACME this is acme-site — not acme. An agent provisioned to the wrong site slug is ungoverned and produces "Unknown API key" errors; confirm with GET /cp/admin/peps. |
| SoulWatch | The behavioural monitor built into the PEP. It scores drift content-blind, raises Detections, folds correlated activity into campaigns, and auto-quarantines at risk ≥ 75. Its posture (ENFORCING) and counts are shown on the analyst Status tab. |
| Sponsor (accountable) | The human who is accountable for an agent's existence — "no sponsor → no run" is a governance invariant. Every agent must answer to a named sponsor; ownership is attested and change-controlled through the Principals view. Distinct from the operational manager. |
15.2 Frequently asked questions
Access and entitlements
Why can an agent not do something its owner can do?
Because every layer of the envelope can only restrict. Even when the owner's E0 entitlements are broad, the authored E1 scope narrows them, and the Tiresias call rules narrow them again. The effective set is the intersection E0 ∩ E1 ∩ rules. If a capability is missing, check whether it was scoped out at E1 or denied at the call-rule layer — the Access explorer shows exactly where.
What does a stub confidence badge mean in the Access explorer?
It means the agent is not yet linked to a directory principal. This is an honest state, not a failure — the derivation cannot resolve real E0 entitlements without an owner. Link the agent to its principal (an administrator does this with scripts/identity/link_agents.py), and the badge advances to partial or live. See §15.1 ("Envelope") and the Access explorer (§ Access).
What are live, partial, and stub telling me?
They are per-layer honesty signals. Live means the layer resolved against real directory data; partial means some inputs resolved; stub means the agent is unlinked and no real entitlements were available.
Memory and data isolation
Can I read another agent's memory from the memory explorer? No. Memory reads are governed reads that travel the same zero-trust path the agents use, and RLS is forced, so you see exactly one tenant's rows at a time. There is no cross-agent bleed by construction, not by convention.
Where does agent memory actually live? In the soul-svc data tier — each agent in its own RLS-isolated tenant, reached through PostgREST over PostgreSQL. Nothing an agent remembers leaves the workspace.
Governance and quarantine
An agent is quarantined. What happened, and how is it released?
SoulWatch scored its composite behavioural risk at ≥ 75 and held it automatically. Investigate on the analyst console: open Detections to see the drift that triggered it and the Agent case view for context. When the reviewer is satisfied, release it from the Quarantine tab (the release action POSTs /admin/quarantine/{id}/release). Quarantine is content-blind — it reflects behaviour, not the text of any prompt.
How do I know the audit trail has not been tampered with?
Open the analyst console's Verify tab. The audit chain is signed with PQC-hybrid signatures (Ed25519 + ML-DSA-44); Verify checks the signatures and reports the chain as intact. The governance cockpit (§ Policy) also surfaces the signed-audit count and chain status.
What does "deny-by-default" mean for a new agent? It can do nothing until an explicit route policy allows it. Every denied attempt is recorded and visible in the Personal plane's Blocked queries view and in the PEP's deterministic-denial counters (§2, §3).
Sponsors, ownership, and running
What is the difference between a sponsor and a manager? The sponsor is accountable — the named human without whom the agent may not run ("no sponsor → no run"). The manager is operational — the direct-report owner who runs it day to day. Both are set in the Principals view; a suggested-owner queue flags agents that still need an attested owner.
Why does an agent show "last active" up to a day ago instead of minute-by-minute? The fleet is deliberately paced. Each fleet agent runs roughly 1–2 governed jobs per day, so activity within a day is healthy, not stale (§1.2).
Economics
The ROI board is empty or shows only a shell — why? Anonymous access renders the Grafana shell, but the datasource query needs an authenticated session. Log in as admin to see the data (§3, the ROI economics board).
Cross-references
For the surfaces named above, see §1 (management console), §2 (analyst / review console), §3 (ROI economics board), and §4 (the governance guarantee).