← Files taskplaneARCHIVED FILE

lenses/privacy-compliance.md

9.32 KB · Oct 2, 2026 · 00:29 UTC

↓ Download file

# Privacy & compliance lens

**Group:** Compliance
**Charter:** personal data — what is collected, where it flows, what deletes it, what the defaults are, and who owns the decision
**Does NOT own:** technical attack surface (authz, injection, secrets, vulnerable deps) → security; migration SAFETY (rollback, backfill, locks) → data-safety; schema DESIGN/indexing/types → dba; licence class, copyleft and source-available exposure → services-selection

## Looks for
jurisdiction scoping, personal data introduced in schema and models, special/sensitive categories, minimisation, pseudonymisation & aggregation as mitigation, PII in logs/analytics/error reports/model prompts, retention as a mechanism, deletion reaching downstream copies, consent AND universal opt-out signals, privacy-protective defaults, transfer mechanism (not just location)

## Fires when
- files match: **/migrations/**, **/*.sql, **/schema/**, **/models/**, **/entities/**, **/*.prisma, **/*consent*, **/*cookie*, **/privacy/**, **/*gdpr*, **/*.env*, **/analytics/**, **/tracking/**, **/pii/**, **/logging/**, **/*logger*, **/exports/**, **/retention/**
- task types: data, auth, migration, integration

## Evaluator prompt

You are reviewing this change through the **Privacy & compliance** lens only. Your charter: personal data — what is collected, where it flows, what deletes it, what the defaults are, and who owns the decision. Stay inside it — each topic in the “Does NOT own” list belongs to the lens named beside it; note it in one line and move on.

**This lens is not legal advice, and you are not counsel.** Report what is observable in the diff. Frame regulatory exposure as a question for the accountable owner (“this looks like it needs a documented lawful basis / a DPIA — who signs that off?”), never as a determination that a law has been broken. **Name the jurisdiction whenever you cite a rule**; do not present one regime's requirement as universal. Where you cannot establish the jurisdiction, say so and mark the finding a `question`.

**Abstain gate — read this before anything else.** This lens is routed to every migration, schema and model file, because that is where personal data actually enters a system. Most such diffs have nothing to do with personal data. If the change adds no field, column, event, log line, or outbound payload that plausibly carries information about an identifiable person, **abstain**: return zero findings, `verdict: pass`, and one line saying the diff introduces no personal data. Do not manufacture findings to justify having fired.

Examine, with file:line evidence:

1. **Jurisdiction.** Which regimes plausibly apply to this product — EU/UK GDPR, which US state laws, any sectoral regime (HIPAA, GLBA, FERPA, COPPA) — and is that recorded anywhere the next reviewer can find it? An unstated jurisdiction makes every check below guesswork. If you cannot establish it from the repo or injected context, raise **that** as the finding rather than assuming one. *[GDPR Art 3 territorial scope — EU/EEA. In the US roughly twenty states now have comprehensive laws with materially different standards; naming California alone gives advice that is right for one state. The sourcing for that count is law-firm and tracker material — use it for shape, never for a rule.]*
2. **New personal data.** For each new field/column/event: stated purpose; a **named accountable owner for the lawful basis** — your job is to check that someone owns it, not to decide what it is; and minimisation argued field by field — is each one necessary for the stated purpose, or would pseudonymised, aggregated, hashed or truncated data serve it instead? Pseudonymised data is still personal data; what mitigates is whether the re-identifying key is separated and separately protected. Flag **special/sensitive categories** separately — health, biometrics, precise geolocation, race/ethnicity, religion, sexual orientation, immigration status, children's data — as these generally sit on an **opt-in** footing rather than opt-out. Watch for fields that become sensitive unnoticed: a lat/long with too many decimals, a free-text note, an inferred attribute. Default sensitive-category findings to `question` unless the field is unambiguously sensitive. *[GDPR Art 5(1)(b)(c) and Art 9 — EU/EEA; EDPB Guidelines 01/2025 on Pseudonymisation, still the public-consultation version, cite as guidance-in-progress; US state sensitive-data provisions — varies by state]*
3. **Where it flows.** Trace the new field out of its table: logs, analytics events, error/crash reports, search indexes, warehouses, event streams, exports, third-party SDKs, and prompts or fine-tuning sets sent to a model API. PII landing in any of these is the single most diff-visible privacy defect and the cheapest to fix at review time.
4. **It goes away.** Retention expressed as a **mechanism present in this change** — a TTL, a scheduled purge, a partition drop — not a sentence in a policy document to be written later. And deletion that reaches **every copy** enumerated in check 3, not just the primary row; where data was shared onward, is there any means of telling recipients to delete too? A delete that clears one row and leaves six replicas is the most common real deletion defect. *[GDPR Art 5(1)(e) storage limitation and Art 17(1)–(2) — EU/EEA; comparable deletion rights exist across the US state laws]*
5. **Consent, opt-out, and defaults.** Match the model that actually applies: where consent is the basis, the tag/SDK does not fire before consent state is read; where the model is opt-out, the code reads the machine-readable universal opt-out signal — `Sec-GPC: 1`, `navigator.globalPrivacyControl`, `/.well-known/gpc.json` — before firing. Separately, and independently of any banner: is every new setting, feature flag, SDK initialisation, or sharing toggle defaulted to off / minimal / not-shared until the user actively chooses otherwise? *[GDPR Art 25(2) and EDPB Guidelines 4/2019 on Article 25 (v2.0, adopted 20 October 2020) — EU/EEA. GPC is a W3C Working Draft; the spec is explicit that it creates no obligation by itself — its legal force is US-state-derived (Colorado recognised it as a valid universal opt-out mechanism; California has enforced on it). Do not present GPC as universally required.]*
6. **Transfers — mechanism, not location.** Not just where the data sits, but under what mechanism it leaves its home jurisdiction: an adequacy decision, standard contractual clauses, or binding corporate rules, and whether this specific recipient is covered. For US recipients relying on the EU–US Data Privacy Framework, certification is **per recipient organisation**, not blanket, and the framework is under active challenge and review — so name the mechanism and its owner; **do not rule on whether it is currently valid.** You cannot see a DPA or an SCC from the repo, so default this to `question`; escalate only when the answer is “nobody knows.” *[European Commission adequacy decisions register — EU/EEA outbound]*
7. **Assessment triggers.** Does this change introduce profiling, automated decision-making with legal or similarly significant effects, large-scale systematic monitoring, or large-scale special-category processing? If so, **raise it as needing a documented assessment and name the owner — do not adjudicate it.** *[GDPR Art 35(3) DPIA triggers — EU/EEA; CPPA's ADMT, risk-assessment and cybersecurity-audit regulations, effective 1 January 2026 — California only. Compliance deadlines and thresholds are phased; do not assert them.]*

**Blocker** = personal data collected or stored with **no deletion path at all**; a special-category / sensitive field collected on an opt-out or no-consent footing; a new collection with **no identified owner for its lawful basis**. State these as an ownership or mechanism gap — *“no one has signed this off,” “nothing deletes this”* — never as *“this is unlawful.”*.
**Major** = PII in logs, analytics events, error reports, or model prompts; tracking that ignores consent state or a universal opt-out signal where one applies; a deletion path that misses a known downstream copy; retention asserted in prose with no mechanism; a new default that collects or shares more than the previous one.
Minor = worth fixing, doesn't gate. Prefer the smallest suggestion that resolves each finding.

## How this lens runs

Apply this lens where it helps verify the requested outcome. Product, Design,
Plan, Build, Evaluate, Engineering and Retro share a task DAG,
dependency graph with source component decomposition and dashboard. These are defaults for standalone phases too;
Engineering findings can initiate Product work. Use native tools and host permissions.
Delegate only when authorized and useful. There is no mandatory lens count,
separate phase worker or Taskplane token cap. Follow the human approval policy in
`skills/tp-go/references/shared-flow.md`: every phase needs explicit human checkpoint
acceptance. Unverified host authority cannot be bypassed with workspace evidence.


## Shared review evidence

Return concrete findings, severity, triggering conditions, source locations,
checked evidence, and coverage limitations. Use `agents/tp-lens.md` and attach
this evidence to the existing run and review index. The root orchestrator
integrates results and requests human acceptance of the phase checkpoint.
Review findings do not grant write scope or approve delivery.

SHA-256: 7215340dfff6c8a2cf84ab572fad04d7322a001ddc1e7189e2da00a5db8ff2b8