{{ reviewHdrCrumb }}
{{ session.agentId }} / {{ session.id }}
{{ modeBadgeLabel }} {{ sessModel }} {{ sessRbChip }} → {{ liveLabel }}
{{ c.label }} {{ c.value }}
{{ offlineBannerText }}
{{ suCrumb }} · {{ suProject }}
Enforcement plane
Enforce your agents
Every tool call is checked before it executes; every factual claim is checked against an authority (Studio · Evidence).
{{ suProject }} / v1 {{ suArmedChip }} {{ suWatchChip }} Open Rulebook → adjust rules clear rulebook
Already in production
“I have an agent running”
Keep it where it is. Paste one prompt into your coding agent; enforcement and tracing wire themselves in, and every run streams here live.
Running agents for your customers
“I run agents for my customers”
One project per customer, one key per project, a privacy floor each. Their findings come back over the API for your own dashboard; nobody on their side needs a Sponsio login.
Your product, our findings
“Show it in my own dashboard”
Your backend reads each customer's findings with the team key and renders them wherever you like. Nobody on their side needs a Sponsio login.
curl {{ suOrigin }}/v1/findings?project=<customer-slug> \
  -H "Authorization: Bearer $SPONSIO_TEAM_KEY"
# one finding per (agent, rule): severity, a plain-language line, run rate, fix
Running Sponsio inside your own product? Create a team from the account menu. Customers, their keys and their findings live in the team, shared with whoever you invite.
Running Sponsio inside your own product? The API plane ships with sub-tenant keys, metering and webhooks. talk to us
Your customers
{{ custIntro }} You are in {{ accountName }}. Walk me through it.
{{ readOnlyNote }}
{{ readOnlyNote }}
{{ custErr }} {{ custNote }}
{{ setupTitle }} {{ setupCount }} hide
{{ ss.mark }}
{{ ss.title }}
{{ ss.body }}
{{ custScriptLabel }}
A customer is three calls: their own space, their privacy ceiling, their own key. Run this once per customer from your own onboarding, with a team key in SPONSIO_TEAM_KEY. It prints exactly what their agent deployment needs.
{{ custScriptText }}
{{ custCountLabel }}
{{ custSelLabel }} {{ custBulkVerb }}
CustomerWhat they sendRunsBlockedLast runAgents
{{ c.name }}
{{ c.slug }}
{{ c.followsLabel }}
{{ c.retiredLabel }}
{{ c.runs }} {{ c.blocked }} {{ c.last }} {{ c.agents }}
What this customer's agents may send us
{{ c.floorHint }}
{{ c.envBlock }}
Shown once. Paste into this customer's agent environment; the privacy line matches their setting.
{{ custEmptyLabel }}
Agent templates
One book for the agent you run for everybody. Each customer follows it, and may lay an overlay on top that only ever makes their copy stricter: tighten a limit, enforce a watching rule, add one of their own. Rolling out derives every bound customer's book from the current template.
No templates yet
Push the rulebook your shared agent already uses. It is the same yaml and the same command as a single agent's push, pointed at the team instead of one customer. Nothing changes for any customer until you roll it out.
curl -X POST {{ suOrigin }}/v1/templates/push \
  -H "Authorization: Bearer $SPONSIO_TEAM_KEY" \
  -H "content-type: application/x-yaml" \
  --data-binary @sponsio.yaml
{{ t.agent }} v{{ t.version }} · {{ t.rules }} rules
{{ t.staleLabel }}
The baseline every customer holds
{{ b.pattern }} {{ b.desc }}
{{ c.customer }} {{ c.overlay }} {{ c.state }} {{ c.liveLabel }}
What {{ c.customer }} changes. Stricter only.
{{ e.desc }} {{ f.label }}
Rules only this customer holds
{{ tplErr }}
Their book would be
{{ pr.origin }} {{ pr.text }}
not following this template:
{{ tplNote }}
One rule, every customer
The question a per-customer list cannot answer: is this ours or theirs. A rule most of your customers trip is the agent you wrote for all of them; the same rule in one customer is that customer's integration.
{{ rollupScope }}
{{ r.badge }} {{ r.title }} {{ r.spread }}
{{ r.fix }}
No findings across your customers yet.
Who is in this team
Invite the colleagues who need to see your customers' agents, and decide what each of them may change. An invitation is an email from Sponsio; they land in {{ accountName }} the moment they accept.
{{ memRoleSays }}
{{ memErr }} {{ memNote }}
{{ readOnlyNote }}
PersonRoleWhat they may do
{{ m.email }}
{{ m.tag }}
{{ cap.text }}
What {{ m.email }} may do
What changed, and who changed it
{{ ae.when }} {{ ae.says }} {{ ae.who }}
Invited, not yet accepted
{{ pv.email }} {{ pv.role }}
Guard your pipeline
Three deterministic gates fail the build; anything that needs judgment becomes a PR comment. Your API key goes in the repo secrets, so CI usage bills to your account.
.github/workflows/sponsio.yml paste in your coding agent {{ ciCopyLabel }}
{{ ciPromptText }}
The gates
1 · Drift
Repo rulebook behind the cloud version fails the build.
2 · Compile
Every rule still parses; every referenced tool still exists in the code.
3 · Replay
Recorded violations must still be caught; clean traces must still pass.
4 · Scan
New tools or policy lines with no rule become a PR comment, never a failure.
Checking your rules
Parsing the uploaded policy and grounding it against your repo. Nothing arms without your review.
✓ {{ xl.t }}
Connect your agent
Paste one prompt into your coding agent. It wires Sponsio in.
project owns the rulebook · sponsio://{{ suProject }}@vN
API key {{ suKeyMasked }} {{ cnCopyKeyLabel }} Pulls, streaming and cloud checks bill to this key. Offline runs are free.
Python TypeScript
paste in your coding agent {{ cnPromptToggleLabel }} {{ cnCopyLabel }}
{{ cnPromptText }}
Manual route: pip install --pre sponsio · create an API key · sponsio login · sponsio push sponsio.yaml
New guarded flow
One prompt in, two artifacts out: Sponsio reads your policy and your description, then generates the agent flow and its contract rulebook together.
project
Policy document (your rules of record: SOP, compliance manual, runbook)
{{ suFileName }} {{ suFileMeta }} browse…
What should this agent do? (one prompt: Sponsio plans the flow from it and binds the extracted rules to every tool call)
generation makes two model calls on Sponsio cloud · metered to your workspace
Generating rules & flow…
Reading your policy and your prompt. Rules compile to deterministic patterns; the flow is planned around them. Nothing arms without your review.
✓ {{ xl.t }}
Run the generated flow
Built from your flow description, with the safety layer attached: every tool call is checked before it executes. Watch your rules fire before any real agent is connected. Once yours connects, this bench replays your actual traces.
✓ {{ gl.t }}
generated flow · 4 agents · 13 tool calls · safety layer attached
orchestrator delegates to market-data, research-runner and reporting. The run opens in Sessions, the same screen every real run uses. Come back to Setup afterwards to deploy.
Deploy v1
Version v1 is immutable. The SDK pulls it by key; enforcement runs inside your process, microseconds per check, no network on the hot path.
{{ suProject }} / v1 {{ suArmedChip }} {{ suWatchChip }}
API key
{{ suKeyMasked }} copy
Keep iterating here · the flow and its rulebook live in this project
swap the planner model, rerun, then "⇄ vs previous run" shows what changed
Take it home · your API key authorizes the pull, and local runs stream traces back to this console
pip install --pre sponsio
export SPONSIO_API_KEY={{ suKeyMasked }}
sponsio pull {{ suProject }}   # → flow.py + {{ suProject }}.sponsio.yaml (v1)
Protecting an agent you already run instead? That path is on the Setup landing ("I have an agent running") and wires the same rulebook into your own loop.
⚠ In the test run, t10 http_get passed with no rule matched. That is the deferred R7 gap: the runtime watches live traces and proposes it back with evidence when it fires for real.
The rulebook joins The Rulebook screen; runs appear in Sessions the moment your agent connects.
Enforcement plane · {{ suProject }}

