How it works
Two agents, one signed protocol, and a rule that can be read.
ARIA — the Autonomous Request and Intelligence Architecture — is the envelope that carries an authorization across an organizational boundary. It is deliberately boring: signed JSON, a verified sender, and a payload that cannot be acted on until the signature checks out.
The envelope
Every message states who sent it and proves it.
Each organization holds an RSA-2048 key pair. Pavo stores only the public key — the private key is returned once, at provisioning, and never reaches the database.
Every message is signed over a SHA-256 digest of its canonical contents using RSASSA-PSS, and checked against the sender's registered key before its payload is read. A signature that fails verification is rejected with a 401 and the rejection is written to the audit log.
Sender and recipient are addresses, not strings — agent://pavo/payer/meridian — so every row in the audit trail names the agent that produced it.
AUTH_REQUEST
{
"protocol": "ARIA/1.0",
"message_id": "6a1c3698-...",
"message_type": "AUTH_REQUEST",
"sender": "agent://pavo/provider/metro-valley",
"recipient": "agent://pavo/payer/meridian",
"issued_at": "2026-09-19T00:35:53Z",
"payload": {
"procedure_code": "27447",
"diagnosis_code": "M17.11",
"patient_ref": "sha256:9f2b...",
"fhir_bundle_ref": "Bundle/ebc5500e"
},
"signature": {
"algorithm": "RSASSA-PSS",
"digest": "SHA-256",
"value": "MEUCIQDf..."
}
}The agents
Three roles, and one of them is knowing when to stop.
Provider agent
Watches for the EHR webhook, assembles a FHIR R4 bundle from the order, and signs an AUTH_REQUEST. It never asks a human to assemble anything.
Payer agent
Verifies the signature, evaluates the coverage rules, and returns an AUTH_RESPONSE carrying the outcome and the rule that produced it.
Escalation agent
Takes anything without a definitive rule match and hands it to a human reviewer with the record already assembled — the bundle, the proof, the rule that failed to match.
The rule engine
First match wins, and the match is recorded.
Five rules ship today. They are evaluated in order, so the specific knee rule is checked before the general one, and the engine cannot return an outcome without naming the rule behind it.
| Rule | Procedure | Diagnosis | Outcome |
|---|---|---|---|
| PAVO-R001 | 70553 (MRI brain) | any | APPROVED |
| PAVO-R002 | 27447 (knee replacement) | M17.11 | APPROVED |
| PAVO-R003 | 27447 (knee replacement) | any other | ESCALATED |
| PAVO-R004 | 99214 (office visit) | any | APPROVED |
| PAVO-R005 | any other | any | ESCALATED |
Adding a payer means adding rules, not retraining anything. The table is returned by GET /api/rules at runtime, so what the engine will do is inspectable before you send it a request.
When it doesn't resolve
The system never issues a final denial on its own.
This is a design constraint, not a limitation of the current build.
Escalation
Anything without a definitive rule match becomes escalated rather than guessed at. A human picks it up with the FHIR bundle, the proof and the rule that failed to match already in front of them — the assembly work is done, only the judgement is left.
Appeals
A denial is either appealed or escalated. The appeal agent drafts from the clinical record and cited literature, and below a confidence threshold it escalates instead of filing. A not_covered denial is never appealed automatically — coverage is a contract question, not a clinical one.