docs: end-to-end photo data-flow threat model (#20) #71

Closed
rockachopa wants to merge 0 commits from timmy/20-photo-dataflow-threat-model into main
pull from: timmy/20-photo-dataflow-threat-model
Member

Closes #20

What

Adds the end-to-end photo data-flow threat model required before beta, as an enforced document rather than a one-off writeup.

  • docs/PHOTO-DATAFLOW-THREAT-MODEL.md — mermaid data-flow diagram covering the browser, API ingress, model worker, transient buffers, training opt-in store, sanitized logs, exports, and deletion; six trust boundaries; component-by-component data lifetimes (including "a photo awaiting consent is never written to disk"); and a numbered threat register — T1 replay, T2 oversized input, T3 metadata leakage, T4 dataset poisoning, T5 unauthorized training, T6 operator access — where each entry carries a mitigation, an owner, a tracked follow-up ticket, and the artifact that will count as evidence.
  • tests/threat-model.test.js — enforces all of the above: diagram coverage of every byte-bearing component, owner + follow-up presence per abuse case with the follow-up number validated against ROADMAP ticket numbers, and the non-diagnostic / synthetic-fixtures boundary.
  • package.json — registers the test in npm test, so it also runs in the CI quality gate and in scripts/build_release.py.
  • docs/PRODUCT-DECISIONS.md — links the model from the accepted decision record so reviewers and the clinical/privacy gate can find it.

TDD evidence

  • RED: wrote tests/threat-model.test.js first and watched it fail — 3 × ENOENT: no such file or directory ... docs/PHOTO-DATAFLOW-THREAT-MODEL.md, plus 1 × AssertionError: the governing decision record must point reviewers at the threat model. Not typos.
  • GREEN: added the document and the decision-record link → 4/4 pass.
  • Sensitivity check: removed the - **Owner:** line from T3 → not ok 2 ... 'metadata leakage needs a named owner'; restored → green. The content assertions bite, not just the file's existence.
  • Full suite: npm test 108/108 (104 before, 4 new). npm audit --audit-level=high → 0 vulnerabilities. npm run check:syntax, npm run check:diff, and python3 tests/staging-deploy.test.py (20 tests) all pass.

Demo path

No user-visible feature changed, so scripts/record_release_demo.mjs and its visual acceptance assertions in tests/release-demo.test.js are deliberately untouched — this render path is docs + test only. The nearest honest user-visible effect is the consent, export, and deletion surface the model describes; no demo caption, tap, or UI state was invented for it.

Boundary

The non-diagnostic boundary is unchanged and restated in the model, not relaxed. No real medical images, no model weights, no publicly exposed inference, no infrastructure purchases, no production service changes. Every abuse case that is not yet fully mitigated appears under Accepted residual risks with an owner and a bounded claim (host compromise, model accuracy, hosted provider profiles) rather than a claim of elimination.

Follow-ups referenced (not merged here)

#16, #17, #24, #25, #29, #32, #39, #41 — this PR only names them as the tickets that will prove each mitigation.

Closes #20 ## What Adds the end-to-end photo data-flow threat model required before beta, as an enforced document rather than a one-off writeup. - `docs/PHOTO-DATAFLOW-THREAT-MODEL.md` — mermaid data-flow diagram covering the browser, API ingress, model worker, transient buffers, training opt-in store, sanitized logs, exports, and deletion; six trust boundaries; component-by-component data lifetimes (including "a photo awaiting consent is never written to disk"); and a numbered threat register — T1 replay, T2 oversized input, T3 metadata leakage, T4 dataset poisoning, T5 unauthorized training, T6 operator access — where each entry carries a mitigation, an owner, a tracked follow-up ticket, and the artifact that will count as evidence. - `tests/threat-model.test.js` — enforces all of the above: diagram coverage of every byte-bearing component, owner + follow-up presence per abuse case with the follow-up number validated against ROADMAP ticket numbers, and the non-diagnostic / synthetic-fixtures boundary. - `package.json` — registers the test in `npm test`, so it also runs in the CI quality gate and in `scripts/build_release.py`. - `docs/PRODUCT-DECISIONS.md` — links the model from the accepted decision record so reviewers and the clinical/privacy gate can find it. ## TDD evidence - **RED:** wrote `tests/threat-model.test.js` first and watched it fail — 3 × `ENOENT: no such file or directory ... docs/PHOTO-DATAFLOW-THREAT-MODEL.md`, plus 1 × `AssertionError: the governing decision record must point reviewers at the threat model`. Not typos. - **GREEN:** added the document and the decision-record link → 4/4 pass. - **Sensitivity check:** removed the `- **Owner:**` line from T3 → `not ok 2 ... 'metadata leakage needs a named owner'`; restored → green. The content assertions bite, not just the file's existence. - **Full suite:** `npm test` 108/108 (104 before, 4 new). `npm audit --audit-level=high` → 0 vulnerabilities. `npm run check:syntax`, `npm run check:diff`, and `python3 tests/staging-deploy.test.py` (20 tests) all pass. ## Demo path No user-visible feature changed, so `scripts/record_release_demo.mjs` and its visual acceptance assertions in `tests/release-demo.test.js` are deliberately untouched — this render path is docs + test only. The nearest honest user-visible effect is the consent, export, and deletion surface the model describes; no demo caption, tap, or UI state was invented for it. ## Boundary The non-diagnostic boundary is unchanged and restated in the model, not relaxed. No real medical images, no model weights, no publicly exposed inference, no infrastructure purchases, no production service changes. Every abuse case that is not yet fully mitigated appears under **Accepted residual risks** with an owner and a bounded claim (host compromise, model accuracy, hosted provider profiles) rather than a claim of elimination. ## Follow-ups referenced (not merged here) #16, #17, #24, #25, #29, #32, #39, #41 — this PR only names them as the tickets that will prove each mitigation.
rockachopa added 1 commit 2026-10-10 08:03:48 +00:00
docs: add end-to-end photo data-flow threat model (#20)
Quality gates / quality (pull_request) Successful in 2m4s
29ea045671
- docs/PHOTO-DATAFLOW-THREAT-MODEL.md: browser, API ingress, model worker,
  transient buffers, training opt-in store, logs, exports, and deletion,
  with trust boundaries and a numbered threat register
- every named abuse case (replay, oversized input, metadata leakage,
  poisoning, unauthorized training, operator access) carries a mitigation,
  an owner, a tracked follow-up ticket, and the artifact that will prove it
- tests/threat-model.test.js enforces diagram coverage, owner/follow-up
  presence against ROADMAP ticket numbers, and the non-diagnostic boundary
  with synthetic-only fixtures
- link the model from the accepted product decision record
rockachopa closed this pull request 2026-10-10 12:02:07 +00:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.