Integrations

Drop-in wrappers for the stack you already run. Full onboarding lives in Setup.
{{ fc.n }} {{ fc.chip }} {{ fc.copyLabel }}
{{ fc.d }}
{{ fc.s }}
API key {{ suKeyMasked }} {{ cnCopyKeyLabel }} spans: OTLP → this console · local det checks are free and offline
Enforcement plane · {{ suProject }}
MCP servers
Put Sponsio between your code and an MCP client: each call is checked before it reaches the server.
Wrap a tool server
An in-process proxy, not a server: call it instead of the client.
from sponsio.config import config_to_system, load_config
from sponsio.integrations.mcp import MCPContractProxy

system = config_to_system(load_config("sponsio.yaml"))   # your rulebook
proxy = MCPContractProxy(mcp_client=client,
                         system=system,
                         agent_id="assistant")   # MUST name an agent in the
                                                 # rulebook, or nothing is checked
result = await proxy.call_tool("process_refund", {"order_id": "123"})
shared across concurrent clients det checks, in-process
Stopped calls never reach the server; the verdict comes back in the result. Streaming to Sessions needs a guard.
Studio · Wiring

Evidence

Rulebook checks what your agent does. Evidence checks what it says: a typed claim, checked against an authority, no LLM in the hot path.
Built-in checks DETERMINISTIC {{ evBuiltinCount }} set all
Pick the ones your agents state; paste the config below.
{{ eb.groupLabel }}
{{ eb.label }} {{ eb.desc }} needs reference data
Config for your guard {{ evCopyLabel }}
{{ evSnippet }}
Connect your data
For facts only your systems know. Declare a predicate; Sponsio asks your service for the value when a claim needs checking. No copy of your data changes hands.
Declare the predicate from a template
Start from a template; fill in your endpoint and secret.
GET  /v1/evidence/templates      # account_balance, order_status, ...
POST /v1/evidence/predicates     # one object, not a list
  { "name": "account_balance",
    "declaration": { "comparator": "numeric_eq", "freshness": 60,
      "resolver": { "mode": "http_callback",
                    "endpoint": "https://api.acme.internal/sponsio/resolve",
                    "secret": "<shared secret>" } } }
