SKY-POL-002Policy GuardrailsRev. 2026.10
Stop the call before it becomes an action.
Guardrails that read a model's output after the fact are a smoke alarm. Skyla's gate is a door lock: it checks every tool call before anything leaves the runtime, and it fails closed.
One choke point, in front of every tool.
Agents in Skyla never hold network access to your systems. The only path from a proposal to a tool runs through the gate, inside the same process that owns the state machine. There is no side door for a clever prompt to find, because the agent process simply has no route out.
The gate sees a fully typed proposal: which tool, which arguments, under which capability token, from which machine state. It answers with one of three verdicts. Admit, deny or escalate. Nothing else is possible, and the verdict is written to the ledger before the next step begins.
Checks that understand your data, not just its shape.
Schemas catch the easy mistakes: a string where a number belongs, a missing field, a negative quantity. Invariants catch the expensive ones. They relate the proposal to current state. The payment must not exceed the open balance. The medication order must belong to an active encounter for this patient. The firewall change must leave port 22 closed to the internet.
Invariants are written in a small, total expression language. It has no loops and no recursion, so every check finishes in bounded time, and we can analyse a policy set for contradictions before it is switched on.
policy treasury-v14
invariant amount_within_balance:
proposal.amount <= ledger.invoice(proposal.invoice).open_balance
invariant vendor_matches_invoice:
proposal.vendor == ledger.invoice(proposal.invoice).vendor_id
invariant bank_change_cooling:
days_since(vendor(proposal.vendor).bank_updated_at) >= 10
otherwise escalate(role="treasury-controller", quorum=2)Limit the damage of a mistake you did not foresee.
No policy anticipates everything, so every run also carries a blast-radius budget. Quotas cap the total effect of a run rather than the number of calls: dollars moved, rows changed, recipients emailed, hosts restarted. They are counted on the proposed state diff, so splitting one large action into many small ones does not help.
Budgets apply per run, per principal and per hour. When a proposal would cross a line, the gate does not guess whether it is fine. It stops and asks someone who knows.
Humans decide the hard cases, with the right facts in front of them.
An escalation freezes the machine in a named state and sends a request to the approvers the policy names. They see the exact state diff, the invariants that passed, the limit that tripped and a short plain-language summary. They do not have to scroll through an agent's chain of thought to work out what is being asked.
Approvals can require a quorum and expire on a timer. If nobody answers in time, the default is to deny. Silence never authorises anything.
When in doubt, do nothing, and say why.
If the gate cannot reach the state it needs to evaluate an invariant, it denies. If the signer is down, the run waits. A denial returns a structured reason to the planner, coarse enough not to teach a model how to probe the policy, but specific enough for it to correct an honest error and try again.
Most denials in practice are not attacks. They are malformed arguments, stale assumptions or a missing field. A good denial turns them into a second, correct attempt.
Write policy like code, because it is code.
Policies are versioned, reviewed and tested like any other change. The harness can backtest a new policy against months of recorded ledgers and tell you which past actions it would have denied. You can run it in shadow mode beside the current policy before it ever blocks anything.
That loop is where teams gain confidence. A guardrail you can test against your own history is one you can actually trust.