pt
// PROJECT_CONSTRAINTS.md (Example Structure)
Architecture Directives
- Default to Server Components. Add client boundaries only when state, effects, or browser APIs are required.
- Data fetching must occur in Server Components or Route Handlers. Client-side data fetching via useEffect is prohibited.
- State mutations route through Server Actions. Ad-hoc API endpoints are reserved for third-party webhooks only.
- Business logic extraction is mandatory. Components handle presentation; lib/ handles domain operations.
**Rationale:** Imperative syntax reduces token ambiguity. By specifying where data fetching lives and where mutations route, you eliminate the agent's tendency to scatter logic across UI layers. The rule about client boundaries directly addresses React's rendering model, preventing unnecessary client-side hydration. This approach works because LLMs treat explicit directives as hard constraints during generation, significantly reducing architectural drift.
### Phase 2: Enforce Verification Pipelines
Agents cannot self-validate without explicit execution instructions. Without command definitions, the agent assumes syntactic correctness equals functional correctness. You must inject verification gates.
**Implementation:**
Define your validation commands and mandate their execution before task completion.
```bash
## Verification Pipeline
- Type validation: bunx tsc --noEmit
- Static analysis: bunx eslint --max-warnings=0
- Test suite: bunx vitest run --coverage=false
## Execution Policy
- Run type validation and static analysis before marking any task complete.
- If verification fails, apply fixes and re-run until clean. Do not proceed without passing gates.
Rationale: The execution policy is the critical differentiator. Most teams define commands but omit the enforcement clause. Without it, the agent reports success on broken code. With it, the agent enters a self-correction loop, catching type mismatches and lint violations before they reach your review queue. This mirrors CI/CD gates but operates at generation time, reducing feedback latency from hours to seconds.
Phase 3: Implement Negative Constraints
Positive rules tell the agent what to do. Negative constraints tell it what to avoid. Negative constraints are highly effective at pruning search space and blocking common anti-patterns.
Implementation:
Add a dedicated anti-pattern section to your constraint file.
## Prohibited Patterns
- Do not introduce new dependencies without verifying existing capabilities.
- Do not suppress type errors using any or @ts-ignore. Resolve the underlying type mismatch.
- Do not reformat or reorder files outside the scope of the requested change.
- Do not inline configuration values. Use environment variables or centralized config modules.
Rationale: Negative constraints work by explicitly removing high-probability failure modes from the generation distribution. LLMs frequently default to any or @ts-ignore when type resolution becomes complex. By explicitly prohibiting suppression, you force the agent to engage in proper type narrowing. The file-scoping rule prevents unnecessary git diffs, which reduces merge conflicts and code review noise. This section acts as a filter, ensuring the agent's output stays within acceptable operational boundaries.
Phase 4: Deploy Specialized Subagents
General-purpose prompts produce general-purpose reviews. Subagents isolate context windows and enforce focused evaluation criteria. They are the highest-leverage configuration for maintaining code quality at scale.
Implementation:
Define a subagent manifest that scopes its role, output format, and evaluation criteria.
# SUBAGENTS/code-reviewer.yaml
name: diff-reviewer
description: "Evaluates staged changes for correctness and maintainability. Invoked post-generation."
scope: git diff only
output_format:
- π΄ Critical: Logic errors, security risks, or breaking changes
- π‘ Warning: Performance bottlenecks, missing error handling, or type fragility
- π΅ Suggestion: Refactoring opportunities or documentation gaps
rules:
- Reference exact file paths and line numbers for all findings
- Ignore formatting issues handled by automated formatters
- Do not approve changes containing unresolved π΄ or π‘ findings
Rationale: Subagents solve the context window problem. A general agent reviewing a full codebase dilutes focus. A diff-scoped reviewer concentrates on the actual change surface, applying consistent evaluation criteria. The structured output format ensures findings are actionable and prioritized. By prohibiting rubber-stamping and requiring exact references, you transform the review process from subjective commentary into deterministic quality assurance.
Pitfall Guide
1. Vague Directives
Explanation: Using phrases like "follow best practices" or "write clean code" provides zero deterministic guidance. LLMs interpret these as permission to default to training data averages.
Fix: Replace suggestions with testable rules. Instead of "optimize performance," specify "cache database queries with a 5-minute TTL and invalidate on mutation."
2. Missing Execution Gates
Explanation: Defining commands without mandating their execution allows the agent to skip validation. The agent assumes completion upon generating the final code block.
Fix: Append explicit enforcement clauses to your command section. Require re-execution on failure and prohibit task completion without passing gates.
3. Context Window Overflow
Explanation: Packing constraint files with exhaustive examples, legacy patterns, and framework documentation exhausts the agent's context window, degrading generation quality.
Fix: Keep constraint files under 2,000 tokens. Use references to external documentation instead of embedding it. Prioritize active conventions over historical patterns.
4. Static Rule Sets
Explanation: Treating constraint files as one-time setup leads to drift as frameworks evolve. Rules written for Next.js 13 break under Next.js 14/15 conventions.
Fix: Version-control your constraint files. Schedule quarterly reviews aligned with major framework releases. Use CI checks to validate rule syntax and token limits.
5. Subagent Context Bleed
Explanation: Allowing subagents to access the entire codebase instead of scoped triggers causes evaluation dilution and inconsistent feedback.
Fix: Restrict subagent scope to specific triggers (e.g., git diff, specific file patterns, or PR boundaries). Pass only relevant context via tool arguments.
Explanation: Writing rules that depend on Claude Code or Cursor-specific syntax prevents cross-tool compatibility and complicates team onboarding.
Fix: Abstract core rules into a framework-agnostic format. Use tool-specific wrappers only for execution commands or subagent invocation syntax. Maintain a single source of truth for architectural constraints.
7. Ignoring Environment Variables
Explanation: Hardcoding paths, API endpoints, or configuration values in constraint files breaks across local, staging, and production environments.
Fix: Reference environment variables or centralized config modules. Instruct the agent to read configuration from .env or runtime context rather than embedding values.
Production Bundle
Action Checklist
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| Solo Developer / Prototype | Single constraint file with core rules + verification commands | Minimizes setup overhead while preventing common anti-patterns | Low (1-2 hours initial setup) |
| Small Team (3-8 engineers) | Shared constraint file + diff-scoped subagent + CI validation | Enforces consistency across contributors without manual review bottlenecks | Medium (4-6 hours setup + maintenance) |
| Enterprise / Multi-Repo | Centralized constraint registry + tool-agnostic rules + automated token validation | Scales conventions across teams while preventing context drift | High (1-2 weeks implementation + governance) |
| Legacy Migration | Phased constraint rollout targeting active modules only | Prevents overwhelming the agent with deprecated patterns while modernizing incrementally | Medium (Ongoing alignment effort) |
Configuration Template
# PROJECT_CONSTRAINTS.md
# Compatible with: Claude Code, Cursor, and generic LLM coding agents
## Architecture Directives
- Default to Server Components. Add client boundaries only when state, effects, or browser APIs are required.
- Data fetching must occur in Server Components or Route Handlers. Client-side data fetching via useEffect is prohibited.
- State mutations route through Server Actions. Ad-hoc API endpoints are reserved for third-party webhooks only.
- Business logic extraction is mandatory. Components handle presentation; lib/ handles domain operations.
## Verification Pipeline
- Type validation: bunx tsc --noEmit
- Static analysis: bunx eslint --max-warnings=0
- Test suite: bunx vitest run --coverage=false
## Execution Policy
- Run type validation and static analysis before marking any task complete.
- If verification fails, apply fixes and re-run until clean. Do not proceed without passing gates.
## Prohibited Patterns
- Do not introduce new dependencies without verifying existing capabilities.
- Do not suppress type errors using any or @ts-ignore. Resolve the underlying type mismatch.
- Do not reformat or reorder files outside the scope of the requested change.
- Do not inline configuration values. Use environment variables or centralized config modules.
## Subagent: diff-reviewer
- Scope: git diff only
- Output: π΄ Critical / π‘ Warning / π΅ Suggestion with exact file:line references
- Rules: Ignore formatter-handled issues. Do not approve changes with unresolved π΄ or π‘ findings.
Quick Start Guide
- Initialize Constraint File: Create
CLAUDE.md or .cursorrules in your project root. Copy the configuration template above and adjust architecture directives to match your stack.
- Validate Token Budget: Run a token counter against the file. Ensure it stays under 2,000 tokens. Remove framework documentation or legacy examples that dilute context.
- Test Execution Gates: Trigger a generation task. Verify the agent runs type validation and static analysis before reporting completion. If it skips verification, append explicit enforcement clauses to the execution policy.
- Deploy Subagent: Configure the diff-scoped reviewer according to your tool's subagent syntax. Test by generating a change and invoking the review trigger. Confirm output matches the structured format.
- Commit & Iterate: Add the constraint file to version control. Monitor agent output for one week. Adjust negative constraints and verification commands based on observed deviation patterns.