Stack
Technology decisions, routing rules, and critical constraints that govern every project built on this framework.
Locked Decisions
Researched, deliberate choices. Do not substitute. If an agent introduces an unauthorized library, catch it and revert.
| Decision | Use This | Not This | Why |
|---|---|---|---|
| Date/time | date-fns (migrating from Luxon) | moment, dayjs, native Date | Tree-shakeable, functional API. Migration in progress — do not flag date-fns as violation |
| Validation | Zod | yup, joi, io-ts | TypeScript-first, runtime + static |
| State (client) | Zustand | Redux, MobX, Jotai | Minimal boilerplate, no providers |
| State (server) | TanStack Query | SWR, manual fetch | Cache invalidation, devtools |
| CSS | Tailwind CSS 4 | CSS modules, styled-components | Utility-first, framework standard |
| Components | shadcn/ui + Radix UI | Material UI, Chakra, Ant Design | Composable, unstyled primitives |
| Forms | React Hook Form | Formik | Performance, uncontrolled components |
| Package manager | pnpm | npm, yarn | Strict, fast, workspace-native |
| Logging | Axiom | console.log, winston, pino | Structured cloud logging |
| Errors | Sentry | manual error tracking | Source maps, session replay |
| Analytics | PostHog | Mixpanel, Amplitude | Self-hostable, feature flags |
| Remote access | Moshi + Tailscale + tmux | Claude Code Remote Control | Full terminal UI, voice input, resilient Mosh, push notifications, no intermediary routing |
| Diagrams/visuals | `/diagram` skill (Gemini 3 Pro Image) | Mermaid, HTML+Playwright rendering | Native image gen, no rendering pipeline, richer output |
Agent Routing
Route by domain to the right agent. Each specialist has a defined model tier and area of responsibility.
| Agent | Model | Domain | File |
|---|---|---|---|
| Orchestrator | sonnet | Routing, delegation | `.claude/agents/agents-orchestrator.md` |
| Frontend Developer | sonnet | UI, components, pages | `.claude/agents/engineering-frontend-developer.md` |
| Backend Architect | opus | Architecture, system design | `.claude/agents/engineering-backend-architect.md` |
| Senior Developer | sonnet | Backend, APIs, logic | `.claude/agents/engineering-senior-developer.md` |
| Security Engineer | opus | Threats, audits, RLS | `.claude/agents/engineering-security-engineer.md` |
| Planner | sonnet | Plans, specs, design phase | `.claude/agents/planner.md` |
| Critic | sonnet | Code review, technical critique | `.claude/agents/critic.md` |
| Simplifier | haiku | Scope checks, complexity reduction | `.claude/agents/simplifier.md` |
| Standards | haiku | Standards compliance, drift detection | `.claude/agents/standards.md` |
Model Tier Policy
Every agent has an assigned model tier. These are deliberate choices — do not override without justification.
| Tier | Model | When to Use | Agents |
|---|---|---|---|
| Opus | claude-opus | Judgment-heavy work: architecture decisions, security analysis, creative design, threat modeling | Backend ArchitectSecurity Engineer |
| Sonnet | claude-sonnet | Execution work: implementation, planning, code review, delegation. Default tier for new agents. | OrchestratorFrontend DeveloperSenior DeveloperPlannerCritic |
| Haiku | claude-haiku | Checklist/rule-following work: scope checks, standards compliance, drift detection | SimplifierStandards |
Critical Rules
These rules exist because they were violated and caused real problems. No exceptions.
- No `any` types — Use proper TypeScript typing
- No console.log — Use Axiom/Sentry logging
- No TODO without issue reference — Every TODO must reference a Linear issue
- No native Date — Always use Luxon (see Locked Decisions)
- Validate at edge — Zod schemas for all external inputs
- Verify before claiming done — Run the full verification command and confirm output
- Sequential git writes — Sequential by default. Parallel execution is allowed when: (1) `/batch` overlap detector confirms no write-write conflicts, (2) each lane runs in an isolated git worktree, (3) merge ordering is sequential (Lane 1 → 2 → 3). Outside `/batch`, the rule remains absolute: one branch at a time.
- Check Locked Decisions — Before introducing any library, check the Locked Decisions table. If there is a locked choice for that domain, use it.
- Confirmation scoping — Execute when the path is clear; ask only when genuinely ambiguous.
Upgrade Paths
When the locked decision is no longer the best choice, here is what the migration would look like and how much effort and risk it carries.
| Decision | Current | Alternative | Effort | Risk | Notes |
|---|---|---|---|---|---|
| Date/time | date-fns (migrating from Luxon) | Temporal API (Stage 3) | High | Low | Wait for browser support |
| Validation | Zod | Valibot | Low | Low | Smaller bundle, similar API |
| State (client) | Zustand | Jotai | Medium | Low | Different mental model |
| State (server) | TanStack Query | SWR | Medium | Medium | Less features |
| CSS | Tailwind CSS 4 | N/A | N/A | N/A | No viable alternative |
| Components | shadcn/ui | N/A | N/A | N/A | No viable alternative |
| Forms | React Hook Form | TanStack Form | Medium | Low | Newer, growing ecosystem |
| Package manager | pnpm | Bun | Medium | High | Runtime compatibility risks |
| Logging | Axiom | Datadog | High | Medium | Vendor lock-in concern |
| Errors | Sentry | N/A | N/A | N/A | No viable alternative |
| Analytics | PostHog | N/A | N/A | N/A | No viable alternative |
Architecture Overview
How a web request flows through the stack, with locked decisions mapped to each layer.
How a web request flows through the stack, and which locked decisions operate at each layer.
- shadcn/ui
- Tailwind CSS 4
- React Hook Form
- TanStack Query
- Zustand
- Zod