solidprivacy-binding-triage-worker commited on
Commit
c8d0ebd
·
1 Parent(s): 58b60eb

Finalize Scrub Key document binding gap triage

Browse files
CHANGELOG.md CHANGED
@@ -1,3 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ## 2026-07-27 18:55 Europe/Amsterdam — SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION
2
 
3
  Status: completed; deterministic validation passed; PR verification pending.
 
1
+ ## 2026-07-27 19:18 Europe/Amsterdam — SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE
2
+
3
+ Status: completed; targeted validation passed; PR verification pending.
4
+
5
+ Purpose:
6
+ - Determine the smallest safe cross-format mitigation for the critical document/Scrub-Key binding gap before changing schema, placeholders, export or reinsert behavior.
7
+
8
+ Files added:
9
+ - `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`
10
+ - `output/validation/mvp_scrub_key_document_binding_gap_triage.json`
11
+ - `output/validation/mvp_scrub_key_document_binding_gap_triage_validation.json`
12
+ - `tests/test_mvp_scrub_key_document_binding_gap_triage.py`
13
+ - `tests/test_mvp_scrub_key_document_binding_gap_triage_validation.py`
14
+ - `handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md`
15
+ - `workpackage_claims/scrub_wp_mvp_scrub_key_document_binding_gap_triage.md`
16
+
17
+ Files changed:
18
+ - `WORKPACKAGES.md`
19
+ - `CHANGELOG.md`
20
+ - `ROADMAP.md`
21
+ - `MVP_PHASE6_EXECUTION_PLAN.md`
22
+ - `RISK_REGISTER.md`
23
+ - `DECISION_LOG.md`
24
+
25
+ Triage result:
26
+ - Primary MVP threat: accidental wrong-document/key pairing.
27
+ - Secondary MVP threat: accidental key corruption.
28
+ - Deferred threat: malicious tampering requiring protected signing-key infrastructure.
29
+ - Recommended primary control: document-specific non-sensitive binding ID in all placeholders and the key.
30
+ - Recommended complementary control: canonical SHA-256 mapping digest.
31
+ - Explicitly not sufficient: document labels, filenames, content hashes, placeholder-list hashes or metadata-only binding.
32
+ - Legacy v1.0 keys require explicit unbound status and warning; they must not be silently treated as bound.
33
+ - Bound-key mismatch, mixed IDs and digest mismatch must fail closed with zero replacements.
34
+ - Human review remains required; production readiness remains false.
35
+
36
+ Intentionally not changed:
37
+ - product code or UI;
38
+ - Scrub Key schema/version or serialization;
39
+ - placeholder generation or grammar;
40
+ - export/download or reinsert semantics;
41
+ - document processing;
42
+ - cloud, AI, OCR or secret storage.
43
+
44
+ Next recommended step:
45
+ - Start `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS` before implementation.
46
+
47
+ ---
48
+
49
  ## 2026-07-27 18:55 Europe/Amsterdam — SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION
50
 
51
  Status: completed; deterministic validation passed; PR verification pending.
DECISION_LOG.md CHANGED
@@ -4,6 +4,49 @@ This file records accepted strategic, product and architecture decisions.
4
 
5
  ---
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  ## 2026-07-27 — D032 — Roundtrip evidence requires document/key-binding triage before implementation
8
 
9
  Status: accepted evidence-routing decision
 
4
 
5
  ---
6
 
