Also folds in the spec correction noted in the plan's known follow-up
\#1: subscribe takes consumerFeature: string as a second arg between
descriptor and handler. § 3.3 and § 5.4 updated.
gen event consume now emits a second file: an __events-<publisher>-
<event>.task.ts Payload task that delegates to the consumer's
container-resolved wrapped handler. The bind block also binds the
wrapped handler into the per-feature container by symbol so the
task can resolve it. With this, PayloadJobsEventBus is fully wired
end-to-end with no manual per-event task hand-write required.
Removes the corresponding Known Follow-up item.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
56 bite-sized tasks across 9 phases implementing the spec at
docs/superpowers/specs/2026-05-08-events-and-jobs-design.md:
core-shared/jobs (IJobQueue + 2 impls), core-events package
(IEventBus + 2 impls), recording test helpers, two ESLint rules,
existing-feature anchor retrofit (5 features × 6 anchors), bindAll
bus/queue swap, three Plop generators with anchor-comment protocol,
end-to-end proof-of-life (sign-up → welcome email), and the full
documentation set (ADR-015 + new guide + AGENTS/CLAUDE/scaffolding
updates). Self-review caught and fixed one type-inconsistency
(3-arg subscribe) and explicitly deferred the production task-
registration gap. TDD-ordered with one commit per task.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Long-form design for a future ADR-015. Defines IEventBus (new
@repo/core-events) and IJobQueue (@repo/core-shared/jobs); the bind/swap
rules; the events/, events/handlers/, jobs/, integrations/cms/jobs/
folder layout; the on-<publisher>-<event-kebab>.handler.ts naming rule;
the span+capture sandwich extension with op: "event-handler" and
op: "job"; three new ESLint rules; RecordingEventBus and RecordingJobQueue
for tests; pnpm turbo gen event {publish|consume} and gen job generators
plus the // <gen:*> anchor-comment protocol; and the existing-feature
retrofit. Status: draft pending user review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Plan 10 documented R44 (capture at originating-throw layer) but only the
R43 repo leg was wired. captureException had zero call sites in any
controller or use-case body. This commit closes the gap.
Mechanism:
- Extract __sentryReported flag helpers into core-shared/instrumentation/
reported-flag.ts. SentryLogger switches to importing them; RecordingLogger
carries an inlined copy (tooling → core boundary disallows the import).
- Add withCapture(logger, tags, fn) higher-order wrapper paralleling
withSpan. On throw: capture-with-tags, mark, re-throw. Bail if the flag
was already set — covers the bubbled-from-repo case so each error
surfaces in the logger exactly once with the inner-most layer's tags.
- Apply withSpan(withCapture(factory)) in every feature's bind-production
and bind-dev-seed: auth (3 use cases × 3 controllers), blog (3×3),
marketing-pages (2×2), navigation (1×1), media (3×3). Span is outermost
so the errored span timing reflects the capture-and-rethrow.
- RecordingLogger.captureException now also honours the flag — test
capture counts stay honest when both repo and outer layer wrap.
Tests:
- packages/core-shared/src/instrumentation/with-capture.test.ts —
4 cases covering success, capture-on-throw, mark-on-capture, no-double
via the flag.
- packages/blog/tests/r44-no-double-capture.test.ts — 3 cases: repo throw
→ 1 capture with repo tags; controller parse fail → 1 capture with
controller tags; success → 0 captures.
Verification: pnpm test 26/26, pnpm lint 15/15, pnpm typecheck 14/14.
Docs: ADR-014 and the refactor log gain a "Post-merge follow-up" section
recording the gap, the fix, and the underlying lesson (don't describe
intent as shipped state — grep first).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the ADR-014 stub with the full Accepted-status decision record:
context, the 7 numbered decisions (vendor-neutral interfaces, full-depth
instrumentation, throw-site capture, PII rules, three Sentry projects,
ESLint boundary, Recording* test pair), alternatives considered,
positive/negative consequences, and an "execution notes" section
covering the spec deviations and surprises encountered.
Updates the refactor log: ticks all 33 tasks, populates "Decisions
deviated from spec" (PII key list extended with ipaddress; spec
section appended as §16 not §10; vite.config skipped; HTML section
numbering kept conservative) and "Notable surprises" (apps needed
direct core-shared deps; deep subpath exports for dynamic import;
peerDependenciesMeta.optional for @sentry/node and @sentry/react;
pre-existing lint debt; allowlist patterns needed **/-prefix for
flat-config glob matching from sub-package cwd).
Final verification (run before commit):
- pnpm test → 26/26 tasks pass
- pnpm lint → 15/15 tasks pass (warnings-only)
- pnpm typecheck → 14/14 tasks pass
- R31 grep gate (sendDefaultPii: true) → clean, no matches
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
33-task TDD plan implementing the R31–R55 spec across 9 phases:
foundation interfaces (NoopTracer/NoopLogger/withSpan), Sentry adapters
(SentryTracer/SentryLogger with __sentryReported double-report guard,
beforeSend + beforeSendTransaction PII scrubbers), DI binders + bindAll
Rule 0 dispatcher (orthogonal to USE_DEV_SEED/NODE_ENV), test
infrastructure (RecordingTracer/RecordingLogger + no-sentry guard),
per-feature wiring for all 5 features (blog/auth/marketing-pages/
navigation/media), contract suite span assertions, three-app integration
(web-next/cms/web-tanstack including @sentry/node + @sentry/react +
@sentry/vite-plugin variants), ESLint boundary rule + CI grep gate, and
docs + HTML updates (data-flow-explainer §06, di-explainer
instrumentation symbols, ADR-014).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Defines the post-Plan-9 instrumentation subsystem: vendor-agnostic
Tracer/Logger interfaces in core-shared, full-depth tracing
(procedure → controller → use-case → repository) with use-case +
controller spans applied via withSpan at DI binding time and explicit
tracer.startSpan in every repository method, throw-site error capture
with __sentryReported double-report guard, and hard PII rules
(sendDefaultPii:false, default-mask replay, beforeSend/beforeSendTransaction
scrubbers, opaque user IDs only, build-time CI grep gate).
Three apps in scope (web-next, cms, web-tanstack), each with its own
Sentry project and DSN. Instrumentation binding is orthogonal to
USE_DEV_SEED/NODE_ENV repo binding. Optional dev-mode Sentry: NoopTracer
default, real SDK initializes only if DSN env is set.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- CLAUDE.md Key Conventions: 'App bootstrap' rule rewritten as 'Three
binding modes per feature' — describes USE_DEV_SEED + NODE_ENV
resolution order and the new ./di/bind-dev-seed export.
- AGENTS.md (root): exports list now mentions ./ui + ./di/bind-dev-seed;
Per-feature public-API surface table gains a row; Apps section shows
the bindAll() dispatcher with three-rule logic.
- docs/architecture/vertical-feature-spec.md §6: file shape now
includes bind-dev-seed.ts, bind-dev-seed.test.ts, __seeds__/dev.ts;
package.json exports list updated to include ./di/bind-dev-seed.
- docs/architecture/data-flow-explainer.html: anatomy tree gains
__seeds__/ row; LAYERS.di description updated with new binders +
cross-link to di-explainer.html; new LAYERS.seeds entry; public-
surface card expanded to six subpaths.
- docs/superpowers/refactor-logs/2026-05-06-input-output-unification.md
§7: new 'Post-Plan-9: dev-seed binders' entry summarizing the rollout
(commits, per-feature additions, app wiring, tests, turbo, docs).
- bind-production.test.ts: dispatcher tests use vi.stubEnv (typesafe
way to test process.env in TypeScript 5+ with @types/node read-only
process.env types). 4 dispatcher tests + 2 bindAllProduction tests
= 7 tests total.
First slice of the combined Plan 8 + Plan 9 doc-update pass:
- CLAUDE.md Key Conventions: append schema-in-use-case, presenter,
controller unknown input, feature-scoped tRPC error mapping, public
surface split (./ui)
- packages/core-shared/AGENTS.md: document defineErrorMiddleware export
+ t re-export from trpc/init
- docs/superpowers/plans/2026-05-05-plan-8-*.md and matching spec:
one-line note that some controller/router patterns shifted in Plan 9;
link to the Plan 9 refactor log
- docs/architecture/overview.md: data-flow box now shows xProcedure +
xInputSchema + xOutputSchema.parse + presenter + middleware lanes;
three explanatory paragraphs added (schemas, presenter, error mapping)
- docs/architecture/dependency-flow.md: app-side ./ui subpath note,
allowed/disallowed examples updated for Plan 9 paths
Remaining doc-pass items (root AGENTS.md, per-feature AGENTS.md ×5,
core-testing AGENTS.md, adding-a-feature.md, tdd-workflow.md,
testing-strategy.md, vertical-feature-spec.md) follow in subsequent
commits — to be dispatched in parallel.
Final reviewer flagged two changelog inaccuracies:
- Summary said 14 commits; actual is 15 (88db39b..HEAD).
- §7 Task 8 said +144 tests; correct delta is +35 (325 → 360, +11%).
The +144 figure was a typo from the implementer's draft.
Both reconciled. Plan 9 ships.
Records the Plan 9 architectural decision (schemas in use-case file,
runtime output validation, presenter pattern, feature-scoped error
middleware, ./ui subpath split). ADR-012 gets a one-line cross-
reference to the new ADR. Refactor log gets a Summary section with
commit table and conformance checklist.
Plan 9 complete. The deferred doc-update pass (CLAUDE.md / AGENTS.md /
guides) — combined with the still-pending Plan 8 items — is the next
follow-up.
Refactor log: Summary, doc-update checklist
Spec: R29, R30
Straggler fixes: web-next and web-tanstack app callers did not pass {}
to queryOptions()/caller calls after Plan 9 added .input(z.object({}).strict())
to siteSettings and header procedures. All 360 tests pass, full typecheck
green across 14 packages. Refactor log §7 updated with verification summary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spec reviewer noted §6.3 was missed during Task 3 commit. The presenter
tests exist in code (sign-in / sign-up controller tests assert cookie
shape, not full use-case output); the changelog just didn't record it.
Pure docs change.
Per Plan 9 (spec R1-R28):
- Use cases: input + output schemas (signIn, signUp); input-only for
signOut (void output). Use case body validates output via
outputSchema.parse before returning.
- Controllers: receive `unknown`; safeParse with the use-case schema;
presenter (returning cookie) for signIn/signUp; void return for
signOut.
- New integrations/api/procedures.ts with authProcedure built via
defineErrorMiddleware([[InputParseError,"BAD_REQUEST"],
[AuthenticationError,"UNAUTHORIZED"], [UnauthenticatedError,
"UNAUTHORIZED"], [UnauthorizedError,"FORBIDDEN"]]).
- Router uses authProcedure + .input(xInputSchema) for every procedure.
- src/index.ts exports schemas + types + IUseCase/IController aliases.
- package.json gains ./ui subpath; src/ui/index.ts placeholder
(auth has no query builders today).
- New tests: R25 output-validation per use case (signIn, signUp);
R26 router error-mapping (UNAUTHORIZED on missing user,
BAD_REQUEST on schema fail).
Refactor log: §1, §2, §3.1, §3.2, §3.3, §5.1, §5.2, §6.1, §6.2
Spec: R1–R6, R8–R15, R18, R19, R22–R26
Factory takes [[ErrorCtor, TRPC_CODE], ...] tuples and returns a tRPC
middleware that translates matching domain errors to TRPCError. Discrim-
inates by instanceof; preserves original error as cause; unmapped
errors propagate (tRPC then wraps them as INTERNAL_SERVER_ERROR with
the original error as .cause — middleware does not interfere).
core-shared never enumerates feature errors — each feature passes its
own constructors in via integrations/api/procedures.ts (Tasks 3-7).
Also exports the `t` instance from trpc/init.ts so feature procedure
files can do t.procedure.use(...).
Also fixes tsconfig.json: rootDir set to "." and @/* path alias added
so test files using @/ resolve correctly under tsc --noEmit.
Refactor log: §1, §2, §4
Spec: R13–R17
Empty section template plus the doc-update checklist that the
post-Plan-9 follow-up pass will work through (combined with the still-
pending Plan 8 items so docs are written once).
Spec: docs/superpowers/specs/2026-05-06-input-output-unification-design.md §10, R30.
9 tasks, TDD throughout, one commit per task:
1. Refactor changelog scaffold
2. core-shared/trpc/define-error-middleware.ts factory + tests
3. auth migration (3 use cases — schemas + presenter + procedures.ts + router + ./ui + tests)
4. blog migration (3 use cases)
5. marketing-pages migration (2 use cases)
6. navigation migration (1 use case)
7. media migration (3 use cases)
8. Final verification + boundary sweep
9. ADR-013 + final changelog summary
Every step has concrete code; no placeholders. Self-review shows full
spec coverage (R1–R30) with each rule mapped to one or more tasks.
Spec: docs/superpowers/specs/2026-05-06-input-output-unification-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codifies a single source of truth for use-case input/output contracts:
- Every use case exports xInputSchema/XInput and xOutputSchema/XOutput
from its own file; controllers and tRPC procedures import the same
schema. Use case body runtime-validates output via .parse before
returning.
- Controllers gain a co-located top-level `function presenter`
(Lazar-style) that reshapes entity output to view DTO; controller
return type = ReturnType<typeof presenter>.
- Domain error → TRPCError mapping moves to per-feature
integrations/api/procedures.ts via a defineErrorMiddleware factory
in core-shared/trpc/. core-shared never enumerates feature errors.
- Per-feature public-API surface cleaned: feature root = contracts
only (types, errors, schemas, IUseCase aliases, router type); new
./ui subpath holds query builders / components.
30 numbered rules using RFC-2119 MUST/SHOULD language so every
enforceable decision is citable from CLAUDE.md and per-feature AGENTS.md
during the post-Plan-9 doc-update pass. Includes file-shape templates,
migration order (~9 commits), doc-update mapping per rule, and an
ADR-013 mandate.
Spec: docs/superpowers/specs/2026-05-06-input-output-unification-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First slice of the Plan 8 deferred doc-update checklist:
- CLAUDE.md Key Conventions: factory-function use cases/controllers,
entities/models/<x>.ts paths, .toDynamicValue DI bindings, direct
injection in tests
- docs/architecture/overview.md data-flow box updated to factory style
(controller resolved via container.get<IXController>; use case factory
takes deps as args)
- docs/decisions/adr-012-lazar-conformance.md created — records the
conformance decision and four intentional divergences
- docs/superpowers/plans/2026-05-05-plan-7-tdd-foundation.md and the
matching spec annotated with a "pre-Plan-8 layout" note pointing at
the refactor log
Remaining Plan 8 doc-update items (root AGENTS.md, per-feature AGENTS.md,
adding-a-feature.md, tdd-workflow.md, testing-strategy.md,
vertical-feature-spec.md §6/§10, core-testing AGENTS.md) intentionally
paused — Plan 9 (input/output unification) will change overlapping
content, so resuming after Plan 9 lands avoids double-churn.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All conformance checks pass per spec §12 acceptance criteria. Summary
section populated with 9 task commits, file count breakdown, and
verification results. Doc-update checklist (deferred) remains untouched
— ready for follow-up doc pass.
Test count: 244 → 325 (+81). All features now structurally conformant
with Lazar Nikolov Clean Architecture pattern (with intentional
divergences documented in spec §4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Use case (get-header) → factory function with IGetHeaderUseCase alias
- Controller renamed header.controller.ts → get-header.controller.ts (verb-noun); converted to factory function with IGetHeaderController alias
- DI module wires factories with .toDynamicValue()
- tRPC router resolves controller via container
- Use case + controller tests refactored to direct factory injection (no container rebinding)
- container.test.ts verifies IGetHeaderUseCase + IGetHeaderController symbols
Refactor log: §1, §4.1, §4.2, §5.1
Spec: §6.4
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use cases (sign-in, sign-up, sign-out) → factory functions with I*UseCase aliases
- Controllers → factory functions with I*Controller aliases
- DI symbols + module updated with .toDynamicValue() bindings for factories
- New: real UsersRepository (Payload-backed, SanitizedConfig, contract-tested)
- New: real AuthenticationService (node:crypto hashing/UUIDs; createSession/
validateSession/invalidateSession deferred — see refactor log §7)
- bindProductionAuth swaps both mocks for real impls (was a no-op before)
- Tests refactored to construct mocks and inject directly (no container rebinding)
- Feature test constructs full chain via direct factory injection
Refactor log: §2, §4.1, §4.2, §5.1, §5.2, §6.1, §7
Spec: §6.1, §7
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 5 features (auth, blog, marketing-pages, navigation; media has no
entities yet) now follow Lazar's pattern:
- entities/<x>.ts → entities/models/<x>.ts
- entities/errors.ts → entities/errors/<domain>.ts + errors/common.ts
Updates all import paths across factories, contracts, tests, use cases,
controllers, repositories, integrations, and src/index.ts exports.
navigation divergence: had no errors.ts; errors/header.ts +
errors/common.ts added as new forward-looking stubs.
Refactor log: docs/superpowers/refactor-logs/2026-05-05-lazar-pattern-conformance.md
Spec: §5, §9.3
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Empty section template plus the full doc-update checklist that the
follow-up pass will work through after the refactor is merged. Captures
the substitution map (paths, naming, patterns) so the doc updater can
apply changes mechanically.
Spec: docs/superpowers/specs/2026-05-05-lazar-pattern-conformance-design.md §10
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ten TDD'd tasks executing the Lazar Nikolov Clean Architecture pattern
across all 5 features. Task 1 scaffolds the refactor changelog (sole
artifact for the deferred doc-update pass). Tasks 2-3 are foundation
(entities split, file renames). Tasks 4-7 refactor each existing feature
to factory-function pattern. Task 8 scaffolds media as a full Clean
Architecture feature. Task 9 aligns factory/contract imports. Task 10
final verification.
External docs (CLAUDE.md, AGENTS.md, adding-a-feature.md, tdd-workflow.md,
ADR-012) explicitly NOT touched during the refactor — captured as a
checklist in the refactor changelog for a single batched doc-update pass
afterwards.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings every feature into structural conformance with the reference
nextjs-clean-architecture repo: factory-function use cases and
controllers, entities/{models,errors}/ split, .mock.ts file suffix,
per-use-case controller files, real PayloadUsersRepository and
PayloadAuthenticationService for auth, full Clean Architecture
scaffold for media. Documents intentional divergences (per-feature DI,
inversify retained, colocated tests). All external doc updates
deferred to a follow-up pass driven by the refactor changelog.
Spec: docs/superpowers/specs/2026-05-05-lazar-pattern-conformance-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Catalogues the ten gaps that prevent reliable TDD by agents and humans
in this monorepo, and specifies the closure plan: a new @repo/core-testing
package (factories + contract suites + RTL helpers + payload mocks),
jsdom + safety defaults in core-typescript Vitest bases, tests in core-*
and apps, Storybook test-runner, coverage thresholds, CI workflow, and
two new docs (tdd-workflow.md plus a restructured adding-a-feature.md
that interleaves tests with implementation).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aligns tooling packages with the core-* naming convention used by all
other foundation packages (core-shared, core-cms, core-api, core-trpc,
core-ui). Updates ~50 files: package.json names, devDependencies,
tsconfig extends, eslint.config imports, vitest.config imports, AGENTS.md
references, and the boundaries plugin patterns to match the new paths.
The tooling-specific patterns in boundaries/elements are now ordered BEFORE
the broader core-* pattern to ensure correct first-match-wins behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
20 tasks in 5 phases: A) migrate ui→core-ui, repoint apps/cms+storybook,
delete 6 legacy packages; B) eslint-plugin-boundaries with three-tag
model + composition exceptions; C) Playwright in both apps with smoke
specs + root test:e2e task; D) full doc rewrite (overview, dependency
flow, guides, root+per-package AGENTS.md, 4 new ADRs, 4 updated/
superseded ADRs, delete 6 stale plans); E) all-green final check.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Server uses superjson via core-shared/trpc/init's initTRPC config.
Client httpBatchLink must match or complex types (Date, Map, Set)
silently break on the wire. Caught during execution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
17 tasks: populate core-trpc with React client + per-framework providers;
add bindProduction(config) helpers to each payload-backed feature;
swap web-next deps from @repo/api/api-client/ui to core-* + features;
wire tRPC route handler with idempotent bindAllProduction(); render
example pages (home with nav + site name + article list, /about,
/blog/[slug]); parallel-prove framework portability in web-tanstack.
First plan that produces browser-rendered output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TypeScript emits an informational diagnostic when source files span
multiple top-level dirs (src/ + tests/) without explicit rootDir.
Setting rootDir="." satisfies the recommendation and matches the
include pattern. Updates blog, auth, marketing-pages — and Plan 4
doc so navigation (still pending) starts correct.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
17 tasks: marketing-pages with Pages collection + SiteSettings global +
read use-cases + tRPC router; navigation with Header global + read
use-case + tRPC router. Composes both into core-cms (now 4 collections,
2 globals) and core-api (now 4 namespaces). All Plan 2/3 lessons baked in.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
17 tasks: full auth feature canonical migration (entities, services,
use-cases, DI with constructor-injected service, controllers, users
collection, tRPC router); skeleton media feature (collection only);
restore blog's author→users relation and featuredImage→media upload.
Bakes in all Plan-2 lessons (vitest alias, no rootDir, relative imports
in src, no @repo/core-cms in feature deps).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Discovered during execution: when downstream packages like @repo/core-api
typecheck and follow imports into a feature, they don't have the feature's
@/ alias and fail with TS2307. Source files use relative imports;
@/ is reserved for test files within the feature's own context.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>