forge: install genesis seeds at their declared node ids #1

Merged
will.anderson merged 7 commits from feat/genesis-seed-install into main 2026-08-16 13:17:14 +00:00
Owner

What

Adds a seed_type: "genesis" branch to forge install. Seeds without a seed_type reach the identical persona code they always did.

Why

A persona seed is generative: values and biography are prose, the installer mints an id per node, and the ids are incidental because nothing outside the graph refers to them.

A genesis seed is declarative. It ships identity_nodes[] with explicit ids and edges[] written in terms of those ids, and the ids are the artifactis_protected_node() in neuron-api.el keys on exact ids, and all 214 declared edges reference them.

install.el only understood the persona schema. It never read identity_nodes or edges, so installing Neuron's genesis seed minted 102 unrelated nodes. State in the live graph today:

declared nodes absent 87 / 102
present with only their label as content 2 (kn-10fa60db… 30 bytes vs 4263 declared, kn-04368bee… 22 vs 2590)
intact 13
declared edges never laid 202 / 214

How

Render the declared nodes and edges into a snapshot-format file and hand it to the engram, which honors the ids — POST /api/nodes/reseed where available, POST /api/load-merge otherwise. Both skip nodes already present and dedup edges by (from, to, relation), so a rerun is a no-op by construction, not by a flag.

Three things this path does differently, each inherent to what a genesis seed is:

It never provisions. A persona seed gets a port and a launchd Engram; a genesis seed installs into an engram that already exists and is owned by something else. The :8742 refusal is inverted too — that guard stops a foreign soul landing in Neuron's engram, and Neuron's own identity graph is the one thing that belongs there. GENESIS_CONFIRM takes its place, because rewriting the graph a running CGI reads itself out of should never happen because someone typed a familiar command with an unfamiliar file.

It splices raw JSON tokens rather than decoding and re-escaping. The seed bodies are multi-KB markdown with newlines, quotes and \u escapes. A round-trip through str_escape_json would have to reproduce every escape the author wrote, and any it does not know about silently corrupts the body. Copying a token verbatim cannot corrupt what it never decodes.

It verifies by re-reading. The bug this replaces reported success while delivering empty bodies, so success is not what the write call returned — it is what the graph now holds. Every declared id is re-read and audited against the hollow signature, and the manifest names the failing ids.

[forge] ── genesis manifest ─────────────────────────────
[forge]   created: 87
[forge]   filled:  2
[forge]   skipped: 13
[forge]   failed:  0
[forge]   nodes verified: 102/102
[forge]   edges declared: 214 (engram dedups by from/to/relation)

Hollow detection is deliberately conservative — under 40% of the declared body and under 400 bytes — so a node whose body legitimately grew in the graph is left alone. Genesis restores what is missing; it does not overwrite what the graph has learned.

Also

  • Registers Neuron in registry.json, installed:false until the identity load is authorized. engram_api_key is left empty on purpose: the key for a pre-existing engram belongs to that engram's launchd environment, not to a file in this repo.
  • -DHAVE_CURL in CFLAGS. Without it the el-compiler runtime links fine and then answers every http_get/http_post_json with {"error":"not built with HAVE_CURL"} — forge is entirely HTTP, so it dies at the first engram call. No-op against the SDK release runtime CI pulls.

Verification

Sandbox engram on a throwaway port with a throwaway data dir, seeded to mirror the live graph's state for this seed (15 resident declared nodes including the 2 hollow, plus all 694 of their real incident edges). No prod or stage writes.

manifest created 87, filled 2, skipped 13, failed 0
nodes present after 102 / 102, 0 hollow signatures remaining
byte-exact against seed 89 / 89 written; the 13 skipped keep their longer live bodies by design
edges laid 214 / 214, weights exact
non-seed incident edges preserved 682 / 682 through the two in-place replaces
rerun absent: 0 hollow: 0 intact: 102, 0 nodes and 0 edges added
against an engram with no reseed route creates the 87, fills 0, fails loudly naming the 2, registry not updated
gate refuses without GENESIS_CONFIRM
persona path unchanged — reinstall short-circuit still fires, no launchd touched

Content-length distribution after install: min 286, median 1728, max 4679, 0 nodes under 100 chars. A run that returns success while delivering empty content is the exact failure mode being fixed, so the audit is on the output distribution, not on the exit status.

Branch note

Branched from local main, which carries 6 commits not yet on the remote. Those are pre-existing and untouched; they ride along in this PR because install_genesis calls registry_replace_slug, which one of them introduced.

