File size: 10,420 Bytes
6061197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# REINSERT_UI_SPEC — v13.3 Deterministic local reinsert UI

Status: planning/specification only.  
Workpackage: WP8 — v13.3 Deterministic reinsert UI planning.  
Repository: `solidprivacy-nl/scrub`.

This document specifies the future UI integration for deterministic local reinsert. It does **not** implement UI behavior.

---

## 1. Purpose

The deterministic reinsert UI should let a user locally restore original values into scrubbed text by using a previously validated Scrub Key.

Target workflow:

```text
Scrub → Review → Scrub Key → AI → Reinsert → Export → Audit
```

For this specific UI step, the product should stay local and deterministic:

```text
Scrubbed or AI-generated text + validated Scrub Key → restored text + audit summary
```

The reinsert step must not call AI and must not send text or keys to a cloud service.

---

## 2. Existing helpers to use

The future UI implementation should use the verified helper:

```python
from scrub_key_reinsert import reinsert_from_scrub_key
```

Relevant helper API:

```python
reinsert_from_scrub_key(text, scrub_key) -> dict
```

The helper already returns:

- `text`;
- `replacement_count`;
- `item_count`;
- `active_item_count`;
- `excluded_item_count`;
- `placeholders_not_found`;
- `unknown_placeholders`;
- `duplicate_placeholders`;
- `validation_issues`;
- `reinserted`;
- `local_only`;
- `ai_processing`;
- `cloud_processing`.

The future UI should not duplicate the replacement logic. It should call the helper and render the result.

---

## 3. Placement in the current app flow

The reinsert UI should appear after the existing Scrub Key import/reload section, near the current download/export area.

Recommended placement order in the future UI:

```text
4. Download opgeschoonde bestanden
Eindcontrole vóór download
Extra exportcontrole
Scrub Key (JSON)
Scrub Key laden
Originele waarden terugzetten
Existing TXT/CSV/DOCX/PDF downloads
```

Rationale:

- The user first creates or loads a Scrub Key.
- The user then pastes scrubbed or AI-generated text.
- The user explicitly chooses to restore original values locally.
- Existing downloads remain available and unchanged.

The UI must not silently reinsert values when a key is loaded. Reinsertion must require a separate visible user action.

---

## 4. Suggested UI labels

Section label:

```text
Originele waarden terugzetten
```

Input label:

```text
Plak hier de tekst waarin u originele waarden lokaal wilt terugzetten
```

Action button:

```text
Zet originele waarden lokaal terug
```

Output label:

```text
Herstelde tekst
```

Download label:

```text
Download herstelde tekst (.txt)
```

Optional audit label:

```text
Controleverslag terugzetten
```

---

## 5. User interaction flow

The future UI should follow this sequence:

1. User scrubs a document and reviews replacements.
2. User exports or loads a valid Scrub Key.
3. User opens the section `Originele waarden terugzetten`.
4. User pastes scrubbed or AI-generated text into the text area.
5. User clicks `Zet originele waarden lokaal terug`.
6. UI calls `reinsert_from_scrub_key(pasted_text, scrub_key)`.
7. UI displays warnings, restored text and audit summary.
8. User may download restored text as `.txt`.

The UI should only use a Scrub Key that is already validated by the current Scrub Key export/import flow or by the helper validation in `reinsert_from_scrub_key(...)`.

---

## 6. Required state handling

Future UI implementation should define one clear source for the active Scrub Key.

Preferred order:

1. Use a successfully imported Scrub Key from the existing import/reload flow.
2. If no imported key exists, use the Scrub Key built from the current reviewed replacement table.
3. If neither exists or validation fails, show a validation warning and do not reinsert.

Possible Streamlit state keys for future implementation:

```text
st.session_state["active_scrub_key"]
st.session_state["scrub_key_import_rows"]
st.session_state["reinsert_input_text"]
st.session_state["reinsert_result"]
```

The exact state key names may differ, but the future implementation must keep the state explicit and auditable.

The UI must not overwrite the replacement table, Scrub Key export, or imported mapping rows while reinserting text.

---

## 7. Helper call contract

Future UI implementation should call:

```python
result = reinsert_from_scrub_key(reinsert_input_text, active_scrub_key)
```

The UI should then read:

```python
result["text"]
result["replacement_count"]
result["item_count"]
result["active_item_count"]
result["excluded_item_count"]
result["placeholders_not_found"]
result["unknown_placeholders"]
result["duplicate_placeholders"]
result["validation_issues"]
result["reinserted"]
result["local_only"]
result["ai_processing"]
result["cloud_processing"]
```

If `validation_issues` is not empty, the UI must show those issues and must not present the result as successfully restored.

If `replacement_count` is `0`, the UI should explain that no placeholders were replaced.

---

## 8. Output behavior

The future UI should display:

- restored text in a read-only or editable text area labelled `Herstelde tekst`;
- a `.txt` download button labelled `Download herstelde tekst (.txt)`;
- audit summary in a compact visible block;
- warnings for unknown, duplicate or missing placeholders where applicable.

