The Socket supply-chain filter (ADR-023) was added after the initial
library-trace backfill, leaving the 36 traces dated 2026-05-14 without
the socketRisk filter-results field the trace schema now expects.
Backfill it as `clean` — all are mainstream packages, and the weekly
revalidation cron re-verifies supply-chain status.
The root devDependency carried a "*" wildcard, and ADR-019 documented a
nonexistent ^2.73.0 pin — the package's installed version is 0.5.10.
Pin to ^0.5.10 and correct ADR-019 to match.
The implemented IAnalytics refined the signature ADR-024 sketched:
events are attributed to the user set by identify() (the standard SDK
model) rather than passed per track() call, the attribute parameter is
named `attributes` consistently, and AnalyticsUser stays id-only with
traits riding identify()'s second argument. The code is the more
idiomatic contract and docs/guides/analytics.md already matched it —
update the ADR's interface block, manifest example, and PII-boundary
section to describe what shipped.
Add a "Policy templates" section to docs/compliance/README.md explaining
the docs/compliance/templates/ directory, the copy-to-compliance/ workflow,
the [FILL IN:] placeholder convention, and the verification one-liner.
Add four glossary entries: fill-in template, [FILL IN:] marker,
pre-launch compliance checklist, and compliance overview.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maps all 22 DPA/GDPR playbook sections to their covering ADR, guide,
template, or epic in this template. Restates ADR-025's four explicit
deferrals (RBAC, MFA, breach-detection, GDPR Art. 22) and documents
consumer/infra-scope items (EU region, TLS, MDM, legal instruments).
Includes a full reference index linking every compliance guide, ADR,
template, and epic.
Fix broken forward reference to compliance-overview.md (story 05 output)
by replacing the hyperlink with plain text annotated as forthcoming.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two-column table covering all 22 playbook sections organised by 13
groups (Infrastructure, Data, Application, Secrets, Sub-Processors,
Logging, Breach, DSR, Backup, SDLC, Workforce, Legal, Documentation).
Every "Shipped by template" row names a runnable verification command.
Consumer and infra responsibilities are explicitly labelled. ADR-025
deferrals (GDPR Art. 22, MFA/lockout, breach-detection patterns) are
called out inline. Links outward to compliance-overview.md, all seven
policy templates, audit-and-compliance.md, operator-checklist.md, and
ADR-025.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Five skeleton templates for docs/compliance/templates/. Each has YAML
frontmatter (status: template, playbook-section), a "not code-enforced"
banner, and [FILL IN:] markers throughout. password-policy banner cites
ADR-025 §Deferred items by number (MFA + password policy + lockout
deferral). Cross-template relative links all resolve.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Generated 1 epic + 6 stories under docs/work/epics/ from the approved
PRD docs/work/prds/compliance-docs-scaffolds.prd.md. Stories cover
landing + refreshing operator-checklist.md, the seven fill-in policy
templates, the pre-launch compliance checklist, the compliance-overview
hub, and doc wiring (CLAUDE.md, README, glossary). Final epic of
ADR-025. Ready for `pnpm work dispatch --execute`.
Amends release-please.yml with conditional steps that run only when
release-please cuts a release:
- checkout + pnpm install to give @cyclonedx/cyclonedx-npm the full
resolved workspace graph
- pnpm dlx @cyclonedx/cyclonedx-npm generates a CycloneDX 1.6 JSON SBOM
named sbom-<tag>.cdx.json; --ignore-npm-errors is required because
npm ls exits non-zero for dev-deps-of-dev-deps pnpm correctly elides
- softprops/action-gh-release@<SHA> (v3.0.0, Renovate-managed) attaches
the file to the GitHub release as a downloadable asset
Adds ADR-023 §9 amendment documenting the step shape, rationale for
pnpm dlx (avoids lockfile per ADR-022), --ignore-npm-errors behaviour,
SHA pinning per ADR-023 §1, and the extended failure-mode table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Next.js middleware.ts to apps/cms that applies all six security
headers on every response using the framework-agnostic
buildSecurityHeaders builder. No nonce is generated or forwarded —
the CMS is server-side only so CSP nonces are not required.
Includes a test suite mirroring the web-next pattern that asserts all
six headers are set, no x-nonce is emitted, and CSP mode switches
correctly between dev (unsafe-inline) and prod (strict-dynamic).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add @tanstack/start + vinxi to deps so defineConfig is available
- Uncomment defineConfig registration in app.config.ts — middleware
is now actually wired into the Nitro server hook, not just defined
- Update __root.tsx loader to call getNonce(getEvent().node.req)
from @repo/core-shared/security/tanstack so the per-request nonce
is read server-side and injected via <meta name="csp-nonce">
- Update __root.test.tsx: mock provides useLoaderData and asserts
the nonce meta tag is rendered with the correct content
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apps (web-next, web-tanstack, cms) do not configure @vitest/coverage-v8
so their source files never appear in the merged lcov; gate them out of
the cover-the-diff check.
core-shared/src/instrumentation/sentry/** is explicitly excluded from
per-package vitest coverage (see core-shared/vitest.config.ts) — exclude
from the diff gate to mirror that decision.
Adds tests for both new exclusion patterns.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Register core-shared/security/tanstack server middleware in app.config.ts
as a Nitro/H3 hook that emits the six security headers and forwards the
per-request nonce. Update instrumentation-client to read the nonce from
<meta name="csp-nonce"> and pass it to initSentryClientReact.
Add nonce support to initSentryClientReact (feedbackIntegration receives
styleNonce/scriptNonce), mirroring the initSentryClient pattern already
in place for web-next.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add apps/web-next/middleware.ts calling withSecurityHeaders() from
core-shared/security/next; exports matcher config excluding static assets
- Update layout.tsx to call getNonce() and render <meta name="csp-nonce">
so client-side JS can read the per-request nonce
- Update instrumentation-client.ts to read nonce from csp-nonce meta tag
and pass it to initSentryClient for feedbackIntegration CSP compliance
- Add nonce option to initSentryClient (InitClientOpts.nonce) and thread
styleNonce + scriptNonce into feedbackIntegration when provided
- Add middleware test asserting all six headers, prod/dev CSP shape, and
x-nonce presence; add feedbackIntegration nonce tests to core-shared
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exports withSecurityHeaders() and getNonce() from the
./security/tanstack subpath. withSecurityHeaders() returns all six
security headers plus x-nonce for use inside a TanStack/Nitro H3
server middleware; getNonce() reads x-nonce from the node request
headers forwarded by that middleware.
Mirrors the ./security/next adapter pattern while staying free of
any @tanstack/start dependency — the adapter works with plain H3
IncomingMessage types that TanStack Start exposes at wiring time
(Story 09).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements security/next subpath with withSecurityHeaders() middleware
and getNonce() Server Component helper. Middleware generates a per-request
nonce, calls buildSecurityHeaders, sets all six headers + x-nonce on the
response, and forwards the nonce via request headers for Server Component
access. Adds next as optional peer + dev dependency.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implementation seed for ADR-025 Epic D, the final epic: seven fill-in
policy templates under docs/compliance/templates/ (2 anchored, 5
skeleton with not-code-enforced banner), a two-column pre-launch
compliance checklist mapping playbook obligations to template
mechanisms, a compliance-overview.md hub, and a landed + refreshed
operator-checklist.md. Pure docs — no code, no conformance changes.
Status: approved — ready for pnpm work decompose.
Adds framework-agnostic security headers module to core-shared/security:
- SecurityHeadersConfig + CspMode types
- generateNonce() using crypto.randomBytes(16)
- buildSecurityHeaders() emitting all six headers (HSTS, X-Frame-Options,
X-Content-Type-Options, Referrer-Policy, Permissions-Policy, CSP) with
prod (strict-dynamic + nonce threading) and dev (unsafe-inline/eval +
ws/localhost) CSP modes; URL validation throwing InvalidSecurityHeadersConfig
on malformed allowedConnect/Img/FontOrigins
- Full unit test suite (24 tests, 100% coverage on runtime files)
- Exported from core-shared barrel and ./security subpath
Blocks story 07 (framework adapters) and stories 08-09 (app wiring).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
core-eslint has no @vitest/coverage-v8 so it never generates lcov data.
Add it to the tooling-packages allowlist alongside core-testing so changes
to rule source files don't trip the no-coverage-data gate.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add withRateLimit(rateLimit, fn) in rate-limit/with-rate-limit.ts,
attaching the RateLimited brand at DI bind time
- Extend wireUseCase to accept optional rateLimit?: IRateLimit and
compose withRateLimit innermost (before analytics/audit); propagate
__rateLimited through analytics + audit inline wrappers
- Extend withSpan and withCapture PROPAGATED_BRANDS to include
__rateLimited so the outermost binding carries the brand
- Extend assertFeatureConformance to require __rateLimited brand when
manifest.useCases[name].rateLimit.length > 0; refactored into
helper functions to stay within complexity thresholds
- Add rateLimit?: IRateLimit to BindContext; default to NoopRateLimit
in web-next bindAllProduction and bindAllDevSeed aggregators
- Unit tests for withRateLimit brand attachment, factory passthrough,
and composition; synthetic fixture tests for conformance errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the `no-undeclared-rate-limit` ESLint rule (warn severity) that
enforces rate-limit drift at lint time:
- Warns when rateLimit.consume("X", _) is called inside a use-case but
"X" is absent from manifest.useCases[name].rateLimit
- Warns when a declared rateLimit budget has no matching consume call
in the use-case body (unusedDeclaration)
- Is a no-op outside use-case files
Extends _manifest-ast.js to extract the rateLimit[] field from both
parseManifestUseCases and parseManifestFully. Updates _manifest-ast
tests to include the new field in expected shapes. Registers the rule
at warn severity in plugin.js and base.js. Adds RuleTester fixtures
for all four cases (declared+matching, undeclared, unused, non-use-case).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>