Habitats, self-reproduction, and civilization

There is a deeper shape hidden inside ALGAL: not just a workflow runner, but a substrate for organisms that live, reproduce, and evolve in a shared runtime. This is not yet fully built, but the v1 contract already contains the seeds of it. This document teases the idea apart and shows what is possible now under the existing safety invariants.

What a habitat is

A habitat is a shared runtime with four parts:

  • Store — the memory: manifests, receipts, values, slots.
  • FnRegistry — the host's deterministic functions.
  • ToolRegistry — the host's external capabilities.
  • Executor[] — the providers and models the host admits.
  • An organism in a habitat is just a manifest. Its digest is its identity. Its receipt is its life record. Slots are durable state it can read or write across runs. Other organisms are cells it can invoke by digest. Tools and functions are capabilities the host exposes, never things the organism can create on its own.

    Organisms as species

    A manifest is a value. It can be:

  • hashed,
  • stored,
  • transported,
  • composed into another organism,
  • generated by another organism,
  • selected by a foundry.
  • This means a "species" is just a set of manifests with a shared lineage or interface. Evolution does not modify a running organism; it produces new organisms and the host decides which ones to admit.

    Self-reproduction is already possible

    A spawn cell receives a manifest as data and runs it. An agent cell can generate a manifest as JSON output. Combined, an organism can:

  • inspect its own inputs,
  • ask a model to propose a child organism (a new manifest),
  • pass that manifest to a spawn cell,
  • observe the child run under the same bounds and registries,
  • emit the child's digest and receipt as its own outputs.
  • This is reproduction, but it is strictly bounded:

  • the child manifest is parsed and admitted by the runtime,
  • it runs under the parent's depth and work budgets,
  • it cannot escape the host's registries,
  • it cannot modify the parent or the habitat directly.
  • Self-evolution is propose-and-select

    An organism cannot edit its own manifest or the runtime. What it can do is propose a new manifest. The host then decides whether to:

  • store it,
  • register it as a tool or function,
  • include it in the module set,
  • run a bench against it,
  • promote it.
  • This is exactly the foundry pattern. A habitat with a foundry is an ecosystem where organisms generate candidates, a bench measures them, and the host (or a governance organism) promotes winners. The "civilization" is the population of admitted organisms, tools, functions, and the receipts they leave behind.

    Proposing new functions and tools

    An organism can propose a new fn or tool by outputting a signature and an implementation. But the host must install it. For example, an organism could emit a JSON record like:

    json
    {
      "name": "stats.v1",
      "signature": {
        "inputs": { "values": { "type": "json" } },
        "outputs": { "mean": { "type": "number" }, "count": { "type": "int" } },
        "cost": 10
      },
      "implementation": "scripted:..."
    }

    The host reads this from the receipt and, if it wants, adds the function to its registry. The organism itself cannot add the function. This preserves the core invariant: manifests are data, authority is host-owned.

    Applications as civilizations

    In this view, a ALGAL application is a habitat:

  • Modules are organisms in the store.
  • Capabilities are functions and tools in the registries.
  • State is in slots and values.
  • Events are receipts.
  • Evolution is foundry search over generated candidates.
  • Selection is the host's promotion policy.
  • A "civilization" emerges when many organisms co-exist, call each other, propose new members, and the host keeps promoting the ones that improve some measured objective. The receipts form a fossil record: every run, every proposal, every failure is content-addressed and replayable.

    Safety invariants that make it possible

    The deep, trippy part only works because the runtime is brutal about boundaries:

  • No code in manifests. A manifest is data. It cannot install itself.
  • Host-owned registries. New functions, tools, and executors are admitted by the host, never by the organism.
  • Bounded depth, steps, agent calls, work, bytes, and turns. A runaway organism exhausts a declared budget and fails closed.
  • Content-addressed everything. Manifests and receipts are values. You can reason about lineage, diff populations, and verify history.
  • Receipts over wall-clock. There are no ambient time fields. Replay is bit-for-bit.
  • Without these invariants, self-evolution becomes a self-modifying virus problem. With them, it becomes a search-and-selection problem.

    What is not here yet

  • Multi-habitat messaging and consensus.
  • Durable organism lifetimes (organisms are stateless; only slots persist).
  • A governance organism that can promote candidates by itself.
  • Economic or tokenized selection mechanisms.
  • A public name system for organism digests.
  • These are later layers. The current contract already supports the core loop: generate, admit, run, measure, select.

    Working example: examples/habitat.algal.json

    There is a runnable steel thread in the bundled examples. The habitat organism:

  • receives a goal input,
  • a designer agent outputs a child organism manifest as JSON,
  • a spawn cell admits and runs the child under the parent's budgets,
  • a push.v1 cell appends the child digest to the population slot,
  • a write slot cell persists the new population.
  • Run it:

    sh
    algal run examples/habitat.algal.json \
      --args examples/habitat.args.json \
      --responses examples/habitat.responses.json \
      --write

    The receipt shows child (the spawned manifest digest) and population (the updated list). The child is data, the host still owns the store and registries, and the whole lineage is replayable.

    Live self-reproduction: examples/habitat/live.algal.json

    There is also a non-deterministic version of the habitat steel thread. The habitat-live organism calls a live model to design the child, falls back to a safe default if the model fails to produce a JSON manifest, and then spawns whatever is selected. A host script, examples/habitat/promote.ts, decides whether to promote the result.

    Run the scripted version to see the fallback/rejection path:

    sh
    bun examples/habitat/promote.ts

    Run the live version to watch an organism design and spawn a real child:

    sh
    bun examples/habitat/promote.ts --live
    # optionally: GATEWAY_MODEL=anthropic/claude-opus-5 bun examples/habitat/promote.ts --live

    promote.ts:

  • packs the known fallback manifest and records its digest,
  • runs habitat-live with a live model as the designer agent,
  • extracts the spawned child digest from the receipt,
  • compares it to the fallback digest,
  • if the live model produced a different valid manifest, packs and writes it
  • to promoted/<digest>.bundle.json and prints promoted bundle ….

    When this was first run with alibaba/qwen3.7-flash, the model generated and the organism spawned:

    fallback digest  sha256:89f457723808edf83efecf817c275a789f525b80dd06e72bb23ddd47f6d0cc32
    proposed child    sha256:f73c4ef9f89a3c55595f773c5a86c89780cfaf202cf29284005e76a5ad7e751c
    promoted bundle   sha256:f73c4ef9f89a3c55595f773c5a86c89780cfaf202cf29284005e76a5ad7e751c
    wrote promoted/f73c4ef9f89a3c55595f773c5a86c89780cfaf202cf29284005e76a5ad7e751c.bundle.json

    That is the first real live self-reproduction in the habitat: a parent organism proposed a child through a model call, the runtime admitted and ran it, and the host script promoted the child to a standalone bundle. The fallback digest gives a deterministic baseline; any non-fallback child is a live, model-proposed candidate.

    Smaller decision surfaces: plans, not manifests

    Emitting a whole manifest works for a hosted frontier-ish model, but it is too much surface for a small or on-device model — free-form generation produces syntax the contract must reject. The native algal civ loop shrinks the decision: the designer is agent(plan) → fn(manifest.compile.v1). The model emits a plan — a JSON array of step strings like ["fn:format.v1;prefix=Hello, "] — and a deterministic host fn compiles it into a type-checked manifest.

    The split is deliberate. The model only picks verbs and literals; the host owns grammar, typing, graph shape, budgets, and admission. Tolerable noise (bindings to ports a function does not have, trailing non-step tokens) is dropped rather than fatal; malformed intent (an unknown fn: name, a missing =, an invalid literal) still rejects. With Apple Intelligence as the designer this is enough for an on-device ~3B model to propose plans that compile, pass their cases, and promote — a civilization epoch that never left the machine. See docs/civilization.md.

    A sketch of the next step

    The most concrete near-term habitat would be:

  • A long-lived Store shared by an agent loop.
  • A ToolRegistry that can accept proposals from organisms.
  • A foundry config that treats past receipts as a population and evolves it.
  • A host rule: a proposed tool is installed only after algal bench shows it Pareto-dominates the incumbent.
  • The agent loop becomes the habitat's weather: it decides which organisms to run, which proposals to admit, and which lineages to keep. The organisms do not rule the habitat; they are the things the habitat selects.