Skip to main content

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:

AdapterExample
SQLiteWHERE order_id = :value AND customer_id = :customer_id
PostgresWHERE order_id = %(value)s AND customer_id = %(customer_id)s
MySQLWHERE order_id = %(value)s AND customer_id = %(customer_id)s
HTTP/orders/{value}?customer={customer_id}
MCParguments: {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:

ValueBehavior
blockFail closed. Default and recommended for consequential actions.
holdRequire human review. The reviewer sees that verification was unavailable.
allowFail open and let this check contribute allow.
Fail-open configuration

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.