The Build Plan
Code rules as testable assertions, agent instruction files, and a Master PRD Index that decomposes 150+ features into a sequenced build order.
~8 minute read
Code Rules: The Constraint System
AI agents follow rules. But they only follow rules they can read. The constraint system is a set of files, checked into the repo, that every agent reads before writing code. Without these files, each agent session invents its own conventions.
There are two types of rule files: RULES.md (for the codebase) and CLAUDE.md or equivalent (for the AI agent's behavior).
RULES.md: Per-Package Constraints
Every package in the monorepo has its own RULES.md. The root RULES.md defines global constraints. Package-level files define local constraints. The agent reads both before working in that package.
What Makes a Good Rule
Every rule must be a testable assertion. Not "keep things organized" but "apps import from packages, never from other apps." The first is a suggestion. The second can be verified by a linter, an import restriction, or an architectural fitness test.
# Root Rules
## Import Boundaries
- Apps import from packages, never from other apps.
- packages/api is the sole bridge to infrastructure.
Apps never import packages/db directly.
- packages/ui owns all shared UI components.
No component is defined in an app directory.
- packages/ai is the sole LLM gateway.
No app calls OpenAI/Anthropic directly.
## Tenant Isolation
- Every table with user data has a workspace_id column.
- Every query uses workspaceDb(workspaceId), never the raw db.
- Every tRPC mutation validates the resource belongs to
the current workspace before modifying it.
## Naming Conventions
- Database tables: snake_case plural (issues, projects, cycles)
- TypeScript types: PascalCase (Issue, Project, Cycle)
- tRPC routers: camelCase (issue.list, issue.create)
- File names: kebab-case (issue-list.tsx, create-issue.ts)
- CSS tokens: kebab-case with double-dash (--color-accent)
## Testing
- No shallow assertions: toBeDefined(), toBeTruthy(),
toBeFalsy() are banned as standalone assertions.
- Every async test uses expect.assertions(N).
- Every DB test verifies state with an independent query.
- Every new table has a tenant isolation test.
# Database Package Rules
## Migrations
- Migrations are forward-only. No down migrations.
- If a migration needs reverting, write a new forward
migration that undoes the change.
## Schema
- Every table has: id (uuid), workspace_id (uuid),
created_at (timestamptz), updated_at (timestamptz).
- Use timestamptz, never timestamp (timezone-naive).
- Soft delete: use archived_at (timestamptz), never
delete rows.
## RLS
- Every new table must have an RLS policy:
workspace_id = current_setting('app.workspace_id')::uuid
- RLS is enabled on the table, not just defined.
Agent Instruction Files
Agent instruction files (CLAUDE.md for Claude Code, .cursorrules for Cursor, etc.) tell the AI agent how to behave in this specific project. They are different from code rules: code rules constrain what the code does, agent instructions constrain how the agent works.
What Agent Instructions Cover
- Read before working: Which files to read before modifying any file in this directory.
- Commands to use: Which test runner, linter, and build tool to use. The exact commands.
- Patterns to follow: "When creating a new tRPC router, follow the pattern in packages/api/src/routers/issue.ts."
- What never to do: "Never use
anytype. Never useconsole.log(use the logger package). Never install packages without checking the allow-list."
Tiered Structure
Agent instructions are tiered: root-level for global behavior, directory-level for package-specific behavior. The agent reads both, with local instructions overriding global ones for that directory.
# Repository structure of agent instructions
.claude/ or equivalent for your agent
CLAUDE.md Root: global behavior, commands, project overview
packages/db/
CLAUDE.md DB-specific: migration workflow, schema conventions
packages/api/
CLAUDE.md API-specific: router patterns, error handling
packages/ui/
CLAUDE.md UI-specific: component structure, token usage, accessibility
The Master PRD Index
The Master PRD Index is the complete roadmap. Every feature is a named unit with an ID, milestone assignment, category, dependencies, and test pair. This is the document that answers: "What do I build next?"
Structure
The index is organized by milestone. Each milestone has a name, a theme, and a list of units. Each unit has:
| Field | Description |
|---|---|
| ID | Unique identifier: M[milestone]-U[number]. Example: M1-U03. |
| Title | Descriptive name: "Issue List View," "Notification Engine." |
| Category | Frontend, Backend, or Full Stack. |
| Depends On | Unit IDs that must be complete before this unit starts. |
| Test Pair | Which unit verifies this one (backend tested by its frontend unit). |
| Status | Not started, PRD written, Verified, In progress, Complete. |
M0: Foundation (Auth + Workspace)
| ID | Title | Cat | Depends |
|---|---|---|---|
| M0-U01 | Auth Backend (Clerk integration) | Backend | None |
| M0-U02 | Workspace CRUD | Backend | M0-U01 |
| M0-U03 | Team CRUD | Backend | M0-U02 |
| M0-U04 | Member Roles and Permissions | Backend | M0-U02 |
| M0-U05 | Auth UI (Login, Signup, Invite) | Frontend | M0-U01 |
| M0-U06 | Workspace Settings UI | Frontend | M0-U02, M0-U05 |
| M0-U07 | Team Settings UI | Frontend | M0-U03, M0-U05 |
| M0-U08 | App Shell (Sidebar, Layout, Navigation) | Frontend | M0-U05 |
M1: Issue Data Model + List Views
| ID | Title | Cat | Depends |
|---|---|---|---|
| M1-U01 | Issue Data Model (tables, schema) | Backend | M0-U03 |
| M1-U02 | Issue CRUD API | Backend | M1-U01 |
| M1-U03 | Issue List View | Frontend | M1-U02, M0-U08 |
| M1-U04 | Issue Detail Page | Frontend | M1-U02, M0-U08 |
| M1-U05 | Issue Filters and Saved Views | Full Stack | M1-U03 |
| M1-U06 | Issue Relations (blocks, related) | Backend | M1-U01 |
| M1-U07 | Bulk Actions | Full Stack | M1-U03 |
| M1-U08 | Comments and Activity Feed | Full Stack | M1-U04 |
| M1-U09 | M1 Integration Tests | Full Stack | All M1 |
| M1-U10 | M1 Consolidation | Full Stack | M1-U09 |
Note that every milestone ends with an Integration Test unit and a Consolidation unit. These are not optional. They are first-class units in the build plan.
Sequencing Strategy
The build order follows three principles:
1. Backend before frontend. The API must exist before the UI can consume it. Backend units create tables, routers, and business logic. Frontend units create components that call those routers.
2. Core before periphery. Auth and workspace management before features. CRUD before advanced views. Data model before reporting.
3. Integration test + consolidation per milestone. Every milestone ends with cross-unit integration tests and a refactoring pass. This prevents technical debt from compounding across milestones.
What You Leave With
| Document | Size | Key Output |
|---|---|---|
| Root RULES.md | 1-2 pages | Global constraints: import boundaries, naming, testing, tenant isolation |
| Package RULES.md (per package) | 0.5-1 page each | Package-specific constraints: migration rules, router patterns, component structure |
| Agent instruction files | 1-3 pages each | Agent behavior: read-before-working, commands, patterns, prohibitions |
| Master PRD Index | 5-15 pages | Every unit across all milestones with IDs, dependencies, categories, status |
This completes the foundation layer. You now have: product definition (Part 1), infrastructure decisions (Part 2), visual language (Part 3), and build plan (Part 4). Everything a PRD needs to reference exists. Part 5 begins the building phase: writing PRDs that AI agents can execute.