Appearance
Stage 0: Conception ♥
The sperm meets the egg. The project exists. The first heartbeat happens.
Status: ✅ Complete Tests: 5/5 passing Code: ~30 lines
What This Stage Is
The organism has ONE thing: a heartbeat. It ticks every 5 seconds and logs that it's alive. Nothing else. No brain, no senses, no memory. Just proof of life.
Files
orbita-core/
├── pulse.md ← The organism's self-description
├── src/
│ ├── index.ts ← Entry point (14 lines)
│ └── pulse/
│ └── heart.ts ← The heartbeat (26 lines)
└── test/
└── heart.test.ts ← Proof of life (5 tests)The Code
heart.ts — The Heart
typescript
export interface Heart {
stop: () => void;
getTick: () => number;
isBeating: () => boolean;
}
export interface HeartOptions {
intervalMs?: number;
onBeat?: (tick: number) => void;
}
export function startHeart(options: HeartOptions = {}): Heart {
const { intervalMs = 5000, onBeat } = options;
let tick = 0;
let alive = true;
const timer = setInterval(() => {
tick++;
if (onBeat) onBeat(tick);
}, intervalMs);
return {
stop: () => { alive = false; clearInterval(timer); },
getTick: () => tick,
isBeating: () => alive,
};
}index.ts — Entry Point
typescript
import { readFileSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { startHeart } from "./pulse/heart.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const pulseFile = resolve(__dirname, "..", "pulse.md");
// Read and display the pulse
console.log(readFileSync(pulseFile, "utf-8"));
console.log("─".repeat(40));
// Start the heart
const heart = startHeart({
intervalMs: 5000,
onBeat: (tick) => {
console.log(`♥ beat ${tick} — ${new Date().toISOString()}`);
},
});
// Graceful shutdown
process.on("SIGINT", () => {
console.log("\n♥ Heart stopping...");
heart.stop();
console.log("♥ Stopped. Goodbye.");
process.exit(0);
});
console.log("♥ Heart started. Press Ctrl+C to stop.\n");Running It
bash
# Start the organism
npm start
# Output:
# ♥ Heart started. Press Ctrl+C to stop.
# ♥ beat 1 — 2026-04-04T16:29:17.532Z
# ♥ beat 2 — 2026-04-04T16:29:22.533Z
# ♥ beat 3 — 2026-04-04T16:29:27.534ZTests
bash
# Run proof of life
npm test
# Output:
# ✓ Heart starts and beats
# ✓ Heart ticks at configured interval
# ✓ Heart can be stopped gracefully
# ✓ Heart reports correct tick count
# ✓ pulse.md exists and is readable
# Test Files 1 passed (1)
# Tests 5 passed (5)Design Decisions
Why a heartbeat first?
Every living thing has a pulse. Before the organism can think, sense, or act, it must be alive. The heartbeat is the foundation everything else hooks into. In future stages, onBeat will check inboxes, detect overdue tasks, and run health checks.
Why pulse.md?
The organism should be able to describe itself. pulse.md is the organism's self-awareness. Later, agents will auto-update this file with current status — how many tasks, last message time, agent health. It's the organism's vital signs dashboard.
Why startHeart() returns an object?
The heart needs to be stoppable (graceful shutdown), inspectable (how many ticks), and queryable (is it still beating?). This interface grows as the organism grows — future heartbeats will report health metrics.
What's Next: Stage 1 (Amoeba)
The heart starts beating. Now it needs a brain (one agent), senses (HTTP endpoint), muscles (tasks), and memory (state). The simplest complete organism.
Stage 0: ♥ (heart only)
Stage 1: ♥ + 🧠 + 👂 + 💪 + 🧠 (complete single cell)