docs(guides): developer runbook — day-1 onboarding

This commit is contained in:
2026-05-13 09:04:28 +02:00
parent cf8d69106e
commit 05ebbb4719

283
docs/guides/runbook.md Normal file
View File

@@ -0,0 +1,283 @@
# Developer Runbook
You just cloned this repo. This is the only doc you need to read end-to-end. Everything else is reference.
---
## Prerequisites
| Tool | Version | Why |
| ------- | ------- | ------------------------------------- |
| Node.js | 22+ | Runtime for all apps + scripts |
| pnpm | 9+ | Package manager (workspace-aware) |
| Docker | 24+ | Local Postgres + sandcastle sandboxes |
| Git | 2.40+ | Version control + worktrees |
Recommended editor: VS Code or Cursor with the official TypeScript, ESLint, and Prettier extensions.
---
## First-time setup
```bash
# 1. Clone + install
git clone <repo-url> template-vertical
cd template-vertical
pnpm install
# 2. Start Postgres (background)
docker compose up -d
# 3. Copy env template and fill in secrets
cp .env.example .env
# Edit .env (see "Environment variables" section below for what each one does)
# 4. Verify the gate stack is green
pnpm typecheck
pnpm test
pnpm lint
pnpm conformance
pnpm fallow
pnpm turbo boundaries
```
All six should exit 0. If any fails on a fresh clone, file an issue — the main branch is supposed to stay green.
```bash
# 5. Start the dev servers
pnpm dev
```
This runs Next.js (3000), Payload CMS (3001), TanStack Start (3002), and Storybook (6006) in parallel. The `bindAll()` dispatcher in each app picks the dev-seed binders by default (mock repositories, no Payload connection needed beyond Postgres).
---
## Daily commands
```bash
# Development
pnpm dev # all dev servers
pnpm dev --filter @repo/web-next # one app
# Tests
pnpm test # everything
pnpm test --filter @repo/auth # one package
pnpm test:e2e # Playwright e2e
pnpm test:stories # Storybook smoke tests
pnpm test:visual # visual regression (Playwright screenshots)
# Linting + type checking
pnpm typecheck # tsc across all packages
pnpm lint # ESLint across all packages
pnpm format # Prettier write
pnpm format:check # Prettier check (CI mode)
# Conformance gates
pnpm conformance # cross-feature event closure
pnpm fallow # whole-codebase: dead exports, dupes, complexity
pnpm fallow:audit # AI-change audit (run before commits)
# Boundary validation
pnpm turbo boundaries # workspace dependency graph
# Work system
pnpm work status # tree of epics + stories
pnpm work next # next ready story
pnpm work ready # all ready stories
pnpm work blocked # blocked stories + what they wait on
pnpm work rebuild-state # regenerate docs/work/_state.json
pnpm work dispatch # print next dispatch plan
pnpm work dispatch --execute # invoke sandcastle (requires ANTHROPIC_API_KEY)
```
---
## Environment variables
Copy `.env.example` to `.env` and fill what you need. NOT every variable is required for `pnpm dev` — defaults are dev-friendly.
### Required for `pnpm dev`
| Var | Example | Why |
| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------- |
| `DATABASE_URL` | `postgresql://postgres:postgres@localhost:5433/template` | Postgres connection (docker compose default) |
| `PAYLOAD_SECRET` | `your-secret-here` | Payload CMS encryption key (any random 32+ char string in dev) |
### Optional — app URLs (defaults work in dev)
| Var | Default | Why |
| --------------------- | ----------------------- | ------------------------------------------------------ |
| `NEXT_PUBLIC_APP_URL` | `http://localhost:3000` | Public-facing web-next URL |
| `CMS_URL` | `http://localhost:3001` | Payload CMS URL |
| `USE_DEV_SEED` | `true` in dev | Force dev-seed binders (mock repos) instead of Payload |
| `NODE_ENV` | inherited | `production` flips bind dispatcher to real Payload |
### Optional — Sentry observability (no DSN = no-op tracer/logger)
| Var | Why |
| ----------------------------------------------------- | ------------------------------------------------- |
| `WEB_NEXT_SENTRY_DSN` | Server-side OTel + Sentry for web-next |
| `NEXT_PUBLIC_WEB_NEXT_SENTRY_DSN` | Browser Sentry for web-next |
| `CMS_SENTRY_DSN` | Server-side for Payload CMS |
| `WEB_TANSTACK_SENTRY_DSN` | Server-side for TanStack Start |
| `VITE_WEB_TANSTACK_SENTRY_DSN` | Browser-side for TanStack Start |
| `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT_*` | Source-map upload at build time |
| `SENTRY_TRACES_SAMPLE_RATE` | OTel trace sample rate (`0.1` recommended in dev) |
| `SENTRY_ENVIRONMENT` | `development` / `staging` / `production` |
### Optional — Git commit SHA for releases
| Var | Why |
| ------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `VERCEL_GIT_COMMIT_SHA` / `VITE_GIT_COMMIT_SHA` / `NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA` | Surfaces commit SHA in Sentry releases + UI footers |
### Optional — core-audit (only when `gen core-package audit` is scaffolded)
| Var | Why |
| ---------------------- | -------------------------------------------------------------------------------------------------- |
| `AUDIT_PSEUDONYM_SALT` | Salt for the audit log's GDPR-erasure pseudonymisation (production only — must be a stable secret) |
### Optional — sandcastle dispatch (only when running `pnpm work dispatch --execute`)
| Var | Why |
| --------------------- | ------------------------------------------------- |
| `ANTHROPIC_API_KEY` | Claude API key (sandcastle's default agent) |
| `OPENAI_API_KEY` | OpenAI/Codex alternative |
| `GITHUB_TOKEN` | GitHub access for PR creation by the orchestrator |
| `SANDCASTLE_PROVIDER` | `docker` (default) / `podman` / `vercel` |
---
## The agent-first workflow
This template enforces a **manifest-first, generator-driven, gate-protected** workflow.
### When adding a new feature
```bash
pnpm turbo gen feature <name>
```
This emits:
- `packages/<name>/src/feature.manifest.ts` — the conformance manifest (use cases, audits, publishes, consumes)
- `packages/<name>/src/di/bind-production.ts` with `assertFeatureConformance(...)` at the tail (refuses to boot on drift)
- Mock repository, factory, seed, entity, use-case, controller, tests — full Lazar-conformant shape
- `packages/<name>/src/index.ts` exports
After scaffolding, the four-step ordering for any new use case:
1. **Manifest entry** — declare the use case in `feature.manifest.ts`
2. **Contracts** — export `xInputSchema`, `xOutputSchema`, `IXUseCase` (factory body throws `not implemented`)
3. **Tests (red)** — write the failing test
4. **Implementation (green)** — fill the factory body
The five conformance gates catch drift at every step. See `docs/guides/conformance-quickref.md` for the manifest field reference.
### When adding cross-feature primitives
```bash
pnpm turbo gen event # event contract or handler (needs gen core-package events)
pnpm turbo gen job # background job
pnpm turbo gen realtime # realtime channel or handler (needs gen core-package realtime)
pnpm turbo gen core-package <x> # optional core package (events/realtime/trpc/ui/audit)
pnpm turbo gen core-ui-component <x> # atomic-design component (needs gen core-package ui)
```
**Always prefer generators over hand-rolling.** The generators emit the canonical shape; hand-rolled code drifts from generator output and breaks the CI scaffold-drift check.
### Tracking work
The repo uses `docs/work/` for epic/story/task tracking:
```
docs/work/
├── README.md
├── _state.json # derived, regenerated by pre-commit hook
├── prds/ # PRDs go here
├── _templates/ # markdown templates
└── <epic-slug>/
├── _epic.md
└── <story-slug>/
└── _story.md # contains the Tasks checklist
```
Use `pnpm work next` to see what's ready. Use `pnpm work dispatch` to plan the next sandcastle dispatch.
---
## The five conformance gates
| Gate | Latency | What it catches | Runs when |
| ------------------------------- | ------- | ------------------------------------------------------------------------------------------------ | --------------------- |
| TypeScript brands | 0s | forgotten `withSpan` / `withCapture` / `withAudit`; manifest ↔ binding-slot type mismatch | on save (IDE) |
| ESLint (8 conformance/\* rules) | <1s | manifest code drift; missing sibling test; missing manifest; atomic-tier import direction | on save / `pnpm lint` |
| Boot assertion | ~3s | runtime binding without required brand; manifest edited without rebinder | `pnpm dev` startup |
| `pnpm conformance` | ~120s | orphan event consumers across features | CI |
| `pnpm fallow` | ~3060s | dead exports / unused files; duplicate code; circular deps; complexity hotspots; AI-change audit | CI |
For the full design see `docs/architecture/agent-first-workflow-and-conformance.md`. For the daily reference see `docs/guides/conformance-quickref.md`.
---
## Troubleshooting
**`pnpm dev` refuses to boot with `ConformanceError`**
A feature's binding lost a required brand. The error message tells you which use case + which brand. Re-bind through `withSpan` / `withCapture` / `withAudit` as needed.
**`pnpm lint` errors with `conformance/feature-must-have-manifest`**
You created a feature with use cases but no `feature.manifest.ts`. Run `pnpm turbo gen feature <name>` to scaffold the canonical shape, or hand-write the manifest at `packages/<feature>/src/feature.manifest.ts`.
**`pnpm conformance` says "orphan consumer"**
A feature declares `consumes: ["X"]` but no feature publishes `X`. Either add the publish to the producing feature's manifest + factory, or remove the consumer.
**`pnpm fallow` reports new dead exports or dupes**
Your change added unused exports or duplicated logic. Either remove the dead code or accept with `pnpm fallow:audit --gate all` (the audit considers the baseline; only NEW findings fail).
**Pre-commit hook refuses to commit with "state-sync-guard"**
You staged `docs/work/_state.json` but it's not byte-identical to `pnpm work rebuild-state` output. Run `pnpm work rebuild-state && git add docs/work/_state.json` and try again.
**Tests fail in `@repo/turbo-generators` with Vitest worker timeouts**
Known flaky on slow machines. Re-run; if persistent, increase the `turbo-generators` package's vitest `testTimeout`.
**`pnpm work dispatch --execute` errors with "ANTHROPIC_API_KEY required"**
You're trying to run the sandcastle orchestrator without an agent API key. Set the env var, or run `pnpm work dispatch` (no flag) to just print the plan.
---
## Where to read next
Once you've got `pnpm dev` running:
1. **`AGENTS.md`** package map, boundary rules, per-package conventions
2. **`CLAUDE.md`** full convention reference (manifest-first ordering, factory patterns, instrumentation rules)
3. **`docs/guides/conformance-quickref.md`** daily manifest + gates reference
4. **`docs/guides/tdd-workflow.md`** red-green-refactor with the gate stack
5. **`docs/guides/scaffolding-a-feature.md`** `pnpm turbo gen feature` reference
6. **`docs/guides/adding-a-feature.md`** end-to-end walkthrough
7. **`docs/architecture/agent-first-workflow-and-conformance.md`** the full design
8. **`docs/architecture/feature-conformance-explainer.html`** interactive explainer (open in browser)
For deeper topics:
- **`docs/guides/events-and-jobs.md`** cross-feature events (requires `gen core-package events`)
- **`docs/guides/realtime.md`** Socket.IO channels (requires `gen core-package realtime`)
- **`docs/guides/audit-and-compliance.md`** DPA-compliant audit logging (requires `gen core-package audit`)
- **`docs/guides/frontend-work-shape.md`** atomic design + Storybook conventions
- **`docs/guides/infrastructure-work-shape.md`** ADR-first flow for new infrastructure
---
## Common pitfalls
- **Skipping the generator.** Always run `pnpm turbo gen <kind>` before hand-rolling. Generators emit the canonical shape; the CI scaffold-drift check will fail on hand-rolled features.
- **Forgetting `pnpm work rebuild-state` after editing `docs/work/` markdown.** The pre-commit hook handles this automatically when you stage markdown; only matters if you push without committing.
- **Bypassing `--no-verify` on commits.** The pre-commit hook catches drift early. If it's blocking a legitimate change, fix the underlying issue, not the hook.
- **Hand-editing `_state.json`.** Don't. The state-sync-guard refuses commits that drift from rebuild output. Edit the markdown; let the rebuild script propagate.
- **Committing `.env`.** It's gitignored. Use `.env.example` for new vars.
---
For deeper philosophy: this template is built around the assumption that **AI agents will author most feature work**. The conformance system is designed as an agent feedback loop. Latency-layered gates compound: 0s + <1s + 3s + 120s + 60s. The faster the inner loop, the more iterations agents can make per task.
If you're a human contributor, the same workflow applies the gates aren't punitive, they're navigational aids.