Complete Architecture Guide β A Self-Improving AI Research System
The Ouroboros Colony is an autonomous AI research system that:
It's named after the Ouroboros β the snake eating its own tail β because the system can modify its own code based on the research it discovers.
Stigmergy is how real ant colonies work. Ants don't talk to each other β they leave chemical trails (pheromones) that other ants can smell. Good paths get more pheromones; bad paths fade away.
| Real Ants | Ouroboros Colony |
|---|---|
| Leave chemicals on the ground | Write records to SQLite database |
| Chemicals evaporate over time | Records decay using math formula |
| Strong trails attract more ants | Strong signals get prioritized |
| Colony finds food efficiently | Colony finds research efficiently |
When an ant finds interesting research, it deposits a pheromone signal:
// An ant found a good paper and marks it deposit(db, { type: 'candidate', // Signal type target_node: 'finding-123', // What we found strength: 0.85, // How confident (0-1) claim: 'High relevance paper on Mamba SSM' });
Every signal weakens over time using exponential decay:
// The decay formula (runs every hour) // S(t) = Sβ Γ e^(-Ξ»t) // // S(t) = strength at time t // Sβ = original strength // Ξ» = decay rate (different per type) // t = hours elapsed const newStrength = currentStrength * Math.exp(-decayRate * hoursElapsed); // Example: candidate with 25%/hr decay // After 1 hour: 1.0 Γ e^(-0.25 Γ 1) = 0.78 (78%) // After 4 hours: 1.0 Γ e^(-0.25 Γ 4) = 0.37 (37%) // After 12 hours: nearly gone
When multiple ants confirm something, the signal gets stronger:
// Asymptotic reinforcement (approaches max smoothly) // S_new = S_old + Ξ±(S_max - S_old) // // Ξ± = learning rate (0.2) // S_max = maximum strength (2.0) const MAX_STRENGTH = 2.0; const alpha = 0.2; const newStrength = oldStrength + alpha * (MAX_STRENGTH - oldStrength); // Example: starting at 0.5 // Hit 1: 0.5 + 0.2(2.0 - 0.5) = 0.80 // Hit 2: 0.8 + 0.2(2.0 - 0.8) = 1.04 // Hit 3: 1.04 + 0.2(2.0 - 1.04) = 1.23 // Approaches 2.0 but never overshoots
Each "ant" is a Node.js script that runs on a schedule. They don't know about each other β they only communicate through pheromones in the database.
| Ant | Schedule | What It Does |
|---|---|---|
research-scout.js |
Every hour | Searches Brave for topics in active_queries.json |
github-scout.js |
Every hour | Searches GitHub for relevant code and repos |
arxiv-scout.js |
Every hour | Fetches latest AI/ML papers from ArXiv |
recursive-scout.js |
Every 2h | Follows "breadcrumb" trails left by other scouts |
batch-scout.js |
Every 4h | Spawns 10 parallel mini-scouts for burst discovery |
deep-scout.js |
Daily | Fetches full content for high-value findings |
| Ant | Schedule | What It Does |
|---|---|---|
filter-ant.js |
Every hour | Scores findings using keyword matching (no API cost) |
deep-reader-ant.js |
Every hour | π₯ Uses Gemini 3 Flash to analyze papers deeply |
connector-lite.js |
Every 3h | Builds knowledge graph by connecting similar findings |
dedup-ant.js |
Daily | Removes duplicate findings using embedding similarity |
analyzer-ant.js |
Every 2h | Statistical analysis of colony trends |
embedder-lite.js |
Every hour | Computes embeddings for new findings |
| Ant | Schedule | What It Does |
|---|---|---|
validator-ant.js |
Every 3h | Promotes candidates β breakthroughs based on evidence |
optimizer-ant.js |
2x daily | Tunes query priorities based on hit rates |
reflector-ant.js |
Every 6h | π₯ Monitors colony health, detects problems, suggests fixes |
implementer-ant.js |
2x daily | π₯ CAN MODIFY COLONY CODE! (with safety limits) |
synthesis-ant.js |
Every 4h | Generates research summaries from breakthroughs |
| Ant | Schedule | What It Does |
|---|---|---|
safeguard-ant.js |
Daily 3AM | Creates backups, health checks, emergency preservation |
consolidator-ant.js |
Daily 4AM | Compresses old findings to save space |
kb-learner-ant.js |
Daily | Learns from external knowledge bases |
Pheromones are the colony's shared memory. Each pheromone record contains:
// What a pheromone looks like in the database { pheromone_id: "abc123-...", // Unique ID type: "candidate", // What kind of signal target_node: "finding-456", // What this refers to strength: 0.85, // Signal intensity (0-2) decay_rate: 0.25, // 25% per hour claim: "High relevance SSM paper", deposited_by: "research-scout", deposited_at: "2026-02-11T15:00:00Z", last_updated: "2026-02-11T16:00:00Z", embedding: <16-byte BLOB> // For similarity search }
Findings must "earn" their status through multiple confirmations:
To find similar research, we convert text into numbers (embeddings). Our system uses a 128-bit binary embedding β fast and compact.
// The embedding has two parts: // 64 bits = domain features (does text mention "transformer"? "mamba"? etc.) // 64 bits = content hash (SHA256 truncated) function embed(text) { let bits = 0n; // BigInt for 128 bits // Part 1: Check 64 domain patterns const patterns = [ /transformer|attention/i, // bit 0 /mamba|ssm|state.?space/i, // bit 1 /memory|remember/i, // bit 2 // ... 61 more patterns ... ]; patterns.forEach((pattern, i) => { if (pattern.test(text)) { bits |= (1n << BigInt(i)); // Set bit i to 1 } }); // Part 2: Hash the content (adds uniqueness) const hash = sha256(text).slice(0, 16); // First 64 bits bits |= (BigInt('0x' + hash) << 64n); // Convert to 16-byte buffer (BLOB) return Buffer.from(bits.toString(16).padStart(32, '0'), 'hex'); }
// Compare two embeddings using Hamming distance // (count how many bits are different) function similarity(embeddingA, embeddingB) { let differentBits = 0; // XOR the bytes and count 1s for (let i = 0; i < 16; i++) { let xor = embeddingA[i] ^ embeddingB[i]; while (xor) { differentBits++; xor &= xor - 1; // Clear lowest set bit } } // Convert to similarity (0 = opposite, 1 = identical) return 1 - (differentBits / 128); } // Speed: ~700,000 comparisons per second!
// reflector-ant.js β Monitors colony and detects problems async function run() { // 1. GATHER METRICS const metrics = { recentFindings: countFindingsLast6Hours(), conversionRate: breakthroughs / candidates, // How many make it avgStrength: averagePheromoneStrength(), evaporated: countWeakPheromones(), }; // 2. DETECT ANOMALIES const anomalies = []; // Too few discoveries? if (metrics.recentFindings < baseline * 0.5) { anomalies.push({ type: 'discovery_stall', severity: 'medium', message: 'Discovery rate dropped 50%', suggestion: 'Add new queries or boost scout frequency' }); } // Echo chamber? (too many breakthroughs = not selective enough) if (metrics.conversionRate > 0.5) { anomalies.push({ type: 'echo_chamber', severity: 'high', message: '50% of candidates become breakthroughs (suspicious)', suggestion: 'Raise breakthrough threshold or increase decay' }); } // 3. GENERATE PATCHES if (anomalies.length > 0) { const suggestion = await llm.analyze(anomalies); createPatch(suggestion); // Queue for implementer } }
// implementer-ant.js β THE OUROBOROS ITSELF // This ant can modify colony code based on research findings! // Risk classification determines what gets auto-applied function classifyRisk(code, targetFile) { // HIGH RISK β never auto-apply if (code.includes('child_process')) return 'high'; // Shell commands if (code.includes('eval(')) return 'high'; // Code execution if (targetFile.includes('implementer')) return 'high'; // Can't modify itself! // MEDIUM RISK β auto-apply with logging if (code.includes('function ')) return 'medium'; // New functions if (code.includes('require(')) return 'medium'; // New imports // LOW RISK β auto-apply immediately return 'low'; // Config changes, thresholds, etc. } // Process patches based on risk level for (const patch of pendingPatches) { if (patch.risk === 'low') { applyPatch(patch); // β Auto-apply } else if (patch.risk === 'medium') { applyPatch(patch); // β‘ Auto-apply (upgraded!) notifyDiscord('Applied MEDIUM risk patch'); } else { logOnly(patch); // π Human must review } }
// implementer-ant.js β Generate patches from validated breakthroughs async function analyzeBreakthroughsForPatches(breakthroughs) { const prompt = ` You are the self-improvement module of an AI research colony. These validated breakthroughs were discovered: ${breakthroughs.map(b => b.claim).join('\n')} Suggest ONE specific, safe improvement to the colony code. Format: TARGET_FILE: pheromones-db.js CHANGE_TYPE: algorithm DESCRIPTION: Use exponential decay instead of linear CODE: const newStrength = strength * Math.exp(-rate * hours); RISK: medium REASON: Research shows this preserves memory shadows better `; const suggestion = await claude.complete(prompt); // Parse and create the patch const patch = parseSuggestion(suggestion); createPatch(patch); // Will be applied next implementer run }
| Capability | Status | Risk Level |
|---|---|---|
| Query priorities | β AUTO | LOW |
| Decay rates | β AUTO | LOW |
| Filter thresholds | β AUTO | LOW |
| New algorithm formulas | β‘ AUTO | MEDIUM |
| New utility functions | β‘ AUTO | MEDIUM |
| Core system logic | π MANUAL | HIGH |
| Security/auth code | π MANUAL | HIGH |
| The implementer itself | π BLOCKED | FORBIDDEN |
These are actual patches the colony has applied to itself based on research it discovered:
| Date | 2026-02-11 |
| File | pheromones-db.js |
| Risk | LOW |
| Research Basis | Ring Attention papers on faster adaptation |
// BEFORE (slower decay) candidate: 0.25, // 25%/hr breakthrough: 0.12, // 12%/hr // AFTER (faster decay - self-modified!) candidate: 0.30, // 30%/hr - proves itself faster breakthrough: 0.15, // 15%/hr - stays relevant or dies
Why: Ring Attention research showed faster signal adaptation improves system responsiveness. Stale data clears faster, making room for fresh discoveries.
| Date | 2026-02-11 |
| File | connector-lite.js |
| Risk | MEDIUM |
| Research Basis | Mamba SSM papers on noise reduction |
// BEFORE (loose connections) const CONNECTION_THRESHOLD = 0.50; // 50% similarity // AFTER (tighter connections - self-modified!) const CONNECTION_THRESHOLD = 0.65; // 65% similarity
Why: Mamba SSM research indicated focusing on stronger relationships reduces noise. Fewer edges, but each one more meaningful.
Everything lives in SQLite: data/colony.db
// database.js β High-performance settings const db = new Database('colony.db'); // WAL mode: allows reads while writing db.pragma('journal_mode = WAL'); // NORMAL sync: safe + fast (vs FULL which is slow) db.pragma('synchronous = NORMAL'); // 64MB cache: keeps hot data in memory db.pragma('cache_size = -64000'); // Temp tables in RAM (faster sorting/joins) db.pragma('temp_store = MEMORY');
-- FINDINGS: Research items discovered by scouts CREATE TABLE findings ( id TEXT PRIMARY KEY, title TEXT, url TEXT, content TEXT, -- Snippet or full text source TEXT, -- 'brave', 'github', 'arxiv' score INTEGER, -- 0-100 quality score status TEXT, -- 'new', 'analyzed', 'duplicate', 'noise' embedding BLOB, -- 16-byte binary vector created_at TEXT, analyzed_at TEXT ); -- PHEROMONES: Signal/memory layer CREATE TABLE pheromones ( pheromone_id TEXT PRIMARY KEY, type TEXT, -- 'candidate', 'breakthrough', etc. target_node TEXT, -- What this refers to strength REAL, -- 0.0 to 2.0 decay_rate REAL, -- % per hour deposited_at TEXT, deposited_by TEXT, -- Which ant claim TEXT, -- Human-readable reason last_updated TEXT, -- For decay calculation embedding BLOB ); -- EDGES: Knowledge graph connections CREATE TABLE edges ( id INTEGER PRIMARY KEY, source_id TEXT, -- Finding A target_id TEXT, -- Finding B weight REAL, -- Similarity score reinforced INTEGER, -- Times rediscovered edge_type TEXT -- 'semantic', 'citation', etc. ); -- PATCHES: Self-modification queue CREATE TABLE patches ( id TEXT PRIMARY KEY, title TEXT, description TEXT, target_file TEXT, code TEXT, reason TEXT, risk TEXT, -- 'low', 'medium', 'high' status TEXT, -- 'pending', 'applied', 'failed' created_at INTEGER, applied_at INTEGER );
Multiple colonies can run simultaneously and share discoveries through stigmergy (no direct communication).
42 cron jobs run the colonies. Alpha and Beta are staggered by 10 minutes to avoid conflicts.
// safeguard-ant.js β Runs at 3 AM // 1. CREATE BACKUP db.backup(`backups/colony-${timestamp}.db`); // Keeps 7 days of backups, auto-deletes older // 2. HEALTH CHECK const health = { findings: countFindings(), // Alert if < 10 pheromones: countPheromones(), // Alert if < 20 avgStrength: avgPheromoneStrength(), // Alert if < 10% breakthroughs: countBreakthroughs() // Alert if = 0 }; // 3. EMERGENCY PRESERVATION if (health.findings < 5) { // CRITICAL: Protect top findings from decay db.run(` UPDATE pheromones SET decay_rate = 0 WHERE type IN ('breakthrough', 'validated') `); alertDiscord('π EMERGENCY: Knowledge collapse prevented'); }
child_process)eval() or Function() (no code injection)ai-memory-colony/ βββ data/ β βββ colony.db # SQLite database (all state) β βββ active_queries.json # What to search for β βββ backups/ # Daily backups (7 days) β βββ federation/ # Shared with other colonies β βββ patches/ # Self-modification history βββ src/ β βββ ants/ # All 20 ant scripts β β βββ research-scout.js β β βββ deep-reader-ant.js β β βββ reflector-ant.js # Anomaly detection β β βββ implementer-ant.js # Self-modification β β βββ ... β βββ core/ # Shared modules β β βββ database.js # SQLite connection β β βββ pheromones-db.js # Stigmergy system β β βββ embeddings.js # 128-bit binary LSH β β βββ model-router.js # LLM routing β βββ config.js # Settings βββ logs/ # Ant output logs βββ docs/ # This documentation
# Install dependencies cd ai-memory-colony npm install # Run a single ant manually node src/ants/research-scout.js # Check colony status node scripts/colony-status.js # Install all cron jobs ./scripts/setup-cron.sh # View cron jobs crontab -l | grep ai-memory-colony
π Ouroboros Colony β Complete Architecture Guide
Generated:
"The snake that eats its own tail grows stronger with each bite."