Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c513ecb
Add evidence-driven organism promotion.
0thernet Sep 17, 2026
ba43a80
Complete verifiable organism foundry flow.
0thernet Sep 17, 2026
086013f
Add bounded evolutionary organism search.
0thernet Sep 17, 2026
eb487ea
Verify and operate complete search histories.
0thernet Sep 17, 2026
a293acc
Record token fitness in foundry evidence.
0thernet Sep 17, 2026
7ecf7a9
Add metered Vercel Gateway execution.
0thernet Sep 17, 2026
97c989b
Add typed external tool effects.
0thernet Sep 18, 2026
1a5e022
Add verifiable cross-system workload benchmarks.
0thernet Sep 18, 2026
6b25dd2
Add disagreement-triggered ensemble escalation example.
0thernet Sep 18, 2026
b0211bf
Add batch-decomposition bench workload and modules loading.
0thernet Sep 18, 2026
097c589
Add declarative tool registries and a tool-grounded benchmark case st…
0thernet Sep 18, 2026
63fe2e2
Document and surface the tool-grounded invest case study.
0thernet Sep 18, 2026
7c4a658
Add dollar-denominated Pareto and aicharts.io cost references to benc…
0thernet Sep 18, 2026
345a485
Add `morphogen call` and `morphogen tool-def` for using organisms as …
0thernet Sep 18, 2026
75fa95e
Add `morphogen call --args -` and `docs/why-unique.md`.
0thernet Sep 18, 2026
25486fa
Add `docs/habitats.md` — self-reproduction, evolution, and civilization.
0thernet Sep 18, 2026
7800a4c
Add a working habitat steel thread: `examples/habitat`.
0thernet Sep 18, 2026
cbcbea5
Add live habitat self-reproduction with host promotion.
0thernet Sep 18, 2026
2b79c4b
Fix CodeQL prototype-pollution warnings in bench and foundry.
0thernet Sep 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ node_modules/
dist/
site/dist/
.morphogen/
promoted/
.env
.env.*
!.env.example
Expand Down
14 changes: 9 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@

- `src/` — the contract (`contract.ts`, `graph.ts`), the scheduler (`run.ts`),
the effect seam (`effects.ts`), the store (`store.ts`), verification
(`verify.ts`), bundles (`bundle.ts`), transports (`transport.ts`),
canonical values and digests, and colocated tests.
(`verify.ts`), Vercel AI Gateway execution (`gateway.ts`), typed external
tools (`tools.ts`), foundry evaluation and search (`foundry.ts`,
`search.ts`), benchmark comparison (`bench.ts`, `bench-verify.ts`),
bundles (`bundle.ts`), transports (`transport.ts`), canonical values and
digests, and colocated tests.
- `cli.ts` — the Bun CLI (`run`, `check`, `verify`, `inspect`, `explain`,
`diff`, `runs`, `digest`, `store`, `manifests`, `manifest`, `slots`,
`slot`, `pack`, `unpack`, `example`, `suite`).
`diff`, `foundry`, `bench`, `runs`, `digest`, `store`, `manifests`,
`manifest`, `slots`, `slot`, `pack`, `unpack`, `example`, `suite`).
- `index.ts` — the package's public surface.
- `examples/` — bundled manifests and scripted responses used by `suite`.
- `spec/v1/organism.md` — the authoritative contract prose.
- `spec/v1/organism.md`, `spec/v1/foundry.md`, `spec/v1/search.md`,
`spec/v1/bench.md` — authoritative contract prose.
- `site/` — the static morphogen.dev source; `build.ts` writes `site/dist`.
- `README.md`, `CONTRIBUTING.md`, `SECURITY.md` — the public contract.

Expand Down
290 changes: 286 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ Status: early. The v1 contract, scheduler, effect seam, nested organisms, and
offline verification are implemented and tested. Hosted habitats, multi-owner
messaging, and workflow breeding are deliberately deferred.

## Why this is a new primitive

Morphogen is a third thing between deterministic programs and open-ended agents:
a bounded, typed, content-addressed probabilistic program. The manifest is a
value; the receipt is evidence; and model judgment is isolated behind explicit
cells with declared contracts and budgets. See [`docs/why-unique.md`](docs/why-unique.md)
for the full comparison with prompts, agent loops, DAG engines, probabilistic
programming, smart contracts, and FaaS.

### Where this could go

