Files
agentic-dev-template/docs/guides/operator-checklist.md
Danijel Martinek b23b1d0b89 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>
2026-05-20 12:06:42 +00:00

10 KiB

Operator checklist

The decisions and code that make this template's security + supply-chain stack work are landed in code (ADR-022, ADR-023, the library-evaluation epic, the CI-security epic). This doc covers the human-side actions required to put it into operation in a real GitHub-hosted repo. Read top to bottom on first adoption; revisit the "Ongoing" section weekly.

The biggest leverage move is #1 (push to a remote) — until that happens, the entire .github/workflows/ surface is inert. Everything else cascades from there.


Right now (unblocks everything else)

1. Push to a GitHub remote. No remote is configured by default on a fresh template clone, which means CI doesn't run anywhere. Either:

  • gh repo create <owner>/template-vertical --source=. --private --push (or --public)
  • Or push to an existing remote: git remote add origin <url> && git push -u origin main

Decision attached: public vs private. Public → CodeQL is free, Socket free tier just works. Private → CodeQL needs GitHub Pro/Team/Enterprise plan (workflow runs unconditionally but GitHub gates execution).


During the dispatch loop (the agent drives this; you watch)

2. Continue the in-flight library-evaluation epic. Run pnpm work dispatch --execute. The dispatcher picks up the next unticked bullet and marches through.

Refresh ~/.claude/.credentials.json from the macOS keychain when sandcastle returns 401 (the keychain one-liner; happens ~every 30 days):

security find-generic-password -s "Claude Code-credentials" -a "$USER" -w \
  > ~/.claude/.credentials.json
chmod 600 ~/.claude/.credentials.json

3. After library-evaluation epic completes, the CI-security epic unblocks. pnpm work dispatch --execute picks up its story 01 automatically.


After all implementation lands (one-time setup, ~30 minutes total)

4. Install GitHub Apps (one click each, free tier):

  • Renovatehttps://github.com/apps/renovate → grant repo access. After install, Renovate opens an onboarding PR — merge it to enable. First real PR is the Action SHA-pin sweep (rewrites @v4@<sha> across all workflows). Merge that too.
  • Socket Securityhttps://github.com/apps/socket-security → grant repo access. PR comments start appearing on the next package.json diff.

5. Toggle GitHub repo settings (Settings → Code security and analysis):

  • Dependabot alerts (server-side vuln scan) — your passive monitoring surface
  • Dependabot security updates — OFF (Renovate handles bumps; alerts stay on for visibility)
  • Secret scanning + push protection — blocks known token patterns at the GitHub edge
  • CodeQL alerts (auto-enabled by the workflow)

6. Configure branch protection on main (Settings → Branches → main):

  • Require status checks: validate, socket-security, CodeQL
  • Require linear history (matches release-please's expectations)
  • Do not add library-policy/re-evaluation as a blocker — ADR-023 explicitly decided against gating main on revalidation issues

7. Add TURBO_TOKEN + TURBO_TEAM as repo secrets/variables for Turborepo remote caching (already documented in ci.yml's comment block).

8. Sentry DSNs if you want production observability per ADR-014 / ADR-017 (WEB_NEXT_SENTRY_DSN, CMS_SENTRY_DSN, etc.) — set as repo secrets for the apps you actually deploy.


Ongoing (per-decision, weekly cadence)

9. Renovate's weekly PR stream.

  • Minor + patch bumps auto-merge if green. Nothing to do.
  • Major bumps block until evaluate-library re-runs and refreshes the trace's last-revalidated. The dispatch loop can pick these up via story-style task — or you walk the skill manually (/evaluate-library <name> --tier <feature|core> --target <path>).

10. Weekly trace-revalidation cron fires every Monday 06:30 UTC.

  • Soft divergence → appended to the rolling library-policy/dashboard issue. Skim weekly; mostly no-action.
  • Hard divergence → fresh library-policy/re-evaluation issue per affected dep. Human triage required (ADR-023 §3, no auto-dispatch). Decide: re-walk evaluate-library, accept-with- allowlist, or migrate off the library. Add the issue to the dispatch queue if the re-walk is mechanical.

11. CVE accepted-risk decisions. When pnpm audit flags something with no patch available, add accepted-cves: [CVE-XXXX-YYYY] to the relevant trace's frontmatter with a note explaining why the risk is accepted.

12. License-allowlist requests. ADR-022 names MIT/Apache-2.0/BSD/ISC/MPL-2.0 as allowlisted. If a real need surfaces (e.g. a GPL-3.0-with-classpath-exception library), you decide whether 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:

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:

# 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) — human reading-room for the 9 filters + 3 prompts
  • docs/guides/ci-security.md (CI-security epic story 09) — human reading-room for the four pillars + failure-mode hierarchy table

Cleanup notes

  • Untracked files in repo rootcheck-shas-cjs.js, check-shas.mjs, check-shas2.mjs, check-shas3.mjs. These appeared during SHA-experimentation work and aren't part of any commit. Decide whether to delete or .gitignore.
  • apps/*/tsconfig.tsbuildinfo continues to churn on every typecheck. A chore: gitignore tsbuildinfo commit would stop that drift.

  • 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
  • docs/guides/ci-security.md — security stack reference