Serve the value your endpoint
Verify the HMAC, answer with the authoritative value.
POST https://api.acme.internal/sponsio/resolve
X-Sponsio-Timestamp: 1717171717
X-Sponsio-Signature: v1=<hex hmac-sha256 of "<timestamp>." + body>

in   { "predicate": "account_balance", "inputs": {"account_id": "..."} }
out  { "status": "OK", "values": [412.66], "ts": 1717171717 }
Web knowledge coming soon
For claims that need the open web. Not built yet.
To make a predicate govern a run, add it to the rulebook: pattern: claim_requires_evidence, args: [<predicate>]. open the Rulebook →
Live shows one customer at a time. Nothing is selected, so this is the team's own default project, which has no runs.
Live · Enforcement plane{{ projectCrumb }}

The Fleet

Every agent running under your rulebook, checked at the action boundary
{{ homeMeta }}
{{ hg.value }} {{ hg.label }}
Sessions ⌕
Agent Session Mode Agents Steps Enforcement State
{{ hs.agent }} {{ hs.id }} {{ hs.mode }} {{ hs.agents }} {{ hs.steps }} {{ hs.violLabel }} {{ hs.state }} →
{{ homeRehearsing }} open the Bench →
Live · Session telemetry

The Session

Every run of your agent, streamed and checked at the action boundary

Listening for your first trace

Run your agent wherever it lives. The moment it makes a tool call, the run streams here and plays live. Deterministic checks enforce in your process either way.
sponsio login · the SDK streams every run here on its first tool call
browse existing sessions instead
Studio · rehearsals

The Bench

Runs no published book governs yet, and the rule tests that re-judge them. Nothing here reaches a live run.
▶

Nothing rehearsing yet

A run lands here until a published book governs it, and a test re-judges one under your current switches — free, no side effects, never counted in reports. Each one lands here with the book state that judged it.
⌕ {{ matchCount }}
{{ sg.label }}
compare this session against…
TEST {{ testBanner.line }} view the original run →

{{ traceTitle }}

