rotascale authority and evidence for AI agents See the demo

Developers

Three lines, and the refusal is a value.

No runtime to adopt and no framework to migrate to. The governed unit is the action, so this is a call you make before a consequential one — and the answer is recorded either way.

pip install rotascale
from rotascale import Rotascale

rs = Rotascale()                      # reads ROTASCALE_URL and ROTASCALE_API_KEY

# The agent appears here, the first time it speaks. Nobody registers it.
agent = rs.agent("refund-assistant")

# One episode of work, recorded as it happens.
with rs.witness(agent, goal={"ticket": "TICKET-88123"}) as t:

    # Ask BEFORE acting. The answer is recorded either way.
    decision = t.authorize(grant_id, {"tools": ["issue_refund"]},
                           amount_minor=4_500, currency="EUR")

    if decision.allowed:
        ...                            # do the thing
        t.outcome(decision="refunded", outcome_amount_minor=4_500)
    else:
        # A refusal is not an exception. It is the product working.
        t.outcome(decision="refused", reason=decision.reason)

Two rules the SDK will not let you break

Capture fails open
A recording problem must never break a production agent. Evidence is worth a lot; it is not worth an outage. Capture calls do not raise.
Enforcement fails closed
If the control plane is unreachable, the honest position is that the action is ungoverned — and an ungoverned action is worse than a delayed one. Teams who genuinely cannot accept that set fail_open_enforcement=True and own the consequence explicitly, which is at least a recorded decision rather than an accident.

The refusal types name the remedy: Blocked means change the grant, Exhausted means raise the budget or issue a new one, Gated means the context was tainted and needs approval or a declared sanitiser, ReviewRequired means park it, a person is deciding. That is why they are distinct types rather than one Refused.

Where to go

Reference documentation lives in the console at /developers, because it knows which deployment you are integrating against — whether taint enforcement is on, which market profile resolves, and whether the signing key is deployment-held or yours. A static page can only say "it depends"; that one says which.