The future UI should not automatically create DOCX or PDF restored files in the first implementation. Start with text output only.

---

## 9. Required audit summary fields

The future UI should show at least:

- mapping item count;
- active item count;
- excluded item count;
- replacement count;
- placeholders not found;
- unknown placeholders;
- duplicate placeholders;
- validation issues;
- local-only status;
- no-AI status;
- no-cloud status.

Suggested Dutch rendering:

```text
Mappingregels totaal: <item_count>
Actieve mappingregels: <active_item_count>
Uitgesloten mappingregels: <excluded_item_count>
Aantal teruggezette waarden: <replacement_count>
Niet gevonden placeholders: <placeholders_not_found>
Onbekende placeholders in tekst: <unknown_placeholders>
Dubbele placeholders in sleutel: <duplicate_placeholders>
Validatieproblemen: <validation_issues>
Lokaal uitgevoerd: ja
AI-verwerking: nee
Cloudverwerking: nee
```

---

## 10. Required warnings

The future UI must display this warning near the action button and/or output:

```text
Let op: terugzetten herstelt originele gevoelige waarden. De uitvoer kan weer persoonsgegevens of vertrouwelijke informatie bevatten. Controleer het resultaat zorgvuldig voordat u het deelt.
```

The future UI must also clearly communicate:

- reinsertion restores original sensitive values;
- restored text may again contain personal or confidential information;
- restored output must be manually reviewed before sharing;
- a Scrub Key is reversible/pseudonymization, not full anonymization;
- the key must remain local and protected;
- no AI/cloud processing is involved in this reinsert step.

Suggested additional caption:

```text
Deze stap wordt lokaal uitgevoerd met uw Scrub Key. Er wordt geen AI- of cloudverwerking gebruikt voor het terugzetten.
```

---

## 11. What must not happen automatically

The future UI must not:

- reinsert values automatically when a Scrub Key is loaded;
- silently replace the current reviewed replacement table;
- silently overwrite scrubbed output;
- automatically rehydrate DOCX, PDF or original documents;
- call AI services;
- send Scrub Key contents to any external service;
- change existing TXT/CSV/DOCX/PDF export behavior;
- change existing Scrub Key JSON export behavior;
- change existing Scrub Key import/reload behavior;
- store Scrub Keys server-side;
- store secrets, tokens or real personal data.

---

## 12. Required tests for future UI implementation

The future UI implementation workpackage should add tests, likely in a new file such as:

```text
tests/test_scrub_key_reinsert_ui_patch.py
```

Required test coverage:

1. The Streamlit patch imports `reinsert_from_scrub_key`.
2. The UI contains `Originele waarden terugzetten`.
3. The UI contains the paste input label.
4. The UI contains the button `Zet originele waarden lokaal terug`.
5. The UI contains `Herstelde tekst`.
6. The UI contains `Download herstelde tekst (.txt)`.
7. The required warning about restoring sensitive values is present.
8. The pseudonymization/reversibility warning remains present.
9. The audit summary fields are represented in the UI patch.
10. The helper is called only after a visible button action.
11. The UI does not add AI calls or cloud processing.
12. The UI does not call `st.stop()` or block existing downloads.
13. Existing `Download Scrub Key (.json)` remains present.
14. Existing TXT/CSV/DOCX/PDF download markers are not removed.
15. The import/reload UI remains present.
16. No automatic document rehydration wording or behavior is introduced.

Suggested targeted validation after future implementation:

```bash
PYTHONPATH=. pytest -q tests/test_scrub_key_reinsert.py
PYTHONPATH=. pytest -q tests/test_scrub_key_reinsert_ui_patch.py
PYTHONPATH=. pytest -q tests/test_scrub_key_import_ui_patch.py
PYTHONPATH=. pytest -q tests/test_scrub_key_ui_patch.py
```

If feasible:

```bash
PYTHONPATH=. pytest -q
```

---

## 13. Non-goals for the next UI implementation

The next implementation should not include:

- AI-output-specific parsing beyond accepting pasted text;
- calls to AI providers;
- cloud processing;
- DOCX/PDF rehydration;
- replacing uploaded source documents;
- metadata cleaning;
- batch processing;
- server-side key storage;
- durable project vault storage;
- automatic sharing/export of restored text.

Those should remain separate future workpackages.

---

## 14. Suggested future workpackage sequence

Recommended next workpackage:

```text
WP8B — v13.3 Deterministic reinsert UI implementation
```

Scope for WP8B:

- update `fix_streamlit_nested_expanders.py` only;
- add `tests/test_scrub_key_reinsert_ui_patch.py`;
- keep UI integration sequential;
- do not add AI/cloud behavior;
- do not change existing export/download semantics;
- ask for app verification after sync because UI behavior changes.

Later workpackage, only after WP8B is verified:

```text
WP9 — AI-output reinsert workflow review
```

That later workpackage should explicitly review whether AI-output-specific behavior is needed and how to keep it safe.