solidprivacy commited on
Commit
b092a49
·
1 Parent(s): dea3bdc

Remove temporary Scrub Key binding fixture validator

Browse files
.github/workflows/mvp-scrub-key-binding-app-fixture-validation.yml DELETED
@@ -1,199 +0,0 @@
1
- name: MVP Scrub Key binding app fixture validation
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- paths:
8
- - "operator_triggers/mvp_scrub_key_binding_app_fixture_validation.txt"
9
-
10
- permissions:
11
- contents: write
12
-
13
- jobs:
14
- validate-fixtures:
15
- runs-on: ubuntu-latest
16
- env:
17
- PYTHONPATH: ${{ github.workspace }}
18
- steps:
19
- - name: Check out deployed main
20
- uses: actions/checkout@v4
21
- with:
22
- ref: main
23
- fetch-depth: 0
24
- - name: Set up Python
25
- uses: actions/setup-python@v5
26
- with:
27
- python-version: '3.10'
28
- - name: Install fixture dependencies
29
- run: |
30
- python -m pip install --upgrade pip
31
- python -m pip install python-docx reportlab pymupdf
32
- - name: Validate synthetic app-verification fixtures against product helpers
33
- shell: bash
34
- run: |
35
- set -euo pipefail
36
- mkdir -p output/validation
37
- python - <<'PY'
38
- import json
39
- from copy import deepcopy
40
- from io import BytesIO
41
- from pathlib import Path
42
-
43
- from docx import Document
44
-
45
- from scrub_key import build_scrub_key, scrub_key_to_json
46
- from scrub_key_binding import validate_bound_scrub_key
47
- from scrub_key_bound_export import build_bound_scrub_key
48
- from scrub_key_document_reinsert import reinsert_docx_bytes
49
- from scrub_key_import import build_scrub_key_import_result
50
- from scrub_key_reinsert import reinsert_from_scrub_key
51
-
52
- binding_a = "BK7M4Q2XR5TD3W6YZ"
53
- binding_b = "BABCDEFGHIJKLMNOP"
54
- expected_digest = "c92e42f38fd523920e982ddaa4c01d7d52fe79b0389366f416ec1d576fc05cdc"
55
-
56
- def placeholder(label, binding, index=1):
57
- return f"[{label}_{binding}_{index:02d}]"
58
-
59
- def rows(binding):
60
- data = [
61
- ("PERSOON", "Mila Voorbeeld", "PERSON", "Persoon"),
62
- ("DOSSIERNUMMER", "SYN-2026-0042", "CASE_NUMBER", "Dossiernummer"),
63
- ("ORGANISATIE", "Stichting Proefdocument", "ORGANIZATION", "Organisatie"),
64
- ("EMAILADRES", "verificatie@example.com", "EMAIL_ADDRESS", "E-mailadres"),
65
- ]
66
- return [
67
- {
68
- "original_value": original,
69
- "placeholder": placeholder(label, binding),
70
- "entity_type": entity_type,
71
- "type_label": type_label,
72
- "source": "synthetic_app_verification",
73
- "review_status": "synthetic_verified",
74
- "include": True,
75
- "timestamp": f"2026-07-28T01:0{index}:00+02:00",
76
- "document_label": "Synthetische gebonden verificatie",
77
- }
78
- for index, (label, original, entity_type, type_label) in enumerate(data)
79
- ]
80
-
81
- correct = build_bound_scrub_key(
82
- rows(binding_a),
83
- document_binding_id=binding_a,
84
- document_label="Synthetische gebonden verificatie",
85
- )
86
- wrong = build_bound_scrub_key(
87
- rows(binding_b),
88
- document_binding_id=binding_b,
89
- document_label="Synthetische verkeerde sleutel",
90
- )
91
- tampered = deepcopy(correct)
92
- tampered["mapping_digest"] = "0" * 64
93
-
94
- legacy_rows = [
95
- {
96
- "original_value": "Legacy Persoon",
97
- "placeholder": "[PERSOON_01]",
98
- "entity_type": "PERSON",
99
- "type_label": "Persoon",
100
- "source": "synthetic_app_verification",
101
- "review_status": "synthetic_verified",
102
- "include": True,
103
- "timestamp": "2026-07-28T01:10:00+02:00",
104
- "document_label": "Synthetische legacyverificatie",
105
- },
106
- {
107
- "original_value": "LEG-2026-0007",
108
- "placeholder": "[DOSSIERNUMMER_01]",
109
- "entity_type": "CASE_NUMBER",
110
- "type_label": "Dossiernummer",
111
- "source": "synthetic_app_verification",
112
- "review_status": "synthetic_verified",
113
- "include": True,
114
- "timestamp": "2026-07-28T01:11:00+02:00",
115
- "document_label": "Synthetische legacyverificatie",
116
- },
117
- ]
118
- legacy = build_scrub_key(
119
- legacy_rows,
120
- document_label="Synthetische legacyverificatie",
121
- )
122
-
123
- assert correct["mapping_digest"] == expected_digest
124
- assert validate_bound_scrub_key(correct)["ok"] is True
125
- assert validate_bound_scrub_key(wrong)["ok"] is True
126
- assert validate_bound_scrub_key(tampered)["ok"] is False
127
- assert build_scrub_key_import_result(scrub_key_to_json(correct))["ok"] is True
128
- assert build_scrub_key_import_result(scrub_key_to_json(tampered))["ok"] is False
129
- assert build_scrub_key_import_result(scrub_key_to_json(legacy))["ok"] is True
130
-
131
- bound_text = (
132
- f"Cliënt {placeholder('PERSOON', binding_a)}; "
133
- f"dossier {placeholder('DOSSIERNUMMER', binding_a)}."
134
- )
135
- match = reinsert_from_scrub_key(bound_text, correct)
136
- mismatch = reinsert_from_scrub_key(bound_text, wrong)
137
- legacy_result = reinsert_from_scrub_key(
138
- "Cliënt [PERSOON_01]; dossier [DOSSIERNUMMER_01].",
139
- legacy,
140
- )
141
- assert match["binding_status"] == "bound_match"
142
- assert match["replacement_count"] == 2
143
- assert mismatch["binding_status"] == "binding_mismatch"
144
- assert mismatch["replacement_count"] == 0
145
- assert mismatch["text"] == bound_text
146
- assert legacy_result["binding_status"] == "legacy_unbound"
147
- assert legacy_result["replacement_count"] == 2
148
-
149
- document = Document()
150
- document.add_paragraph(f"Cliënt: {placeholder('PERSOON', binding_a)}")
151
- table = document.add_table(rows=1, cols=1)
152
- table.cell(0, 0).text = placeholder("DOSSIERNUMMER", binding_a)
153
- section = document.sections[0]
154
- section.header.paragraphs[0].text = placeholder("ORGANISATIE", binding_a)
155
- section.footer.paragraphs[0].text = placeholder("EMAILADRES", binding_a)
156
- stream = BytesIO()
157
- document.save(stream)
158
- source_docx = stream.getvalue()
159
- docx_match = reinsert_docx_bytes(source_docx, correct)
160
- docx_mismatch = reinsert_docx_bytes(source_docx, wrong)
161
- assert docx_match["binding_status"] == "bound_match"
162
- assert docx_match["replacement_count"] == 4
163
- assert docx_mismatch["binding_status"] == "binding_mismatch"
164
- assert docx_mismatch["replacement_count"] == 0
165
- assert docx_mismatch["docx_bytes"] == source_docx
166
-
167
- report = {
168
- "workpackage": "SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY",
169
- "status": "synthetic_fixture_validation_passed",
170
- "deployed_product_commit": "4a21c2d93acf3c166534a4a0501e602954c5606d",
171
- "binding_a": binding_a,
172
- "binding_b": binding_b,
173
- "correct_mapping_digest": correct["mapping_digest"],
174
- "correct_key_valid": True,
175
- "wrong_key_structurally_valid": True,
176
- "wrong_key_document_match_blocked": True,
177
- "tampered_digest_rejected": True,
178
- "legacy_key_import_valid": True,
179
- "legacy_reinsert_unverified_warning_status": True,
180
- "docx_correct_match_replacements": docx_match["replacement_count"],
181
- "docx_mismatch_original_bytes_preserved": True,
182
- "synthetic_data_only": True,
183
- "app_verification_required": True,
184
- }
185
- Path("output/validation/mvp_scrub_key_binding_app_fixture_validation.json").write_text(
186
- json.dumps(report, ensure_ascii=False, indent=2) + "\n",
187
- encoding="utf-8",
188
- )
189
- print(json.dumps(report, ensure_ascii=False, indent=2))
190
- PY
191
- - name: Commit fixture validation evidence
192
- shell: bash
193
- run: |
194
- set -euo pipefail
195
- git config user.name 'solidprivacy-fixture-validator'
196
- git config user.email 'actions@users.noreply.github.com'
197
- git add output/validation/mvp_scrub_key_binding_app_fixture_validation.json
198
- git commit -m 'Record Scrub Key binding app fixture validation'
199
- git push origin HEAD:main