Because manifests are values and receipts are evidence, organisms can generate,
store, and propose new organisms. A shared `Store`, `ToolRegistry`, and
`FnRegistry` becomes a habitat: a population of organisms that evolve through
foundry search and host admission. The organism cannot rewrite its own runtime,
but it can *propose* children, functions, and tools; the host decides what to
admit. See [`docs/habitats.md`](docs/habitats.md) for the design sketch,
[`examples/habitat.morphogen.json`](examples/habitat.morphogen.json) for a
deterministic working steel thread, and `bun examples/habitat/promote.ts --live`
for a live model-driven reproduction loop.

## What is this?

An **organism** is a manifest (`morphogen.organism.v1`): a set of cells with
Expand All @@ -21,6 +42,11 @@ Cell kinds:
- `const` — a literal producer. Ports are declared values.
- `fn` — a pure function from the host's registry (`echo.v1`, `tag.v1`,
`coalesce.v1`, `pick.v1`, `format.v1` ship built in).
- `tool` — a typed external effect resolved only from the host's tool registry.
Read/write class, inputs, outputs, work cost, output bytes, timeout, and
idempotency key are explicit; results and failures are receipted and replayed
without repeating live IO. Agent cells may request the same admitted tools
during bounded turns alongside pure function callbacks.
- `agent` — a bounded model call: a declared context view, a prompt, a typed
output contract, an optional route, declared tool callbacks, and byte, turn,
and wall-clock (`budget.maxEffectMs`) budgets — a hung executor becomes a
Expand Down Expand Up @@ -94,6 +120,48 @@ and leaves to the model only what is declared inside a cell boundary. A run is
then something you can replay, diff, and audit rather than a transcript you
have to trust.

## Where it wins

Morphogen wins where the work is **structured, verifiable, and cheaper to split
into many small decisions** than to pack into one long prompt. The fastest wins
are workloads where a single LLM call is missing information or has no way to
check itself:

- **Tool-grounded investigation** — a model call cannot look up a customer
record, run a calculation, or inspect a ledger; Morphogen routes a typed
`tool` cell before the judgment, then checks the result deterministically.
- **Multi-decision classifiers over one shared context** — dozens of narrow
`classifier` cells see only the slices they need, each with a tiny prompt,
instead of one monolithic completion.
- **Escalation by disagreement** — two cheap lanes plus an `assert.v1` guard
escalate only when the cheap models disagree; frontier inference is sparse,
not the default.
- **Verification before promotion** — a generated organism must pass train,
validation, and holdout cases, and `morphogen verify` replays every receipt
bit-for-bit before the organism is promoted.

### Case study: billing-dispute investigation

`examples/invest/` runs six support tickets where the correct decision depends
on a charge ledger. A lone model sees only the ticket; the Morphogen organism
retrieves the ledger through a typed `tool` cell and then classifies.

Live Vercel AI Gateway run:

|| system | passed | effect calls | cost | input tokens | output tokens | Pareto |
|---|---|---:|---:|---:|---:|---|
|| cheap-single (qwen3.5, no evidence) | 4/6 | 6 | $0.00371 | 759 | 14,087 | yes |
|| frontier-single (claude-opus-5, no evidence) | 4/6 | 6 | $0.02625 | 4,214 | 207 | — |
|| **organism-cheap (qwen3.5 + ledger tool)** | **6/6** | **12** | **$0.00131** | **1,210** | **4,716** | **yes** |
|| organism-ensemble (qwen3.5 + qwen3.7 + tool) | 6/6 | 19 | $0.00676 | 3,692 | 6,776 | — |

A Qwen Flash organism with a typed ledger lookup is **100% accurate on this
workload**, while a Claude Opus call without the tool is **67% accurate**.
Opus fails the same evidence-only cases as Qwen does when neither can look up
the charges. The Pareto set keeps both the organism (quality winner) and the
frontier single call (fewest round-trips), so the tradeoff is explicit and
can be chosen per deployment.

## First value

```sh
Expand Down Expand Up @@ -158,6 +226,111 @@ bun run cli pack examples/inbox.morphogen.json --modules examples > bundle.json
bun run cli unpack bundle.json --dir /tmp/elsewhere # installs, digests verified
```

## Foundry: select organisms by evidence

A foundry evaluates a bounded population against explicit train and validation
cases, promotes one manifest digest, and only then runs that winner on the
holdout split. A case passes only when the organism completes and its interface
outputs canonically equal the expected record. Every candidate manifest and run
receipt is persisted.

Candidates may be named files or manifests emitted as data by a generator
organism. The generator runs under the same executor, registry, store, and
budgets as any other organism; its digest and receipt become the population's
lineage. A generator may itself use `each`, `repeat`, `spawn`, slots, and gates,
so bounded populations, iterative search, durable journals, and approval are
composition rather than privileged foundry code.