7
+ ## 2026-07-27 — D033 — Bind new Scrub Keys through document-specific placeholder namespaces
8
+
9
+ Status: accepted planning/architecture decision; implementation requires green contract tests
10
+
11
+ Decision:
12
+
13
+ ```text
14
+ For new bound Scrub Keys, carry one locally generated, non-sensitive document binding ID in every automatic and manual placeholder and in the corresponding Scrub Key. Complement this with a canonical SHA-256 mapping digest for accidental key-corruption detection. Reinsert must fail closed before any replacement when a bound key mismatches the document, the document contains mixed binding IDs, or the mapping digest is invalid.
15
+ ```
16
+
17
+ Reason:
18
+
19
+ - Generic placeholder namespaces allow a wrong valid key to restore wrong originals without an audit mismatch.
20
+ - A binding token inside placeholders survives pasted-text, TXT, DOCX and PDF-text roundtrips when the placeholders themselves survive.
21
+ - Labels, filenames, metadata, content hashes and placeholder-list hashes are not reliable cross-format AI-roundtrip bindings.
22
+ - A digest detects accidental edits but is not authenticity; malicious tampering requires later protected signing-key infrastructure.
23
+
24
+ Compatibility and UX boundaries:
25
+
26
+ - Introduce an explicit new bound-key contract; do not silently reinterpret legacy v1.0 keys.
27
+ - Legacy unbound keys may remain dual-readable with a visible unbound warning.
28
+ - Preserve the document-first three-step reinsert flow and the final confidential-download acknowledgement.
29
+ - Add no repeated confirmation buttons or checkboxes.
30
+ - Preserve unknown, duplicate and missing-placeholder audit reporting.
31
+ - No cloud processing, server secret, OCR or restored-PDF behavior.
32
+ - Human review remains mandatory; no production-readiness claim.
33
+
34
+ Approved sequence:
35
+
36
+ 1. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`
37
+ 2. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_MODEL_IMPLEMENTATION`
38
+ 3. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_EXPORT_INTEGRATION`
39
+ 4. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_REINSERT_INTEGRATION`
40
+ 5. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY`
41
+
42
+ Evidence:
43
+
44
+ - `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`
45
+ - `output/validation/mvp_scrub_key_document_binding_gap_triage.json`
46
+ - `output/validation/mvp_scrub_key_roundtrip_validation_report.json`
47
+
48
+ ---
49
+
50
  ## 2026-07-27 — D032 — Roundtrip evidence requires document/key-binding triage before implementation
51
 
52
  Status: accepted evidence-routing decision
MVP_PHASE6_EXECUTION_PLAN.md CHANGED
@@ -32,6 +32,8 @@ Test correct, missing, duplicate, altered, translated, merged and malformed plac
32
 
33
  Classify the critical finding that a structurally valid wrong key can reuse the same placeholder namespace and restore incorrect values without a detectable mismatch. Decide whether document/key binding requires a key identifier, content fingerprint, manifest binding or another explicit contract. Do not change schema, export or reinsert semantics in the triage package.
34
 
 
 
35
  ### 5. SCRUB-WP_MVP_AUDIT_RESIDUAL_RISK_EVIDENCE
36
 
37
  Produce a consistent machine-readable and human-readable evidence summary covering automatic findings, manual additions, unresolved candidates, document-hygiene warnings, exports, reinsert completeness and known limitations.
 
32
 
33
  Classify the critical finding that a structurally valid wrong key can reuse the same placeholder namespace and restore incorrect values without a detectable mismatch. Decide whether document/key binding requires a key identifier, content fingerprint, manifest binding or another explicit contract. Do not change schema, export or reinsert semantics in the triage package.
34
 
35
+ Triage result: use a non-sensitive document binding ID in every placeholder and the corresponding key, complemented by a canonical mapping digest. Implement sequentially through contract tests, pure model helpers, export integration, reinsert integration and live verification. Legacy unbound keys remain explicit; malicious tampering remains outside the MVP without protected signing-key management.
36
+
37
  ### 5. SCRUB-WP_MVP_AUDIT_RESIDUAL_RISK_EVIDENCE
38
 
39
  Produce a consistent machine-readable and human-readable evidence summary covering automatic findings, manual additions, unresolved candidates, document-hygiene warnings, exports, reinsert completeness and known limitations.
RISK_REGISTER.md CHANGED
@@ -43,7 +43,7 @@ The Scrub Key is shared, leaked, retained too long, tampered with or mishandled,
43
 
44
  Current mitigations include warnings and acknowledgements. Export/download UX grouping is implemented directly in `presidio_streamlit.py` so the key file is visually separated from normal document exports and shown with a specific warning. Live app verification confirmed the grouped export UI. Reinsert now keeps the key-sensitivity warning visible, automatically applies the existing structural validation to a supplied key, and preserves one explicit confidentiality acknowledgement at the restored-output download boundary. Redundant pre-processing acknowledgements are removed because they obscured workflow state without adding key validation.
45
 
46
- The manual missed-value entry flows through the existing replacement table and existing Scrub Key/export paths without changing key semantics. No key storage, schema or lifecycle behavior is added by the automatic reinsert flow. The Phase 6 adversarial roundtrip matrix exposes a critical unresolved gap: a structurally valid wrong or tampered key that reuses the same placeholder namespace can restore incorrect original values without a detectable mismatch. This is routed to `SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE`; no schema or export change is authorized by the validation package.
47
 
48
  ---
49
 
@@ -58,7 +58,7 @@ Risk:
58
  An AI system rewrites, translates, merges or deletes placeholders, causing deterministic reinsert to fail or restore incompletely.
59
  ```
60
 
61
- Current mitigations include placeholder robustness helper/test work and reinsert audit reporting. The Phase 6 roundtrip matrix validates translated, merged, unknown, repeated and malformed mutations. Unknown grammar-valid placeholders are visible, while malformed tokens outside the strict grammar are signalled indirectly through expected placeholders not found. This diagnostic limitation is included in the document-binding gap triage.
62
 
63
  ---
64
 
 
43
 
