Compliance engine
Resolve current facts and effective policy into an explainable, expiring decision before a contact, disclosure, AI tool call, or account action can execute.
The compliance engine is a decision boundary, not a warning banner. It evaluates one concrete proposed action for one subject at one time. A blocked action does not execute; a missing required fact is not treated as permission.
Decision contract
| Outcome | Meaning | Executor behavior |
|---|---|---|
allowed |
All applicable rules passed on sufficiently fresh facts. | May proceed before expiry if authorization and state still hold. |
allowed_with_warning |
No prohibition matched, but configured risk or proximity threshold exists. | Proceed only under the warning’s declared policy. |
approval_required |
A permitted human must accept the frozen action and evidence. | Hold; creator cannot self-approve where separation applies. |
blocked |
At least one non-overridable rule prohibits this path. | Do not execute; record blocked outcome and next safe route. |
missing_facts |
A required fact is absent, contradictory, or stale. | Refresh, collect evidence, or route to review. |
Outcomes include expiresAt and a decision ID. Expiry is deliberately short for contact, restriction, and money-sensitive actions.
Evaluate a proposed action
curl -X POST "$BASE/v1/servicing/compliance/evaluations" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: evaluate-harbor-call-2027-05-01T101158" \
-d '{
"action": "send_interaction",
"subject": {
"customerId": "412",
"loanIds": ["7204"]
},
"parameters": {
"channel": "voice",
"purpose": "collections",
"contactPointId": "cp_MAYA_MOBILE_1"
},
"asOf": "2027-05-01T10:11:58-07:00"
}'
{
"decisionId": "dec_CONTACT_81",
"outcome": "allowed",
"expiresAt": "2027-05-01T10:16:58-07:00",
"rules": [
{ "ruleId": "contact-time-CA-v4", "outcome": "pass" }
],
"factsFreshness": "fresh"
}
Resolution pipeline
typed action
↓
scope resolution ─ tenant · product · debt · purpose · channel · jurisdiction
↓
fact resolution ─ value · source · asOf · observedAt · freshness · confidence
↓
effective rules ─ authority · applicability · exceptions · version · dates
↓
rule results ─ pass · warn · approval · block · missing
↓
aggregate + persist + expire
The aggregator does not use a simplistic numerical score. A scoped hard stop dominates a general allow; missing input to a required rule prevents an allow; an approval requirement cannot be downgraded by a lower-risk rule.
Fact contract
Every fact used in a durable decision records:
- canonical name and typed value;
- subject and scope;
- source and source reference;
- source
asOfand LendEasyobservedAttimes; - freshness classification and maximum age;
- confidence or verification state where relevant.
Balances can tolerate a different freshness budget than bankruptcy, cease, consent, or payment-in-flight state. Bring your own core integrations publish these budgets explicitly.
Planning versus execution
A direct evaluation helps a UI present available choices. It does not let the caller bypass the action-owning API. POST /v1/servicing/interactions, action submission, and other execution endpoints perform their own last-moment decision and link it to the result.
Boundaries
The engine can apply versioned controls approved for a tenant; it does not decide which law applies, replace legal review, verify that policy text is legally sufficient, or turn a product label into a regulatory conclusion. Those are governance responsibilities represented in the rule lifecycle.