```sh
bun run cli foundry examples/generated-foundry.config.json \
--responses examples/foundry-generator.responses.json \
--dir .morphogen --out foundry-report.json
bun run cli foundry inspect foundry-report.json
bun run cli foundry verify foundry-report.json --dir .morphogen
bun run cli foundry pack foundry-report.json --dir .morphogen --out bundles
```

A `morphogen.foundry.config.v1` file declares the generator, cases, and optionally
additional candidate paths:

```json
{
"contract": "morphogen.foundry.config.v1",
"generator": {
"manifest": "generator.morphogen.json",
"args": { "task": "Return the input unchanged." },
"output": "candidates",
"field": "candidates"
},
"cases": [
{ "id": "train-a", "split": "train", "args": { "q": "a" }, "expect": { "answer": "a" } },
{ "id": "validation-b", "split": "validation", "args": { "q": "b" }, "expect": { "answer": "b" } },
{ "id": "holdout-c", "split": "holdout", "args": { "q": "c" }, "expect": { "answer": "c" } }
]
}
```

Paths resolve relative to the config. Promotion prefers validation pass rate,
then train pass rate, then fewer agent calls and work units, with manifest digest
as the final tie-breaker. Non-promoted candidates never run against holdout
cases. A `morphogen.foundry.v1` report records expectations, outputs, work, token
usage, manifest and receipt digests, generator lineage, and the winner's holdout result.
`foundry verify` checks the report digest, scores, selection, claimed outputs,
and every run receipt by offline replay. `foundry pack` verifies that evidence
before exporting the promoted organism's content-addressed closure.

A bounded search repeats generation and selection while keeping holdout sealed.
The previous winner survives into the next population, and the generator sees
only prior train/validation scores, work, and manifest digests:

```sh
bun run cli foundry search examples/search.config.json \
--responses examples/evolving-generator.responses.json \
--dir .morphogen --out search-report.json
bun run cli foundry search-inspect search-report.json
bun run cli foundry search-verify search-report.json --dir .morphogen
bun run cli foundry search-pack search-report.json --dir .morphogen --out bundles
```

`morphogen.search.v1` bounds a search to eight generations. Every generation
records its generator receipt, proposals, full population evidence, and winner.
Verification replays the complete history, checks survivor continuity and that
every proposal was evaluated, and rejects any holdout evidence in generation
records. Baseline manifests may enter through the config's `candidates` list and
compete with generated organisms from generation zero onward.

## Bench: compare systems on one workload

A bench measures several systems — each an organism plus a host-resolved
executor list — against the same cases. "One cheap call", "one frontier call",
and "a decomposed organism whose frontier call is a guarded escalation branch"
are the same kind of contender. A case passes only when the run completes and
its declared outputs canonically equal `expect`; every case's receipt is
persisted and replayable.

```sh
bun run cli bench examples/bench.config.json --dir .morphogen --out bench-report.json
bun run cli bench inspect bench-report.json
bun run cli bench verify bench-report.json --dir .morphogen
```

A `morphogen.bench.config.v1` file names case `args`/`expect` pairs and systems
whose `executors` map names to `gateway:<provider/model>` (Vercel AI Gateway),
`scripted:<file>`, or `cmd:<command>` specs; the first entry is the default and
named entries answer `route.preset`. The report records per-case results, work,
token usage, per-model effect attribution, and the non-dominated pareto set on
(quality ↑, tokens ↓, effect calls ↓). `examples/bench.config.json` runs it
deterministically; `examples/bench-live.config.json` swaps the scripted lanes
for `alibaba/qwen3.5-flash` and `anthropic/claude-opus-5` through the gateway.

For tool-grounded baselines, pass `--tools <file>`: a registry of named tools
with typed signatures and `scripted:<data>` or `cmd:<shell>` executors. The
billing-dispute case in `examples/invest/bench-invest-live.config.json` uses it
to compare a Qwen organism with a charge-ledger lookup against a Claude Opus
call that can only read the ticket. Add a `prices` map to the bench config
(`examples/invest/bench-invest-priced.config.json`) to put the Pareto in
aicharts.io-denominated dollars.

`check` admits a manifest without running it: parse, graph validation, and
interface resolution only. `explain` prints the compiled signature — every
cell's resolved input/output ports (including ports inherited from embedded
Expand All @@ -166,10 +339,12 @@ embed others resolve sub-manifests by digest from the store; `--modules <dir>`
loads a directory of `*.morphogen.json` files first.