44
  Current mitigations include warnings and acknowledgements. Export/download UX grouping is implemented directly in `presidio_streamlit.py` so the key file is visually separated from normal document exports and shown with a specific warning. Live app verification confirmed the grouped export UI. Reinsert now keeps the key-sensitivity warning visible, automatically applies the existing structural validation to a supplied key, and preserves one explicit confidentiality acknowledgement at the restored-output download boundary. Redundant pre-processing acknowledgements are removed because they obscured workflow state without adding key validation.
45
 
46
+ The manual missed-value entry flows through the existing replacement table and existing Scrub Key/export paths without changing key semantics. No key storage, schema or lifecycle behavior is added by the automatic reinsert flow. The Phase 6 adversarial roundtrip matrix exposes a critical unresolved gap: a structurally valid wrong or tampered key that reuses the same placeholder namespace can restore incorrect original values without a detectable mismatch. This is routed to `SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE`; no schema or export change is authorized by the validation package. Triage recommends a non-sensitive document binding ID inside every automatic/manual placeholder and the corresponding key, plus a canonical mapping digest for accidental corruption. Contract tests must define legacy v1.0 behavior and fail-closed mismatch rules before implementation. Signatures/HMAC remain deferred until protected local signing-key management exists.
47
 
48
  ---
49
 
 
58
  An AI system rewrites, translates, merges or deletes placeholders, causing deterministic reinsert to fail or restore incompletely.
59
  ```
60
 
61
+ Current mitigations include placeholder robustness helper/test work and reinsert audit reporting. The Phase 6 roundtrip matrix validates translated, merged, unknown, repeated and malformed mutations. Unknown grammar-valid placeholders are visible, while malformed tokens outside the strict grammar are signalled indirectly through expected placeholders not found. This diagnostic limitation is included in the document-binding gap triage. It is not part of the critical binding implementation line; an optional later diagnostic-hardening package may report malformed near-placeholders directly without guessing or repairing values.
62
 
63
  ---
64
 
ROADMAP.md CHANGED
@@ -11,7 +11,7 @@ Use it together with:
11
  - `DECISION_LOG.md` for accepted strategic and architecture decisions;
12
  - `PROJECT_PROMPT.md` for worker rules and project governance.
13
 
14
- Last roadmap strategy update: 2026-07-27 — Scrub Key roundtrip validation is complete and exposed a critical document/key-binding gap; evidence triage is now active before any schema or export change.
15
 
16
  ---
17
 
@@ -111,6 +111,7 @@ SCRUB-WP_EXECUTION_INTERFACE_SIMPLIFICATION_* through SCRUB-WP_MANUAL_CORRECTION
111
  SCRUB-WP_MVP_DOCUMENT_HYGIENE_FIDELITY_HARDENING — merged, synchronized and live-app verified for DOCX body, table, header and footer restoration.
112
  SCRUB-WP_MVP_REINSERT_AUTO_FLOW_SIMPLIFICATION_IMPLEMENTATION — completed, synchronized and live-app verified.
113
  SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION — completed with 15/15 cases passing and a critical document/key-binding gap routed to triage.
 
114
  ```
115
 
116
  Important UX status:
@@ -228,9 +229,14 @@ Current execution queue:
228
  3. SCRUB-WP_MVP_DOCUMENT_HYGIENE_FIDELITY_HARDENING — completed and app-verified
229
  4. SCRUB-WP_MVP_REINSERT_AUTO_FLOW_SIMPLIFICATION_IMPLEMENTATION — completed and app-verified
230
  5. SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION — completed
231
- 6. SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — active
232
- 7. SCRUB-WP_MVP_AUDIT_RESIDUAL_RISK_EVIDENCE
233
- 8. SCRUB-WP_MVP_PHASE6_QUALITY_GATE_CLOSEOUT
 
 
 
 
 
234
  ```
235
 
236
  Execution principles:
 
11
  - `DECISION_LOG.md` for accepted strategic and architecture decisions;
12
  - `PROJECT_PROMPT.md` for worker rules and project governance.
13
 
14
+ Last roadmap strategy update: 2026-07-27 — document/key-binding triage is complete; test-first bound-placeholder and Scrub Key contract work is now active before implementation.
15
 
16
  ---
17
 
 
111
  SCRUB-WP_MVP_DOCUMENT_HYGIENE_FIDELITY_HARDENING — merged, synchronized and live-app verified for DOCX body, table, header and footer restoration.
112
  SCRUB-WP_MVP_REINSERT_AUTO_FLOW_SIMPLIFICATION_IMPLEMENTATION — completed, synchronized and live-app verified.
113
  SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION — completed with 15/15 cases passing and a critical document/key-binding gap routed to triage.
114
+ SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — completed with a bound-placeholder plus mapping-digest recommendation and a test-first implementation sequence.
115
  ```
116
 
117
  Important UX status:
 
229
  3. SCRUB-WP_MVP_DOCUMENT_HYGIENE_FIDELITY_HARDENING — completed and app-verified
230
  4. SCRUB-WP_MVP_REINSERT_AUTO_FLOW_SIMPLIFICATION_IMPLEMENTATION — completed and app-verified
