βΌ βΌ
db-specialist ui-specialist ruflo-agents
β (critical/high/medium)
βΌ
Council Mode β for complex decisions
(N parallel Claude instances)
### The God Agent Loop
The orchestrator runs as a standalone Node process managed by PM2. Every cycle it pulls pending tasks, classifies them, and makes routing decisions.
// god-agent-loop.mjs
import Anthropic from '@anthropic-ai/sdk';
import { createClient } from '@supabase/supabase-js';
import { readFileSync, writeFileSync } from 'fs';
const client = new Anthropic();
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);
const WISDOM_PATH = './god-wisdom.json';
const CYCLE_INTERVAL_MS = 2 * 60 * 1000;
async function loadWisdom() {
try {
return JSON.parse(readFileSync(WISDOM_PATH, 'utf8'));
} catch {
return { lessons: [], totalCycles: 0, successPatterns: {} };
}
}
async function runCycle() {
const wisdom = await loadWisdom();
const { data: tasks } = await supabase
.from('tasks')
.select('*')
.eq('status', 'pending')
.order('priority', { ascending: false })
.limit(10);
if (!tasks?.length) return;
const classifiedTasks = await classifyAndRoute(tasks, wisdom);
for (const task of classifiedTasks) {
await dispatchToSpecialist(task, wisdom);
}
wisdom.totalCycles++;
writeFileSync(WISDOM_PATH, JSON.stringify(wisdom, null, 2));
}
setInterval(runCycle, CYCLE_INTERVAL_MS);
runCycle(); // run immediately on start
### Task Classification
The classifier sends task descriptions to Claude with context from accumulated wisdom. This is where the system starts feeling intelligent β it's not just keyword matching, it's understanding intent.
// lib/classify-task.ts
export async function classifyTask(
task: Task,
wisdom: WisdomStore
): Promise<ClassifiedTask> {
const recentLessons = wisdom.lessons.slice(-10).join('\n');
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 500,
messages: [{
role: 'user',
content: `Classify this task and route it to the appropriate specialist.
Categories: db | ui | infra | analysis
Specialists: db-specialist | ui-specialist | ruflo-critical | ruflo-high | ruflo-medium
Recent wisdom from previous cycles:
${recentLessons}
Task: ${task.description}
Priority: ${task.priority}
Respond with JSON: { category, specialist, reasoning, estimatedComplexity }`
}]
});
return JSON.parse(response.content[0].text);
}
The `recentLessons` injection is the key. If the system learned last week that "Supabase RLS policy tasks always need the db-specialist even when they look like infra tasks," that lesson surfaces here and influences every future routing decision.
### The Wisdom System
`god-wisdom.json` is the system's long-term memory. It persists across restarts, crashes, and deployments. Each completed task cycle generates a lesson.
// lib/wisdom.ts
interface WisdomStore {
lessons: string[];
totalCycles: number;
successPatterns: Record<string, number>;
failurePatterns: Record<string, string>;
lastUpdated: string;
}
export async function extractLesson(
task: Task,
result: TaskResult,
specialist: string
): Promise<string> {
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 200,
messages: [{
role: 'user',
content: `Extract a single, reusable lesson from this task execution.
Be specific and actionable. Max 2 sentences.
Task: ${task.description}
Specialist used: ${specialist}
Outcome: ${result.success ? 'SUCCESS' : 'FAILED'}
Notes: ${result.notes}
Lesson:`
}]
});
return response.content[0].text.trim();
}
export function appendLesson(wisdom: WisdomStore, lesson: string): WisdomStore {
return {
...wisdom,
lessons: [...wisdom.lessons.slice(-99), lesson], // keep last 100
lastUpdated: new Date().toISOString()
};
}
After a few hundred cycles, `god-wisdom.json` reads like engineering documentation written by the system itself. It's genuinely useful to read.
### Council Mode
For high-complexity tasks β architectural decisions, ambiguous requirements, anything the classifier marks with `estimatedComplexity > 8` β the system spins up a council: multiple Claude instances with different prompt framings, then synthesizes their outputs.
// lib/council.ts
const COUNCIL_PERSPECTIVES = [
'You are a skeptical senior engineer. Identify risks and edge cases.',
'You are an optimistic architect focused on elegant solutions.',
'You are a pragmatist focused on the fastest path to working code.'
];
export async function conveneCouncil(task: Task): Promise<CouncilDecision> {
const opinions = await Promise.all(
COUNCIL_PERSPECTIVES.map(perspective =>
client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 800,
messages: [
{ role: 'user', content: ${perspective}\n\nTask: ${task.description} }
]
})
)
);
// Synthesize the council
const synthesis = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1000,
messages: [{
role: 'user',
content: `Three engineers reviewed a task. Synthesize their views into a final recommendation.
${opinions.map((o, i) => Engineer ${i + 1}:\n${o.content[0].text}).join('\n\n')}
Provide: { recommendation, consensus_level, action_items[], risks[] }`
}]
});
return JSON.parse(synthesis.content[0].text);
}
Council mode is expensive β 4 Claude calls per task β so the cost guard (below) is critical.
## Pitfall Guide
1. **Wisdom File Concurrency & Corruption**: Using synchronous `readFileSync`/`writeFileSync` in a recurring loop creates race conditions and risks data loss if the process crashes mid-write or multiple instances run. **Best Practice:** Implement atomic writes (write to `.tmp` β `fs.rename`) or migrate the wisdom store to a lightweight embedded database like SQLite for concurrent-safe persistence.
2. **Context Window Saturation & Prompt Drift**: Blindly appending raw lessons to every classification prompt quickly consumes context windows and introduces semantic noise, degrading routing accuracy over time. **Best Practice:** Implement vector-based retrieval for only the top-K most relevant lessons, or schedule periodic summarization jobs to condense the wisdom store into actionable patterns.
3. **Council Mode Cost Blowup**: Spinning up 4 parallel Claude instances per complex task can rapidly exceed budget limits if complexity thresholds are misconfigured or ambiguous tasks flood the queue. **Best Practice:** Enforce strict `estimatedComplexity > 8` gates, implement response caching for semantically similar architectural queries, and set hard API spend limits with PM2 process monitoring and alerting.
4. **Fragile JSON Parsing & LLM Hallucination**: Relying on `JSON.parse(response.content[0].text)` without validation will crash the orchestration loop on malformed outputs, markdown wrapping, or missing fields. **Best Practice:** Wrap parsing in try-catch blocks, enforce structured output schemas using Zod or TypeScript interfaces, and add explicit JSON formatting instructions with retry logic on parse failure.
5. **Lack of Human-in-the-Loop Escalation**: Fully autonomous routing can silently misroute critical production incidents or high-stakes architectural changes, leading to cascading failures. **Best Practice:** Implement a confidence threshold; tasks below a certain routing confidence or marked `critical` should trigger Slack/PagerDuty alerts for human validation before dispatch to specialist agents.
## Deliverables
- **Autonomous Orchestrator Blueprint**: Complete architecture diagram, dependency map (Next.js 14, Supabase, PM2, Claude SDK), and data flow specification detailing the God Agent loop, wisdom persistence, and specialist dispatch pipeline.
- **Production Readiness Checklist**: Pre-deployment validation steps including atomic file I/O implementation, Zod schema validation for LLM outputs, cost-guardrail configuration, fallback routing mechanisms, and PM2 restart policy tuning.
- **Configuration Templates**: Ready-to-use `god-wisdom.json` schema, PM2 ecosystem config with environment variable injection and memory limits, and Supabase SQL schema for task persistence with priority indexing and status lifecycle management.