- Split globals.css into globals.css + theme.css so Storybook can
import design tokens without the @import "tailwindcss" directive
that breaks Vite's preview module loading
- Prepend @tailwindcss/vite plugin for correct processing order
- Add @source to scan core-ui components for utility class generation
Webpack (Next.js transpilePackages) resolves from .ts source directly
and cannot find .js files. The bind-production binders already used
extensionless imports; align bind-dev-seed to match. Also fixes the
turbo gen feature template so new features are consistent.
Bring docs/architecture/ in line with the current repo:
- feature-conformance-explainer.html: drop the "proposed / not yet
implemented" framing — the system is shipped. Four enforcement points
become five (adds `pnpm fallow` as the whole-codebase audit). Manifest
playground shows `coverage`, `analyticsEvents`, `rateLimit`,
`requiresConsent`. Milestone / anchor / open-question sections kept
but marked historical.
- agent-first-workflow-and-conformance.md: four → five enforcement
layers; layer table gains the Fallow row.
- di-explainer.html: bind-production sample rewritten to show
wireUseCase() + assertFeatureConformance() + the full wrapper stack
(span → capture → audit? → analytics? → consent? → rateLimit?).
- data-flow-explainer.html: same bind-production refresh for the
data-flow narrative.
- audit-and-compliance-explainer.html: AuditAction enum 6 → 10 values
(CONSENT_GRANT / WITHDRAW / RESTRICT / UNRESTRICT);
BindProductionContext example gains analytics, consentFactory,
rateLimit.
- vertical-feature-spec.md: §5 layout lists the 8 optional cores plus
core-testing; §9.5 hedges the turbo.json snippet against the live
file; §10.4 drops the dated "360 tests" metric for the ADR-020
coverage architecture; §11 gains a historical lead-in pointing at
docs/decisions/ as the canonical 25-ADR set.
Align the architecture docs with the current repo:
- Boundary matrix: feature may depend on core, feature, tooling — a
feature may import another feature's public exports. overview.md,
dependency-flow.md, and vertical-feature-spec.md all said the stale
`feature -> core, tooling`.
- Optional-core lists completed with core-analytics, core-consent,
core-dsr; tooling list completed with core-testing.
- Package count corrected to the accurate 19-package breakdown.
- BindContext table gained analytics, consentFactory, rateLimit.
Deeper drift (the HTML explainers, vertical-feature-spec §5/§9.5/§11)
is tracked in the local .tmp/ working note, not yet addressed.
In-session skill counterparts to `pnpm work decompose --execute` and
`pnpm work dispatch --execute`. They dispatch sub-agents — a decomposer
for /work-decompose; separate worktree-isolated implementer and
read-only reviewer sub-agents for /work-dispatch's implement-review loop.
Single source of truth: the skills read `.sandcastle/*.prompt.md` at
dispatch time and never copy them — the prompt files stay authoritative
for both Sandcastle and the skills, so the role definitions cannot
drift. `.sandcastle/` and `pnpm work` are untouched; this is additive.
turbo.json's boundary config already allows `feature -> feature`, and
the cross-feature event system depends on it — a consumer must import
the publisher's event contract from `@repo/<publisher>`. But the ESLint
boundaries config, ADR-010, and AGENTS.md still declared
`feature -> [core, tooling]`, contradicting turbo.json and the shipped
code (marketing-pages imports @repo/auth).
Align all three to turbo.json: a feature may import another feature's
published public exports. Internals stay sealed by the `exports` map,
and cross-feature behaviour still flows through IEventBus.
The core-package e2e tests cover each generator in isolation. None
exercised generators running in sequence — so the feature template
shipping without an integrations/cms/index.ts barrel went unnoticed
until `gen job` failed against a scaffolded feature.
This test scaffolds a feature, then runs `gen job` against it. `gen job`
throws at its `<gen:job-tasks>` anchor assertion if the barrel is
missing, so the composition gap now fails loudly.
Two CLAUDE.md conventions had no mechanical gate, so both drifted:
entity models shipped without sibling tests, and feature test files
imported src modules via `../` instead of the `@/` alias.
- `entity-must-have-test` — every entities/models/<x>.ts needs a sibling
<x>.test.ts (errors and barrels excluded).
- `no-relative-parent-import-in-tests` — feature test files must import
src via `@/`, not `../`. Scoped to feature packages; core packages are
governed by their own generator templates.
Both register at warn level, bringing the conformance rule count to 15.
The rule only matched bus.publish("string-literal", ...), but the
canonical pattern that `gen event` prescribes is
bus.publish(eventDescriptor, payload) — an imported identifier, never a
literal. The rule therefore never fired on real code, which is how the
auth signUp publish drifted from its manifest undetected.
Add `_event-ast.js`: resolves a `bus.publish(<identifier>)` argument by
following the import to the event-contract file and extracting the name
from either `defineEvent("...", schema)` or an inline `{ name }` object.
Unresolvable arguments are skipped, so the rule never false-positives.
bind-production.types.test.ts imported feature.manifest and the sign-in
use case with `../` parent paths. Test files import src modules via the
`@/` alias per the repo convention — this clears the way for the new
no-relative-parent-import-in-tests rule.
Each core-package e2e test's `onTestFinished` cleanup `rmSync`-es a temp
clone containing a full installed `node_modules`. That delete can exceed
vitest's 10s default hook timeout under load, failing 2-8 of the 8 e2e
tests per run. Set `hookTimeout: 120_000` to match the per-test timeout.
The feature generator emitted no `src/integrations/cms/index.ts`, but
`gen job` and `gen event consume` both `assertAnchors` on that file's
`<gen:job-tasks>` anchor — so they failed on any freshly-scaffolded
feature. Add a `cms/index.ts.hbs` template carrying the anchor, wire the
add action into the generator, and export `./cms` from the package.json
template to match all five existing features.
container.test.ts imported cross-directory modules with `../...` paths.
Test files use the `@/` alias for src imports per the repo convention;
this was the outlier vs auth/media/navigation.
cookie.ts was the only entity model in the feature packages without a
sibling test. Covers minimal/full attributes, invalid sameSite, and a
missing required field.
The signUp use case calls `bus.publish(userSignedUpEvent, ...)` but its
manifest entry declared `publishes: []`. The conformance event graph was
blind to the entire auth -> marketing-pages welcome-email flow as a
result. Declaring "auth.user.signed-up" makes `pnpm conformance` surface
the event and its publisher.
Storybook's `stories` glob was emptied when core-ui became an optional
scaffoldable package. With core-ui present in the repo, wire the glob
back so its six stories are discovered — the manual post-scaffold step
the `gen core-package ui` generator already documents.
The analytics, consent, and dsr optional-core generators lacked the
byte-identical reconstruction e2e tests the other five optional cores
already have. Add the three tests and their snapshots.
Adding three more tests exposed a latent flaw in the suite: each test
does a full `pnpm install` in a temp clone, and running all eight in
parallel saturated vitest's workers (RPC timeout) while the never-cleaned
temp dirs filled the disk. Run the suite sequentially via
`fileParallelism: false` and remove each temp clone with `onTestFinished`;
also exclude the local `.pnpm-store` from the clone.
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>