231
  5. SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION — completed
232
+ 6. SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — completed
233
+ 7. SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS — active
234
+ 8. SCRUB-WP_MVP_SCRUB_KEY_BINDING_MODEL_IMPLEMENTATION
235
+ 9. SCRUB-WP_MVP_SCRUB_KEY_BINDING_EXPORT_INTEGRATION
236
+ 10. SCRUB-WP_MVP_SCRUB_KEY_BINDING_REINSERT_INTEGRATION
237
+ 11. SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY
238
+ 12. SCRUB-WP_MVP_AUDIT_RESIDUAL_RISK_EVIDENCE
239
+ 13. SCRUB-WP_MVP_PHASE6_QUALITY_GATE_CLOSEOUT
240
  ```
241
 
242
  Execution principles:
WORKPACKAGES.md CHANGED
@@ -1,3 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ## 2026-07-27 18:55 Europe/Amsterdam — SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION
2
 
3
  Status: completed; deterministic validation passed; PR verification pending.
 
1
+ ## 2026-07-27 19:18 Europe/Amsterdam — SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE
2
+
3
+ Status: completed; targeted validation passed; PR verification pending.
4
+
5
+ Summary:
6
+ - Classified the critical same-placeholder wrong-key finding by accidental pairing, accidental corruption and malicious tampering.
7
+ - Rejected document labels, complete-content hashes, placeholder-list hashes, filenames, hidden metadata and extra sidecars as sufficient primary binding controls.
8
+ - Recommended a non-sensitive document binding ID carried in every automatic/manual placeholder and the corresponding Scrub Key.
9
+ - Recommended a canonical SHA-256 mapping digest as a complementary accidental-corruption control, not as an authenticity signature.
10
+ - Deferred signature/HMAC protection until a trusted local signing-key lifecycle exists.
11
+ - Preserved the three-step document-first reinsert flow without new confirmation buttons or checkboxes.
12
+ - Changed no product code, UI, schema, placeholders, export or reinsert semantics.
13
+
14
+ Approved sequential implementation line:
15
+ 1. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`
16
+ 2. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_MODEL_IMPLEMENTATION`
17
+ 3. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_EXPORT_INTEGRATION`
18
+ 4. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_REINSERT_INTEGRATION`
19
+ 5. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY`
20
+
21
+ Optional later package:
22
+ - `SCRUB-WP_MVP_MALFORMED_PLACEHOLDER_DIAGNOSTIC_HARDENING`.
23
+
24
+ Active next package:
25
+ - `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`.
26
+
27
  ## 2026-07-27 18:55 Europe/Amsterdam — SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION
28
 
29
  Status: completed; deterministic validation passed; PR verification pending.
handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Handover — SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE
2
+
3
+ Repository worked in: solidprivacy-nl/scrub
4
+
5
+ ## Workpackage title
6
+
7
+ SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE
8
+
9
+ ## Status
10
+
11
+ Completed; targeted validation passed; PR verification pending.
12
+
13
+ ## Summary
14
+
15
+ The critical same-placeholder wrong-key finding was classified and routed to a test-first implementation line. The recommended MVP contract adds one non-sensitive document binding ID to every automatic/manual placeholder and the corresponding Scrub Key, plus a canonical mapping digest for accidental corruption. No product behavior was changed.
16
+
17
+ ## Files added
18
+
19
+ - `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`
20
+ - `output/validation/mvp_scrub_key_document_binding_gap_triage.json`
21
+ - `output/validation/mvp_scrub_key_document_binding_gap_triage_validation.json`
22
+ - `tests/test_mvp_scrub_key_document_binding_gap_triage.py`
23
+ - `tests/test_mvp_scrub_key_document_binding_gap_triage_validation.py`
24
+ - `handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md`
25
+ - `workpackage_claims/scrub_wp_mvp_scrub_key_document_binding_gap_triage.md`
26
+
27
+ ## Files changed
28
+
29
+ - `WORKPACKAGES.md`
30
+ - `CHANGELOG.md`
31
+ - `ROADMAP.md`
32
+ - `MVP_PHASE6_EXECUTION_PLAN.md`
33
+ - `RISK_REGISTER.md`
34
+ - `DECISION_LOG.md`
35
+
36
+ ## Tests
37
+
38
+ - Source critical finding must be consumed by triage.
39
+ - Accidental mismatch, accidental corruption and malicious tampering must remain distinct.
40
+ - Weak binding options must remain rejected.
41
+ - Recommended binding must be cross-format and preserve the three-step UX.
42
+ - Mapping digest must not be represented as authenticity.
43
+ - Bound mismatch/mixed IDs/invalid digest must be fail-closed requirements.
44
+ - Approved sequence must remain test-first.
45
+ - Validation evidence and temporary-workflow cleanup are contract-tested.
46
+
47
+ ## Validation
48
+
49
+ - Targeted triage and source-evidence tests: passed.
50
+ - Critical findings triaged: 1.
51
+ - Medium findings triaged: 1.
52
+ - Implementation authorized: false.
53
+ - GitHub Actions: pending PR validation.
54
+ - Hugging Face sync: not functionally applicable; no runtime/app code changed.
55
+ - App verification: not applicable; no visible behavior changed.
56
+
57
+ ## Notes / risks
58
+
59
+ - Binding IDs mitigate accidental wrong-key pairing but are not secret and do not stop a fully malicious editor who changes both document and key.
60
+ - An unkeyed mapping digest detects accidental edits but is not a signature.
61
+ - Strong malicious-tampering protection requires protected local signing-key management.
62
+ - Legacy keys remain unbound and require explicit status/warning.
63
+ - Human review remains mandatory; production readiness remains false.
64
+
65
+ ## Next recommended step
66
+
67
+ - Start `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`.
scripts/finalize_mvp_scrub_key_document_binding_gap_triage.py DELETED
@@ -1,286 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from pathlib import Path
4
-
5
- ROOT = Path(__file__).resolve().parents[1]
6
- TITLE = "SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE"
7
- MARKER = f"## 2026-07-27 19:18 Europe/Amsterdam — {TITLE}"
8
- HANDOVER = ROOT / "handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md"
9
-
10
-
11
- def read(path: str) -> str:
12
- return (ROOT / path).read_text(encoding="utf-8")
13
-
14
-
15
- def write(path: str, text: str) -> None:
16
- (ROOT / path).write_text(text, encoding="utf-8")
17
-
18
-
19
- def prepend_once(path: str, marker: str, block: str) -> None:
20
- text = read(path)
21
- if marker not in text:
22
- write(path, block.rstrip() + "\n\n" + text)
23
-
24
-
25
- workpackages_block = f"""{MARKER}
26
-
27
- Status: completed; targeted validation passed; PR verification pending.
28
-
29
- Summary:
30
- - Classified the critical same-placeholder wrong-key finding by accidental pairing, accidental corruption and malicious tampering.
31
- - Rejected document labels, complete-content hashes, placeholder-list hashes, filenames, hidden metadata and extra sidecars as sufficient primary binding controls.
32
- - Recommended a non-sensitive document binding ID carried in every automatic/manual placeholder and the corresponding Scrub Key.
33
- - Recommended a canonical SHA-256 mapping digest as a complementary accidental-corruption control, not as an authenticity signature.
34
- - Deferred signature/HMAC protection until a trusted local signing-key lifecycle exists.
35
- - Preserved the three-step document-first reinsert flow without new confirmation buttons or checkboxes.
36
- - Changed no product code, UI, schema, placeholders, export or reinsert semantics.
37
-
38
- Approved sequential implementation line:
39
- 1. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`
40
- 2. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_MODEL_IMPLEMENTATION`
41
- 3. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_EXPORT_INTEGRATION`
42
- 4. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_REINSERT_INTEGRATION`
43
- 5. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY`
44
-
45
- Optional later package:
46
- - `SCRUB-WP_MVP_MALFORMED_PLACEHOLDER_DIAGNOSTIC_HARDENING`.
47
-
48
- Active next package:
49
- - `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`.
50
- """
51
- prepend_once("WORKPACKAGES.md", MARKER, workpackages_block)
52
-
53
- changelog_block = f"""{MARKER}
54
-
55
- Status: completed; targeted validation passed; PR verification pending.
56
-
57
- Purpose:
58
- - Determine the smallest safe cross-format mitigation for the critical document/Scrub-Key binding gap before changing schema, placeholders, export or reinsert behavior.
59
-
60
- Files added:
61
- - `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`
62
- - `output/validation/mvp_scrub_key_document_binding_gap_triage.json`
63
- - `output/validation/mvp_scrub_key_document_binding_gap_triage_validation.json`
64
- - `tests/test_mvp_scrub_key_document_binding_gap_triage.py`
65
- - `tests/test_mvp_scrub_key_document_binding_gap_triage_validation.py`
66
- - `handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md`
67
- - `workpackage_claims/scrub_wp_mvp_scrub_key_document_binding_gap_triage.md`
68
-
69
- Files changed:
70
- - `WORKPACKAGES.md`
71
- - `CHANGELOG.md`
72
- - `ROADMAP.md`
73
- - `MVP_PHASE6_EXECUTION_PLAN.md`
74
- - `RISK_REGISTER.md`
75
- - `DECISION_LOG.md`
76
-
77
- Triage result:
78
- - Primary MVP threat: accidental wrong-document/key pairing.
79
- - Secondary MVP threat: accidental key corruption.
80
- - Deferred threat: malicious tampering requiring protected signing-key infrastructure.
81
- - Recommended primary control: document-specific non-sensitive binding ID in all placeholders and the key.
82
- - Recommended complementary control: canonical SHA-256 mapping digest.
83
- - Explicitly not sufficient: document labels, filenames, content hashes, placeholder-list hashes or metadata-only binding.
84
- - Legacy v1.0 keys require explicit unbound status and warning; they must not be silently treated as bound.
85
- - Bound-key mismatch, mixed IDs and digest mismatch must fail closed with zero replacements.
86
- - Human review remains required; production readiness remains false.
87
-
88
- Intentionally not changed:
89
- - product code or UI;
90
- - Scrub Key schema/version or serialization;
91
- - placeholder generation or grammar;
92
- - export/download or reinsert semantics;
93
- - document processing;
94
- - cloud, AI, OCR or secret storage.
95
-
96
- Next recommended step:
97
- - Start `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS` before implementation.
98
-
99
- ---
100
- """
101
- prepend_once("CHANGELOG.md", MARKER, changelog_block)
102
-
103
- roadmap = read("ROADMAP.md")
104
- roadmap = roadmap.replace(
105
- "Last roadmap strategy update: 2026-07-27 — Scrub Key roundtrip validation is complete and exposed a critical document/key-binding gap; evidence triage is now active before any schema or export change.",
106
- "Last roadmap strategy update: 2026-07-27 — document/key-binding triage is complete; test-first bound-placeholder and Scrub Key contract work is now active before implementation.",
107
- )
108
- roadmap = roadmap.replace(
109
- "6. SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — active\n7. SCRUB-WP_MVP_AUDIT_RESIDUAL_RISK_EVIDENCE\n8. SCRUB-WP_MVP_PHASE6_QUALITY_GATE_CLOSEOUT",
110
- "6. SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — completed\n7. SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS — active\n8. SCRUB-WP_MVP_SCRUB_KEY_BINDING_MODEL_IMPLEMENTATION\n9. SCRUB-WP_MVP_SCRUB_KEY_BINDING_EXPORT_INTEGRATION\n10. SCRUB-WP_MVP_SCRUB_KEY_BINDING_REINSERT_INTEGRATION\n11. SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY\n12. SCRUB-WP_MVP_AUDIT_RESIDUAL_RISK_EVIDENCE\n13. SCRUB-WP_MVP_PHASE6_QUALITY_GATE_CLOSEOUT",
111
- )
112
- status_anchor = "SCRUB-WP_MVP_SCRUB_KEY_ROUNDTRIP_VALIDATION — completed with 15/15 cases passing and a critical document/key-binding gap routed to triage."
113
- if "SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — completed with" not in roadmap:
114
- roadmap = roadmap.replace(
115
- status_anchor,
116
- status_anchor
117
- + "\nSCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE — completed with a bound-placeholder plus mapping-digest recommendation and a test-first implementation sequence.",
118
- )
119
- write("ROADMAP.md", roadmap)
120
-
121
- plan = read("MVP_PHASE6_EXECUTION_PLAN.md")
122
- triage_text = (
123
- "### 4A. SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE\n\n"
124
- "Classify the critical finding that a structurally valid wrong key can reuse the same placeholder namespace and restore incorrect values without a detectable mismatch. Decide whether document/key binding requires a key identifier, content fingerprint, manifest binding or another explicit contract. Do not change schema, export or reinsert semantics in the triage package."
125
- )
126
- replacement = triage_text + "\n\nTriage result: use a non-sensitive document binding ID in every placeholder and the corresponding key, complemented by a canonical mapping digest. Implement sequentially through contract tests, pure model helpers, export integration, reinsert integration and live verification. Legacy unbound keys remain explicit; malicious tampering remains outside the MVP without protected signing-key management."
127
- plan = plan.replace(triage_text, replacement)
128
- write("MVP_PHASE6_EXECUTION_PLAN.md", plan)
129
-
130
- risk = read("RISK_REGISTER.md")
131
- r2_anchor = "This is routed to `SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE`; no schema or export change is authorized by the validation package."
132
- r2_replacement = r2_anchor + " Triage recommends a non-sensitive document binding ID inside every automatic/manual placeholder and the corresponding key, plus a canonical mapping digest for accidental corruption. Contract tests must define legacy v1.0 behavior and fail-closed mismatch rules before implementation. Signatures/HMAC remain deferred until protected local signing-key management exists."
133
- risk = risk.replace(r2_anchor, r2_replacement)
134
- r3_anchor = "This diagnostic limitation is included in the document-binding gap triage."
135
- r3_replacement = r3_anchor + " It is not part of the critical binding implementation line; an optional later diagnostic-hardening package may report malformed near-placeholders directly without guessing or repairing values."
136
- risk = risk.replace(r3_anchor, r3_replacement)
137
- write("RISK_REGISTER.md", risk)
138
-
139
- decision = read("DECISION_LOG.md")
140
- decision_marker = "## 2026-07-27 — D033 — Bind new Scrub Keys through document-specific placeholder namespaces"
141
- if decision_marker not in decision:
142
- insertion = f"""{decision_marker}
143
-
144
- Status: accepted planning/architecture decision; implementation requires green contract tests
145
-
146
- Decision:
147
-
148
- ```text
149
- For new bound Scrub Keys, carry one locally generated, non-sensitive document binding ID in every automatic and manual placeholder and in the corresponding Scrub Key. Complement this with a canonical SHA-256 mapping digest for accidental key-corruption detection. Reinsert must fail closed before any replacement when a bound key mismatches the document, the document contains mixed binding IDs, or the mapping digest is invalid.
150
- ```
151
-
152
- Reason:
153
-
154
- - Generic placeholder namespaces allow a wrong valid key to restore wrong originals without an audit mismatch.
155
- - A binding token inside placeholders survives pasted-text, TXT, DOCX and PDF-text roundtrips when the placeholders themselves survive.
156
- - Labels, filenames, metadata, content hashes and placeholder-list hashes are not reliable cross-format AI-roundtrip bindings.
157
- - A digest detects accidental edits but is not authenticity; malicious tampering requires later protected signing-key infrastructure.
158
-
159
- Compatibility and UX boundaries:
160
-
161
- - Introduce an explicit new bound-key contract; do not silently reinterpret legacy v1.0 keys.
162
- - Legacy unbound keys may remain dual-readable with a visible unbound warning.
163
- - Preserve the document-first three-step reinsert flow and the final confidential-download acknowledgement.
164
- - Add no repeated confirmation buttons or checkboxes.
165
- - Preserve unknown, duplicate and missing-placeholder audit reporting.
166
- - No cloud processing, server secret, OCR or restored-PDF behavior.
167
- - Human review remains mandatory; no production-readiness claim.
168
-
169
- Approved sequence:
170
-
171
- 1. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`
172
- 2. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_MODEL_IMPLEMENTATION`
173
- 3. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_EXPORT_INTEGRATION`
174
- 4. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_REINSERT_INTEGRATION`
175
- 5. `SCRUB-WP_MVP_SCRUB_KEY_BINDING_APP_VERIFY`
176
-
177
- Evidence:
178
-
179
- - `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`
180
- - `output/validation/mvp_scrub_key_document_binding_gap_triage.json`
181
- - `output/validation/mvp_scrub_key_roundtrip_validation_report.json`
182
-
183
- ---
184
-
185
- """
186
- decision = decision.replace("---\n\n## 2026-07-27 — D032", "---\n\n" + insertion + "## 2026-07-27 — D032", 1)
187
- write("DECISION_LOG.md", decision)
188
-
189
- claim_path = "workpackage_claims/scrub_wp_mvp_scrub_key_document_binding_gap_triage.md"
190
- claim = read(claim_path)
191
- claim = claim.replace("Status: in_progress", "Status: completed; targeted validation passed; PR verification pending")
192
- claim = claim.replace(
193
- "- Inspect current placeholder/key architecture, evaluate binding options and record a decision-backed implementation sequence.",
194
- "- Merge after GitHub Actions pass, then start `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`.",
195
- )
196
- if "Triage result:" not in claim:
197
- claim += """
198
-
199
- Triage result:
200
- - Recommended primary control: non-sensitive document binding ID in every automatic/manual placeholder and the corresponding key.
201
- - Recommended complementary control: canonical SHA-256 mapping digest for accidental key corruption.
202
- - Legacy v1.0 keys remain explicit unbound compatibility, not silently bound.
203
- - Bound mismatch, mixed IDs and invalid digest must fail closed with zero replacements.
204
- - Signatures/HMAC deferred until protected local signing-key lifecycle exists.
205
- - Targeted triage/source-evidence tests passed.
206
- - Implementation authorized in this package: false.
207
- - Production ready: false; human review required: true.
208
- - Triage: `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`.
209
- - Evidence: `output/validation/mvp_scrub_key_document_binding_gap_triage.json`.
210
- - Validation evidence: `output/validation/mvp_scrub_key_document_binding_gap_triage_validation.json`.
211
- - Handover: `handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md`.
212
- """
213
- write(claim_path, claim)
214
-
215
- HANDOVER.parent.mkdir(parents=True, exist_ok=True)
216
- HANDOVER.write_text(
217
- f"""# Handover — {TITLE}
218
-
219
- Repository worked in: solidprivacy-nl/scrub
220
-
221
- ## Workpackage title
222
-
223
- {TITLE}
224
-
225
- ## Status
226
-
227
- Completed; targeted validation passed; PR verification pending.
228
-
229
- ## Summary
230
-
231
- The critical same-placeholder wrong-key finding was classified and routed to a test-first implementation line. The recommended MVP contract adds one non-sensitive document binding ID to every automatic/manual placeholder and the corresponding Scrub Key, plus a canonical mapping digest for accidental corruption. No product behavior was changed.
232
-
233
- ## Files added
234
-
235
- - `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`
236
- - `output/validation/mvp_scrub_key_document_binding_gap_triage.json`
237
- - `output/validation/mvp_scrub_key_document_binding_gap_triage_validation.json`
238
- - `tests/test_mvp_scrub_key_document_binding_gap_triage.py`
239
- - `tests/test_mvp_scrub_key_document_binding_gap_triage_validation.py`
240
- - `handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md`
241
- - `workpackage_claims/scrub_wp_mvp_scrub_key_document_binding_gap_triage.md`
242
-
243
- ## Files changed
244
-
245
- - `WORKPACKAGES.md`
246
- - `CHANGELOG.md`
247
- - `ROADMAP.md`
248
- - `MVP_PHASE6_EXECUTION_PLAN.md`
249
- - `RISK_REGISTER.md`
250
- - `DECISION_LOG.md`
251
-
252
- ## Tests
253
-
254
- - Source critical finding must be consumed by triage.
255
- - Accidental mismatch, accidental corruption and malicious tampering must remain distinct.
256
- - Weak binding options must remain rejected.
257
- - Recommended binding must be cross-format and preserve the three-step UX.
258
- - Mapping digest must not be represented as authenticity.
259
- - Bound mismatch/mixed IDs/invalid digest must be fail-closed requirements.
260
- - Approved sequence must remain test-first.
261
- - Validation evidence and temporary-workflow cleanup are contract-tested.
262
-
263
- ## Validation
264
-
265
- - Targeted triage and source-evidence tests: passed.
266
- - Critical findings triaged: 1.
267
- - Medium findings triaged: 1.
268
- - Implementation authorized: false.
269
- - GitHub Actions: pending PR validation.
270
- - Hugging Face sync: not functionally applicable; no runtime/app code changed.
271
- - App verification: not applicable; no visible behavior changed.
272
-
273
- ## Notes / risks
274
-
275
- - Binding IDs mitigate accidental wrong-key pairing but are not secret and do not stop a fully malicious editor who changes both document and key.
276
- - An unkeyed mapping digest detects accidental edits but is not a signature.
277
- - Strong malicious-tampering protection requires protected local signing-key management.
278
- - Legacy keys remain unbound and require explicit status/warning.
279
- - Human review remains mandatory; production readiness remains false.
280
-
281
- ## Next recommended step
282
-
283
- - Start `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`.
284
- """,
285
- encoding="utf-8",
286
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
workpackage_claims/scrub_wp_mvp_scrub_key_document_binding_gap_triage.md CHANGED
@@ -4,7 +4,7 @@ Repository: solidprivacy-nl/scrub
4
 
5
  Workpackage title: SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE
6
 
7
- Status: in_progress
8
 
9
  Claimed by: ChatGPT GitHub worker
10
 
@@ -31,4 +31,19 @@ Boundaries:
31
  - Human review remains required; no production-readiness claim.
32
 
33
  Next step:
34
- - Inspect current placeholder/key architecture, evaluate binding options and record a decision-backed implementation sequence.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  Workpackage title: SCRUB-WP_MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE
6
 
7
+ Status: completed; targeted validation passed; PR verification pending
8
 
9
  Claimed by: ChatGPT GitHub worker
10
 
 
31
  - Human review remains required; no production-readiness claim.
32
 
33
  Next step:
34
+ - Merge after GitHub Actions pass, then start `SCRUB-WP_MVP_SCRUB_KEY_BINDING_CONTRACT_TESTS`.
35
+
36
+
37
+ Triage result:
38
+ - Recommended primary control: non-sensitive document binding ID in every automatic/manual placeholder and the corresponding key.
39
+ - Recommended complementary control: canonical SHA-256 mapping digest for accidental key corruption.
40
+ - Legacy v1.0 keys remain explicit unbound compatibility, not silently bound.
41
+ - Bound mismatch, mixed IDs and invalid digest must fail closed with zero replacements.
42
+ - Signatures/HMAC deferred until protected local signing-key lifecycle exists.
43
+ - Targeted triage/source-evidence tests passed.
44
+ - Implementation authorized in this package: false.
45
+ - Production ready: false; human review required: true.
46
+ - Triage: `MVP_SCRUB_KEY_DOCUMENT_BINDING_GAP_TRIAGE.md`.
47
+ - Evidence: `output/validation/mvp_scrub_key_document_binding_gap_triage.json`.
48
+ - Validation evidence: `output/validation/mvp_scrub_key_document_binding_gap_triage_validation.json`.
49
+ - Handover: `handover/workpackages/20260727_1918_mvp_scrub_key_document_binding_gap_triage.md`.