CAIN-42 · See what your agents do
CAIN Plans
Checks an agent's plan before it starts, then holds it to that plan.
Last reviewed 2026-10-01
Live Core platform · agent
What it is
AI agent planning and orchestration.
Where it fits
Part of See what your agents do: Every action, every decision, replayed and searchable. Every CAIN-42 product runs behind the same rule: an AI agent's action is checked before it runs (identity, authority, policy, risk), decided as allow, hold for a human, or block, and recorded as signed evidence. Unknown or error never becomes allow.
Use it
- Open it
https://cainstudio.online/plans - Documentation
https://cainstudio.online/docs/actionproof - API endpoint:
https://cainstudio.online/fabric/plans— needs your API key (get a free key)
Recorded status: PRODUCTION. "Live" on this page means its link answered when the catalog was last checked (2026-10-01T18:22 UTC).
Live now
Checked from your browser when this page opened, not from a cached list.
Fire a real decision
Send an action through the live CAIN-42 pipeline from this page, with no account, and watch every stage decide. This is the same pipeline every product here sits behind; it runs for a throwaway demo tenant and is rate limited.
For AI engineers
Every product sits behind one decision path: your agent proposes an action with the exact arguments, CAIN runs it through identity, authority, policy, risk, trust and quorum consensus, and answers ALLOW, REQUIRE_APPROVAL or DENY with an Ed25519-signed record. A timeout, outage or unknown verdict never becomes ALLOW. A brand-new agent has no trust history, so its first actions usually come back REQUIRE_APPROVAL.
Python (zero dependencies)
pip install https://cainstudio.online/cainstudio-0.3.0-py3-none-any.whl
export CAIN_API_KEY=... # free key: https://cainstudio.online/signup
import cainstudio
@cainstudio.guard()
def transfer(amount_usd: float, to: str) -> str:
... # runs only if CAIN allows this call, with these arguments
try:
transfer(5000, "acme")
except cainstudio.ApprovalRequired as e:
print("held for a human:", e.approval_id)
except cainstudio.ActionBlocked as e:
print("refused:", e.decision.reasons)
except cainstudio.CainUnavailable:
print("CAIN unreachable: not run") # fail-closedSee a real decision with no account
cainstudio try # live pipeline, stage by stage
cainstudio try --list # the other attack scenariosMCP clients (Claude Code, Cursor)
claude mcp add --transport http cain https://cainstudio.online/mcpMore: Python SDK · TypeScript SDK · framework integrations · AI quickstart · decision signing key
Tested guarantees in this area
Every rule in these niches has its own page with its recorded result.
- Evidence, receipts & proofs: 928 tested invariants — Signed records that prove what happened, checkable by anyone.
- Autonomy, control loops & recovery: 407 tested invariants — Agents acting on their own, and how CAIN keeps them in bounds and recovers.
Related
- CAIN Drift — Warns you when an agent, model, tool or policy quietly changes.
- CAIN Observability — A live window into what every agent is doing and why each action was allowed or stopped.
- CAIN Resilience — Shows how CAIN keeps working when parts of it fail.
- CAIN Sentinel — Always-on watchdog that detects trouble and contains it automatically.
- CAIN Trace — A tamper-evident record of every step an agent took, in order.
- CAIN Trajectory — Spots when an agent's chain of actions drifts somewhere it should not go, even in small steps.
- Hubgate — One overview across all the MCPGate tools.
- MCPWatch — Health and metrics for all your MCP servers in one place.
Full documentation
The complete reference, also at /docs/actionproof.
ActionProof#
ActionProof verifies a *plan* -- an ordered list of tool calls the agent intends to make -- against your declared constraints, using an SMT solver. It answers "can this sequence violate a constraint?" before any of it runs.
Enabling it#
verification: actionproof: true profile: billing-constraints
Both lines matter. With actionproof: true and no profile, there are no constraints to prove against, so verification reports not_configured -- which is not a denial, and is not verification either. cain doctor warns about exactly this state, because it is the one most easily mistaken for protection.
Submitting a plan#
> cain is the operator CLI that ships with self-hosted MCPGate; it is not installable on its own yet (CLI reference). With only the SDK, use cainstudio or plain curl (see the quickstart).
cain verify --plan '[{"tool":"refund","args":{"amount":500}},
{"tool":"refund","args":{"amount":500}}]'
decision = cain.verify(
action="execute_plan",
plan=[{"tool": "refund", "args": {"amount": 500}},
{"tool": "refund", "args": {"amount": 500}}],
)
Without a plan, the verification stage reports skipped -- there is nothing to verify. A single call is not a plan.
What it does and does not prove#
It discharges real SMT queries about specific, bounded properties you have declared. That is genuinely stronger than a heuristic.
It is not a proof that your agent is correct, that the platform is correct, or that unlisted constraints hold. We do not describe it as one, and the gaps page says so publicly.
Reading the result#
cain explain <decision-id>
The actionproof stage reports one of:
| verdict | meaning |
allow | the solver found no violation of your constraints |
deny | the solver found a violation -- and can usually name the step |
not_configured | no profile: nothing to prove against |
skipped | no plan submitted |
unavailable | the service could not be reached |
unavailable becomes UNKNOWN at the client under strict mode, and UNKNOWN is not permission.
Try CAIN-42 on your own agents
Create a free account and every new account starts with a 7-day trial of the full platform. Or try the sandbox first, with no account at all.
Create a free account → · Try the sandbox · See the whole ecosystem