Configuration schema
Every rule document carries a schema version. Local YAML then has two optional configuration keys:
schema_version: 1
tools: {}
sources: {}
schema_version is required for newly created files. ActionRail currently
supports version 1 and rejects unknown versions before installing rules. Files
created during the private beta without a marker are interpreted as version 1,
then normalized when saved through the Console.
Console-managed SDK responses carry the same tools rule object plus separately registered Source metadata.
Tool rule
tools:
<tool_name>:
kind: consequential
args: {}
write: {}
| Field | Type | Required | Description |
|---|---|---|---|
kind | string | No | Defaults to consequential when loaded. Use consequential for gated tools. |
args | object | No | Argument name to argument rule. |
write | object | No | Proposed-effect preview and reporting allowlist. |
Argument rule
args:
<argument_name>:
policy: amount <= 200
ground:
checks: []
| Field | Type | Description |
|---|---|---|
policy | string | One numeric comparison using <, <=, >, >=, ==, or !=. |
ground.checks | list | Required Source checks; every check must pass. |
Policy and grounding can coexist on one argument.
Common check fields
- source: billing-production
match: []
on_fail: block
retry:
attempts: 0
on_error: block
| Field | Type/default | Description |
|---|---|---|
source | string, required | Name of the configured Source. |
match | list, default existence | Shared match conditions. |
on_fail | block or hold; default block | Outcome after a definitive mismatch. |
retry.attempts | integer; default 0 | Retries after the first Source exception. |
retry.on_error | block, hold, or allow; default block | Outcome after retry exhaustion. |
Adapter-specific request fields:
| Adapter | Check fields |
|---|---|
| SQLite | query using :name bindings. |
| Postgres | query using %(name)s bindings. |
| MySQL | query using %(name)s bindings. |
| HTTP | path, optional method (GET default), optional select. |
| MCP | No request fields in the normal convention; tool mapping lives on the Source. |
Match condition
Field condition:
- column: customer_id
op: eq
ctx: customer_id
Choose one target key unless the operator is set or empty:
| Target key | Meaning |
|---|---|
ctx | Compare with trusted context. |
arg | Compare with another proposed argument. |
value | Compare with a literal. |
now | Compare as time against now plus an optional offset. |
op defaults to eq. Supported values are eq, ne, gt, gte, lt, lte, contains, in, set, and empty.
Result-count condition:
- rows: eq
value: 0
rows accepts eq, ne, gt, gte, lt, or lte.
Write metadata
write:
preview: Refund order {order_id} for {amount}
report_args:
- amount
| Field | Type | Description |
|---|---|---|
preview | format string | Local proposed-effect preview. All model-facing values are redacted. |
report_args | list of argument names | Values permitted to render in the control-plane preview. Empty by default. |
Source object
schema_version: 1
sources:
<source_name>:
adapter: postgres
# adapter fields
Common field:
| Field | Type | Description |
|---|---|---|
adapter | string | sqlite, postgres, mysql, http, or mcp. |
Adapter field references:
Environment references use ${env:VARIABLE} and resolve recursively inside Source configuration in the SDK process.
Complete example
sources:
billing-production:
adapter: postgres
host: postgres.internal
dbname: billing
user: actionrail_reader
password: ${env:BILLING_DB_PASSWORD}
sslmode: verify-full
sslrootcert: /etc/ssl/certs/postgres-ca.pem
tools:
issue_refund:
kind: consequential
args:
amount:
policy: amount <= 200
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
on_fail: block
retry:
attempts: 1
on_error: block
write:
preview: Refund order {order_id} for {amount}
report_args: []