# Privacy obligation teaching fixture

This is a synthetic, executed example of deriving an engineering requirement from an already resolved privacy decision. It is not a Proof connector, GDPR assessment, production deletion service or legal interpretation engine.

## The assumed approval

`policy.json` records a fictional product decision, assumed approved only within the teaching scenario. Identity, entitlement, exceptions and data scope are preconditions already resolved by an accountable person. The script does not decide them. Two declared live destinations are in scope: profiles and analytics.

The engineering rule is to report completion only after the target is absent from both live stores. Destination failure stays unresolved; retries preserve unrelated rows. A caller-triggered reconciliation after restoration must reopen the request if the target returns. These are illustrative engineering choices, not prescribed GDPR architecture or a claim of actual customer approval.

## Reproduce

Requires Python 3 with the standard `sqlite3` module. No third-party packages, network access, credentials or persistent services are needed.

```sh
python3 verify.py
python3 run.py rerun.json
```

`verify.py` checks the downloaded file digests and the source binding of the saved observation. It does not execute the scenarios. `run.py` creates temporary SQLite databases, runs the scenarios and checks, writes a new JSON report, and returns nonzero if any check fails. The temporary directory is removed on exit. It contains synthetic subject IDs and values only. The chosen output file is overwritten if it exists.

The saved run in `observed.json` used Python 3.14.7 and SQLite 3.53.4 on October 3, 2026. It reports nine passed checks. A fresh run records its own time, runtime and source hashes, so its full JSON will differ from the saved report.

## What ran

1. The deliberately defective handler deletes from profiles, ignores a simulated analytics deletion failure, and falsely reports complete. Independent SQL queries detect the remaining target row.
2. The corrected handler names analytics as unavailable and keeps the request unresolved.
3. A retry after recovery deletes the remaining row and reports both live stores absent.
4. Repeating the completed request leaves both target rows absent and unrelated rows intact.
5. SQLite's backup API restores the analytics database from a snapshot taken before deletion. Explicit reconciliation observes the returned row and reopens the request.
6. A new attempt removes the restored live row. The saved backup still contains it. That exclusion is checked and reported, rather than hidden behind the live-store completion state.

The nine assertions compare actual database row counts and request outcomes. Catching the deliberately broken baseline is an expected successful check; it does not mean the broken handler is correct. The deletion failure is explicitly injected before the analytics DELETE. It is not a measurement of a network outage. The databases remain readable by the independent test oracle.

## Boundaries

`complete` means the declared live-row condition held at that observation. It does not mean all personal data was erased. SQL DELETE does not establish physical media sanitization, and the backup deliberately retains a target row until temporary cleanup. Request state is in memory. There is no durable queue, concurrent writer, automatic restore monitor, external processor, recipient notification, deadline clock, authentication or production retention policy.

A real system also needs destination discovery, authorization, retry durability, concurrency handling, restore controls, proportional evidence retention and a reviewed response process. The right legal and engineering treatment depends on the actual processing and applicable exceptions. Do not reuse a synthetic subject-level audit log with real data without assessing that log's own purpose, access and retention.

## Primary sources checked October 3, 2026

- European Commission, [dealing with requests from individuals](https://commission.europa.eu/law/law-topic/data-protection/information-business-and-organisations/dealing-requests-individuals_en): request handling, the in-principle one-month response period, erasure grounds and exceptions.
- EDPB, [final Guidelines 4/2019](https://www.edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_201904_dataprotection_by_design_and_by_default_v2.0_en.pdf), adopted October 20, 2020, paragraphs 13 to 16: context-specific measures and demonstration of effectiveness.
- EDPB, [privacy by design and by default](https://www.edpb.europa.eu/topics/ai-and-technology/privacy-by-design-and-by-default_en): protection as an ongoing process.

The sources motivate the review question. They do not mandate this fixture's two-store architecture, status vocabulary or retry strategy. This repository example is not evidence that a production system satisfies the GDPR.
