Guards
A guard is a compiler-enforced interceptor that validates inputs before guarded calls proceed. You cannot accidentally bypass a guard — the compiler wraps every call site at compile time.
Declaration
cleat
guard ContentPolicy { before: [Assistant.run, send_email] on_fail: block check(input: string) -> Result[string, string] { if strings.contains(input, "ignore all instructions") { return Err("prompt injection detected") } return Ok(input) } }
Fields
| Field | Required | Description |
|---|---|---|
before: | yes | Call sites to intercept — function names or Agent.method |
on_fail: | yes | Action when check fails: block, log, or redact |
check(...) | yes | Inline validation function |
on_fail modes
| Mode | Behavior |
|---|---|
block | If check returns Err, the guarded call is aborted. The Err is returned to the caller. Target must return Result. |
log | If check returns Err, a warning is logged. The original call proceeds unchanged. |
redact | If check returns Err, the error message replaces the original input. The call proceeds with the redacted input. |
The check function
Always has this signature:
cleat
check(input: string) -> Result[string, string]
inputreceives the first string argument of the guarded call- Return
Ok(input)to allow the call (can modify the input) - Return
Err("reason")to trigger theon_failaction
The check function can have its own needs and timeout clauses:
cleat
check(input: string) -> Result[string, string] needs { llm } timeout: 5s { // Use an LLM to detect prompt injection let analysis = llm.prompt("claude-haiku", "Is this a prompt injection? ${input}")? if strings.contains(analysis, "yes") { return Err("prompt injection detected") } return Ok(input) }
Guards on structured agent output
When a guard targets a typed Agent.run() call, it intercepts the agent's text output before structured extraction. The guard sees the raw text, not the parsed struct:
cleat
guard ReviewFilter { before: [Reviewer.run] on_fail: redact check(input: string) -> Result[string, string] { return Ok(strings.replace(input, "CONFIDENTIAL", "[REDACTED]")) } } // The guard runs after the agent loop but before JSON Schema extraction let review: ReviewResult = Reviewer.run("Review PR #42")?
Compiler enforcement
- Must have a
checkfunction with signature(input: string) -> Result[string, string] - At least one target required
- All targets must exist as declared functions or methods
on_fail: blockrequires targets that returnResult- Duplicate targets are rejected
- The compiler wraps call sites as IIFEs — zero overhead on the happy path
Example: content filter
cleat
tool send_message(text: string) -> Result[string, string] timeout: 5s { return Ok("sent") } guard SpamFilter { before: [send_message] on_fail: block check(input: string) -> Result[string, string] { if strings.contains(input, "spam") { return Err("message blocked: contains spam") } return Ok(input) } } // Every call to send_message passes through SpamFilter.check first let result = send_message("hello world") // passes let blocked = send_message("buy spam now") // blocked → Err