eyeprolog

AuroraCare

Should this use of a patient’s health data be permitted, and why?

A regional health-data platform receives seven requests to use one patient’s records: for care, quality improvement, research, insurance, and AI training. Each request is checked against purpose-based policies (in the style of the W3C ODRL and DPV vocabularies), the patient’s consent, and the care relationship, and every decision comes with its reason.

Run it in the playground · Source


The question

The same health record is requested seven times, in scenarios A to G:

For each request: permit or deny, which policy matched, and why?


Policies as facts

policyUid(policyQi, "urn:policy:qi-2025-aurora").
purposeAllowed(policyQi, ensureQualitySafetyHealthcare).
requireEnvironment(policyQi, "secure_env").
requireAllCategory(policyQi, labResults).
requireAllCategory(policyQi, patientSummary).
duty(policyQi, requireConsent).
duty(policyQi, noExfiltration).

policyUid(policyDenyInsurance, "urn:policy:deny-insurance").
prohibitPurpose(policyDenyInsurance, insuranceManagement).

consentAllow(ruben, healthcareScientificResearch).
consentDeny(ruben, trainTestAndEvaluateAiSystemsAlgorithms).

A policy is a set of facts: the purposes it allows, the environment and data categories it requires, and the duties it imposes. The patient’s consent is recorded the same way.


Matching a request

qi_policy_match(S) :-
  purpose(S, ensureQualitySafetyHealthcare),
  environment(S, "secure_env"),
  category(S, labResults),
  category(S, patientSummary).

prohibition_match(S) :- insurance_prohibition_match(S).
prohibition_match(S) :- subject_opt_out(S).

no_policy_match(S) :-
  scenario(S),
  \+ permission_match(S),
  \+ prohibition_match(S).

decision(S, "PERMIT") :- permission_match(S), \+ prohibition_match(S).
decision(S, "DENY") :- prohibition_match(S).
decision(S, "DENY") :- no_policy_match(S).

Each policy branch is a named relation over a scenario. A request is permitted when some permission matches and no prohibition applies; a prohibited purpose or the patient’s opt-out always denies; and a request that matches nothing is denied by default. Parallel reason/2 and matchedPolicyUid/2 rules report why.


The answer

eyeprolog examples/auroracare.pl
decision(scenarioA, "PERMIT").
decision(scenarioE, "PERMIT").
decision(scenarioB, "PERMIT").
decision(scenarioF, "PERMIT").
decision(scenarioD, "DENY").
decision(scenarioG, "DENY").
decision(scenarioC, "DENY").

Four permits and three denials, among 117 answers in all: labels, descriptions, reasons, matched policy identifiers, audit traces, and ten report checks per scenario (full output). Scenario C is denied because the analyst requested lab results only, while the quality policy requires lab results and the patient summary.


The reason

eyeprolog --proof examples/auroracare.pl
step(decision(scenarioB, "PERMIT"),
     rule(153),
     ['S' = scenarioB],
     [permission_match(scenarioB), \+ prohibition_match(scenarioB)]).
step(permission_match(scenarioB), rule(145), ['S' = scenarioB], [qi_policy_match(scenarioB)]).
step(qi_policy_match(scenarioB),
     rule(140),
     ['S' = scenarioB],
     [purpose(scenarioB, ensureQualitySafetyHealthcare),
      environment(scenarioB, "secure_env"),
      category(scenarioB, labResults),
      category(scenarioB, patientSummary)]).

Scenario B is permitted because the quality-improvement policy matched (right purpose, secure environment, and both required data categories) and no prohibition applies. Each positive premise is a scenario fact that the proof can point to; the absence of a prohibition is recorded as an absent step.


The check

condition('C1', resolution, ok, 181).
condition('C4', coverage, ok, 287).
condition('C6', boundary_consistency, ok, 6).
obligation(absent, theory_scoped, \+ permission_match(scenarioC)).
obligation(absent, theory_scoped, \+ prohibition_match(scenarioC)).
verdict(checked_with_obligations).

All 181 rule and fact steps replay against the program, and every one of the 117 claims is covered. The seven negations (no prohibition for the four permits, no opt-out for research, and nothing at all matching scenario C) cannot be replayed; they are listed as obligations. The checker compared six of them with the program’s own evidence and found none contradicted.


Try it

Related: ODRL policy reasoning and Cross-organization data sharing. Learn more in The Art of EyeProlog, Chapter 25.