Compile an agent's constitution into a sandbox.
Sluice is a policy language (.sluice) and a capability-limited runtime for AI agents. Budget, tool side effects, human approval, data egress and the decision trajectory are first-class in the language instead of glue code, where prompt injection can bypass them. A policy compiles to a verifiable DAG plus a WASM-subset bytecode module, and the harness adjudicates every step up front and records a SHA-256 hash chain.
General-purpose authorization engines answer whether a principal may perform an action on a resource. Sluice answers whether this agent, given budget, context and risk, may invoke this tool next, whether approval is required, whether data may leave the zone, and what evidence to keep.
- Agent process control as syntax —
side_effect(none/read/write),risk,budget,quota,require_approvalwith named approval channels, and adataflowlatticepublic < internal < confidential < restricted. - Compile-time guarantees — the verifier rejects a policy before it ships when a
require_approvalhas no matchingapprovaldefinition (permission closure), the DAG has a cycle or an unbounded step, no path reaches End within budget, orrestricteddata can reachsendunmasked. - DENY-first adjudication — a matching
forbidoverridespermit, and any call that matches no rule returnsDENYwith a reason so the agent can change strategy. - Capability sandbox — the emitted module runs on a WASM-subset interpreter with fuel, linear memory and an allowlisted set of host imports; unregistered imports are refused.
- Tamper-evident audit — canonical events are hashed into a chain. The replayer rebuilds budget and decisions from the event stream, and the content-addressed policy version is bound to the trajectory.
# Typecheck and verify the invoice policy
python3 -m sluice check examples/finance-approver.sluice --search std
# End-to-end demo: file read -> SQL -> approval -> transfer denied
python3 -m sluice demo
# Web console for the decision trajectory
python3 demo/web/server.pyDSL -> Lexer -> Parser -> AST -> Type Checker -> DAG IR -> Verifier -> WASM + Manifest
Static analysis covers permission closure, DAG acyclicity, budget reachability and sensitive egress. Runtime evaluation order is forbid -> permit / require_approval plus budget and quota -> default deny.
The same tool takes different paths depending on data class, and every adjudication is pinned to the evidence chain.
| Step | Tool | Data class | Decision |
|---|---|---|---|
| 1 | file_read |
internal | ALLOW |
| 2 | sql_query |
internal | ALLOW |
| 3 | sql_query |
confidential | ESCALATE to slack:#finance-ops |
| 4 | sql_query |
confidential | ALLOW after human approval |
| 5 | transfer_money |
restricted | DENY (forbid overrides permit) |
sluice/ compiler, engine, WASM subset, harness, audit
std/ reusable policy modules
examples/ finance-approver.sluice
tests/ syntax, types, engine, WASM, audit, E2E
demo/web/ decision-trajectory console
adapters/ Python / TypeScript agent adapters
docs/TECHNICAL_BLOG.md
The specification targets Rust plus Wasmtime, and this repository implements the compiler, engine and harness in Python because the build environment has no rustc. The WASM layer is a subset interpreter aligned with Wasmtime's capability model (fuel, linear memory, host-import allowlist). Syntax, DAG verification, engine semantics and the audit format match the specification, so codegen can later target a real Wasmtime module without changing .sluice sources.
Part of LANDSLIDE — weird ideas, made real.