Depends on

neuron-technologies/el PR for POST /api/nodes/reseed. Forge degrades gracefully without it — creates every absent node and lays every edge, then reports the 2 hollow nodes as failed rather than reaching for a destructive substitute.

## What Adds a `seed_type: "genesis"` branch to `forge install`. Seeds without a `seed_type` reach the identical persona code they always did. ## Why A **persona** seed is generative: values and biography are prose, the installer mints an id per node, and the ids are incidental because nothing outside the graph refers to them. A **genesis** seed is declarative. It ships `identity_nodes[]` with explicit ids and `edges[]` written in terms of those ids, and **the ids are the artifact** — `is_protected_node()` in `neuron-api.el` keys on exact ids, and all 214 declared edges reference them. `install.el` only understood the persona schema. It never read `identity_nodes` or `edges`, so installing Neuron's genesis seed minted 102 unrelated nodes. State in the live graph today: | | | |---|---| | declared nodes absent | **87 / 102** | | present with only their label as content | **2** (`kn-10fa60db…` 30 bytes vs 4263 declared, `kn-04368bee…` 22 vs 2590) | | intact | 13 | | declared edges never laid | **202 / 214** | ## How Render the declared nodes and edges into a snapshot-format file and hand it to the engram, which honors the ids — `POST /api/nodes/reseed` where available, `POST /api/load-merge` otherwise. Both skip nodes already present and dedup edges by `(from, to, relation)`, so **a rerun is a no-op by construction**, not by a flag. Three things this path does differently, each inherent to what a genesis seed is: **It never provisions.** A persona seed gets a port and a launchd Engram; a genesis seed installs into an engram that already exists and is owned by something else. The `:8742` refusal is inverted too — that guard stops a *foreign soul* landing in Neuron's engram, and Neuron's own identity graph is the one thing that belongs there. `GENESIS_CONFIRM` takes its place, because rewriting the graph a running CGI reads itself out of should never happen because someone typed a familiar command with an unfamiliar file. **It splices raw JSON tokens rather than decoding and re-escaping.** The seed bodies are multi-KB markdown with newlines, quotes and `\u` escapes. A round-trip through `str_escape_json` would have to reproduce every escape the author wrote, and any it does not know about silently corrupts the body. Copying a token verbatim cannot corrupt what it never decodes. **It verifies by re-reading.** The bug this replaces reported success while delivering empty bodies, so success is not what the write call returned — it is what the graph now holds. Every declared id is re-read and audited against the hollow signature, and the manifest names the failing ids. ``` [forge] ── genesis manifest ───────────────────────────── [forge] created: 87 [forge] filled: 2 [forge] skipped: 13 [forge] failed: 0 [forge] nodes verified: 102/102 [forge] edges declared: 214 (engram dedups by from/to/relation) ``` Hollow detection is deliberately conservative — under 40% of the declared body **and** under 400 bytes — so a node whose body legitimately grew in the graph is left alone. Genesis restores what is missing; it does not overwrite what the graph has learned. ## Also - Registers Neuron in `registry.json`, `installed:false` until the identity load is authorized. `engram_api_key` is left empty on purpose: the key for a pre-existing engram belongs to that engram's launchd environment, not to a file in this repo. - `-DHAVE_CURL` in `CFLAGS`. Without it the el-compiler runtime links fine and then answers every `http_get`/`http_post_json` with `{"error":"not built with HAVE_CURL"}` — forge is entirely HTTP, so it dies at the first engram call. No-op against the SDK release runtime CI pulls. ## Verification Sandbox engram on a throwaway port with a throwaway data dir, seeded to mirror the live graph's state for this seed (15 resident declared nodes including the 2 hollow, plus all 694 of their real incident edges). No prod or stage writes. | | | |---|---| | manifest | created 87, filled 2, skipped 13, failed 0 | | nodes present after | **102 / 102**, 0 hollow signatures remaining | | byte-exact against seed | 89 / 89 written; the 13 skipped keep their longer live bodies by design | | edges laid | **214 / 214**, weights exact | | non-seed incident edges preserved | **682 / 682** through the two in-place replaces | | rerun | `absent: 0 hollow: 0 intact: 102`, 0 nodes and 0 edges added | | against an engram with no reseed route | creates the 87, fills 0, **fails loudly** naming the 2, registry not updated | | gate | refuses without `GENESIS_CONFIRM` | | persona path | unchanged — reinstall short-circuit still fires, no launchd touched | Content-length distribution after install: min 286, median 1728, max 4679, **0 nodes under 100 chars**. A run that returns success while delivering empty content is the exact failure mode being fixed, so the audit is on the output distribution, not on the exit status. ## Branch note Branched from local `main`, which carries 6 commits not yet on the remote. Those are pre-existing and untouched; they ride along in this PR because `install_genesis` calls `registry_replace_slug`, which one of them introduced. ## Depends on `neuron-technologies/el` PR for `POST /api/nodes/reseed`. Forge degrades gracefully without it — creates every absent node and lays every edge, then reports the 2 hollow nodes as failed rather than reaching for a destructive substitute.
will.anderson added 7 commits 2026-08-10 21:45:53 +00:00
Port formula: daemon = engram_port + 100. Bobby Anderson 8801→8901
through Stephen Colbert 8825→8925. All souls with installed:true and
a real engram_root_id now have their daemon URL for direct dispatch.
Adds `forge soul daemon <install|start|stop|status>` subcommand that
manages launchd-resident neuron binary instances (one per soul), serving
on ports 8901-8926. Builds SOUL_IDENTITY from seed file values, biography,
voice profile, reasoning patterns, and relationships; XML-escapes for plist.
Installs and loads all 26 soul daemons via `forge soul daemon install --all`.
A persona seed is generative: values and biography are prose, the installer
mints an id for each node, and the ids are incidental because nothing
outside the graph refers to them. A genesis seed is declarative -- it ships
identity_nodes[] with explicit ids and edges[] written in terms of them,
and the ids are the artifact. is_protected_node keys on exact ids and every
declared edge references them.

