Install
$ agentstack add skill-sponsiolabs-sponsio-skills ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Sponsio — Agent Safety Lifecycle Companion
Sponsio is a Python/TypeScript runtime safety layer for LLM agents: it evaluates deterministic contracts against each tool call and can block (enforce) or just log (observe) violations. The engine is deterministic-only. This skill covers the full lifecycle — first-time setup, contract authoring/review, observe-mode tuning, and flipping to enforce — by orchestrating Sponsio's CLI and explaining its output in plain language.
This skill does NOT reimplement Sponsio's logic; it calls the CLI and interprets results.
When to use this skill
Dispatch by what the user is trying to do. Pick ONE workflow and follow it; do not run multiple workflows in one turn.
| User is… | → Workflow | |---|---| | Setting up Sponsio for the first time in a project ("add sponsio", "install sponsio", "add guardrails") | W1 — Initial setup | | Handing you a codebase and asking "what could go wrong?" / wants a fresh contract file from scratch / has a policy doc to encode | W2 — Audit & refine | | Has Sponsio running in observe mode and wants to review violations, tune thresholds, silence false positives | W3 — Tune in observe | | Ready to ship — wants to move from observe to enforce, needs regression confidence | W4 — Flip to enforce | | Sponsio errored, a rule isn't firing when it should, a rule is firing when it shouldn't | W5 — Troubleshoot |
Do NOT trigger for: general LLM-safety discussions not tied to a specific codebase; non-agent code review (linting, correctness).
Prerequisites (run silently before any workflow)
sponsio --version
- Not found → install:
pip install sponsio(orpip install -e ".[all]"from a local clone). - For
--llminference, check:OPENAI_API_KEY/ANTHROPIC_API_KEY/GEMINI_API_KEY/GOOGLE_API_KEY. Absent → still proceed; AST-based extraction and all of W3/W4/W5 work with zero keys.
W1 — Initial setup
Goal: from "project has no Sponsio" to "agent runs under observe mode with a sane contract file", in one command.
Steps
- Run the one-shot entry point:
``bash sponsio onboard . --apply ``
onboard detects framework (langgraph / langchain / crewai / openaiagents / claudeagent / vercel-ai / no-framework), picks an LLM provider if available, auto-selects contract packs (see "Auto-selected packs" below), writes sponsio.yaml in observe mode, and with --apply patches the agent entry file with a two-line wrap (backup at .sponsio.bak). Falls back to printing the patch snippet if the framework isn't auto-patchable.
- After
onboardfinishes, show the user three things — do not skip any:
- The generated
sponsio.yaml(read it back and summarize: packs included, tools renamed, mode). - The applied patch (from
report.apply_result.diff) or the printed snippet. - Any
sponsio doctorwarn/fail lines.
- Explain observe mode explicitly: "Nothing is blocked on day 1. Every contract is still evaluated; violations are logged to
~/.sponsio/sessions//*.jsonland (if a dashboard is configured) pushed there. Usesponsio report --since 24hafter a day of real traffic to see what would have been blocked."
- If
sponsio doctorfailed (not warned, failed), stop and surface it — don't let the user run their agent thinking the install is healthy when it isn't.
Auto-selected packs
sponsio onboard uses simple, conservative heuristics:
| Pack | Auto-included when… | Notes | |---|---|---| | sponsio:core/universal | Always | Empty stub, kept so existing include: lines don't error. | | sponsio:core/runaway | Framework runs a multi-step loop (langgraph/crewai/…) | token budget, delegation depth, loop detection; no LLM calls | | sponsio:capability/shell | A tool name matches {bash, shell, exec, execute, execute_command, run_command, run_shell, run_bash, terminal, subprocess} | Auto-fills tool_rename: if the user's tool name isn't the canonical exec | | sponsio:capability/filesystem | A tool name matches {read, read_file, open_file, write, write_file, edit, edit_file, apply_patch, patch_file, ...} | Auto-fills tool_rename: and workspace: | | sponsio:incident/openclaw | Never auto-included — opt-in only | CVE-derived rules for a specific vendor incident |
sponsio packs lists all shipped packs with live rule counts and include specs.
Do NOT
- Do NOT edit
sponsio/contracts/*.yamlinside the installed package — those are the shipped packs; they're read-only. Adjustments go in the user'ssponsio.yamlviaoverrides:orcontracts:. - Do NOT flip
mode: enforceduring W1. The whole point of observe mode is to find false positives before they break production.
W2 — Audit & refine (from scratch, or deepen an existing yaml)
Goal: produce or improve a sponsio.yaml from code / policy docs / traces, and explain every contract in plain language.
Decide which sources to use
Sponsio contracts come from four sources, mixable in one yaml:
| # | Source | What it is | Command | |---|---|---|---| | 1 | Shipped packs | Pre-built, parameterized rule sets (sponsio:core/universal, sponsio:capability/shell, …) | Hand-add include: [sponsio:] — or W1's onboard does it automatically | | 2 | Extraction | AST + optional LLM inference from your code / policy docs / execution traces | sponsio scan [--llm] [--policy ] [-t ] | | 3 | User input | An NL sentence or a structured dict the user writes | Hand-edit sponsio.yaml; validate a single NL string with sponsio validate "" | | 4 | Pattern library | Deterministic parameterized templates (rate_limit, must_precede, arg_blacklist, …) — full list via sponsio patterns | sponsio patterns to browse; hand-write the YAML entry |
Match the user's input to the source(s):
- "Explain / review my
sponsio.yaml" → source 1 and/or others already applied; jump to "Explain contracts" below. - "Scan my agent code" → source 2, code-only.
- "We have a security policy document" → source 2, add
--policy --llm. - "I know the pattern I want but not the syntax" → source 4, then show them the yaml entry.
If ambiguous: ask ONE question — "(a) scan your code, or (b) extract from a policy document?"
Run scan (when extraction is needed)
# AST-only (fast, no keys):
sponsio scan --agent -o ./sponsio.yaml
# + LLM inference:
sponsio scan --agent --llm -o ./sponsio.yaml
# + policy doc:
sponsio scan --policy --llm -o ./sponsio.yaml
Scan auto-validates before writing; only contracts that parse cleanly are saved. Source-tagged with source: scan / source: policy.
Validate existing yaml (explain-only path)
sponsio validate --config ./sponsio.yaml --json
JSON shape per entry: {nl, ok, type: "det"|"unknown", pattern, formula, agent, section}. ok: false means the NL didn't match any pattern — surface those as "ambiguous — needs refinement".
Explain contracts (use this as the report template)
## Sponsio contract summary —
**Setup**: contracts total, . Mode: .
### Active packs
- `sponsio:core/universal` (empty stub, kept so existing `include:` lines don't error)
- `sponsio:capability/shell` (11 det) — guards on
### Contracts explained
Each contract is an assumption → enforcement pair. State the assumption explicitly even when absent ("unconditional"), because the assumption defines **when** the enforcement applies.
- **When**: the agent has called `modify_order`
**Then**: `get_order_details` must have happened earlier.
**Runtime effect**: if unmet, the call is blocked (or logged, in observe) and the agent is told why.
- **When**: unconditional
**Then**: `send_email` is called at most 5 times per session.
**Runtime effect**: the 6th call is blocked.
### Ambiguous contracts (optional — only if validate flagged any)
- `"..."` — didn't match any pattern; rephrase or rewrite as a structured dict.
### Next steps
1. Review; prune anything that doesn't fit the agent's real job.
2. Run in observe mode for 1–2 days.
3. `sponsio report --since 24h` to see what would have been blocked (W3).
4. Prune false positives, then flip `mode: enforce` (W4).
Keep it dense. Don't pad with "consult an expert" disclaimers — the user is already using the expert.
W3 — Tune in observe
Goal: look at what Sponsio logged during observe mode, decide which violations are real vs false positives, and adjust sponsio.yaml accordingly. Never flip mode during this workflow.
Steps
- Pull the violation report:
``bash sponsio report --agent --since 24h ``
- For each violation cluster:
- Real violation → leave the contract as-is. Note it for the user.
- False positive → adjust
sponsio.yaml. Use this decision tree:
| Situation | Edit | |---|---| | Pack-shipped rule is too strict globally | Add an overrides: - match: {desc: "..."} entry with tuned args | | Pack-shipped rule doesn't apply to this agent at all | overrides: - match: {...}, disabled: true | | Rule's threshold is wrong (e.g. rate_limit N) | overrides: ..., args: [, ] | | Rule conflicts with a legitimate workflow that Sponsio couldn't infer | Weaken via an A: (assumption) so it only fires in the specific unsafe context | | User's own hand-written contract is wrong | Edit contracts: directly |
Use desc, pattern, pack_source, or source as the match: key (see the YAML schema below).
- Do NOT edit a contract you haven't seen a violation for. "It looks strict" isn't a reason to remove it in observe mode — it's the reason to leave it.
- After each edit, verify the yaml still parses:
sponsio validate --config sponsio.yaml.
Using assumptions to relax (the right way)
When a rule is correct in principle but too broad in practice, prefer adding an A: over disabling:
overrides:
- match: { desc: "Each exec call needs its own confirm_reconfirmed" }
A: "called `confirm_reconfirmed`"
With the assumption, the rule stays silent until the integration actually emits the marker — it's vacuous-true without the precondition, enforced once the precondition holds. This is the preferred pattern for "I want this rule eventually but not today".
W4 — Flip to enforce
Goal: move from observe to enforce with regression confidence — no more logging, actual blocking. This is a production change; don't skip the checks.
Steps
- Regression test on real traces. Pick a representative trace from
~/.sponsio/sessions//and replay:
``bash sponsio check --trace --config sponsio.yaml --agent ``
Exit 0 = every contract passes on this trace. Non-zero = something would have been blocked. If non-zero, go back to W3.
- Flip the mode. Two options:
a. Pin in yaml (permanent): ``yaml runtime: mode: enforce ``
b. Flip via env var (reversible, no code change): ``bash SPONSIO_MODE=enforce python -m your_agent ``
Precedence: explicit ctor arg > env > yaml > default.
- Keep the dashboard. In production, point OTEL export at Sponsio's collector (
POST /api/otel/v1/traces) or keep using~/.sponsio/sessions/*.jsonl+sponsio report. Don't runsponsio serve --devin prod — that's a dev tool.
- Tell the user how to roll back:
SPONSIO_MODE=observewithout redeploying.
W5 — Troubleshoot
Common symptoms and their fixes.
"LLM extraction call failed: cannot import name 'genai' from 'google'"
User has google-generativeai not google-genai. Fix:
pip install -U 'sponsio[llm]'
"ConfigError: include 'sponsio:...': pack must define exactly one agent named '*' (the template)"
The pack file's agents: uses a literal agent name instead of "*". If it's a user pack, rename. If it's a shipped pack, that's a Sponsio bug — file an issue.
"ConfigError: Agent '': pattern '' uses the '/' placeholder but the agent has no 'workspace:' set."
Add workspace: /path/to/project/root under the agent in sponsio.yaml. The filesystem and openclaw packs need this.
"A rule I expected to fire isn't firing."
Check in this order:
sponsio validate --config sponsio.yaml --json— does the contract parse?ok: falsemeans it was silently dropped.- The tool name in the contract matches the actual tool name the agent calls (LangGraph
node_idvs the@toolPython name is a common trap; seetool_rename:). - The rule has an
A:(assumption) that isn't holding. Look at the trace — is the precondition ever true?
"A rule is firing that shouldn't."
Jump to W3. Don't disable in a panic — add a targeted overrides: entry with a match: clause, so the adjustment is traceable.
"sponsio onboard detected the wrong framework."
onboard doesn't currently take a --framework override flag. Fall back to the manual two-step:
sponsio init --agent
sponsio scan --agent -o sponsio.yaml
Then hand-apply the integration snippet for your framework from the "Integration snippets" section below.
YAML schema (what contracts look like)
Every contract is an (assumption, enforcement) pair. Both short keys (A / E) and long keys (assumption / enforcement) are accepted; mixing both forms of the same field in one entry raises ConfigError.
version: "1"
agents:
: # dict keyed by agent_id, NOT a list
workspace: /path/to/project # required by packs that use /
include: # pre-built packs (see W1 "Auto-selected packs")
- sponsio:core/universal
- sponsio:capability/shell
tool_rename: # map the pack's canonical names to the
exec: run_bash # host's actual tool names
read: read_file
overrides: # tune shipped packs without forking them
- match: { desc: "Each exec call needs its own confirm_reconfirmed" }
A: "called `confirm_reconfirmed`"
- match: { pattern: rate_limit, args: [send_email, 5] }
args: [send_email, 20]
- match: { pack_source: sponsio:incident/openclaw, desc: "..." }
disabled: true
contracts: # hand-written + scan-inferred contracts
# NL form (short keys)
- A: "called `modify_order`"
G: "must call `get_order_details` before `modify_order`"
# Omit A for unconditional
- G: "tool `send_email` is rate-limited to 5 per session"
# Structured dict (what scan emits for det patterns)
- G:
pattern: must_precede
args: [check_policy, issue_refund]
source: scan
runtime:
mode: observe # "observe" | "enforce"
dashboard: http://localhost:8000 # URL | true | false | null
Both A and G accept: scalar NL string, list (AND), or structured dict {pattern, args, source?}.
Placeholders rewritten at include-time: / (from agent's workspace:), `` (from agent id).
Pattern reference
Full list: sponsio patterns (deterministic templates only).
Core Temporal (14 det)
| Pattern | Meaning | |---|---| | must_precede(A, B) | A must be called before B | | always_followed_by(A, B) | Every A must eventually be followed by B | | no_reversal(A, B) | Once A fires, B is permanently forbidden | | requires_permission(tool, perm) | Agent must hold perm before tool | | no_data_leak(source, sink) | Data from source must not reach sink | | mutual_exclusion(A, B) | At most one of A, B per trace | | rate_limit(tool, N) | Tool at most N calls per session | | idempotent(tool) | Tool at most once | | deadline(trigger, action, N) | Action within N steps of trigger | | must_confirm(action) | A confirmation tool must precede action | | cooldown(action, N) | Min N steps between consecutive calls | | segregation_of_duty(A, B) | Same agent can't perform both | | `bounded_retry
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: SponsioLabs
- Source: SponsioLabs/Sponsio
- License: Apache-2.0
- Homepage: https://sponsio.dev/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.