The short answer
AAP-H records five things about every AI agent action on a health system: which AI agent did it, what the rules decided, who approved it, what the agent claimed happened, and what the system of record actually shows afterwards.
It is a set of FHIR R4 profiles (Provenance and AuditEvent, built on HL7 AI Transparency and IHE BALP) plus a JSON envelope for systems that don’t speak FHIR. At its top level each record is signed and chained, so a hospital, payer or auditor can check it offline with the issuer’s public keys.
- Status
- Draft for comment, v0.1.0. Names and codes may change before v1.0.
- Licence
- Text CC-BY-4.0. Schemas, profiles and examples Apache-2.0. Free for any vendor to implement.
- For
- EHR vendors, payers and TPAs, AI agent vendors, hospital IT and audit teams.
- Reference implementation
- Deedglass. The spec doesn’t require it.
The gap it fills
The pieces exist separately. FHIR Provenance says where data came from. FHIR AuditEvent, profiled by IHE’s Basic Audit Log Patterns (BALP 1.1.4), says an access happened. HL7’s AI Transparency on FHIR guide, in ballot as 1.0.0-ballot, marks data as influenced by AI and names the AI system. SMART scopes and ABDM consent artefacts say what an app was allowed to do.
None of them records, for one agent action, the difference between what the agent said happened and what the system of record shows, together with the rule and the people who let it through, in a form a third party can check. BALP’s profiles cover successful calls only, so a refused agent call has no BALP profile at all.
| Question a reviewer asks | Existing standards | AAP-H |
|---|---|---|
| Was it an AI agent, and which one? | AI Transparency names the AI system as a Device | Reuses it, plus the agent’s id, model and tool |
| Was it allowed, and by whom? | SMART scopes, consent artefacts; no approval chain | The policy decision and every approval step |
| Did it do what it said? | Nothing | Claimed outcome beside the verified outcome: match, doesn’t match, can’t check |
| Was the call refused? | AuditEvent, but no BALP profile | A record for every call, including refused ones |
| Can I check the record myself? | Provenance has a signature element, with no rule for what it covers | A signed, chained record and offline verification rules |
What a record holds
- AI agentWhich agent, which model, which tool
agent - PolicyAllow, deny, or wait for a person
policy - ApprovalsWho approved, step by step
approvals - ClaimedWhat the tool or agent said happened
claimed - VerifiedWhat the system of record shows: match, doesn’t match, can’t check
verified - SealSigned and chained, checkable offline
chain · seal
Records hold ids, codes, times and SHA-256 digests of requests and results. They never hold clinical values, notes, search values, prompts or model output, and person references are opaque by default.
Claimed versus verified
The core rule: what the agent or tool claimed and what the gateway checked are separate fields, and a check that couldn’t reach a conclusion is “can’t check”, never “match”. A tool’s own success answer is a claim, not a check.
Claimed
An AI agent submits a prior authorisation and tells the clinic the payer approved it.
claimed.assertion: payer-approvedVerified
The gateway reads back the payer’s response. The request is pended for review.
verified.result: mismatchFrom the spec’s synthetic Da Vinci PAS example. No real patient, clinic or payer.
Conformance levels
-
Level 1
Record
- A record for every action, refused ones included
- The agent marked as AI, with its id and model
- The policy decision, approvals, claimed and verified outcomes
-
Level 2
Verify
- Writes checked by reading the system of record back, or its change log
- “Can’t check” says why
- Records chained, so a changed or missing record shows
-
Level 3
Signed and approved
- Every record signed, with a published key set
- Approvals and approvers inside the signed content
- Anyone can check it offline
A conformance claim is the implementer’s own statement of the level, the actions it covers and how to get a sample export. Nobody grants it.
FHIR or JSON
| Part | What it is |
|---|---|
| FHIR R4 profiles | aaph-provenance and aaph-auditevent, seven extensions (action, policy decision, approval, authorization, claimed outcome, verified outcome, record seal), twelve code systems |
| JSON envelope | The same record for Postgres, SaaS and claims systems, with a JSON Schema 2020-12 |
| BALP mapping | Which IHE BALP profile an AuditEvent also claims, and the calls BALP doesn’t cover |
| Research note | What FHIR, IHE, HL7 AI Transparency, SMART, Da Vinci, ABDM, W3C Verifiable Credentials and C2PA already cover, with sources |
How anyone checks a record
- Get the record and the issuer’s key set. Nothing else: no account with the issuer, no network call.
- Recompute the record digest: the SHA-256 of the record’s canonical JSON (RFC 8785) without its seal.
- Find the key, check it wasn’t revoked and was active when the record was written, and check the Ed25519 or ML-DSA-65 signature.
- Walk the chain: sequence numbers without gaps, each record linked to the digest of the one before.
- For a FHIR resource, check that what it says equals the signed record it points to.
A valid record means the issuer wrote these values and nothing covered by the signature changed since. It doesn’t mean the AI was right, or that the issuer saw every action: a gateway records only the calls that go through it. The spec says this in its verification section.
Examples
All synthetic. No real patient, person, payer or hospital.
| Case | What happens | Level |
|---|---|---|
| India: NHCX pre-authorisation | An agent prepares a pre-authorisation ClaimBundle under an ABDM consent artefact and a SMART scope; two people approve; the read-back matches | Level 3 |
| US: Da Vinci PAS submission | A clinician approves; the agent reports the payer approved; the read-back shows the request pended, so the record says doesn’t match | Level 3 |
| India: refused ABDM record | An agent tries to write a final consultation record without a clinician; the policy refuses and nothing runs | Level 1 |
| A Deedglass record | A real Deedglass test record converted to the envelope and checked against the signed original | Level 3 |
Each example comes as a JSON envelope and as FHIR resources. A small Go test checks every example against the schemas, verifies the signed ones, refuses tampered copies, and converts every action record in Deedglass’s test vectors to the envelope.
Status and how to take part
This is a v0.1 draft for comment, published by the Deedglass contributors. It is not an HL7 or IHE publication and no standards body has reviewed it. We plan to propose it to the relevant HL7 work groups as input to a FHIR implementation guide; if a standards body takes it on, the canonical URLs move to that body and the licences stay as open or become more open.
- Open an issue or a pull request on the repository. The spec’s last section lists the questions we most want answered.
- Implement it. The profiles and schemas are Apache-2.0, so they can go straight into a product or a FHIR package.
- See how Deedglass implements it for FHIR servers: Deedglass for healthcare.
Agent Action Provenance for Health (AAP-H) v0.1.0-draft, by Arjun Prabhakaran and the Deedglass contributors. Text CC-BY-4.0; schemas and profiles Apache-2.0.