To go live, point `--executor-cmd` at any program that reads an effect request
(JSON) on stdin and prints the model's output on stdout. Morphogen does not
broker provider access; the executor seam is where provider auth lives.
`--executors <file>` takes a JSON map of name → command, so a cell's
`route.provider`/`route.preset` picks its model.
(JSON) on stdin and prints the model's output on stdout, or use
`--gateway-model <provider/model>` for the built-in Vercel AI Gateway executor
(short-lived OIDC or a scoped gateway key from the environment — never the
manifest). Morphogen does not broker provider access; the executor seam is
where provider auth lives. `--executors <file>` takes a JSON map of
name → command, so a cell's `route.provider`/`route.preset` picks its model.

## How does it behave?

Expand Down Expand Up @@ -226,6 +401,110 @@ broker provider access; the executor seam is where provider auth lives.
- This is not a hosted orchestrator, a durable job queue, or a multi-agent
town. Those are later layers; the contract is designed not to need them yet.

## Plug it into your agent or provider

Morphogen is a library and a CLI; the seams are deliberately narrow so you can
use it from a larger system without giving the system ambient authority.

### From code

```ts
import { builtinRegistry, runOrganism, vercelGatewayExecutor } from "morphogen";
import { FileStore } from "morphogen/store"; // or a custom Store

const receipt = await runOrganism({
manifest: myManifest,
args: { src: { ticket: "I was charged twice…" } },
fns: builtinRegistry(),
store: new FileStore(".morphogen"),
executors: [vercelGatewayExecutor({ model: "alibaba/qwen3.5-flash" })],
tools: myToolRegistry, // typed external effects
});
```

The `Executor` interface is one method: `execute(effect, signal?)` returns the
raw effect output. Any provider, local model, or hard-coded fixture fits by
wrapping that method. `runOrganism` does the scheduling, binding, budget
enforcement, and receipt writing.

### From the CLI with any provider

```sh
# scripted replay fixture
bun run cli run ticket.morphogen.json --responses ticket.responses.json

# Vercel AI Gateway
bun run cli run ticket.morphogen.json \
--gateway-model alibaba/qwen3.5-flash --write

# any command that reads JSON on stdin and writes JSON on stdout
bun run cli run ticket.morphogen.json \
--executor-cmd "python -m my_provider_agent"
```

### External tools

Agent cells can request functions from the host registry (`tools: ["pick.v1"]`),
and explicit `tool` cells can call external services. For the CLI, declare the
registry in a `--tools <file>`:

```json
{
"ledger.charges.v1": {
"signature": {
"inputs": { "account": "text" },
"outputs": { "charges": "json" },
"effect": "read",
"cost": 50,
"maxOutputBytes": 8192
},
"exec": "cmd:ledger-cli"
}
}
```

The command receives `{ inputs, requestDigest, idempotencyKey }` on stdin and
must print a JSON object of output ports. For deterministic testing, use
`"exec": "scripted:<data.json>"`.

### As an agent tool

Pack an organism and register it as an OpenAI or Anthropic function tool:

```sh
morphogen pack ticket.morphogen.json --out ./tools
morphogen tool-def ticket.morphogen.json > ticket-tool.json
```

Then call it from an agent:

```sh
morphogen call ./tools/<bundle>.bundle.json \
--args ticket.args.json \
--gateway-model alibaba/qwen3.5-flash
```

The result is compact enough for an agent to consume:

```json
{
"ok": true,
"outputs": { "out": "billing" },
"receiptDigest": "sha256:...",
"manifestDigest": "sha256:..."
}
```

The agent receives the output and a receipt digest it can verify later. See
`docs/agent-tool.md` for a complete example.

### Verification and transport

Receipts are content-addressed canonical JSON; `morphogen verify` replays them
offline with the recorded effects fixed. `morphogen pack` exports a manifest
closure — sub-manifests, `const` refs, and linked bundles — so one digest fully
describes a deployable program.

## How claims are checked

`bun run check` runs the typechecker, the linter, the test suite, and the site
Expand All @@ -238,6 +517,9 @@ detection.
## Deeper documentation

- `spec/v1/organism.md` — the manifest, run, and receipt contract.
- `spec/v1/foundry.md` — candidate generation, evidence, promotion, and verification.
- `spec/v1/search.md` — bounded generations, feedback, survivors, and lineage.
- `spec/v1/bench.md` — workload comparison, attribution, and the pareto claim.
- `docs/` — design notes as they land.

## Related work
Expand Down
Loading
Loading