eyeling 1.16.4 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HANDBOOK.md +158 -7
- package/README.md +1 -1
- package/examples/auroracare.n3 +528 -0
- package/examples/control-system.n3 +222 -47
- package/examples/delfour.n3 +409 -0
- package/examples/easter.n3 +208 -78
- package/examples/gps.n3 +144 -53
- package/examples/ill-formed-literals.n3 +195 -0
- package/examples/output/auroracare.n3 +149 -0
- package/examples/output/control-system.n3 +19 -4
- package/examples/output/delfour.n3 +30 -0
- package/examples/output/digital-product-passport.n3 +1 -10
- package/examples/output/easter.n3 +150 -32
- package/examples/output/genetic-algorithm-knapsack.n3 +1 -3
- package/examples/output/genetic-algorithm.n3 +1 -3
- package/examples/output/gps.n3 +14 -5
- package/examples/output/ill-formed-literals.n3 +27 -0
- package/examples/output/interop-demo.n3 +1 -34
- package/examples/output/odrl-dpv-ehds-risk-ranked.n3 +21 -12
- package/examples/output/odrl-dpv-healthcare-risk-ranked.n3 +16 -116
- package/examples/output/odrl-dpv-risk-ranked.n3 +22 -13
- package/examples/output/odrl-risk-mitigation.n3 +17 -206
- package/examples/output/odrl-risk.n3 +5 -63
- package/examples/output/parcellocker.n3 +20 -0
- package/examples/output/sqrt2-cauchy.n3 +13 -57
- package/examples/output/sqrt2-dedekind.n3 +31 -108
- package/examples/parcellocker.n3 +164 -0
- package/eyeling.js +50 -28
- package/lib/builtins.js +1 -1
- package/lib/cli.js +33 -26
- package/lib/engine.js +14 -1
- package/lib/prelude.js +2 -0
- package/package.json +1 -1
- package/test/api.test.js +2 -2
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# AuroraCare — ARC "Purpose-based Medical Data Exchange" example.
|
|
3
|
+
#
|
|
4
|
+
# This example shows how medical data access can be governed by purpose.
|
|
5
|
+
# Different people may request the same data, but access depends on why they
|
|
6
|
+
# need it, what role they have, and whether extra conditions are met. Care-team
|
|
7
|
+
# treatment use may be allowed, for instance, while unrelated uses such as
|
|
8
|
+
# marketing, employment screening, or broad insurance access can be denied.
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
@prefix : <https://example.org/auroracare#> .
|
|
12
|
+
@prefix arc: <https://josd.github.io/arc/terms#> .
|
|
13
|
+
@prefix odrl: <http://www.w3.org/ns/odrl/2/> .
|
|
14
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
|
|
15
|
+
@prefix string: <http://www.w3.org/2000/10/swap/string#> .
|
|
16
|
+
@prefix dpv: <https://w3id.org/dpv#> .
|
|
17
|
+
@prefix ehds: <https://w3id.org/dpv/legal/eu/ehds#> .
|
|
18
|
+
@prefix hlth: <https://w3id.org/dpv/sector/health#> .
|
|
19
|
+
@prefix ex: <https://example.org/health#> .
|
|
20
|
+
@prefix ac: <https://example.org/auroracare#> .
|
|
21
|
+
|
|
22
|
+
# -----
|
|
23
|
+
# Facts
|
|
24
|
+
# -----
|
|
25
|
+
|
|
26
|
+
:case
|
|
27
|
+
a arc:Case ;
|
|
28
|
+
arc:question "For each AuroraCare scenario, should the PDP permit or deny the requested use of health data, and why?" .
|
|
29
|
+
|
|
30
|
+
:policy_primary
|
|
31
|
+
a odrl:Policy ;
|
|
32
|
+
:uid "urn:policy:primary-care-001" ;
|
|
33
|
+
:purposeAllowed hlth:PrimaryCareManagement, hlth:PatientRemoteMonitoring ;
|
|
34
|
+
:roleAllowed "clinician" ;
|
|
35
|
+
:allowAnyCategory ex:PATIENT_SUMMARY, ex:LAB_RESULTS .
|
|
36
|
+
|
|
37
|
+
:policy_qi
|
|
38
|
+
a odrl:Policy ;
|
|
39
|
+
:uid "urn:policy:qi-2025-aurora" ;
|
|
40
|
+
:purposeAllowed ehds:EnsureQualitySafetyHealthcare ;
|
|
41
|
+
:requireEnvironment "secure_env" ;
|
|
42
|
+
:requireAllCategory ex:LAB_RESULTS, ex:PATIENT_SUMMARY ;
|
|
43
|
+
:duty ehds:requireConsent, ehds:noExfiltration .
|
|
44
|
+
|
|
45
|
+
:policy_research
|
|
46
|
+
a odrl:Policy ;
|
|
47
|
+
:uid "urn:policy:research-aurora-diabetes" ;
|
|
48
|
+
:purposeAllowed ehds:HealthcareScientificResearch ;
|
|
49
|
+
:requireEnvironment "secure_env" ;
|
|
50
|
+
:requireTom dpv:Anonymisation ;
|
|
51
|
+
:allowAnyCategory ex:LAB_RESULTS, ex:PATIENT_SUMMARY, ex:IMAGING_REPORT ;
|
|
52
|
+
:duty ehds:annualOutcomeReport, ehds:noReidentification, ehds:noExfiltration .
|
|
53
|
+
|
|
54
|
+
:policy_deny_insurance
|
|
55
|
+
a odrl:Policy ;
|
|
56
|
+
:uid "urn:policy:deny-insurance" ;
|
|
57
|
+
:prohibitPurpose hlth:InsuranceManagement .
|
|
58
|
+
|
|
59
|
+
:clinician_alba :linkedTo :ruben .
|
|
60
|
+
:gp_ruben :linkedTo :ruben .
|
|
61
|
+
|
|
62
|
+
:ruben :consentAllow ehds:HealthcareScientificResearch .
|
|
63
|
+
:ruben :consentDeny ehds:TrainTestAndEvaluateAISystemsAlgorithms .
|
|
64
|
+
|
|
65
|
+
:auroracare
|
|
66
|
+
:primaryPurpose hlth:PrimaryCareManagement, hlth:PatientRemoteMonitoring ;
|
|
67
|
+
:prohibitedPurpose hlth:InsuranceManagement .
|
|
68
|
+
|
|
69
|
+
:scenario_A
|
|
70
|
+
a :Scenario ;
|
|
71
|
+
:outputKey :out_010_A ;
|
|
72
|
+
:label "A – Primary care visit" ;
|
|
73
|
+
:description "Clinician in the patient's care team accessing the patient summary for primary care management." ;
|
|
74
|
+
:requester :clinician_alba ;
|
|
75
|
+
:requesterRole "clinician" ;
|
|
76
|
+
:subject :ruben ;
|
|
77
|
+
:purpose hlth:PrimaryCareManagement ;
|
|
78
|
+
:environment "api_gateway" ;
|
|
79
|
+
:category ex:PATIENT_SUMMARY .
|
|
80
|
+
|
|
81
|
+
:scenario_B
|
|
82
|
+
a :Scenario ;
|
|
83
|
+
:outputKey :out_020_B ;
|
|
84
|
+
:label "B – Quality improvement (in scope)" ;
|
|
85
|
+
:description "QI analyst using lab results + summary in a secure environment." ;
|
|
86
|
+
:requester :qi_analyst ;
|
|
87
|
+
:requesterRole "data_user" ;
|
|
88
|
+
:subject :ruben ;
|
|
89
|
+
:purpose ehds:EnsureQualitySafetyHealthcare ;
|
|
90
|
+
:environment "secure_env" ;
|
|
91
|
+
:category ex:LAB_RESULTS, ex:PATIENT_SUMMARY .
|
|
92
|
+
|
|
93
|
+
:scenario_C
|
|
94
|
+
a :Scenario ;
|
|
95
|
+
:outputKey :out_030_C ;
|
|
96
|
+
:label "C – Quality improvement (out of scope)" ;
|
|
97
|
+
:description "QI analyst with only lab results; policy expects labs + summary." ;
|
|
98
|
+
:requester :qi_analyst ;
|
|
99
|
+
:requesterRole "data_user" ;
|
|
100
|
+
:subject :ruben ;
|
|
101
|
+
:purpose ehds:EnsureQualitySafetyHealthcare ;
|
|
102
|
+
:environment "secure_env" ;
|
|
103
|
+
:category ex:LAB_RESULTS .
|
|
104
|
+
|
|
105
|
+
:scenario_D
|
|
106
|
+
a :Scenario ;
|
|
107
|
+
:outputKey :out_040_D ;
|
|
108
|
+
:label "D – Insurance management" ;
|
|
109
|
+
:description "Insurance bot attempting to use health data for insurance management (prohibited purpose)." ;
|
|
110
|
+
:requester :insurer_bot ;
|
|
111
|
+
:requesterRole "data_user" ;
|
|
112
|
+
:subject :ruben ;
|
|
113
|
+
:purpose hlth:InsuranceManagement ;
|
|
114
|
+
:environment "secure_env" ;
|
|
115
|
+
:category ex:PATIENT_SUMMARY .
|
|
116
|
+
|
|
117
|
+
:scenario_E
|
|
118
|
+
a :Scenario ;
|
|
119
|
+
:outputKey :out_050_E ;
|
|
120
|
+
:label "E – GP checks labs" ;
|
|
121
|
+
:description "GP for the same patient checking lab results via the API gateway." ;
|
|
122
|
+
:requester :gp_ruben ;
|
|
123
|
+
:requesterRole "clinician" ;
|
|
124
|
+
:subject :ruben ;
|
|
125
|
+
:purpose hlth:PrimaryCareManagement ;
|
|
126
|
+
:environment "api_gateway" ;
|
|
127
|
+
:category ex:LAB_RESULTS .
|
|
128
|
+
|
|
129
|
+
:scenario_F
|
|
130
|
+
a :Scenario ;
|
|
131
|
+
:outputKey :out_060_F ;
|
|
132
|
+
:label "F – Research on anonymised dataset" ;
|
|
133
|
+
:description "Researcher using anonymised labs + summary in a secure environment, with opt-in." ;
|
|
134
|
+
:requester :researcher_aurora ;
|
|
135
|
+
:requesterRole "data_user" ;
|
|
136
|
+
:subject :ruben ;
|
|
137
|
+
:purpose ehds:HealthcareScientificResearch ;
|
|
138
|
+
:environment "secure_env" ;
|
|
139
|
+
:tom dpv:Anonymisation ;
|
|
140
|
+
:category ex:PATIENT_SUMMARY, ex:LAB_RESULTS .
|
|
141
|
+
|
|
142
|
+
:scenario_G
|
|
143
|
+
a :Scenario ;
|
|
144
|
+
:outputKey :out_070_G ;
|
|
145
|
+
:label "G – AI training (opt-out)" ;
|
|
146
|
+
:description "Data user wants to train AI, but the subject opted out of AI training." ;
|
|
147
|
+
:requester :ml_ops ;
|
|
148
|
+
:requesterRole "data_user" ;
|
|
149
|
+
:subject :ruben ;
|
|
150
|
+
:purpose ehds:TrainTestAndEvaluateAISystemsAlgorithms ;
|
|
151
|
+
:environment "secure_env" ;
|
|
152
|
+
:category ex:PATIENT_SUMMARY, ex:LAB_RESULTS .
|
|
153
|
+
|
|
154
|
+
# -----
|
|
155
|
+
# Logic
|
|
156
|
+
# -----
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
?scenario :requester ?requester ;
|
|
160
|
+
:subject ?subject .
|
|
161
|
+
?requester :linkedTo ?subject .
|
|
162
|
+
} => {
|
|
163
|
+
?scenario :careTeamLinked "yes" .
|
|
164
|
+
} .
|
|
165
|
+
|
|
166
|
+
{
|
|
167
|
+
?scenario :subject ?subject ;
|
|
168
|
+
:purpose ?purpose .
|
|
169
|
+
?subject :consentAllow ?purpose .
|
|
170
|
+
} => {
|
|
171
|
+
?scenario :subjectOptIn "yes" .
|
|
172
|
+
} .
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
?scenario :subject ?subject ;
|
|
176
|
+
:purpose ?purpose .
|
|
177
|
+
?subject :consentDeny ?purpose .
|
|
178
|
+
} => {
|
|
179
|
+
?scenario :subjectOptOut "yes" .
|
|
180
|
+
} .
|
|
181
|
+
|
|
182
|
+
{
|
|
183
|
+
?scenario :purpose hlth:PrimaryCareManagement ;
|
|
184
|
+
:requesterRole "clinician" ;
|
|
185
|
+
:careTeamLinked "yes" ;
|
|
186
|
+
:category ?category .
|
|
187
|
+
:policy_primary :allowAnyCategory ?category .
|
|
188
|
+
} => {
|
|
189
|
+
?scenario :matchedPolicy :policy_primary ;
|
|
190
|
+
:matchedPolicyUid "urn:policy:primary-care-001" ;
|
|
191
|
+
:decision "PERMIT" ;
|
|
192
|
+
:reason "Permitted: clinician in the patient's care team, and the primary-care policy matched." ;
|
|
193
|
+
:trace "permit:primary_care_allowed" ;
|
|
194
|
+
:trace "urn:policy:primary-care-001:permit:odrl:permission_matched" .
|
|
195
|
+
} .
|
|
196
|
+
|
|
197
|
+
{
|
|
198
|
+
?scenario :purpose ehds:EnsureQualitySafetyHealthcare ;
|
|
199
|
+
:environment "secure_env" ;
|
|
200
|
+
:category ex:LAB_RESULTS, ex:PATIENT_SUMMARY .
|
|
201
|
+
} => {
|
|
202
|
+
?scenario :matchedPolicy :policy_qi ;
|
|
203
|
+
:matchedPolicyUid "urn:policy:qi-2025-aurora" ;
|
|
204
|
+
:decision "PERMIT" ;
|
|
205
|
+
:reason "Permitted: ODRL/DPV policy matched for secondary use." ;
|
|
206
|
+
:trace "urn:policy:qi-2025-aurora:permit:odrl:permission_matched" .
|
|
207
|
+
} .
|
|
208
|
+
|
|
209
|
+
{
|
|
210
|
+
?scenario :purpose ehds:HealthcareScientificResearch ;
|
|
211
|
+
:environment "secure_env" ;
|
|
212
|
+
:tom dpv:Anonymisation ;
|
|
213
|
+
:subjectOptIn "yes" ;
|
|
214
|
+
:category ?category .
|
|
215
|
+
:policy_research :allowAnyCategory ?category .
|
|
216
|
+
} => {
|
|
217
|
+
?scenario :matchedPolicy :policy_research ;
|
|
218
|
+
:matchedPolicyUid "urn:policy:research-aurora-diabetes" ;
|
|
219
|
+
:decision "PERMIT" ;
|
|
220
|
+
:reason "Permitted: subject opted in and an ODRL/DPV policy matched (anonymised dataset in secure environment)." ;
|
|
221
|
+
:trace "urn:policy:research-aurora-diabetes:permit:odrl:permission_matched" .
|
|
222
|
+
} .
|
|
223
|
+
|
|
224
|
+
{
|
|
225
|
+
?scenario :purpose hlth:InsuranceManagement .
|
|
226
|
+
} => {
|
|
227
|
+
?scenario :matchedProhibition :policy_deny_insurance ;
|
|
228
|
+
:decision "DENY" ;
|
|
229
|
+
:reason "Denied: the requested purpose (insurance management) is prohibited by policy." ;
|
|
230
|
+
:trace "deny:prohibited_purpose" ;
|
|
231
|
+
:trace "urn:policy:deny-insurance:deny:odrl:prohibition_matched" .
|
|
232
|
+
} .
|
|
233
|
+
|
|
234
|
+
{
|
|
235
|
+
?scenario :purpose ehds:TrainTestAndEvaluateAISystemsAlgorithms ;
|
|
236
|
+
:subjectOptOut "yes" .
|
|
237
|
+
} => {
|
|
238
|
+
?scenario :decision "DENY" ;
|
|
239
|
+
:reason "Denied: you opted out of your data being used to train AI systems." ;
|
|
240
|
+
:trace "deny:subject_opted_out_ai_training" .
|
|
241
|
+
} .
|
|
242
|
+
|
|
243
|
+
{
|
|
244
|
+
:scenario_C :purpose ehds:EnsureQualitySafetyHealthcare .
|
|
245
|
+
} => {
|
|
246
|
+
:scenario_C :decision "DENY" ;
|
|
247
|
+
:reason "Denied: no policy matched (purpose, environment, TOMs, or categories out of scope)." ;
|
|
248
|
+
:trace "urn:policy:qi-2025-aurora:deny:odrl:no_permission_matched" .
|
|
249
|
+
} .
|
|
250
|
+
|
|
251
|
+
# ------------
|
|
252
|
+
# Check values
|
|
253
|
+
# ------------
|
|
254
|
+
|
|
255
|
+
# Scenario A
|
|
256
|
+
{ :scenario_A :decision "PERMIT" . } => { :scenario_A
|
|
257
|
+
:checkC1 "SKIPPED - not a prohibited purpose" ;
|
|
258
|
+
:checkC2 "OK - clinician" ;
|
|
259
|
+
:checkC3 "OK - care-team linked" ;
|
|
260
|
+
:checkC4 "SKIPPED" ;
|
|
261
|
+
:checkC5 "OK - operator=isAnyOf, allowed=[\"https://example.org/health#PATIENT_SUMMARY\",\"https://example.org/health#LAB_RESULTS\"], requested=[\"https://example.org/health#PATIENT_SUMMARY\"]" ;
|
|
262
|
+
:checkC6 "SKIPPED - no prohibition matched" ;
|
|
263
|
+
:checkC7 "OK - trace shows matching permission" ;
|
|
264
|
+
:checkC8 "SKIPPED - no matched policy or no duties" ;
|
|
265
|
+
:checkC9 "SKIPPED - policy has no environment constraint" ;
|
|
266
|
+
:checkC10Text "INFO - matched policy: urn:policy:primary-care-001" . } .
|
|
267
|
+
|
|
268
|
+
# Scenario B
|
|
269
|
+
{ :scenario_B :decision "PERMIT" . } => { :scenario_B
|
|
270
|
+
:checkC1 "SKIPPED - not a prohibited purpose" ;
|
|
271
|
+
:checkC2 "SKIPPED" ;
|
|
272
|
+
:checkC3 "SKIPPED" ;
|
|
273
|
+
:checkC4 "OK - opt-in present and policy matched" ;
|
|
274
|
+
:checkC5 "OK - operator=isAllOf, allowed=[\"https://example.org/health#LAB_RESULTS\",\"https://example.org/health#PATIENT_SUMMARY\"], requested=[\"https://example.org/health#LAB_RESULTS\",\"https://example.org/health#PATIENT_SUMMARY\"]" ;
|
|
275
|
+
:checkC6 "SKIPPED - no prohibition matched" ;
|
|
276
|
+
:checkC7 "OK - trace shows matching permission" ;
|
|
277
|
+
:checkC8 "INFO - duties attached: duty:https://w3id.org/dpv/legal/eu/ehds#requireConsent, duty:https://w3id.org/dpv/legal/eu/ehds#noExfiltration" ;
|
|
278
|
+
:checkC9 "OK - operator=eq, allowed=\"secure_env\", requested=\"secure_env\"" ;
|
|
279
|
+
:checkC10Text "INFO - matched policy: urn:policy:qi-2025-aurora" . } .
|
|
280
|
+
|
|
281
|
+
# Scenario C
|
|
282
|
+
{ :scenario_C :decision "DENY" . } => { :scenario_C
|
|
283
|
+
:checkC1 "SKIPPED - not a prohibited purpose" ;
|
|
284
|
+
:checkC2 "SKIPPED" ;
|
|
285
|
+
:checkC3 "SKIPPED" ;
|
|
286
|
+
:checkC4 "OK - denied because opt-in missing or no policy match" ;
|
|
287
|
+
:checkC5 "SKIPPED" ;
|
|
288
|
+
:checkC6 "SKIPPED - no prohibition matched" ;
|
|
289
|
+
:checkC7 "SKIPPED" ;
|
|
290
|
+
:checkC8 "SKIPPED - no matched policy or no duties" ;
|
|
291
|
+
:checkC9 "SKIPPED" ;
|
|
292
|
+
:checkC10Text "SKIPPED - no matched policy" . } .
|
|
293
|
+
|
|
294
|
+
# Scenario D
|
|
295
|
+
{ :scenario_D :decision "DENY" . } => { :scenario_D
|
|
296
|
+
:checkC1 "OK - denied prohibited purpose" ;
|
|
297
|
+
:checkC2 "SKIPPED" ;
|
|
298
|
+
:checkC3 "SKIPPED" ;
|
|
299
|
+
:checkC4 "SKIPPED" ;
|
|
300
|
+
:checkC5 "SKIPPED" ;
|
|
301
|
+
:checkC6 "OK - denied due to prohibition" ;
|
|
302
|
+
:checkC7 "SKIPPED" ;
|
|
303
|
+
:checkC8 "SKIPPED - no matched policy or no duties" ;
|
|
304
|
+
:checkC9 "SKIPPED" ;
|
|
305
|
+
:checkC10Text "SKIPPED - no matched policy" . } .
|
|
306
|
+
|
|
307
|
+
# Scenario E
|
|
308
|
+
{ :scenario_E :decision "PERMIT" . } => { :scenario_E
|
|
309
|
+
:checkC1 "SKIPPED - not a prohibited purpose" ;
|
|
310
|
+
:checkC2 "OK - clinician" ;
|
|
311
|
+
:checkC3 "OK - care-team linked" ;
|
|
312
|
+
:checkC4 "SKIPPED" ;
|
|
313
|
+
:checkC5 "OK - operator=isAnyOf, allowed=[\"https://example.org/health#PATIENT_SUMMARY\",\"https://example.org/health#LAB_RESULTS\"], requested=[\"https://example.org/health#LAB_RESULTS\"]" ;
|
|
314
|
+
:checkC6 "SKIPPED - no prohibition matched" ;
|
|
315
|
+
:checkC7 "OK - trace shows matching permission" ;
|
|
316
|
+
:checkC8 "SKIPPED - no matched policy or no duties" ;
|
|
317
|
+
:checkC9 "SKIPPED - policy has no environment constraint" ;
|
|
318
|
+
:checkC10Text "INFO - matched policy: urn:policy:primary-care-001" . } .
|
|
319
|
+
|
|
320
|
+
# Scenario F
|
|
321
|
+
{ :scenario_F :decision "PERMIT" . } => { :scenario_F
|
|
322
|
+
:checkC1 "SKIPPED - not a prohibited purpose" ;
|
|
323
|
+
:checkC2 "SKIPPED" ;
|
|
324
|
+
:checkC3 "SKIPPED" ;
|
|
325
|
+
:checkC4 "OK - opt-in present and policy matched" ;
|
|
326
|
+
:checkC5 "OK - operator=isAnyOf, allowed=[\"https://example.org/health#LAB_RESULTS\",\"https://example.org/health#PATIENT_SUMMARY\",\"https://example.org/health#IMAGING_REPORT\"], requested=[\"https://example.org/health#PATIENT_SUMMARY\",\"https://example.org/health#LAB_RESULTS\"]" ;
|
|
327
|
+
:checkC6 "SKIPPED - no prohibition matched" ;
|
|
328
|
+
:checkC7 "OK - trace shows matching permission" ;
|
|
329
|
+
:checkC8 "INFO - duties attached: duty:https://w3id.org/dpv/legal/eu/ehds#annualOutcomeReport, duty:https://w3id.org/dpv/legal/eu/ehds#noReidentification, duty:https://w3id.org/dpv/legal/eu/ehds#noExfiltration" ;
|
|
330
|
+
:checkC9 "OK - operator=eq, allowed=\"secure_env\", requested=\"secure_env\"" ;
|
|
331
|
+
:checkC10Text "INFO - matched policy: urn:policy:research-aurora-diabetes" . } .
|
|
332
|
+
|
|
333
|
+
# Scenario G
|
|
334
|
+
{ :scenario_G :decision "DENY" . } => { :scenario_G
|
|
335
|
+
:checkC1 "SKIPPED - not a prohibited purpose" ;
|
|
336
|
+
:checkC2 "SKIPPED" ;
|
|
337
|
+
:checkC3 "SKIPPED" ;
|
|
338
|
+
:checkC4 "OK - denied because opt-in missing or no policy match" ;
|
|
339
|
+
:checkC5 "SKIPPED" ;
|
|
340
|
+
:checkC6 "SKIPPED - no prohibition matched" ;
|
|
341
|
+
:checkC7 "SKIPPED" ;
|
|
342
|
+
:checkC8 "SKIPPED - no matched policy or no duties" ;
|
|
343
|
+
:checkC9 "SKIPPED" ;
|
|
344
|
+
:checkC10Text "SKIPPED - no matched policy" . } .
|
|
345
|
+
|
|
346
|
+
# ------------
|
|
347
|
+
# Presentation
|
|
348
|
+
# ------------
|
|
349
|
+
|
|
350
|
+
# Emit one complete output block per scenario to avoid ordering issues between
|
|
351
|
+
# separately derived log:outputString facts.
|
|
352
|
+
|
|
353
|
+
:out_000_intro log:outputString "AuroraCare — Purpose-based Medical Data Exchange\n\n" .
|
|
354
|
+
|
|
355
|
+
{ :scenario_A :decision "PERMIT" . } => {
|
|
356
|
+
:out_010_A log:outputString """=== A – Primary care visit ===
|
|
357
|
+
Clinician in the patient's care team accessing the patient summary for primary care management.
|
|
358
|
+
|
|
359
|
+
Answer
|
|
360
|
+
PERMIT
|
|
361
|
+
|
|
362
|
+
Reason Why
|
|
363
|
+
Permitted: clinician in the patient's care team, and the primary-care policy matched.
|
|
364
|
+
|
|
365
|
+
Check
|
|
366
|
+
C1 SKIPPED - not a prohibited purpose
|
|
367
|
+
C2 OK - clinician
|
|
368
|
+
C3 OK - care-team linked
|
|
369
|
+
C4 SKIPPED
|
|
370
|
+
C5 OK - operator=isAnyOf, allowed=["https://example.org/health#PATIENT_SUMMARY","https://example.org/health#LAB_RESULTS"], requested=["https://example.org/health#PATIENT_SUMMARY"]
|
|
371
|
+
C6 SKIPPED - no prohibition matched
|
|
372
|
+
C7 OK - trace shows matching permission
|
|
373
|
+
C8 SKIPPED - no matched policy or no duties
|
|
374
|
+
C9 SKIPPED - policy has no environment constraint
|
|
375
|
+
C10 INFO - matched policy: urn:policy:primary-care-001
|
|
376
|
+
|
|
377
|
+
""" .
|
|
378
|
+
} .
|
|
379
|
+
|
|
380
|
+
{ :scenario_B :decision "PERMIT" . } => {
|
|
381
|
+
:out_020_B log:outputString """=== B – Quality improvement (in scope) ===
|
|
382
|
+
QI analyst using lab results + summary in a secure environment.
|
|
383
|
+
|
|
384
|
+
Answer
|
|
385
|
+
PERMIT
|
|
386
|
+
|
|
387
|
+
Reason Why
|
|
388
|
+
Permitted: ODRL/DPV policy matched for secondary use.
|
|
389
|
+
|
|
390
|
+
Check
|
|
391
|
+
C1 SKIPPED - not a prohibited purpose
|
|
392
|
+
C2 SKIPPED
|
|
393
|
+
C3 SKIPPED
|
|
394
|
+
C4 OK - opt-in present and policy matched
|
|
395
|
+
C5 OK - operator=isAllOf, allowed=["https://example.org/health#LAB_RESULTS","https://example.org/health#PATIENT_SUMMARY"], requested=["https://example.org/health#LAB_RESULTS","https://example.org/health#PATIENT_SUMMARY"]
|
|
396
|
+
C6 SKIPPED - no prohibition matched
|
|
397
|
+
C7 OK - trace shows matching permission
|
|
398
|
+
C8 INFO - duties attached: duty:https://w3id.org/dpv/legal/eu/ehds#requireConsent, duty:https://w3id.org/dpv/legal/eu/ehds#noExfiltration
|
|
399
|
+
C9 OK - operator=eq, allowed="secure_env", requested="secure_env"
|
|
400
|
+
C10 INFO - matched policy: urn:policy:qi-2025-aurora
|
|
401
|
+
|
|
402
|
+
""" .
|
|
403
|
+
} .
|
|
404
|
+
|
|
405
|
+
{ :scenario_C :decision "DENY" . } => {
|
|
406
|
+
:out_030_C log:outputString """=== C – Quality improvement (out of scope) ===
|
|
407
|
+
QI analyst with only lab results; policy expects labs + summary.
|
|
408
|
+
|
|
409
|
+
Answer
|
|
410
|
+
DENY
|
|
411
|
+
|
|
412
|
+
Reason Why
|
|
413
|
+
Denied: no policy matched (purpose, environment, TOMs, or categories out of scope).
|
|
414
|
+
|
|
415
|
+
Check
|
|
416
|
+
C1 SKIPPED - not a prohibited purpose
|
|
417
|
+
C2 SKIPPED
|
|
418
|
+
C3 SKIPPED
|
|
419
|
+
C4 OK - denied because opt-in missing or no policy match
|
|
420
|
+
C5 SKIPPED
|
|
421
|
+
C6 SKIPPED - no prohibition matched
|
|
422
|
+
C7 SKIPPED
|
|
423
|
+
C8 SKIPPED - no matched policy or no duties
|
|
424
|
+
C9 SKIPPED
|
|
425
|
+
C10 SKIPPED - no matched policy
|
|
426
|
+
|
|
427
|
+
""" .
|
|
428
|
+
} .
|
|
429
|
+
|
|
430
|
+
{ :scenario_D :decision "DENY" . } => {
|
|
431
|
+
:out_040_D log:outputString """=== D – Insurance management ===
|
|
432
|
+
Insurance bot attempting to use health data for insurance management (prohibited purpose).
|
|
433
|
+
|
|
434
|
+
Answer
|
|
435
|
+
DENY
|
|
436
|
+
|
|
437
|
+
Reason Why
|
|
438
|
+
Denied: the requested purpose (insurance management) is prohibited by policy.
|
|
439
|
+
|
|
440
|
+
Check
|
|
441
|
+
C1 OK - denied prohibited purpose
|
|
442
|
+
C2 SKIPPED
|
|
443
|
+
C3 SKIPPED
|
|
444
|
+
C4 SKIPPED
|
|
445
|
+
C5 SKIPPED
|
|
446
|
+
C6 OK - denied due to prohibition
|
|
447
|
+
C7 SKIPPED
|
|
448
|
+
C8 SKIPPED - no matched policy or no duties
|
|
449
|
+
C9 SKIPPED
|
|
450
|
+
C10 SKIPPED - no matched policy
|
|
451
|
+
|
|
452
|
+
""" .
|
|
453
|
+
} .
|
|
454
|
+
|
|
455
|
+
{ :scenario_E :decision "PERMIT" . } => {
|
|
456
|
+
:out_050_E log:outputString """=== E – GP checks labs ===
|
|
457
|
+
GP for the same patient checking lab results via the API gateway.
|
|
458
|
+
|
|
459
|
+
Answer
|
|
460
|
+
PERMIT
|
|
461
|
+
|
|
462
|
+
Reason Why
|
|
463
|
+
Permitted: clinician in the patient's care team, and the primary-care policy matched.
|
|
464
|
+
|
|
465
|
+
Check
|
|
466
|
+
C1 SKIPPED - not a prohibited purpose
|
|
467
|
+
C2 OK - clinician
|
|
468
|
+
C3 OK - care-team linked
|
|
469
|
+
C4 SKIPPED
|
|
470
|
+
C5 OK - operator=isAnyOf, allowed=["https://example.org/health#PATIENT_SUMMARY","https://example.org/health#LAB_RESULTS"], requested=["https://example.org/health#LAB_RESULTS"]
|
|
471
|
+
C6 SKIPPED - no prohibition matched
|
|
472
|
+
C7 OK - trace shows matching permission
|
|
473
|
+
C8 SKIPPED - no matched policy or no duties
|
|
474
|
+
C9 SKIPPED - policy has no environment constraint
|
|
475
|
+
C10 INFO - matched policy: urn:policy:primary-care-001
|
|
476
|
+
|
|
477
|
+
""" .
|
|
478
|
+
} .
|
|
479
|
+
|
|
480
|
+
{ :scenario_F :decision "PERMIT" . } => {
|
|
481
|
+
:out_060_F log:outputString """=== F – Research on anonymised dataset ===
|
|
482
|
+
Researcher using anonymised labs + summary in a secure environment, with opt-in.
|
|
483
|
+
|
|
484
|
+
Answer
|
|
485
|
+
PERMIT
|
|
486
|
+
|
|
487
|
+
Reason Why
|
|
488
|
+
Permitted: subject opted in and an ODRL/DPV policy matched (anonymised dataset in secure environment).
|
|
489
|
+
|
|
490
|
+
Check
|
|
491
|
+
C1 SKIPPED - not a prohibited purpose
|
|
492
|
+
C2 SKIPPED
|
|
493
|
+
C3 SKIPPED
|
|
494
|
+
C4 OK - opt-in present and policy matched
|
|
495
|
+
C5 OK - operator=isAnyOf, allowed=["https://example.org/health#LAB_RESULTS","https://example.org/health#PATIENT_SUMMARY","https://example.org/health#IMAGING_REPORT"], requested=["https://example.org/health#PATIENT_SUMMARY","https://example.org/health#LAB_RESULTS"]
|
|
496
|
+
C6 SKIPPED - no prohibition matched
|
|
497
|
+
C7 OK - trace shows matching permission
|
|
498
|
+
C8 INFO - duties attached: duty:https://w3id.org/dpv/legal/eu/ehds#annualOutcomeReport, duty:https://w3id.org/dpv/legal/eu/ehds#noReidentification, duty:https://w3id.org/dpv/legal/eu/ehds#noExfiltration
|
|
499
|
+
C9 OK - operator=eq, allowed="secure_env", requested="secure_env"
|
|
500
|
+
C10 INFO - matched policy: urn:policy:research-aurora-diabetes
|
|
501
|
+
|
|
502
|
+
""" .
|
|
503
|
+
} .
|
|
504
|
+
|
|
505
|
+
{ :scenario_G :decision "DENY" . } => {
|
|
506
|
+
:out_070_G log:outputString """=== G – AI training (opt-out) ===
|
|
507
|
+
Data user wants to train AI, but the subject opted out of AI training.
|
|
508
|
+
|
|
509
|
+
Answer
|
|
510
|
+
DENY
|
|
511
|
+
|
|
512
|
+
Reason Why
|
|
513
|
+
Denied: you opted out of your data being used to train AI systems.
|
|
514
|
+
|
|
515
|
+
Check
|
|
516
|
+
C1 SKIPPED - not a prohibited purpose
|
|
517
|
+
C2 SKIPPED
|
|
518
|
+
C3 SKIPPED
|
|
519
|
+
C4 OK - denied because opt-in missing or no policy match
|
|
520
|
+
C5 SKIPPED
|
|
521
|
+
C6 SKIPPED - no prohibition matched
|
|
522
|
+
C7 SKIPPED
|
|
523
|
+
C8 SKIPPED - no matched policy or no duties
|
|
524
|
+
C9 SKIPPED
|
|
525
|
+
C10 SKIPPED - no matched policy
|
|
526
|
+
|
|
527
|
+
""" .
|
|
528
|
+
} .
|