Grounding checks
A grounding check asks one Source to retrieve current trusted facts for one proposed argument value, then evaluates deterministic match conditions against the result.
order_id:
ground:
checks:
- source: billing-production
query: >-
SELECT customer_id, status
FROM orders
WHERE order_id = %(value)s
match:
- column: customer_id
ctx: customer_id
- column: status
value: delivered
Check lifecycle
The Source request and match evaluation are separate. Adapters retrieve data in different ways, but every adapter uses the same match semantics.
Bound values
Every check can bind:
value— the argument being grounded;- any scalar argument from the same proposed tool call;
- any scalar trusted-context field.
Trusted context overrides a tool argument with the same name.
The binding syntax depends on the adapter:
| Adapter | Example |
|---|---|
| SQLite | WHERE order_id = :value AND customer_id = :customer_id |
| Postgres | WHERE order_id = %(value)s AND customer_id = %(customer_id)s |
| MySQL | WHERE order_id = %(value)s AND customer_id = %(customer_id)s |
| HTTP | /orders/{value}?customer={customer_id} |
| MCP | arguments: {order_id: "{value}", customer: "{customer_id}"} |
Do not format values into SQL strings. Use the adapter’s named parameter syntax.
Definitive mismatch
When the Source request succeeds but its result does not satisfy the match conditions, on_fail controls the outcome:
on_fail: block # block (default) or hold
A definitive mismatch is not retried. The Source has answered the question; repetition does not make the fact transient.
Use hold only when a mismatch legitimately requires human judgment. Ownership failures and missing required records should normally block.
Unreachable Source
Exceptions such as timeouts, authentication failures, server errors, invalid queries, or MCP tool errors use retry:
retry:
attempts: 2
on_error: block
attempts is the number of retries after the first request. attempts: 2 can therefore call the Source at most three times.
After retries are exhausted, on_error can be:
| Value | Behavior |
|---|---|
block | Fail closed. Default and recommended for consequential actions. |
hold | Require human review. The reviewer sees that verification was unavailable. |
allow | Fail open and let this check contribute allow. |
on_error: allow converts loss of a trusted verification dependency into permission to execute. Use it only when the action’s risk model explicitly accepts that behavior and another control remains authoritative.
Retry currently has no per-attempt delay inside a check. Keep Source-level connection and statement timeouts bounded so a tool call cannot wait indefinitely.
Multiple checks
All checks across all protected arguments run and participate in one decision. One check can verify ownership in billing while another verifies absence from a refund ledger.
ground:
checks:
- source: billing-production
query: SELECT customer_id FROM orders WHERE order_id = %(value)s
match:
- column: customer_id
ctx: customer_id
- source: refund-api
path: /refunds?order_id={value}
match:
- rows: eq
value: 0
The checks are an AND: the order must belong to the caller and no prior refund may exist.