Agent Rail
Agent Rail
Section titled “Agent Rail”Deterministic, policy-governed operational agents for KYC routing, compliance triage, reconciliation break handling, and evidence pack assembly.
Overview
Section titled “Overview”The Agent Rail provides a control plane for deterministic operational agents that automate case routing, alert triage, reconciliation handling, and evidence assembly. Unlike LLM-powered agents, these agents are fully deterministic — every input produces a predictable, auditable output governed by explicit rules and state machines.
Agents operate within a multi-tenant context and emit structured domain events that integrate with the platform’s event-driven architecture. All agent decisions are recorded for audit trail compliance (SOC2, AAOIFI).
Base URL
Section titled “Base URL”/api/v1/agentsAgents
Section titled “Agents”Deterministic Agents
Section titled “Deterministic Agents”| Agent | Code | Purpose |
|---|---|---|
| KYC Case Router | kyc_router | Routes KYC/KYB cases to the correct review queue |
| Compliance Alert Triage | compliance_triage | Normalizes and triages AML/sanctions/PEP alerts |
| Reconciliation Break Handler | recon_break | Classifies and routes reconciliation breaks |
| Evidence Pack Builder | evidence_pack | Assembles evidence packs for audit and compliance |
Deterministic Report Generator Agents
Section titled “Deterministic Report Generator Agents”These agents wrap pure-function financial statement generators with tenant isolation, audit trail events, and correlation tracking. Same inputs always produce identical output.
| Agent | Code | Purpose | Standard |
|---|---|---|---|
| Trial Balance Generator | trial_balance_generator | Generates Trial Balance from ledger snapshot | AAOIFI FAS-1 |
| Balance Sheet Generator | balance_sheet_generator | Generates Balance Sheet (Assets = Liabilities + Equity) | AAOIFI FAS-1 |
| Income Statement Generator | income_statement_generator | Generates Income Statement (Revenue - Expenses) | AAOIFI FAS-3/4 |
| Zakat Calculation Generator | zakat_calculation_generator | Calculates Zakat (2.5% of zakatable wealth above nisab) | AAOIFI SS-9 |
Non-Deterministic Agents (Advisory, AI-Assisted)
Section titled “Non-Deterministic Agents (Advisory, AI-Assisted)”These agents produce advisory content that requires human review before use. They never compute financial numbers — all figures are sourced from deterministic report generators.
| Agent | Code | Purpose |
|---|---|---|
| Report Commentary | report_commentary | Generates narrative commentary for financial reports |
| Anomaly Detector | anomaly_detector | Statistical anomaly detection with z-score analysis |
| Report Explainer | report_explainer | Plain-language report explanations for stakeholders |
Endpoints
Section titled “Endpoints”Execute Agent
Section titled “Execute Agent”POST /api/v1/agents/executeExecute any agent by type. The agent_type field selects the agent.
Request Body:
{ "tenant_id": "tenant_001", "workspace_id": "ws_001", "agent_type": "kyc_router", "correlation_id": "corr_abc123", "input": { "case_id": "case_001", "case_state": "open", "case_type": "kyc_review", "kyc_review": { "completeness_status": "complete", "risk_band": "high", "jurisdiction_code": "SA", "missing_requirements": [] } }}Response:
{ "success": false, "outcome": "approval_required", "output_summary": "Routed to kyc_manual_review. Approval required: high risk band", "events": [ { "event_type": "case.routed", "entity_type": "case", "entity_id": "case_001", "payload": { "assignee_queue": "kyc_manual_review", "new_state": "in_review", "reason": "high_risk" } }, { "event_type": "approval.requested", "entity_type": "approval_request", "entity_id": "", "payload": { "approval_type": "case_transition", "case_id": "case_001", "reason": "High risk KYC case requires manual review" } } ], "policy_decision": null}Route KYC Case
Section titled “Route KYC Case”POST /api/v1/agents/kyc-routerRoute a KYC case based on completeness, risk, and jurisdiction.
Routing Rules:
| Rule | Condition | Queue | State |
|---|---|---|---|
| 1 | Incomplete application | kyc_missing_info | waiting_for_info |
| 2 | High risk or EDD jurisdiction (IR, KP, SY, AF, MM, YE) | kyc_manual_review | in_review + approval |
| 3 | Medium risk | kyc_standard_review | in_review |
| 4 | Low risk + complete | kyc_fast_track_review | in_review |
Request Body:
{ "tenant_id": "tenant_001", "workspace_id": "ws_001", "input": { "case_id": "case_001", "case_state": "open", "case_type": "kyc_review", "kyc_review": { "completeness_status": "complete", "risk_band": "low", "jurisdiction_code": "SA", "missing_requirements": [] } }}Triage Compliance Alert
Section titled “Triage Compliance Alert”POST /api/v1/agents/compliance-triageTriage a compliance alert (sanctions, PEP, adverse media).
Triage Rules:
| Rule | Condition | Outcome |
|---|---|---|
| 1 | Strong sanctions hit | Escalated, case created, approval required |
| 2 | PEP moderate/strong hit | Routed to manual review |
| 3 | Adverse media below threshold | Triaged |
| 4 | Matching cleared fingerprint | Marked false positive |
| 5 | Critical severity | Requires approval before closure |
Request Body:
{ "tenant_id": "tenant_001", "workspace_id": "ws_001", "input": { "alert_id": "alert_001", "alert_state": "new", "alert_type": "screening", "severity": "high", "screening_type": "sanctions", "hit_strength": "strong", "hit_count": 1, "jurisdiction_code": "SA" }}Handle Reconciliation Break
Section titled “Handle Reconciliation Break”POST /api/v1/agents/recon-breakClassify and route a reconciliation break.
Classification Rules:
| Rule | Condition | Action |
|---|---|---|
| 1 | Timing difference detected | Queue: recon_timing_queue |
| 2 | Duplicate transaction | Queue: recon_duplicate_queue |
| 3 | Missing leg | Queue: recon_missing_leg_queue |
| 4 | Above materiality threshold | Escalate |
| 5 | Timing difference within auto-close age | Auto-close |
Request Body:
{ "tenant_id": "tenant_001", "workspace_id": "ws_001", "input": { "break_id": "break_001", "break_type": "amount_mismatch", "source_amount": 10000, "target_amount": 10050, "source_date": "2025-01-15", "target_date": "2025-01-16", "currency": "SAR" }}Build Evidence Pack
Section titled “Build Evidence Pack”POST /api/v1/agents/evidence-packAssemble an evidence pack for audit or compliance review.
Pack Types: kyc, compliance, reconciliation, audit, shariah_review
Request Body:
{ "tenant_id": "tenant_001", "workspace_id": "ws_001", "input": { "pack_type": "kyc", "entity_id": "case_001", "entity_type": "case", "items": [ { "type": "document", "ref": "doc_passport_001" }, { "type": "screening_result", "ref": "screen_001" } ] }}Response:
{ "success": true, "outcome": "success", "output_summary": "Evidence pack assembled: 2/3 mandatory items (67% complete)", "events": [ { "event_type": "evidence_pack.assembled", "entity_type": "evidence_pack", "entity_id": "ep_001", "payload": { "new_state": "incomplete", "completeness_score": 67, "missing_items": ["proof_of_address"] } } ], "policy_decision": null}Validate State Transition
Section titled “Validate State Transition”POST /api/v1/agents/validate-transitionValidate whether a state machine transition is allowed.
Request Body:
{ "from_state": "open", "to_state": "in_review", "entity_type": "case"}Response:
{ "allowed": true, "reason": "Transition allowed", "from_state": "open", "to_state": "in_review"}Evaluate Policy
Section titled “Evaluate Policy”POST /api/v1/agents/evaluate-policyEvaluate a Cerbos policy decision for a subject-resource-action tuple.
Request Body:
{ "subject": { "id": "user_001", "roles": ["compliance_officer"] }, "resource": { "id": "case_001", "type": "case", "tenant_id": "tenant_001" }, "action": "approve"}Response:
{ "id": "pd_001", "decision": "ALLOW", "pdp_type": "SPDP", "policy_scope": "agent_rail", "matched_rules": ["compliance_officer_can_approve_cases"], "obligations": ["log_approval_decision"]}Agent Context
Section titled “Agent Context”All agent endpoints require a tenant context:
| Field | Type | Required | Description |
|---|---|---|---|
tenant_id | string | Yes | Tenant identifier |
workspace_id | string | Yes | Workspace identifier |
agent_id | string | No | Agent identifier (auto-assigned) |
correlation_id | string | No | Correlation ID for tracing (auto-generated if omitted) |
Agent Result
Section titled “Agent Result”All agents return a standard result structure:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the outcome was successful |
outcome | string | success, approval_required, error |
output_summary | string | Human-readable summary |
events | AgentEvent[] | Domain events emitted |
policy_decision | PolicyDecision | Policy evaluation result (if applicable) |
State Machine
Section titled “State Machine”Cases and alerts follow explicit state machines. Use the /agents/validate-transition endpoint to check whether a transition is valid before attempting it.
Case States: open -> in_review -> approved | rejected | waiting_for_info -> closed
Alert States: new -> normalized -> triaged | under_review | escalated | false_positive -> closed
Events
Section titled “Events”| Event | Description |
|---|---|
case.routed | Case assigned to a queue |
case.transitioned | Case state changed |
alert.normalized | Alert normalized from raw |
alert.triaged | Alert triage completed |
alert.escalated | Alert escalated |
approval.requested | Approval workflow initiated |
task.created | Follow-up task created |
evidence_pack.assembled | Evidence pack built |
Cerbos Policies
Section titled “Cerbos Policies”Agent rail resources are protected by Cerbos ABAC policies:
| Resource | Policy File |
|---|---|
case | policies/agent-rail/resource_policies/case.yaml |
alert | policies/agent-rail/resource_policies/alert.yaml |
evidence-pack | policies/agent-rail/resource_policies/evidence-pack.yaml |
Database Tables
Section titled “Database Tables”The agent rail uses 33 dedicated tables prefixed with ar_. Key tables:
| Table | Purpose |
|---|---|
ar_agents | Agent registry |
ar_cases | Case management |
ar_alerts | Alert tracking |
ar_evidence_packs | Evidence assembly |
ar_reconciliation_breaks | Break tracking |
ar_policy_decisions | Policy audit trail |
ar_timeline_events | Full event audit |
TypeScript
Section titled “TypeScript”import IOF from "@iof/sdk";
const client = new IOF({ apiKey: process.env.IOF_API_KEY });
const result = await client.agents.routeKYC( { tenantId: "tenant_001", workspaceId: "ws_001" }, { case_id: "case_001", case_state: "open", case_type: "kyc_review", kyc_review: { completeness_status: "complete", risk_band: "low", jurisdiction_code: "SA", missing_requirements: [], }, },);Python
Section titled “Python”from iof_sdk import IOF
client = IOF(api_key=os.environ["IOF_API_KEY"])
result = client.agents.route_kyc( tenant_id="tenant_001", workspace_id="ws_001", input={ "case_id": "case_001", "case_state": "open", "case_type": "kyc_review", "kyc_review": { "completeness_status": "complete", "risk_band": "low", "jurisdiction_code": "SA", "missing_requirements": [], }, },)client := iof.NewClient(os.Getenv("IOF_API_KEY"))
ctx := iof.AgentContext{ TenantID: "tenant_001", WorkspaceID: "ws_001",}
result, err := client.Agents.RouteKYC(ctx, map[string]interface{}{ "case_id": "case_001", "case_state": "open", "case_type": "kyc_review", "kyc_review": map[string]interface{}{ "completeness_status": "complete", "risk_band": "low", "jurisdiction_code": "SA", },})See Also
Section titled “See Also”- KYC Rail - KYC verification management
- Compliance Rail - Compliance policy engine
- Reconciliation Rail - Transaction reconciliation
- Payments Rail - Payment processing