You've already forked dokumenta-semantiska-analize
Import UAPF package
rewrite 2.0.0: real process — extract the algorithm into DMN
The 1.x package was a single ai.extract call wrapped in three BPMN
service tasks. No decision logic, no dmn cornerstone, no weights — the
risk/routing/validation algorithm lived invisibly in host code. There
was nothing for a runtime to actually execute.
2.0.0 makes it a real process:
- dmn cornerstone added with three decision tables:
* assess-personal-data-risk — PII regex signals -> risk level
* gdpr-processing-route — risk x centralisation -> CENTRAL/LOCAL,
anonymisation, redaction level
* human-validation-gate — confidence thresholds + PII re-scan
-> REJECTED/PENDING_REVIEW/APPROVED_AUTO
- BPMN expanded 3 -> 6 nodes (3 serviceTask + 3 businessRuleTask),
with horizontal DI.
- Task ids, mappings, docs, manifest (dmn:true), uapf.yaml, lifecycle
and eval-set updated; added a PII-bearing fixture.
Only the semantic extraction remains a model step. Risk classification,
GDPR routing and validation gating are now explicit ranked DMN rules —
inspectable, versioned, portable. Breaking change: structure + outputs.
This commit is contained in:
71
dmn/assess-personal-data-risk.dmn
Normal file
71
dmn/assess-personal-data-risk.dmn
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dmn:definitions xmlns:dmn="https://www.omg.org/spec/DMN/20191111/MODEL/"
|
||||
id="Definitions_AssessPersonalDataRisk"
|
||||
namespace="https://uapf.dev/processes/semantic-document-analysis">
|
||||
<dmn:decision id="assess-personal-data-risk" name="Assess personal-data risk">
|
||||
<dmn:decisionTable hitPolicy="FIRST">
|
||||
<dmn:input id="i_pk" label="Personas kods present">
|
||||
<dmn:inputExpression typeRef="boolean"><dmn:text>personasKodaPresent</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:input id="i_fin" label="Financial identifier present">
|
||||
<dmn:inputExpression typeRef="boolean"><dmn:text>financialDataPresent</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:input id="i_contact" label="Contact data present">
|
||||
<dmn:inputExpression typeRef="boolean"><dmn:text>contactDataPresent</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:input id="i_cnt" label="Distinct PII categories">
|
||||
<dmn:inputExpression typeRef="number"><dmn:text>piiCategoryCount</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:output id="o_risk" label="Personal-data risk" name="personalDataRisk" typeRef="string"/>
|
||||
<dmn:output id="o_rat" label="Rationale" name="riskRationale" typeRef="string"/>
|
||||
<dmn:rule id="R1_personas_kods">
|
||||
<dmn:inputEntry><dmn:text>true</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"HIGH"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"Personas kods (national ID) detected"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R2_financial">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>true</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"HIGH"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"Financial account identifier (IBAN) detected"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R3_multi_category">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>[2..999]</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"MEDIUM"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"Two or more distinct PII categories present"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R4_contact">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>true</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"MEDIUM"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"Contact data (email/phone) detected"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R5_single">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>1</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"LOW"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"Single PII category present"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R6_none">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"NONE"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"No personal data detected by regex scan"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
</dmn:decisionTable>
|
||||
</dmn:decision>
|
||||
</dmn:definitions>
|
||||
60
dmn/gdpr-processing-route.dmn
Normal file
60
dmn/gdpr-processing-route.dmn
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dmn:definitions xmlns:dmn="https://www.omg.org/spec/DMN/20191111/MODEL/"
|
||||
id="Definitions_GdprProcessingRoute"
|
||||
namespace="https://uapf.dev/processes/semantic-document-analysis">
|
||||
<dmn:decision id="gdpr-processing-route" name="GDPR processing route">
|
||||
<dmn:decisionTable hitPolicy="FIRST">
|
||||
<dmn:input id="i_risk" label="Personal-data risk">
|
||||
<dmn:inputExpression typeRef="string"><dmn:text>personalDataRisk</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:input id="i_central" label="Centralisation permitted">
|
||||
<dmn:inputExpression typeRef="boolean"><dmn:text>allowCentralization</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:output id="o_route" label="Processing route" name="processingRoute" typeRef="string"/>
|
||||
<dmn:output id="o_anon" label="Anonymisation required" name="anonymizationRequired" typeRef="boolean"/>
|
||||
<dmn:output id="o_redact" label="Redaction level" name="redactionLevel" typeRef="string"/>
|
||||
<dmn:rule id="R1_sensitive_local">
|
||||
<dmn:inputEntry><dmn:text>"HIGH","MEDIUM"</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>false</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"LOCAL"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"FULL"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R2_any_local">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>false</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"LOCAL"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>false</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"PARTIAL"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R3_sensitive_central">
|
||||
<dmn:inputEntry><dmn:text>"HIGH","MEDIUM"</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>true</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"CENTRAL"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"FULL"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R4_low_central">
|
||||
<dmn:inputEntry><dmn:text>"LOW"</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>true</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"CENTRAL"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>false</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"PARTIAL"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R5_none_central">
|
||||
<dmn:inputEntry><dmn:text>"NONE"</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>true</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"CENTRAL"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>false</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"NONE"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="R6_default">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"CENTRAL"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>false</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>"PARTIAL"</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
</dmn:decisionTable>
|
||||
</dmn:decision>
|
||||
</dmn:definitions>
|
||||
62
dmn/human-validation-gate.dmn
Normal file
62
dmn/human-validation-gate.dmn
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dmn:definitions xmlns:dmn="https://www.omg.org/spec/DMN/20191111/MODEL/"
|
||||
id="Definitions_HumanValidationGate"
|
||||
namespace="https://uapf.dev/processes/semantic-document-analysis">
|
||||
<dmn:decision id="human-validation-gate" name="Human-validation gate">
|
||||
<dmn:decisionTable hitPolicy="FIRST">
|
||||
<dmn:input id="i_pii" label="Output PII error count">
|
||||
<dmn:inputExpression typeRef="number"><dmn:text>outputPiiErrorCount</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:input id="i_conf" label="AI confidence score">
|
||||
<dmn:inputExpression typeRef="number"><dmn:text>aiConfidenceScore</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:input id="i_risk" label="Personal-data risk">
|
||||
<dmn:inputExpression typeRef="string"><dmn:text>personalDataRisk</dmn:text></dmn:inputExpression>
|
||||
</dmn:input>
|
||||
<dmn:output id="o_status" label="Human-validation status" name="humanValidationStatus" typeRef="string"/>
|
||||
<dmn:output id="o_review" label="Requires human review" name="requiresHumanReview" typeRef="boolean"/>
|
||||
<dmn:rule id="V1_pii_leak">
|
||||
<dmn:inputEntry><dmn:text>[1..9999]</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"REJECTED"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="V2_low_confidence">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>[0..0.3)</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"REJECTED"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="V3_mid_confidence">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>[0.3..0.7)</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"PENDING_REVIEW"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="V4_high_risk_review">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>"HIGH"</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"PENDING_REVIEW"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="V5_auto_approve">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>[0.7..1]</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"APPROVED_AUTO"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>false</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
<dmn:rule id="V6_default">
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:inputEntry><dmn:text>-</dmn:text></dmn:inputEntry>
|
||||
<dmn:outputEntry><dmn:text>"PENDING_REVIEW"</dmn:text></dmn:outputEntry>
|
||||
<dmn:outputEntry><dmn:text>true</dmn:text></dmn:outputEntry>
|
||||
</dmn:rule>
|
||||
</dmn:decisionTable>
|
||||
</dmn:decision>
|
||||
</dmn:definitions>
|
||||
Reference in New Issue
Block a user