docs(compliance): refresh operator-checklist with ADR-024 and ADR-025 actions
ADR-024: analytics backend is consumer-chosen; operator must decide whether to wire a vendor and, if so, run /evaluate-library first (ADR-022 gate applies). Documents IAnalytics wiring, flush() shutdown hook, and optional React provider. ADR-025: compliance directory setup — generate and commit compliance/ YAML files as audit evidence; verify drift gate in pre-commit + CI; schedule retention purge job per custom.retention; hand-author compliance/sub-processors.manual.yml for non-npm vendors. All existing ADR-022/023 content preserved unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,101 @@ to extend — and the decision becomes an ADR-022 amendment in a new ADR.
|
||||
|
||||
---
|
||||
|
||||
## Analytics backend (ADR-024)
|
||||
|
||||
**13. Choose and wire an analytics vendor — or skip.** `@repo/core-analytics` ships
|
||||
`IAnalytics` as a vendor-neutral contract with no default backend. The analytics
|
||||
backend is **consumer-chosen**: the template deliberately ships no vendor because
|
||||
the choice requires ADR-022's library evaluation gate (EU residency, license,
|
||||
Socket.dev) and your product's consent model.
|
||||
|
||||
If you want product analytics:
|
||||
|
||||
- **Evaluate the vendor first.** Run
|
||||
`/evaluate-library <name> --tier core --target packages/core-analytics`. The
|
||||
resulting trace at `docs/library-decisions/<date>-<name>.md` is the required
|
||||
evidence before adding the package to your lockfile.
|
||||
- **Implement `IAnalytics`.** Write a wrapper around the vendor SDK that satisfies
|
||||
the four-method interface (`track`, `identify`, `pageView`, `flush`).
|
||||
- **Wire at DI bind time.** Pass the implementation into `ctx.analytics` in
|
||||
`bind-production.ts`. Feature binders pick it up and compose it into the
|
||||
`withAnalytics(...)` wrapper chain automatically.
|
||||
- **Wire `flush()` into graceful shutdown.** Hook `analytics.flush()` into your
|
||||
app's `SIGTERM` / `beforeExit` handler to drain the in-memory batch before the
|
||||
process exits — event loss on container/serverless shutdown is the most common
|
||||
analytics bug.
|
||||
- **Client side (optional).** Wrap your app root in
|
||||
`<AnalyticsProvider value={...}>` from `@repo/core-analytics/react`; expose
|
||||
`IAnalytics` to components via `useAnalytics()`.
|
||||
|
||||
If you don't want analytics, do nothing — the template boots with `NoopAnalytics`
|
||||
by default and no wiring is required.
|
||||
|
||||
---
|
||||
|
||||
## Compliance directory (ADR-025)
|
||||
|
||||
**14. Generate and commit the `compliance/` YAML files.** Three audit-evidence
|
||||
files live at the repo root under `compliance/`, generated from Payload schema
|
||||
declarations and library traces:
|
||||
|
||||
```bash
|
||||
pnpm compliance:emit-all
|
||||
# produces:
|
||||
# compliance/data-map.yml (from Payload field custom.pii tags)
|
||||
# compliance/retention-policy.yml (from Payload collection custom.retention)
|
||||
# compliance/sub-processors.yml (from docs/library-decisions/ traces flagged
|
||||
# is-sub-processor: true)
|
||||
git add compliance/
|
||||
git commit -m "compliance: initial audit-evidence YAML files"
|
||||
```
|
||||
|
||||
Run once after your Payload schema stabilises. Re-run and commit whenever schema
|
||||
changes. The CI drift gate (`pnpm compliance:emit-all --check`) fails if generated
|
||||
output diverges from source.
|
||||
|
||||
**15. Verify the compliance drift gate in pre-commit and CI.**
|
||||
|
||||
- **Pre-commit:** `.husky/pre-commit` should include the
|
||||
`pnpm compliance:emit-all --check` step. Verify after `pnpm install`.
|
||||
- **CI:** `ci.yml`'s `validate` job runs the same check on every PR. Add it to
|
||||
branch-protection required checks (step **6** above) so drift can't land on
|
||||
`main`.
|
||||
|
||||
**16. Schedule the retention purge job.** `core-shared/jobs/retention-purge.job.ts`
|
||||
reads `custom.retention` from each Payload collection at boot and enqueues
|
||||
per-collection purge runs on the declared `purgeSchedule`. To activate:
|
||||
|
||||
1. Set `custom.retention: { activeRetention, postDeletion, purgeSchedule,
|
||||
hardDeleteAfter }` on each Payload collection you want auto-purged. See
|
||||
`docs/compliance/retention-policy.example.yml` for the schema.
|
||||
2. Confirm the job runner is live in production — the purge job enqueues via
|
||||
`IJobQueue`, which requires `@repo/core-events` or Payload's native jobs queue.
|
||||
3. Verify `audit_events` gains `{ action: "DELETE", reason: "retention-policy" }`
|
||||
entries after the first purge cycle.
|
||||
|
||||
**17. Hand-author `compliance/sub-processors.manual.yml` for non-npm vendors.**
|
||||
The sub-processors generator only surfaces vendors that have an npm package in
|
||||
`docs/library-decisions/`. Any vendor you call via a pure REST API — no SDK, no
|
||||
library trace — needs a manual entry:
|
||||
|
||||
```yaml
|
||||
# compliance/sub-processors.manual.yml
|
||||
- name: SendGrid
|
||||
is-sub-processor: true
|
||||
processes-pii: true
|
||||
data-sent: [email-address, display-name]
|
||||
region: US
|
||||
dpa-signed: 2026-01-15
|
||||
sccs-required: true
|
||||
contact: privacy@sendgrid.com
|
||||
```
|
||||
|
||||
Commit this file alongside `compliance/sub-processors.yml`. Both are treated as
|
||||
audit evidence; unlike the generated files, this one is always hand-maintained.
|
||||
|
||||
---
|
||||
|
||||
## Read once the docs land
|
||||
|
||||
- `docs/guides/adding-a-library.md` (library-evaluation epic story 05)
|
||||
@@ -145,6 +240,8 @@ to extend — and the decision becomes an ADR-022 amendment in a new ADR.
|
||||
|
||||
- ADR-022 — Library evaluation policy
|
||||
- ADR-023 — CI security + supply-chain enforcement stack
|
||||
- ADR-024 — Product analytics channel
|
||||
- ADR-025 — EU compliance baseline (DPA/GDPR scope)
|
||||
- `docs/guides/runbook.md` — first-time template setup (Postgres, dev
|
||||
servers, sandcastle auth)
|
||||
- `docs/guides/adding-a-library.md` — adding a runtime dep
|
||||
|
||||
Reference in New Issue
Block a user