- 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.
Three-rule resolution order in bindAll() (first match wins):
1. USE_DEV_SEED === 'true' → bindAllDevSeed (explicit override)
2. NODE_ENV === 'production' → bindAllProduction
3. otherwise → bindAllDevSeed (developer default)
Rationale: 'pnpm dev' should boot the app without requiring Payload to
be running locally — dev seed is the more useful default for non-
production environments. Production servers explicitly set
NODE_ENV=production and get the real binding. The USE_DEV_SEED override
remains the escape hatch (force seed in any NODE_ENV — e.g. staging
preview, design review).
bind-production.test.ts grows from 3 tests to 8 — covers the dispatcher
matrix:
- USE_DEV_SEED='true' wins even when NODE_ENV='production'
- NODE_ENV='production' (no override) → production
- NODE_ENV='development' → dev seed (default)
- NODE_ENV unset → dev seed (default)
- USE_DEV_SEED='false' treated as not-set (only the literal 'true' triggers)
- Pre-existing 'binds all five repos' test now also asserts bindProductionMedia
di-explainer.html conditions table + mode flag strings updated to match
the new three-rule logic.
apps/web-next/src/server/bind-production.ts now exports three functions:
- bindAllProduction() — production-only binders
- bindAllDevSeed() — dev-seed-only binders (NEW, calls all 5 features)
- bindAll() — dispatcher that branches on USE_DEV_SEED env var
All page/route callers (page.tsx, about/page.tsx, blog/[slug]/page.tsx,
api/trpc/[trpc]/route.ts) updated from bindAllProduction → bindAll so the
env flag actually has effect.
docs/architecture/di-explainer.html (NEW): standalone interactive page
explaining the di/ folder file-by-file, the loading sequence (8 stages),
the three binding kinds (.to / .toDynamicValue / .toConstantValue), an
interactive three-mode picker showing how the same blogContainer state
differs across default/dev-seed/production, a conditions table, and a
final card on how tests bypass DI entirely. Sister page to
data-flow-explainer.html.
Refactor log entry + canonical doc updates follow in subsequent commits.
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>
Per-package tags + root boundaries block now enforce the same three-tag
model as eslint-plugin-boundaries:
- app → may depend on: app, core, core-composition, feature, tooling
- feature → may depend on: core, tooling
- core → may depend on: core, core-composition, tooling
- core-composition (core-api, core-cms) → may depend on: core, feature, tooling
- tooling (core-eslint, core-typescript) → may depend on: tooling
Tags applied: 4 apps (app), 3 core foundation packages (core),
2 core composition packages (core-composition), 5 features (feature),
2 tooling packages (tooling). All test suites pass.
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>
next-env.d.ts is a generated file using triple-slash references that
TypeScript requires. ESLint exemption added in apps/web-next config only.
Also declare CI, DATABASE_URL, PAYLOAD_SECRET, NODE_ENV in turbo.json
globalEnv so turbo/no-undeclared-env-vars stops warning.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All public pages (site settings, header, pages, articles) now bypass
Payload's access control checks when reading, as they should be publicly
accessible without authentication. This fixes 403 Forbidden errors on
homepage and article rendering.