Skip to content

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.534Z

Tests

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)

Orbita — We don't build software. We grow organisms.