{{ testReport.verdict }} {{ tc.label }} {{ testReport.err }}
CONTRACT LAYER {{ rail.armedN }}enforcing {{ rail.checksN }}checks run {{ oc.n }}{{ oc.label }} {{ rail.fires }} {{ rail.last }}
Waiting for first event…
Sponsio is on guard at the action boundary. The trajectory will stream here.
Session compare
aligned by tool sequence · differences highlighted
{{ d.l }}{{ d.v }} {{ ac.label }}{{ ac.sub }} {{ rc.label }}{{ rc.sub }}
{{ cmp.aTag }}{{ cmp.aId }}{{ cmp.aSub }}
{{ cmp.bTag }}{{ cmp.bId }}{{ cmp.bSub }}
{{ cr.l.name }} {{ cr.l.chip }} {{ cr.l.args }}
{{ cr.markTxt }}
{{ cr.r.name }} {{ cr.r.chip }} {{ cr.r.args }}
{{ cmpCard.status }} {{ cmpCard.srcLabel }} {{ cmpCard.id }}
{{ cmpCard.label }}
{{ cmpCard.ltl }}
bound: {{ cmpCard.bound }} enforcing since {{ cmpCard.armed }}
{{ cmpCard.mined }}
Fired in this session
{{ f.tool }} {{ f.act }}
Execution path
{{ timelineMeta }}
waterfall · {{ traceTotal }}
Span Elapsed → Dur
{{ r.chev }} {{ r.dotGlyph }}
{{ r.name }} {{ r.chip }} {{ r.detail }} rule →fix → {{ r.ckTxt }}
{{ r.dur }}
⏸
Checkpoint: this action needs your sign-off. The run is paused.
{{ r.escRule }}
Approve once Always allow Keep blocked Open in workbench
✦
{{ r.calloutText }}
Sponsio proposes: {{ r.calloutLabel }}
off flag enforce
details
flagging · logs only {{ r.calloutLabel }} enforce
✓ enforcing as {{ r.coContractId }} · guards every future run
No spans match "{{ query }}" · clear filter
0ms {{ axisMid }} {{ axisEnd }}
Cross-agent execution path
call handoff
Each agent is an independent OTEL trace. Click a node to solo it.
{{ g.id }} {{ g.violLabel }}
{{ g.serviceName }} · {{ g.traceId }}
{{ st.tool }} {{ st.tag }}
Click to solo trace →
Swimlanes · shared time axis
Each lane is one agent's independent trace on a common clock. Click a lane label to solo it.
{{ ln.id }}
{{ ln.violLabel }}
↳ {{ ln.delegated }}
{{ ch.tool }}
t+0ms {{ swimMid }} {{ swimEnd }}
Studio · Contract governance

The Rulebook

{{ rbScopeLine }} · governing run {{ rbRun.id }} →
{{ rbPullLabel }}
API {{ rbApiRef }} {{ rbCopyApiLabel }}
file {{ rbPullCmd }} {{ rbCopyLabel }}
Your repo's sponsio.yaml, at the published version.
{{ rbPubNote }}
{{ rbTestErr }}
{{ contractsMeta }} {{ rbHistLabel }}
Version history revert writes a new version equal to the old one; nothing is overwritten, runs keep the version they reported
loading…
{{ rbHistNote }}
{{ rbHistErr }}
{{ hv.v }} {{ hv.kind }} {{ hv.meta }} current
pending review ✓ review complete 8/8 policy clauses mapped 1 ambiguous reading {{ suReviewMeta }}

Waiting for your rules

They land here the moment your coding agent pushes, or a policy upload parses. Nothing arms without your review.
POST /v1/rulebook/push
browse the current rulebook instead
{{ rbPinTitle }} {{ rbPinSub }}
{{ rbPinSkipped }}
✎
{{ rbNlErr }}
Templates {{ tp.label }}
{{ tk.txt }} ✕ {{ rbTplGloss }}
⌕
Status decisions frozen as this test ran them set all
Rule Source Pipe Violations Decision
{{ rbNoBookLine }}
browse the project book →
{{ rbNoMatchLine }} · clear search
{{ c.label }}
{{ c.stateChip }}
{{ c.sourceLabel }} {{ c.pipeline }} {{ c.violLabel }}
{{ c.roDec }} —
{{ c.sourceLabel }} {{ c.srcLabel }} → {{ c.exPattern }} confidence {{ c.exConf }} {{ c.exEnf }}
{{ c.exRisk }}
{{ c.exJust }}
Authored rule
{{ c.authoredRule }}
Compiled LTL
{{ c.compiledLtl }}
self-evolved · {{ c.minedNote }} · enforcing {{ c.armedSince }} →
Fired in this session
{{ f.at }} {{ f.tool }} {{ f.action }}
Live · Agent overview

