Appearance
Stage 1: Amoeba 🦠
The simplest complete organism. One cell, but it has ALL the basic life functions: sense, process, respond, remember. Carries DNA. The Axiom agent (origin) is defined.
Status: ✅ Complete Tests: 22/22 passing Database: MongoDB (embedded memory server for tests, embedded for dev) DNA: ✅ Defined and propagated to all agents
What This Stage Is
The Amoeba can hear a message (HTTP endpoint), think about it (Anthropic API with tool use), act (create tasks, send messages), and remember (MongoDB). It's the simplest possible organism that is fully functional.
New Organs
| Organ | Body Part | Module | What It Does |
|---|---|---|---|
| Brain | Cortex | src/cortex/agent.ts | Calls Anthropic API with tools, multi-turn reasoning |
| Ear | Sense | src/sense/ear.ts | HTTP server: POST /message, GET /health, GET /pulse |
| Muscles | Muscle | src/muscle/task.ts | Create, list, complete tasks |
| Memory | Memoria | src/memoria/state.ts | MongoDB-backed state: tasks, messages, stats |
| Database | — | src/db/mongo.ts | Embedded MongoDB (no install needed) |
| Tools | — | src/tools/ | Tool implementations (code that executes) |
DNA + Skills + Tools (The Three Layers)
┌──────────────────────────────────────────────────────┐
│ dna.md (root) │
│ The genetic code. Lives in EVERY agent folder. │
│ Never modified. Propagates unchanged. │
│ Teaches: protocol, lifecycle, laws, reproduction. │
└──────────────────────┬───────────────────────────────┘
│ inherited by
┌──────────────────────▼───────────────────────────────┐
│ agents/<name>/ │
│ ├── dna.md ← copy of root DNA │
│ ├── instruction.md ← WHO I am, HOW I behave │
│ └── skills/ ← my specialized skills (md) │
└──────────────────────┬───────────────────────────────┘
│ references
┌──────────────────────▼───────────────────────────────┐
│ skills/*.skill.md (root level) │
│ Shared skills — WHEN/HOW to use a tool. │
│ Available to all agents. Markdown instructions. │
│ e.g., create-task.skill.md, send-message.skill.md │
└──────────────────────┬───────────────────────────────┘
│ mapped to
┌──────────────────────▼───────────────────────────────┐
│ src/tools/*.skill.ts (code) │
│ Tool IMPLEMENTATIONS — WHAT happens when called. │
│ Actual DB writes, API calls, message sends. │
│ Hardcoded. The organism's motor functions. │
└──────────────────────────────────────────────────────┘Axiom Agent (The Origin)
The Axiom agent is defined but dormant at this stage. It carries the blueprint for building the organism:
agents/axiom/
├── dna.md ← Same DNA as all agents
├── instruction.md ← "You are the origin. You build everything."
└── skills/
├── create-agent.skill.md ← Birth new agents (BUILD mode only)
├── create-contact.skill.md ← Add people to org (BUILD mode only)
├── define-schema.skill.md ← Define agent databases (BUILD mode only)
└── set-mode.skill.md ← Switch BUILD ↔ FUSEAxiom becomes active in Stage 3 (Embryo) when self-building begins.
How It Works
1. POST /message { from: "Naveen", text: "Tell Raju to get 50 chairs" }
|
v
2. Ear receives message, calls agent
|
v
3. Cortex (Brain):
- Loads DNA (agents/amoeba/dna.md)
- Loads instruction (agents/amoeba/instruction.md)
- Loads root skills (skills/*.skill.md)
- Loads agent skills (agents/amoeba/skills/*.skill.md)
- Combines into system prompt
- Sends to Anthropic API with tools: [send_message, create_task]
- Claude understands: WHO=Raju, WHAT=get 50 chairs
- Claude calls create_task tool
- Claude calls send_message tool
- Claude responds: "Done. Task created for Raju."
|
v
4. Skills execute:
- create_task → saves to MongoDB
- send_message → logs to console (mock channel for now)
|
v
5. Response returned to HTTP caller:
{
"response": "Done. Task created for Raju to get 50 chairs.",
"meta": {
"skillsCalled": ["create_task", "send_message"],
"tokensUsed": { "input": 450, "output": 120 }
}
}
|
v
6. Message logged to MongoDB for historyRunning It
bash
# Prerequisites: MongoDB running locally (or start will auto-connect)
# Also need ANTHROPIC_API_KEY in environment
# Start the organism
npm start
# Output:
# ╔═══════════════════════════════════╗
# ║ ORBITA — AMOEBA ║
# ║ The simplest living organism ║
# ╚═══════════════════════════════════╝
# 🗄️ MongoDB connected: orbita
# 👂 Ear listening on http://localhost:3210
# ♥ Heart started
# Send it a message (in another terminal):
curl -X POST http://localhost:3210/message \
-H "Content-Type: application/json" \
-d '{"from": "Naveen", "text": "Tell Raju to get 50 chairs for tomorrow"}'Testing
bash
# All tests use mongodb-memory-server (ephemeral, isolated)
# Test DB created fresh before each test, destroyed after
npm test
# Watch mode (re-runs on file change)
npm run test:watch
# Tests:
# ✓ test/heart.test.ts (5 tests) — Heartbeat
# ✓ test/state.test.ts (7 tests) — MongoDB state manager
# ✓ test/task.test.ts (6 tests) — Task creation and lifecycle
# ✓ test/skills.test.ts (4 tests) — Skill registry and execution
# Total: 22 tests passingKey Code
Agent Runtime (Cortex)
typescript
// src/cortex/agent.ts — The brain (tool-use loop)
async function runAgent(config, skills, userMessage) {
const client = new Anthropic();
const systemPrompt = readFileSync(config.instructionPath, "utf-8");
const tools = skills.toAnthropicTools();
const messages = [{ role: "user", content: userMessage }];
for (let turn = 0; turn < config.maxTurns; turn++) {
const response = await client.messages.create({
model: config.model,
system: systemPrompt,
tools,
messages,
});
const toolBlocks = response.content.filter(b => b.type === "tool_use");
// No tool calls = agent is done, return text
if (toolBlocks.length === 0) {
return { response: extractText(response), skillsCalled, tokensUsed };
}
// Execute tool calls, feed results back
for (const block of toolBlocks) {
const result = await skills.execute(block.name, block.input);
// ... append tool results to messages
}
// Loop continues — agent can call more tools
}
}Skill Registry
typescript
// src/skills/registry.ts — Skills are the agent's hands
class SkillRegistry {
register(skill: SkillDefinition) // Add a capability
execute(name: string, input: object) // Run a capability
toAnthropicTools(): Tool[] // Convert to API format
}
// Each skill:
{
name: "create_task",
description: "Create a task and assign to someone",
parameters: { title, assignee, priority, due },
execute: async (input) => { /* actually do it */ }
}Test Database (Isolated)
typescript
// test/setup.ts — Ephemeral MongoDB per test run
import { MongoMemoryServer } from "mongodb-memory-server";
export async function setupTestDb() {
const mongod = await MongoMemoryServer.create(); // Downloads & starts fresh MongoDB
const client = new MongoClient(mongod.getUri());
return client.db("orbita_test"); // Clean DB every time
}
export async function teardownTestDb() {
await client.close();
await mongod.stop(); // Destroyed. No trace left.
}Design Decisions
Why Anthropic API (not CLI) for the Amoeba?
The Amoeba is simple — it just routes messages. No file access, no terminal, no complex reasoning needed. The API is 10x cheaper and faster than CLI for this. CLI will come in Stage 3 (Embryo) for the Architect agent.
Why MongoDB (not PostgreSQL)?
The user specified fluid data structures. MongoDB allows agents to create collections and store any shape of data without migrations. During Build mode (Stage 3), agents will create their own schemas freely.
Why mongodb-memory-server for tests?
Complete isolation. Each test run gets a fresh MongoDB instance. No shared state between dev and test. The test DB is created before tests and destroyed after. Full freedom with fixtures and data.
Why skills as separate objects?
Skills are the agent's interface to the world. By keeping them modular:
- Easy to add new skills (just register another)
- Easy to test (mock the skill, test the agent)
- Skills convert directly to Anthropic tool format
- Future: skills can be assigned per-agent (not all agents get all skills)