The declarative policy checklist every case must satisfy — deterministic checks, thresholds on AI verdicts, and retry behaviour

Goal Rules


Goal Rules are the policy layer of 9thSense. Every agent carries a checklist of rules in its definition; a case cannot complete until every rule passes. Rules turn raw check results — extracted fields, fraud verdicts, match scores — into decisions: approve, retry, review, or deny.

They are declarative JSON, versioned with the agent, and snapshotted into every case — so the audit record shows not just what was decided, but exactly what policy decided it.

Anatomy of a rule

{
  "id": "passport_validity_6m",
  "severity": "hard_stop",
  "check": "date_after",
  "params": {
    "field": "date_of_expiry",
    "source": "passport",
    "min_gap_days": 180,
    "on_fail_message": "Your passport does not have the required 6 months of validity."
  },
  "on_deny": {
    "message": "Passport expires within 6 months.",
    "max_retries": 0,
    "remediate_type": ""
  }
}
FieldPurpose
idStable identifier; shows up in goal progress and the audit trail.
severityhard_stop (fail = case denied, no retry) or require (must pass, resubmission allowed).
checkWhich comparator or verdict to evaluate.
paramsCheck-specific configuration: source document, field, thresholds, user-facing failure message.
on_denyWhat happens on failure: reviewer message, max_retries, and which document slot to ask the applicant to resubmit (remediate_type).

Check types

Deterministic comparators — always the same answer for the same input, zero model involvement:

CheckEvaluates
field_contains / field_equalsAn extracted field contains or equals a value.
field_gte / field_lteNumeric threshold (balance, income, age).
date_after / date_beforeDate validity with configurable gaps (expiry buffers, statement recency).
format_validThe field matches its type's format — including ID checksums: PAN structure, Aadhaar and GSTIN check digits. A synthesized ID number almost never survives a real checksum.
cross_fieldConsistency between fields on the same document (period vs transaction dates, totals vs line items).

Verdict thresholds — gate on the confidence of fraud and integrity checks:

CheckEvaluates
liveness_confidence_gteLiveness verdict for the session or selfie.
deepfake_confidence_belowDeepfake risk stays under your ceiling.
face_match_gteLikeness between selfie and ID photo.
face_anchor_unbrokenThe same person stayed on camera all session.
lipsync_confidence_belowAV desync risk under threshold.
integrity_risk_belowDocument integrity risk under threshold.
cross_match_field_gteCross-document agreement per field.

Custom (AI-evaluated) — for policy that can't be expressed as a comparator, write the rule in plain language and the platform evaluates it against the extracted data:

{
  "id": "outbound_to_thailand",
  "severity": "hard_stop",
  "check": "custom",
  "params": {
    "prompt": "Check whether the FINAL destination of this flight is Thailand. Ignore transit cities.",
    "sources": ["outbound_flight"],
    "on_fail_message": "Your outbound flight does not end in Thailand."
  },
  "on_deny": { "message": "Outbound flight not to Thailand.", "max_retries": 1, "remediate_type": "outbound_flight" }
}

Custom rules run against already-extracted JSON, never the raw image — so they are cheap, fast, and auditable.

Severity and remediation

SeverityOn failure
hard_stopCase denied immediately. Use for disqualifiers: wrong nationality, failed checksum, deepfake verdict.
requireCase blocked; applicant may resubmit the document named in remediate_type up to max_retries times. Use for fixable problems: blurry upload, stale statement, low balance.
💡

Put the user-facing explanation in params.on_fail_message and keep it actionable but non-specific for fraud rules — tell a genuine user how to fix a blurry upload; never tell a fraudster which detector caught them. The precise reason lives in on_deny.message for your reviewers.

Goal progress

As checks complete, each rule's state is tracked on the case as goal progress — visible in the dashboard, the API (GET /v1/cases/{id}), and conversational agents use it to tell the applicant what is still outstanding. When every rule passes, the case moves to completed (or to review if your policy routes flagged cases through a human).

Every rule's outcome is shown on the case with its severity — here a video-KYC case where the deterministic rules (consent, geo, PAN format) passed but the liveness verdict threshold fired a warning:

Rule evaluations table on a case — ten rules with pass, skip, and warn results: consent logged, geo in India, and PAN format passing as hard stops; Aadhaar freshness and video liveness score warning; face match, name match, single person in frame, and single speaker passingRule evaluations table on a case — ten rules with pass, skip, and warn results: consent logged, geo in India, and PAN format passing as hard stops; Aadhaar freshness and video liveness score warning; face match, name match, single person in frame, and single speaker passing

And a clean run — an Income Verification Agent case where both income-threshold rules passed and the case auto-approved, with the extracted fields alongside:

Completed Income Verification Agent case — verdict Approved with 2 of 2 rules passed (Form 16 gross and payslip gross thresholds), and the extracted ITR acknowledgement fields shown belowCompleted Income Verification Agent case — verdict Approved with 2 of 2 rules passed (Form 16 gross and payslip gross thresholds), and the extracted ITR acknowledgement fields shown below

Where to see them in action

Build a KYC Agent

A complete agent with nationality, validity, funds, and custom AI rules. See Build a KYC Agent.

Checks Overview

The fraud checks whose verdicts these rules gate. See Checks Overview.