Production-ready Next.js boilerplate with: - Runtime env validation (fail-fast on missing vars) - Feature-gated config (S3, Stripe, email, OAuth) - Docker + Coolify deployment pipeline - PostgreSQL + pgvector, MinIO S3, Better Auth - TypeScript strict mode (no ignoreBuildErrors) - i18n (en/es), AI modules, billing, monitoring Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
317 lines
7.7 KiB
Markdown
317 lines
7.7 KiB
Markdown
# TCS: AI Agent Methodology Guide
|
|
|
|
> **Purpose**: Enable AI agents to build any compiler/transformer using Triangulated Compiler Synthesis.
|
|
|
|
## Core Principle
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[Input Format] -->|generate| B[Representation 1]
|
|
A -->|generate| C[Representation 2]
|
|
A -->|generate| D[Representation 3]
|
|
B & C & D -->|compare| E{Agreement?}
|
|
E -->|yes| F[Valid Sample]
|
|
E -->|no| G[Spec Gap Found]
|
|
G -->|evolve| H[Updated Spec]
|
|
H -->|rebuild| I[Better Compiler]
|
|
```
|
|
|
|
**Key insight**: When 3 independent representations of the same semantic content disagree, at least one is wrong. This disagreement reveals specification gaps.
|
|
|
|
## The TCS Loop
|
|
|
|
```
|
|
FOR each iteration:
|
|
1. GENERATE samples in parallel (input → 3 representations)
|
|
2. TRIANGULATE to find disagreements
|
|
3. EVOLVE spec based on findings
|
|
4. BUILD/UPDATE compiler modules
|
|
5. TEST compiler against validated samples
|
|
6. FIX failures through diagnosis
|
|
UNTIL convergence (all tests pass, target count reached)
|
|
```
|
|
|
|
## How to Apply TCS to Any Domain
|
|
|
|
### Step 1: Define Your Triangle
|
|
|
|
Choose 3 representations that encode the SAME semantic information differently:
|
|
|
|
| Domain | Rep 1 (Visual) | Rep 2 (Structured) | Rep 3 (Compact) |
|
|
|--------|----------------|-------------------|-----------------|
|
|
| UI Components | JSX/HTML | Component Schema | DSL |
|
|
| Surveys | Flow Diagram | GraphSurvey JSON | LiquidSurvey |
|
|
| APIs | OpenAPI Spec | TypeScript Types | Route DSL |
|
|
| Database | ERD | Prisma Schema | SQL DDL |
|
|
| Forms | Form Builder | JSON Schema | Form DSL |
|
|
| Charts | Chart Image | Chart Config | Chart DSL |
|
|
|
|
### Step 2: Create Initial Spec
|
|
|
|
Write a minimal DSL specification covering:
|
|
|
|
```markdown
|
|
# [Domain] DSL Spec v0.1
|
|
|
|
## Node Types
|
|
- List all semantic entities
|
|
|
|
## Syntax
|
|
- Define symbols and structure
|
|
|
|
## Examples
|
|
- 3-5 simple examples
|
|
|
|
## Edge Cases
|
|
- Known ambiguities (to be resolved)
|
|
```
|
|
|
|
### Step 3: Generate Sample Pairs
|
|
|
|
```typescript
|
|
// Pseudocode for sample generation
|
|
async function generateSample(prompt: string) {
|
|
const [rep1, rep2, rep3] = await Promise.all([
|
|
agent.generate('representation-1', prompt),
|
|
agent.generate('representation-2', prompt),
|
|
agent.generate('representation-3', prompt),
|
|
]);
|
|
|
|
return { prompt, rep1, rep2, rep3 };
|
|
}
|
|
```
|
|
|
|
### Step 4: Triangulate
|
|
|
|
```typescript
|
|
async function triangulate(sample: Sample) {
|
|
const findings = await judge.compare({
|
|
rep1: sample.rep1,
|
|
rep2: sample.rep2,
|
|
rep3: sample.rep3,
|
|
});
|
|
|
|
return {
|
|
isConsistent: findings.disagreements.length === 0,
|
|
disagreements: findings.disagreements,
|
|
specGaps: findings.suggestedSpecChanges,
|
|
};
|
|
}
|
|
```
|
|
|
|
### Step 5: Evolve Spec
|
|
|
|
When disagreements found:
|
|
|
|
```markdown
|
|
## Spec Evolution Entry
|
|
|
|
### Finding
|
|
Rep1 used `onClick` but Rep3 used `@click` for the same action.
|
|
|
|
### Resolution
|
|
Standardize on `onClick` pattern. Update DSL:
|
|
- `@action` → `onClick={action}`
|
|
|
|
### Spec Change
|
|
Added to Section 4.2: "Actions use camelCase event handlers"
|
|
```
|
|
|
|
### Step 6: Build Compiler Modules
|
|
|
|
Standard compiler pipeline:
|
|
|
|
```mermaid
|
|
graph LR
|
|
A[Source DSL] -->|scan| B[Tokens]
|
|
B -->|parse| C[AST]
|
|
C -->|emit| D[Target Format]
|
|
```
|
|
|
|
Build each module to handle the evolved spec:
|
|
|
|
| Module | Input | Output | Responsibility |
|
|
|--------|-------|--------|----------------|
|
|
| Scanner | Source string | Token[] | Lexical analysis |
|
|
| Parser | Token[] | AST | Syntax tree |
|
|
| Emitter | AST | Target | Code generation |
|
|
|
|
### Step 7: Test & Fix Loop
|
|
|
|
```typescript
|
|
for (const sample of validatedSamples) {
|
|
const compiled = compiler.compile(sample.rep3);
|
|
const expected = sample.rep2;
|
|
|
|
if (!deepEqual(compiled, expected)) {
|
|
const diagnosis = await reflector.diagnose({
|
|
input: sample.rep3,
|
|
expected: expected,
|
|
actual: compiled,
|
|
});
|
|
|
|
await applyFix(diagnosis);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Parallel Execution Strategy
|
|
|
|
Maximize throughput by parallelizing independent operations:
|
|
|
|
```mermaid
|
|
graph TD
|
|
subgraph "Parallel Sample Generation"
|
|
S1[Sample 1]
|
|
S2[Sample 2]
|
|
S3[Sample N]
|
|
end
|
|
|
|
subgraph "Parallel Triangulation"
|
|
T1[Judge 1]
|
|
T2[Judge 2]
|
|
T3[Judge N]
|
|
end
|
|
|
|
subgraph "Parallel Module Building"
|
|
M1[Scanner]
|
|
M2[Parser]
|
|
M3[Emitter]
|
|
end
|
|
|
|
S1 & S2 & S3 --> T1 & T2 & T3
|
|
T1 & T2 & T3 --> M1 & M2 & M3
|
|
```
|
|
|
|
## Convergence Criteria
|
|
|
|
TCS converges when:
|
|
|
|
1. **Test Coverage**: `validatedSamples >= targetCount`
|
|
2. **Pass Rate**: `failingTests === 0`
|
|
3. **Spec Stability**: `specChanges.lastN(5) === 0`
|
|
|
|
## Agent Roles
|
|
|
|
| Agent | Prompt Pattern |
|
|
|-------|----------------|
|
|
| Generator | "Given this prompt, generate [representation] that captures..." |
|
|
| Judge | "Compare these 3 representations. Are they semantically equivalent?" |
|
|
| Evolver | "Based on this disagreement, how should the spec change?" |
|
|
| Builder | "Implement this compiler module following the spec..." |
|
|
| Reflector | "This test failed. Diagnose the root cause..." |
|
|
|
|
## Example: Building a Chart DSL Compiler
|
|
|
|
```
|
|
Iteration 1:
|
|
- Generate 10 chart samples (PNG description, ChartConfig, ChartDSL)
|
|
- Find: Bar charts inconsistent on axis labeling
|
|
- Evolve: Add "axis.label" to spec
|
|
- Build: Scanner handles axis tokens
|
|
|
|
Iteration 2:
|
|
- Generate 10 more samples
|
|
- Find: Legends positioned differently
|
|
- Evolve: Add "legend.position: top|bottom|left|right"
|
|
- Build: Parser handles legend node
|
|
|
|
Iteration 3:
|
|
- All 20 samples pass
|
|
- Generate 30 more for coverage
|
|
- Minor fixes to edge cases
|
|
- CONVERGED at 50 samples
|
|
```
|
|
|
|
## Checkpointing
|
|
|
|
Save state after each iteration:
|
|
|
|
```json
|
|
{
|
|
"iteration": 5,
|
|
"spec_version": "0.5",
|
|
"validated_samples": 47,
|
|
"failing_tests": 2,
|
|
"last_findings": ["..."],
|
|
"compiler_hash": "abc123"
|
|
}
|
|
```
|
|
|
|
Resume with: `--resume` flag
|
|
|
|
## Anti-Patterns
|
|
|
|
| Don't | Do Instead |
|
|
|-------|------------|
|
|
| Skip triangulation | Always validate with 3 reps |
|
|
| Ignore small disagreements | Every disagreement reveals spec gap |
|
|
| Build entire compiler first | Build incrementally per finding |
|
|
| Manual spec editing | Let findings drive evolution |
|
|
| Sequential sample generation | Parallelize aggressively |
|
|
|
|
## Quality Principles (MANDATORY)
|
|
|
|
These principles ensure production-ready output:
|
|
|
|
### 1. No Bypassing Issues
|
|
|
|
```
|
|
❌ "Add try-catch to suppress error"
|
|
❌ "Use 'any' type to fix compilation"
|
|
❌ "Skip edge case for now"
|
|
|
|
✅ Trace error to spec gap → evolve spec
|
|
✅ Define proper types matching semantics
|
|
✅ Handle all cases in the grammar
|
|
```
|
|
|
|
**Errors are signals, not noise.** Every failure reveals something about the spec or architecture.
|
|
|
|
### 2. No Isolated Patches
|
|
|
|
```
|
|
❌ "Add special case for sample #47"
|
|
❌ "Hardcode value to pass test"
|
|
|
|
✅ Find pattern across samples → generalize
|
|
✅ Update grammar for all similar constructs
|
|
```
|
|
|
|
If you're adding an `if` statement for one case, you're doing it wrong.
|
|
|
|
### 3. Production-Ready Code Only
|
|
|
|
Every module must have:
|
|
- `strict: true` TypeScript (no `any`, no implicit)
|
|
- Complete error handling with descriptive messages
|
|
- Zero TODOs - every feature fully implemented
|
|
- Zero debug code - no console.log
|
|
- Clean public API with proper exports
|
|
|
|
### 4. Architecture Changes When Needed
|
|
|
|
Signs of bad architecture:
|
|
- Same bug reappearing in different forms
|
|
- Adding features requires many special cases
|
|
- Tests are brittle (small changes break many)
|
|
|
|
**Don't patch bad architecture. Redesign it.**
|
|
|
|
1. Design new structure
|
|
2. Rebuild from scratch
|
|
3. Migrate all tests
|
|
4. Verify all samples pass
|
|
|
|
## Success Metrics
|
|
|
|
Track these per iteration:
|
|
|
|
- `samples_generated`: Total samples this iteration
|
|
- `disagreement_rate`: % samples with inconsistencies
|
|
- `spec_changes`: Number of spec modifications
|
|
- `test_pass_rate`: % tests passing
|
|
- `compilation_time`: Avg compile time
|
|
|
|
Healthy TCS shows: disagreement_rate ↓, test_pass_rate ↑, spec_changes ↓
|