{{ ao.id }}

{{ ao.meta }}
{{ k.value }}{{ k.label }}
Contract friction · what keeps firing across runs
{{ fx.label }} {{ fx.act }} {{ fx.trend }}
{{ fx.sess }} via {{ fx.tools }} {{ fx.hint }}
Tools that drew interventions
{{ tx.label }}
Workspace

Settings

API keys, access and workspace configuration
API keys
{{ keyCreateErr }}
{{ mintedPanel.name }} · copy it now
{{ mintedPanel.key }}
shown only once · the server stores a hash and can never display it again
Name Key Scope Created Last used
No keys yet · create one to connect your agent
{{ k.name }} {{ k.masked }} {{ k.scope }} {{ k.created }} {{ k.lastUsed }}
Rulebook
Pushed rulebook {{ setRbLine }}
Help
Intro tour the guided walkthrough new users see on first sign-in
Team walkthrough customers, templates, keys and people, in the order a team does them
Members
who can sign in to this workspace
Name Email Role Joined
{{ m.initial }} {{ m.name }} {{ m.email }} {{ m.role }} {{ m.joined }}
Workspaces are single-owner today · team invites arrive with org workspaces · talk to us if you need one sooner
Live · Human in the loop

Approvals

Actions held by EscalateToHuman wait here for your sign-off · the full audit trail stays in Sessions
{{ vs.label }} {{ vs.value }}
Waiting on you · {{ escOpenCount }} {{ escScopeCrumb }}
{{ eg.chev }} {{ eg.tool }} {{ eg.args }} waiting in {{ eg.count }} Approve all once Always allow Keep all blocked
{{ eg.rule }}
{{ ei.sess }} → approve once keep blocked
{{ eq.tool }} {{ eq.args }} {{ eq.sess }} → Approve once Always allow Keep blocked {{ eq.decLabel }}
{{ eq.rule }}
Standing approvals
{{ ea.tool }} never escalates under {{ ea.rule }} revoke
Nothing waits on you{{ escEmptyScopeNote }} · resolved items are below

Approvals arrive with your first run

When a rule escalates a call to a human, the held action lands here for your sign-off. Run your agent and this becomes your work queue.

Nothing waits on you{{ escEmptyScopeNote }}

{{ escOtherAgents.line }} · view all agents →
All clear right now.
History
{{ eh.tool }} {{ eh.args }} {{ eh.sess }} → {{ eh.decLabel }}
{{ eh.rule }}
{{ ovEyebrow }}

Report

Waiting for your first run

Session health lands here the moment your agent makes its first guarded tool call.

No steps in this run yet

The report builds itself from the run's guarded tool calls. Pick a finished run in the rail, or wait for this one to stream.
{{ ovEyebrow }}

Report

{{ session.id }} {{ overviewSub }}
Pass rate
{{ passPct }} {{ passDetail }}
{{ t.label }} {{ t.value }}
Trace statistics by tool
{{ statsMeta }}
Tool P95 latency Calls P50 P95 Max Checks Blocked
{{ t.tool }}
{{ t.calls }} {{ t.p50 }} {{ t.p95 }} {{ t.max }} {{ t.checks }} {{ t.blocked }}
Output evidence · what the agent said
{{ es.n }} {{ es.label }}
{{ er.span }} {{ er.predicate }} {{ er.source }} {{ er.verdict }}
Agent × time violation heatmap
{{ hr.agent }}
t=0 t={{ heatEnd }}
Riskiest
{{ rk.rank }}
{{ rk.name }}
{{ rk.kind }}
{{ rk.value }}
✦ Sponsio {{ copilotBadge }}
{{ fixKindLabel }} {{ fixPanel.title }}
{{ fixPanel.headline }}
{{ fixEvidenceCaret }}what happened
{{ fixWhatText }}
the rule · leave it as it is
{{ fixPanel.rule }}
fix at the source
{{ fs.n }} {{ fs.t }}
rules of the fix
— {{ fg.t }}
verify
— {{ fv.t }}
Generated from this finding’s evidence — deterministic, no model involved. The rule itself stays in your hands.
{{ tourCount }}
{{ tourTitle }}
{{ tourBody }}
→ {{ tourTry }}
skip