docs: introduce EU compliance baseline strategy (ADR-025)
ADR-025 plans 4 epics that raise the template's DPA/GDPR coverage from ~50% (ADR-017/018/022/023/024) to ~80%. Adds two optional cores (core-dsr, core-consent), a fourth conformance channel (rate-limit), three new manifest fields, three new generators with CI drift gates, and a docs/compliance/ + compliance/ split for templates vs evidence. Documents the audit ↔ DSR sibling-not-overlap distinction (audit records access; DSR acts on the underlying data). Four explicit deferrals with revisit triggers (RBAC, MFA, breach detection, Art. 22). Glossary updated with DSR, Consent, Rate-limit, PII inventory, Retention policy, Sub-processor, docs/compliance/ vs compliance/ entries.
This commit is contained in:
@@ -255,8 +255,30 @@ The counter/gauge/histogram interface. Same three-impl shape.
|
||||
The product-analytics interface, lives in `@repo/core-analytics` (optional core, scaffolded via `pnpm turbo gen core-package analytics`). Three methods: `track(event, properties?, user?)`, `identify(user)`, `pageView(path, properties?)`. Same three-impl shape as `ITracer`/`ILogger`/`IMetrics`. Used for funnel/cohort/retention analysis; structurally distinct from `IAuditLog` (which is compliance-driven) and from `IEventBus` (which is cross-feature action routing). Server-only by manifest gate; consumer wires React provider for client-side via `@repo/core-analytics/react`.
|
||||
_Avoid:_ confusing analytics events with cross-feature events (bus) or audit events (compliance) — they're three orthogonal capture channels.
|
||||
|
||||
**`withSpan`** / **`withCapture`** / **`withAudit`** / **`withAnalytics`**:
|
||||
The four wrapper composers applied at DI bind time. Composition is nested with `withSpan` outermost; each layer attaches a brand: `withSpan` → `Instrumented`, `withCapture` → `Captured`, `withAudit` → `Audited` (when manifest declares `audits`), `withAnalytics` → `Analyzed` (when manifest declares `analyticsEvents`).
|
||||
**`withSpan`** / **`withCapture`** / **`withAudit`** / **`withAnalytics`** / **`withConsent`** / **`withRateLimit`**:
|
||||
The six wrapper composers applied at DI bind time. Composition is nested with `withSpan` outermost; each layer attaches a brand: `withSpan` → `Instrumented`, `withCapture` → `Captured`, `withAudit` → `Audited` (when manifest declares `audits`), `withAnalytics` → `Analyzed` (when manifest declares `analyticsEvents`), `withConsent` → `ConsentChecked` (when manifest declares `requiresConsent`), `withRateLimit` → `RateLimited` (when manifest declares `rateLimit`). See ADR-025 for the compliance-baseline channels.
|
||||
|
||||
**DSR** (`@repo/core-dsr`):
|
||||
The Data Subject Rights handler — optional core package providing four interfaces that operate on user data in response to GDPR Arts. 15–18 requests. `IDataExport` (Art. 15 access + Art. 20 portability), `IDataDelete` (Art. 17 erasure cascade), `IDataRectify` (Art. 16), `IProcessingRestriction` (Art. 18). Sibling to `core-audit` — audit _records_ access, DSR _acts_ on the underlying data. Walks Payload collections at runtime using field-level `custom.pii` tags. See ADR-025.
|
||||
_Avoid:_ confusing DSR with audit; audit is the immutable journal, DSR is the mutator.
|
||||
|
||||
**Consent** (`@repo/core-consent`):
|
||||
The runtime gate for granular consent categories (essential/functional/analytics/marketing). Optional core package providing `IConsent` interface (`isGranted`/`grant`/`withdraw`/`getCategories`) + `ConsentChecked` brand + `requiresConsent: [...]` manifest field + `no-undeclared-consent-check` ESLint rule. Cookie banner UI ships as atomic component in `core-ui`. See ADR-025.
|
||||
|
||||
**Rate-limit** (`core-shared/rate-limit`):
|
||||
Fourth conformance channel after audit/analytics/consent. `IRateLimit` interface (`consume`/`reset`) + `withRateLimit` wrapper + `RateLimited` brand + `rateLimit: { window, budget }` manifest field. Default budgets in manifest, runtime overrides via `ctx.rateLimit` config. Consumer wires Redis/Upstash impl. See ADR-025.
|
||||
|
||||
**PII inventory**:
|
||||
Personal-data declaration at the Payload field level via `custom.pii = { category, purpose, retention, exportable, restrictable }`. Generator emits `compliance/data-map.yml`. DSR cascade walks this at runtime. See ADR-025.
|
||||
|
||||
**Retention policy**:
|
||||
Per-Payload-collection retention via `custom.retention = { activeRetention, postDeletion, purgeSchedule, hardDeleteAfter }`. Generator emits `compliance/retention-policy.yml`. Background purge job in `core-shared/jobs` reads this at boot. Per-PII-field retention overrides apply (more-specific wins). See ADR-025.
|
||||
|
||||
**Sub-processor**:
|
||||
External service that processes personal data on behalf of the controller (Stripe, SendGrid, PostHog, etc.). Declared via extended ADR-022 library traces — `docs/library-decisions/<date>-<pkg>.md` frontmatter gains `is-sub-processor`, `processes-pii`, `data-sent`, `region`, `dpa-signed`, `sccs-required`, `contact` fields. Generator emits `compliance/sub-processors.yml` from traces filtered to `is-sub-processor: true`. See ADR-025.
|
||||
|
||||
**`docs/compliance/` vs `compliance/`**:
|
||||
Split locations for compliance artifacts. `docs/compliance/` (template-shipped) holds FILL-IN TEMPLATES (`.template.md` runbooks, `.example.yml` references). Root `compliance/` (consumer-created) holds LIVE ARTIFACTS (`data-map.yml`, `retention-policy.yml`, `sub-processors.yml` from generators + consumer-authored filled runbooks). Audit evidence lives in `compliance/`. See ADR-025.
|
||||
|
||||
**Span**:
|
||||
A traced unit of work. Emitted by `tracer.startSpan(...)` (inline in repos) or `withSpan(...)` (composed for use cases + controllers).
|
||||
|
||||
Reference in New Issue
Block a user