Parameters
| Param | Type | Required | Notes |
|---|---|---|---|
tool_name | str | yes | Match against tool_name in your policies. |
session_id | str | yes | Groups events in the audit log. Pick a granularity (per-conversation is common). |
agent_id | str | None | no | Locked to the JWT’s sub. Mismatched values are silently ignored. |
metadata | EvaluationMetadata | None | no | Tool input + framework-specific extras. See below. |
framework | str | None | no | Tag for the audit event. Adapters set this. |
trace | TraceContext | None | no | If set, uploaded and attached to the audit event. |
EvaluationMetadata
- MCP, Claude Agent:
input={...}— the dict the tool was invoked with. - LangChain:
args=[...],kwargs={...}— positional and keyword. - Raw SDK: whatever shape your tools take.
input.<key>, args.<index>, kwargs.<key> respectively.
Returns: EvaluationResult
decision == "allow" with no policy matching, all the matched* fields are None. For deny, the matched rule’s id becomes code and its description becomes reason.
Examples
Plain
With input
input.command:
With trace
traceId is attached to the audit event. See Traces.
Performance
Synchronous portion (returns to caller):- Pure-Python evaluator: ~50–200µs.
- Native (Rust) evaluator: ~5–20µs (
pip install rubric-app[runtime]). - DLP scan: ~50µs (regex), ~1ms (Presidio).
- Trace upload (if attached): 2–5ms.
- Audit event flush: batched, runs every 1s or every 100 events.
Error handling
evaluate() does not raise. If anything goes wrong internally, you get an EvaluationResult(decision="allow", ...) and the error is logged. This is deliberate — a misconfigured Rubric should never block your agent. To enforce default-deny, set spec.defaultEffect: deny in your policy.