install.el only understood the persona schema. It never read identity_nodes
or edges, so installing Neuron's genesis seed minted 102 unrelated nodes
and produced a graph structurally unrelated to the one the seed describes.
The result in the live graph: 87 of 102 declared nodes absent, 2 present
with only their label as content, 202 of 214 edges never laid.

Branch on seed_type. Seeds without one reach the identical persona code
they always did. Genesis seeds render their declared nodes and edges into a
snapshot-format file and hand it to the engram, which honors the ids --
POST /api/nodes/reseed where available, POST /api/load-merge otherwise.
Both skip nodes already present and dedup edges, so a rerun is a no-op by
construction.

Three things this path does differently, all inherent to what a genesis
seed is:

- It never provisions. A persona seed gets a port and a launchd Engram; a
  genesis seed installs into an engram that already exists and is owned by
  something else. The ":8742 refusal" is also inverted -- that guard stops
  a foreign soul landing in Neuron's engram, and Neuron's own identity
  graph is the one thing that belongs there. GENESIS_CONFIRM takes its
  place, because rewriting the graph a running CGI reads itself out of
  should never happen because someone typed a familiar command with an
  unfamiliar file.

- It splices raw JSON tokens rather than decoding and re-escaping. The seed
  bodies are multi-KB markdown with newlines, quotes and \u escapes; a
  round-trip through str_escape_json would have to reproduce every escape
  the author wrote, and any it does not know about silently corrupts the
  body. Copying a token verbatim cannot corrupt what it never decodes.

- It verifies by re-reading. The bug this replaces reported success while
  delivering empty bodies, so success is not what the write returned, it is
  what the graph now holds: every declared id is re-read and audited
  against the hollow signature, and the manifest reports created / filled /
  skipped / failed with the failing ids named.

Hollow detection is deliberately conservative -- under 40% of the declared
body and under 400 bytes -- so a node whose body legitimately grew in the
graph is left alone. Genesis restores what is missing; it does not
overwrite what the graph has learned.

Also registers Neuron in registry.json (installed:false until the identity
load is authorized) and defines HAVE_CURL in CFLAGS, without which the
el-compiler runtime links fine and then answers every HTTP call with
{"error":"not built with HAVE_CURL"}.

Verified against a sandbox engram seeded to mirror the live graph's state
for this seed: created 87, filled 2, skipped 13, failed 0; 102/102 nodes
verified byte-exact against the seed where the seed is authoritative;
214/214 edges laid; 682/682 non-seed incident edges preserved through the
two in-place replaces; rerun reports 102 skipped, 0 nodes and 0 edges
added. Against an engram without the reseed route it creates the 87, fills
none, and fails loudly naming the 2 it could not repair.
will.anderson merged commit 9b0d29a350 into main 2026-08-16 13:17:14 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No labels
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: neuron-technologies/forge-retired#1