Support automation crosses tenant data, tools, background work and money. A model that can approve its own refund is a liability, so the system has to make that impossible by construction, not by prompt.
My role
I designed and built the API, the retrieval, the approval flow, the accounted live path and the console, with coding agents under a spec-first harness.
179 tests passed in its latest recorded suite run, and 17 passed for the live ledger and key failover, run against PostgreSQL 16. The live demo itself has not been measured yet.
Tickets arrive, a team of agents triages them against tenant-scoped knowledge, and every answer cites its sources. Money is the line the model cannot cross: it proposes, a deterministic gate checks, and a human decides. The requester cannot approve their own refund. Open the console and try to.
See it run
The live demo runs this system against a real model and shows every step.
The whole flow. Press play or next to walk through it.
Text version of this diagram
TicketP06. The console sends the ticket with the user's token.
then Tenant from token
Tenant from tokenP05. Tenant and role are read from the token; the request cannot choose them.
then Tenant-scoped search
Tenant-scoped searchP05. Retrieval only sees the ticket's tenant, and answers cite sources.
then Four agents
Four agentsP01. Classifier, researcher, billing and responder, with a step limit.
then Budget ledger
Budget ledgerP05. The cost is reserved in Postgres before the call and fails closed at the ceiling.
then Refund gate (proposal)
Refund gateP05. The proposal becomes an approval request through a deterministic tool.
then Second person
Second personP06. An approver other than the requester decides.
then Simulated refund (approved)
Simulated refundP05. An approved request creates a simulated refund. Nothing real moves.
Decisions
Tenant and role come from the token
The API reads tenant and role from the signed token. A browser token can carry scopes its user's role must not use, so scopes are narrowed by role on the server.
Rejected: Trusting a tenant id or scope list sent by the client.
The model proposes; a gate and a person decide
A refund request goes through a deterministic tool and becomes an approval that a different principal must decide. The amount comes from that tool, not from the model.
Rejected: Letting model output set the amount or approve.
Reserve the cost before the call
Each model call reserves its worst-case cost in a Postgres ledger with one atomic statement that also checks the ceiling. A rate-limit answer moves to the next key and bills nothing; an uncertain call keeps its reservation.
Semantic quality of the answers. Retrieval fixtures prove control flow, not meaning.
Cost and latency of the live demo. No public live run exists yet.
Throughput under load.
Failure gallery
What happened
The first accounted path stopped all later work after any failed attempt.
Cause
It was built for one reviewed local operation, where a failure should block until a person looks. A public service cannot work that way.
What changed
The public path releases the reservation when a provider answered with an error, and keeps it only when the outcome is unknown.
What happened
A clean clone could not install the project.
Cause
An ignore file excluded every locally built wheel, including the ones the lock file points to.
What changed
The five wheels the lock names are tracked and their hashes checked against the lock.
What happened
Triage failed from the console with a generic worker failure.
Cause
The worker runs on the caller's scopes, and the console did not request the scopes its tools need.
What changed
Console scopes now match the agent's scopes, with a note to update both when a tool is added.
Validate it yourself
git clone https://github.com/DiegoVSouza/supportops-platform.git
cd supportops-platform
uv sync --locked && uv run --locked pytest
Expected: The suite passes. The service gate (`scripts/check_full.py`) needs Docker.
What I would do differently
The refund amount is a fixed tool value. I would let the proposal carry a bounded amount read from the ticket, so the model's work shows up in the money decision.