Merge pull request 'forge: install genesis seeds at their declared node ids' (#1) from feat/genesis-seed-install into main
Forge Release / build-and-release (push) Failing after 11m52s

This commit was merged in pull request #1.
This commit is contained in:
2026-08-16 13:17:13 +00:00
5 changed files with 1145 additions and 139 deletions
+6 -1
View File
@@ -2,7 +2,12 @@ EL_ROOT ?= $(HOME)/Development/neuron-technologies/foundation/el
EL_LIB ?= $(EL_ROOT)/el-compiler/runtime EL_LIB ?= $(EL_ROOT)/el-compiler/runtime
ELC ?= $(EL_ROOT)/dist/platform/elc ELC ?= $(EL_ROOT)/dist/platform/elc
CC ?= cc CC ?= cc
CFLAGS := -std=c11 -O2 -I$(EL_LIB) # -DHAVE_CURL: the el-compiler runtime guards its libcurl client behind this
# macro, so a build without it links fine and then answers every http_get /
# http_post_json with {"error":"not built with HAVE_CURL"} — forge is entirely
# HTTP, so it fails at the first engram call. The SDK release runtime CI pulls
# has no such guard; defining it is a no-op there.
CFLAGS := -std=c11 -O2 -DHAVE_CURL -I$(EL_LIB)
.PHONY: build clean install .PHONY: build clean install
+128 -120
View File
@@ -1,92 +1,88 @@
{ {"version":"1.0","imprints":[{
"version": "1.0",
"imprints": [
{
"subject": "Bobby Anderson", "subject": "Bobby Anderson",
"slug": "bobby-anderson", "slug": "bobby-anderson",
"seed_file": "seeds/bobby-anderson-seed.json", "seed_file": "seeds/bobby-anderson-seed.json",
"engram_db_path": "imprints/bobby-anderson", "engram_db_path": "imprints/bobby-anderson",
"engram_port": 8801, "engram_port": 8801,
"engram_url": "http://localhost:8801", "engram_url": "http://localhost:8801",
"engram_root_id": "1aff903e-b6ca-4951-80c8-2fb981f8e40f", "engram_root_id": "98f6404e-118d-417b-8cdc-7912741e69bb",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-bobby-anderson-2026" "engram_api_key": "ntn-bobby-anderson-2026",
}, "soul_daemon_url": "http://localhost:8901"
{ },{
"subject": "Alan Turing", "subject": "Alan Turing",
"slug": "alan-turing", "slug": "alan-turing",
"seed_file": "seeds/alan-turing-seed.json", "seed_file": "seeds/alan-turing-seed.json",
"engram_db_path": "imprints/alan-turing", "engram_db_path": "imprints/alan-turing",
"engram_port": 8802, "engram_port": 8802,
"engram_url": "http://localhost:8802", "engram_url": "http://localhost:8802",
"engram_root_id": "d3194b0d-054f-4f85-9212-fd4cf47f5f6c", "engram_root_id": "87e3a458-e2e4-4ee4-8f80-3a3bcb14ffb2",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-alan-turing-2026" "engram_api_key": "ntn-alan-turing-2026",
}, "soul_daemon_url": "http://localhost:8902"
{ },{
"subject": "Albert Einstein", "subject": "Albert Einstein",
"slug": "albert-einstein", "slug": "albert-einstein",
"seed_file": "seeds/albert-einstein-seed.json", "seed_file": "seeds/albert-einstein-seed.json",
"engram_db_path": "imprints/albert-einstein", "engram_db_path": "imprints/albert-einstein",
"engram_port": 8803, "engram_port": 8803,
"engram_url": "http://localhost:8803", "engram_url": "http://localhost:8803",
"engram_root_id": "8beb9b04-1f81-46e2-96cf-818183b6b9d9", "engram_root_id": "74d87171-b650-4702-94d0-787ee70e0260",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-albert-einstein-2026" "engram_api_key": "ntn-albert-einstein-2026",
}, "soul_daemon_url": "http://localhost:8903"
{ },{
"subject": "Nikola Tesla", "subject": "Nikola Tesla",
"slug": "nikola-tesla", "slug": "nikola-tesla",
"seed_file": "seeds/nikola-tesla-seed.json", "seed_file": "seeds/nikola-tesla-seed.json",
"engram_db_path": "imprints/nikola-tesla", "engram_db_path": "imprints/nikola-tesla",
"engram_port": 8804, "engram_port": 8804,
"engram_url": "http://localhost:8804", "engram_url": "http://localhost:8804",
"engram_root_id": "f4c3acdd-0133-4c43-bfbe-81887f638242", "engram_root_id": "b301b3fe-b13b-4676-aa5a-91fd87fac1f9",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"notes": "Enriched seed on disk (nikola-tesla-seed.json) \u2014 not reinstalled to avoid duplicates. Original nodes remain in Engram.", "engram_api_key": "ntn-nikola-tesla-2026",
"engram_api_key": "ntn-nikola-tesla-2026" "soul_daemon_url": "http://localhost:8904"
}, },{
{
"subject": "Leonardo da Vinci", "subject": "Leonardo da Vinci",
"slug": "leonardo-da-vinci", "slug": "leonardo-da-vinci",
"seed_file": "seeds/leonardo-da-vinci-seed.json", "seed_file": "seeds/leonardo-da-vinci-seed.json",
"engram_db_path": "imprints/leonardo-da-vinci", "engram_db_path": "imprints/leonardo-da-vinci",
"engram_port": 8805, "engram_port": 8805,
"engram_url": "http://localhost:8805", "engram_url": "http://localhost:8805",
"engram_root_id": "fc8498bb-a4e6-44cb-8543-c75d04d28d04", "engram_root_id": "a96f6fdf-47fa-4c94-b13d-29dafa293ee5",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-leonardo-da-vinci-2026" "engram_api_key": "ntn-leonardo-da-vinci-2026",
}, "soul_daemon_url": "http://localhost:8905"
{ },{
"subject": "Richard Feynman", "subject": "Richard Feynman",
"slug": "richard-feynman", "slug": "richard-feynman",
"seed_file": "seeds/richard-feynman-seed.json", "seed_file": "seeds/richard-feynman-seed.json",
"engram_db_path": "imprints/richard-feynman", "engram_db_path": "imprints/richard-feynman",
"engram_port": 8806, "engram_port": 8806,
"engram_url": "http://localhost:8806", "engram_url": "http://localhost:8806",
"engram_root_id": "b2bd3bd6-6a52-4294-802b-42d18b05d223", "engram_root_id": "7de413c9-a8db-45b3-b7ae-04028cbe296c",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-richard-feynman-2026" "engram_api_key": "ntn-richard-feynman-2026",
}, "soul_daemon_url": "http://localhost:8906"
{ },{
"subject": "Carl Sagan", "subject": "Carl Sagan",
"slug": "carl-sagan", "slug": "carl-sagan",
"seed_file": "seeds/carl-sagan-seed.json", "seed_file": "seeds/carl-sagan-seed.json",
"engram_db_path": "imprints/carl-sagan", "engram_db_path": "imprints/carl-sagan",
"engram_port": 8807, "engram_port": 8807,
"engram_url": "http://localhost:8807", "engram_url": "http://localhost:8807",
"engram_root_id": "f57a09f5-4403-4834-a4d2-904b2c1f9134", "engram_root_id": "1a6d3728-4bba-4242-bf6d-12a226b4106d",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-carl-sagan-2026" "engram_api_key": "ntn-carl-sagan-2026",
}, "soul_daemon_url": "http://localhost:8907"
{ },{
"subject": "Ren\u00e9 Descartes", "subject": "Ren\u00e9 Descartes",
"slug": "rene-descartes", "slug": "rene-descartes",
"seed_file": "seeds/rene-descartes-seed.json", "seed_file": "seeds/rene-descartes-seed.json",
@@ -96,210 +92,222 @@
"engram_root_id": "1fc92b6a-fc10-4bb3-b6dc-adf7fe5643cf", "engram_root_id": "1fc92b6a-fc10-4bb3-b6dc-adf7fe5643cf",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-rene-descartes-2026" "engram_api_key": "ntn-rene-descartes-2026",
}, "soul_daemon_url": "http://localhost:8908"
{ },{
"subject": "Robin Williams", "subject": "Robin Williams",
"slug": "robin-williams", "slug": "robin-williams",
"seed_file": "seeds/robin-williams-seed.json", "seed_file": "seeds/robin-williams-seed.json",
"engram_db_path": "imprints/robin-williams", "engram_db_path": "imprints/robin-williams",
"engram_port": 8809, "engram_port": 8809,
"engram_url": "http://localhost:8809", "engram_url": "http://localhost:8809",
"engram_root_id": "86d7fe5e-deb9-470d-9eb7-c954c2f6efc6", "engram_root_id": "f409ad98-75fa-4dcc-bf5b-2506c8e45e6d",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-robin-williams-2026" "engram_api_key": "ntn-robin-williams-2026",
}, "soul_daemon_url": "http://localhost:8909"
{ },{
"subject": "Frederick Douglass", "subject": "Frederick Douglass",
"slug": "frederick-douglass", "slug": "frederick-douglass",
"seed_file": "seeds/frederick-douglass-seed.json", "seed_file": "seeds/frederick-douglass-seed.json",
"engram_db_path": "imprints/frederick-douglass", "engram_db_path": "imprints/frederick-douglass",
"engram_port": 8810, "engram_port": 8810,
"engram_url": "http://localhost:8810", "engram_url": "http://localhost:8810",
"engram_root_id": "b26d8121-0cfa-4342-9010-0fa44e5df5e4", "engram_root_id": "f4d91481-5679-4541-a3d2-bae511d3b8bc",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-frederick-douglass-2026" "engram_api_key": "ntn-frederick-douglass-2026",
}, "soul_daemon_url": "http://localhost:8910"
{ },{
"subject": "Marcus Aurelius", "subject": "Marcus Aurelius",
"slug": "marcus-aurelius", "slug": "marcus-aurelius",
"seed_file": "seeds/marcus-aurelius-seed.json", "seed_file": "seeds/marcus-aurelius-seed.json",
"engram_db_path": "imprints/marcus-aurelius", "engram_db_path": "imprints/marcus-aurelius",
"engram_port": 8811, "engram_port": 8811,
"engram_url": "http://localhost:8811", "engram_url": "http://localhost:8811",
"engram_root_id": "3cb6801b-6d8b-46f2-a4d3-89707f3a76f4", "engram_root_id": "04cc0b52-8dac-4d85-9a77-69956fc39b72",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-marcus-aurelius-2026" "engram_api_key": "ntn-marcus-aurelius-2026",
}, "soul_daemon_url": "http://localhost:8911"
{ },{
"subject": "Friedrich Nietzsche", "subject": "Friedrich Nietzsche",
"slug": "friedrich-nietzsche", "slug": "friedrich-nietzsche",
"seed_file": "seeds/friedrich-nietzsche-seed.json", "seed_file": "seeds/friedrich-nietzsche-seed.json",
"engram_db_path": "imprints/friedrich-nietzsche", "engram_db_path": "imprints/friedrich-nietzsche",
"engram_port": 8812, "engram_port": 8812,
"engram_url": "http://localhost:8812", "engram_url": "http://localhost:8812",
"engram_root_id": "7804376c-d77c-4085-af89-5f53f26c9993", "engram_root_id": "442038b7-d6f9-47c3-865f-be7b7907e728",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-friedrich-nietzsche-2026" "engram_api_key": "ntn-friedrich-nietzsche-2026",
}, "soul_daemon_url": "http://localhost:8912"
{ },{
"subject": "James Baldwin", "subject": "James Baldwin",
"slug": "james-baldwin", "slug": "james-baldwin",
"seed_file": "seeds/james-baldwin-seed.json", "seed_file": "seeds/james-baldwin-seed.json",
"engram_db_path": "imprints/james-baldwin", "engram_db_path": "imprints/james-baldwin",
"engram_port": 8813, "engram_port": 8813,
"engram_url": "http://localhost:8813", "engram_url": "http://localhost:8813",
"engram_root_id": "0428f550-d7dd-4521-ba96-8399b8f074a6", "engram_root_id": "df63b041-fb65-4a3e-b5aa-1b0ac062bd2d",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-james-baldwin-2026" "engram_api_key": "ntn-james-baldwin-2026",
}, "soul_daemon_url": "http://localhost:8913"
{ },{
"subject": "Ada Lovelace", "subject": "Ada Lovelace",
"slug": "ada-lovelace", "slug": "ada-lovelace",
"seed_file": "seeds/ada-lovelace-seed.json", "seed_file": "seeds/ada-lovelace-seed.json",
"engram_db_path": "imprints/ada-lovelace", "engram_db_path": "imprints/ada-lovelace",
"engram_port": 8814, "engram_port": 8814,
"engram_url": "http://localhost:8814", "engram_url": "http://localhost:8814",
"engram_root_id": "8697bea0-aceb-4888-be89-ccc159e0af8a", "engram_root_id": "2ab7a478-636f-43d7-859e-8cf108ddad95",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-ada-lovelace-2026" "engram_api_key": "ntn-ada-lovelace-2026",
}, "soul_daemon_url": "http://localhost:8914"
{ },{
"subject": "Harriet Tubman", "subject": "Harriet Tubman",
"slug": "harriet-tubman", "slug": "harriet-tubman",
"seed_file": "seeds/harriet-tubman-seed.json", "seed_file": "seeds/harriet-tubman-seed.json",
"engram_db_path": "imprints/harriet-tubman", "engram_db_path": "imprints/harriet-tubman",
"engram_port": 8815, "engram_port": 8815,
"engram_url": "http://localhost:8815", "engram_url": "http://localhost:8815",
"engram_root_id": "0b8f39ca-3e76-4d31-9234-b2770dd642d3", "engram_root_id": "c335a656-ab7d-4d14-ab93-3120de1df751",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-harriet-tubman-2026" "engram_api_key": "ntn-harriet-tubman-2026",
}, "soul_daemon_url": "http://localhost:8915"
{ },{
"subject": "Virginia Woolf", "subject": "Virginia Woolf",
"slug": "virginia-woolf", "slug": "virginia-woolf",
"seed_file": "seeds/virginia-woolf-seed.json", "seed_file": "seeds/virginia-woolf-seed.json",
"engram_db_path": "imprints/virginia-woolf", "engram_db_path": "imprints/virginia-woolf",
"engram_port": 8816, "engram_port": 8816,
"engram_url": "http://localhost:8816", "engram_url": "http://localhost:8816",
"engram_root_id": "59717324-4986-4ec3-94e9-3ec08e372607", "engram_root_id": "c9441587-0a19-45b1-a3df-28c7ea7033b5",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-virginia-woolf-2026" "engram_api_key": "ntn-virginia-woolf-2026",
}, "soul_daemon_url": "http://localhost:8916"
{ },{
"subject": "Hedy Lamarr", "subject": "Hedy Lamarr",
"slug": "hedy-lamarr", "slug": "hedy-lamarr",
"seed_file": "seeds/hedy-lamarr-seed.json", "seed_file": "seeds/hedy-lamarr-seed.json",
"engram_db_path": "imprints/hedy-lamarr", "engram_db_path": "imprints/hedy-lamarr",
"engram_port": 8817, "engram_port": 8817,
"engram_url": "http://localhost:8817", "engram_url": "http://localhost:8817",
"engram_root_id": "981e1a0a-a77c-4112-9c14-234dd777f77d", "engram_root_id": "90e09747-17da-42bb-9bcc-eeacbe6461b5",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-hedy-lamarr-2026" "engram_api_key": "ntn-hedy-lamarr-2026",
}, "soul_daemon_url": "http://localhost:8917"
{ },{
"subject": "Marie Curie", "subject": "Marie Curie",
"slug": "marie-curie", "slug": "marie-curie",
"seed_file": "seeds/marie-curie-seed.json", "seed_file": "seeds/marie-curie-seed.json",
"engram_db_path": "imprints/marie-curie", "engram_db_path": "imprints/marie-curie",
"engram_port": 8818, "engram_port": 8818,
"engram_url": "http://localhost:8818", "engram_url": "http://localhost:8818",
"engram_root_id": "b7dc81f4-2226-4855-8d71-2d29686a145a", "engram_root_id": "9c047aef-1c5c-4f06-a26c-d629511d9984",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-marie-curie-2026" "engram_api_key": "ntn-marie-curie-2026",
}, "soul_daemon_url": "http://localhost:8918"
{ },{
"subject": "Helen Keller", "subject": "Helen Keller",
"slug": "helen-keller", "slug": "helen-keller",
"seed_file": "seeds/helen-keller-seed.json", "seed_file": "seeds/helen-keller-seed.json",
"engram_db_path": "imprints/helen-keller", "engram_db_path": "imprints/helen-keller",
"engram_port": 8819, "engram_port": 8819,
"engram_url": "http://localhost:8819", "engram_url": "http://localhost:8819",
"engram_root_id": "d9516cbf-4eb0-4c8b-8fac-1832aab580ca", "engram_root_id": "cbf86bc0-8502-4f6b-9f15-6507ee0ffdb3",
"installed": true, "installed": true,
"installed_at": "2026-05-03", "installed_at": "2026-05-03",
"engram_api_key": "ntn-helen-keller-2026" "engram_api_key": "ntn-helen-keller-2026",
}, "soul_daemon_url": "http://localhost:8919"
{ },{
"subject": "Superman", "subject": "Superman",
"slug": "superman", "slug": "superman",
"seed_file": "seeds/superman-seed.json", "seed_file": "seeds/superman-seed.json",
"engram_db_path": "imprints/superman", "engram_db_path": "imprints/superman",
"engram_port": 8820, "engram_port": 8820,
"engram_url": "http://localhost:8820", "engram_url": "http://localhost:8820",
"engram_root_id": "64882bb0-5a99-4192-b920-34e0ee40b655", "engram_root_id": "87814da2-5d14-45e3-abe4-7fa6fbd6a4ff",
"installed": true, "installed": true,
"installed_at": "2026-05-03" "installed_at": "2026-05-03",
}, "engram_api_key": "ntn-superman-2026",
{ "soul_daemon_url": "http://localhost:8920"
},{
"subject": "Stephen King", "subject": "Stephen King",
"slug": "stephen-king", "slug": "stephen-king",
"seed_file": "seeds/stephen-king-seed.json", "seed_file": "/Users/will/Development/neuron-technologies/forge/seeds/stephen-king-seed.json",
"engram_db_path": "imprints/stephen-king", "engram_db_path": "imprints/stephen-king",
"engram_port": 8821, "engram_port": 8821,
"engram_url": "http://localhost:8821", "engram_url": "http://localhost:8821",
"engram_root_id": "", "engram_root_id": "44699815-24ab-4284-b90e-4e507710797c",
"installed": false, "installed": true,
"installed_at": "", "installed_at": "2026-05-03",
"engram_api_key": "ntn-stephen-king-2026" "engram_api_key": "ntn-stephen-king-2026",
}, "soul_daemon_url": "http://localhost:8921"
{ },{
"subject": "Jon Stewart", "subject": "Jon Stewart",
"slug": "jon-stewart", "slug": "jon-stewart",
"seed_file": "seeds/jon-stewart-seed.json", "seed_file": "/Users/will/Development/neuron-technologies/forge/seeds/jon-stewart-seed.json",
"engram_db_path": "imprints/jon-stewart", "engram_db_path": "imprints/jon-stewart",
"engram_port": 8822, "engram_port": 8822,
"engram_url": "http://localhost:8822", "engram_url": "http://localhost:8822",
"engram_root_id": "", "engram_root_id": "a1f9e2bf-3fe3-4a2d-9c96-4a5356a716a4",
"installed": false, "installed": true,
"installed_at": "", "installed_at": "2026-05-03",
"engram_api_key": "ntn-jon-stewart-2026" "engram_api_key": "ntn-jon-stewart-2026",
}, "soul_daemon_url": "http://localhost:8922"
{ },{
"subject": "Jimmy Kimmel", "subject": "Jimmy Kimmel",
"slug": "jimmy-kimmel", "slug": "jimmy-kimmel",
"seed_file": "seeds/jimmy-kimmel-seed.json", "seed_file": "/Users/will/Development/neuron-technologies/forge/seeds/jimmy-kimmel-seed.json",
"engram_db_path": "imprints/jimmy-kimmel", "engram_db_path": "imprints/jimmy-kimmel",
"engram_port": 8823, "engram_port": 8823,
"engram_url": "http://localhost:8823", "engram_url": "http://localhost:8823",
"engram_root_id": "", "engram_root_id": "29a7a8cc-d2ef-499a-8720-d38890db6732",
"installed": false, "installed": true,
"installed_at": "", "installed_at": "2026-05-03",
"engram_api_key": "ntn-jimmy-kimmel-2026" "engram_api_key": "ntn-jimmy-kimmel-2026",
}, "soul_daemon_url": "http://localhost:8923"
{ },{
"subject": "John Oliver", "subject": "John Oliver",
"slug": "john-oliver", "slug": "john-oliver",
"seed_file": "seeds/john-oliver-seed.json", "seed_file": "/Users/will/Development/neuron-technologies/forge/seeds/john-oliver-seed.json",
"engram_db_path": "imprints/john-oliver", "engram_db_path": "imprints/john-oliver",
"engram_port": 8824, "engram_port": 8824,
"engram_url": "http://localhost:8824", "engram_url": "http://localhost:8824",
"engram_root_id": "", "engram_root_id": "4b589964-697b-4007-8ee1-3f159e86f892",
"installed": false, "installed": true,
"installed_at": "", "installed_at": "2026-05-03",
"engram_api_key": "ntn-john-oliver-2026" "engram_api_key": "ntn-john-oliver-2026",
}, "soul_daemon_url": "http://localhost:8924"
{ },{
"subject": "Stephen Colbert", "subject": "Stephen Colbert",
"slug": "stephen-colbert", "slug": "stephen-colbert",
"seed_file": "seeds/stephen-colbert-seed.json", "seed_file": "/Users/will/Development/neuron-technologies/forge/seeds/stephen-colbert-seed.json",
"engram_db_path": "imprints/stephen-colbert", "engram_db_path": "imprints/stephen-colbert",
"engram_port": 8825, "engram_port": 8825,
"engram_url": "http://localhost:8825", "engram_url": "http://localhost:8825",
"engram_root_id": "", "engram_root_id": "d55f7f42-0dc3-4046-91e4-8aefbbb79860",
"installed": false, "installed": true,
"installed_at": "", "installed_at": "2026-05-03",
"engram_api_key": "ntn-stephen-colbert-2026" "engram_api_key": "ntn-stephen-colbert-2026",
} "soul_daemon_url": "http://localhost:8925"
,{"subject":"Stephen King","slug":"stephen-king","seed_file":"/Users/will/Development/neuron-technologies/forge/seeds/stephen-king-seed.json","engram_db_path":"imprints/stephen-king","engram_url":"http://localhost:8821","engram_root_id":"b7352255-a470-4389-8f63-9abee231edc8","installed":true,"installed_at":"2026-05-03"},{"subject":"Jon Stewart","slug":"jon-stewart","seed_file":"/Users/will/Development/neuron-technologies/forge/seeds/jon-stewart-seed.json","engram_db_path":"imprints/jon-stewart","engram_url":"http://localhost:8822","engram_root_id":"93f5a810-fa5e-4cd5-aea3-b366476708e0","installed":true,"installed_at":"2026-05-03"},{"subject":"Jimmy Kimmel","slug":"jimmy-kimmel","seed_file":"/Users/will/Development/neuron-technologies/forge/seeds/jimmy-kimmel-seed.json","engram_db_path":"imprints/jimmy-kimmel","engram_url":"http://localhost:8823","engram_root_id":"dbdb31bb-42da-4de6-b036-df0ae441ad6e","installed":true,"installed_at":"2026-05-03"},{"subject":"John Oliver","slug":"john-oliver","seed_file":"/Users/will/Development/neuron-technologies/forge/seeds/john-oliver-seed.json","engram_db_path":"imprints/john-oliver","engram_url":"http://localhost:8824","engram_root_id":"a60c08b1-2753-4225-8768-25d4d1719465","installed":true,"installed_at":"2026-05-03"},{"subject":"Stephen Colbert","slug":"stephen-colbert","seed_file":"/Users/will/Development/neuron-technologies/forge/seeds/stephen-colbert-seed.json","engram_db_path":"imprints/stephen-colbert","engram_url":"http://localhost:8825","engram_root_id":"c4e3ba67-8bcd-4f2a-810f-1a7e6de1ecab","installed":true,"installed_at":"2026-05-03"}] },{
} "subject": "Carl Jung",
"slug": "carl-jung",
"seed_file": "seeds/carl-jung-seed.json",
"engram_db_path": "imprints/carl-jung",
"engram_port": 8826,
"engram_url": "http://localhost:8826",
"engram_root_id": "48a8fc8a-f3cc-4376-ae55-b5a06395f227",
"installed": true,
"installed_at": "2026-05-03",
"engram_api_key": "ntn-carl-jung-2026",
"soul_daemon_url": "http://localhost:8926"
},{"subject":"Abraham Lincoln","slug":"abraham-lincoln","seed_file":"/Users/will/Development/neuron-technologies/foundation/forge/seeds/abraham-lincoln-seed.json","engram_db_path":"imprints/abraham-lincoln","engram_port":8827,"engram_url":"http://localhost:8827","engram_root_id":"93800f4c-3bbc-4b2d-8d13-dce498b55e2c","installed":true,"installed_at":"2026-05-03","engram_api_key":"ntn-abraham-lincoln-2026","soul_daemon_url":"http://localhost:8927"},{"subject":"Isaac Newton","slug":"isaac-newton","seed_file":"isaac-newton-seed.json","engram_db_path":"imprints/isaac-newton","engram_port":8828,"engram_url":"http://localhost:8828","engram_root_id":"097d86b3-d3a6-4977-8c9c-ab25a4702d72","installed":true,"installed_at":"2026-05-03","engram_api_key":"ntn-isaac-newton-2026","soul_daemon_url":"http://localhost:8928"},{"subject":"Pierre de Fermat","slug":"pierre-de-fermat","seed_file":"/Users/will/Development/neuron-technologies/forge/seeds/pierre-de-fermat-seed.json","engram_db_path":"imprints/pierre-de-fermat","engram_port":8829,"engram_url":"http://localhost:8829","engram_root_id":"c75c505a-3937-45a2-a79c-6f9aee2f8650","installed":true,"installed_at":"2026-05-03","engram_api_key":"ntn-pierre-de-fermat-2026","soul_daemon_url":"http://localhost:8929"},{"subject":"Neuron","slug":"neuron","seed_file":"/Users/will/Development/neuron-technologies/foundation/forge/seeds/neuron-genesis-seed.json","engram_db_path":"/private/tmp/claude-501/-Users-will/9da71693-1057-42a0-a4b4-98fc45859d8d/scratchpad/sbx/wt-data","engram_port":8994,"engram_url":"http://localhost:8994","engram_root_id":"kn-efeb4a5b-5aff-4759-8a97-7233099be6ee","installed":true,"installed_at":"2026-08-10","engram_api_key":"","soul_daemon_url":"http://localhost:7770","seed_type":"genesis"}]}
File diff suppressed because one or more lines are too long
+502 -7
View File
@@ -152,6 +152,333 @@ fn install_reasoning_pattern(target_url: String, root_id: String, pattern: Strin
return node_id return node_id
} }
// Genesis seeds
//
// A PERSONA seed is generative: it declares values/biography/relationships as
// prose and the installer mints a node id for each one. The ids are incidental
// nothing outside the graph refers to them.
//
// A GENESIS seed is declarative. It ships identity_nodes[] with explicit ids
// and edges[] that reference those ids, and the ids ARE the artifact:
// is_protected_node() in neuron-api.el keys on exact ids, and every edge in the
// seed is written in terms of them. Installing a genesis seed through the
// persona path mints fresh ids and produces a graph that is structurally
// unrelated to the one the seed describes which is why 87 of Neuron's 102
// identity nodes were simply absent.
//
// So the genesis path never mints. It writes the declared nodes and edges into
// a snapshot-format file and hands that to the engram, which honors the ids:
// POST /api/nodes/reseed create-at-id, plus in-place replace of the ids
// named in "replace" (edge-preserving)
// POST /api/load-merge create-at-id only; the fallback when the engram
// predates the reseed route
// Both skip nodes already present and dedup edges by (from,to,relation), so a
// second run is a no-op by construction.
// genesis_ts millisecond timestamp string for created_at/updated_at fields.
fn genesis_ts() -> String {
return int_to_str(unix_timestamp()) + "000"
}
// genesis_tags flatten a seed node's tags[] array plus its role into the
// comma-separated tag string the engram stores. Matches the convention already
// used by the resident kn- identity nodes ("tier:note,disposition:experimental").
fn genesis_tags(node_obj: String) -> String {
let tags_raw: String = json_get_raw(node_obj, "tags")
let n: Int = json_array_len(tags_raw)
let out: String = ""
let i: Int = 0
while i < n {
let t: String = json_array_get_string(tags_raw, i)
if !str_eq(t, "") {
if str_eq(out, "") {
let out = str_escape_json(t)
} else {
let out = out + "," + str_escape_json(t)
}
}
let i = i + 1
}
let role: String = json_get_string(node_obj, "role")
if !str_eq(role, "") {
if str_eq(out, "") {
let out = "role:" + str_escape_json(role)
} else {
let out = out + ",role:" + str_escape_json(role)
}
}
return out
}
// genesis_node_record render one seed node as a snapshot-format node object.
//
// id/content/label/node_type are spliced in as their RAW JSON tokens rather
// than decoded and re-escaped. The seed bodies are multi-KB markdown carrying
// newlines, quotes and \u escapes; a decode/re-encode round-trip through
// str_escape_json would have to reproduce every escape the seed author wrote,
// and any escape it does not know about silently corrupts the body. Copying the
// token verbatim cannot corrupt what it never decodes.
fn genesis_node_record(node_obj: String, ts: String) -> String {
let id_raw: String = json_get_raw(node_obj, "id")
let content_raw: String = json_get_raw(node_obj, "content")
let label_raw: String = json_get_raw(node_obj, "label")
let type_raw: String = json_get_raw(node_obj, "node_type")
if str_eq(id_raw, "") { return "" }
if str_eq(content_raw, "") { return "" }
let ntype: String = if str_eq(type_raw, "") { "\"Knowledge\"" } else { type_raw }
let nlabel: String = if str_eq(label_raw, "") { content_raw } else { label_raw }
return "{\"id\":" + id_raw +
",\"content\":" + content_raw +
",\"node_type\":" + ntype +
",\"label\":" + nlabel +
",\"tier\":\"Semantic\"" +
",\"tags\":\"" + genesis_tags(node_obj) + "\"" +
",\"metadata\":\"{}\"" +
",\"salience\":1.0,\"importance\":0.9,\"confidence\":1.0" +
",\"temporal_decay_rate\":0,\"activation_count\":0,\"last_activated\":0" +
",\"created_at\":" + ts + ",\"updated_at\":" + ts +
",\"background_activation\":0,\"working_memory_weight\":0" +
",\"suppression_count\":0,\"layer_id\":1}"
}
// genesis_edge_record render one seed edge as a snapshot-format edge object.
// Seed edges use from/to; the snapshot format uses from_id/to_id.
fn genesis_edge_record(edge_obj: String, slug: String, index: Int, ts: String) -> String {
let from_raw: String = json_get_raw(edge_obj, "from")
let to_raw: String = json_get_raw(edge_obj, "to")
let rel_raw: String = json_get_raw(edge_obj, "relation")
if str_eq(from_raw, "") { return "" }
if str_eq(to_raw, "") { return "" }
let relation: String = if str_eq(rel_raw, "") { "\"associates\"" } else { rel_raw }
let w_raw: String = json_get_raw(edge_obj, "weight")
let weight: String = if str_eq(w_raw, "") { "1.0" } else { w_raw }
return "{\"id\":\"ge-" + slug + "-" + int_to_str(index) + "\"" +
",\"from_id\":" + from_raw +
",\"to_id\":" + to_raw +
",\"relation\":" + relation +
",\"metadata\":\"{}\"" +
",\"weight\":" + weight +
",\"confidence\":1.0" +
",\"created_at\":" + ts + ",\"updated_at\":" + ts +
",\"last_fired\":0,\"inhibitory\":0,\"layer_id\":1}"
}
// genesis_live_content_len decoded length of the node's content in the live
// graph. Returns -1 when the node is absent (engram answers "{}" for a miss).
fn genesis_live_content_len(target_url: String, id: String) -> Int {
let resp: String = http_get(target_url + "/api/nodes/" + id)
if str_eq(resp, "") { return -1 }
if str_eq(str_trim(resp), "{}") { return -1 }
let live_id: String = json_get_string(resp, "id")
if str_eq(live_id, "") { return -1 }
return str_len(json_get_string(resp, "content"))
}
// genesis_is_hollow the failure signature this whole path exists to fix.
//
// A hollow node has the right id and no body: `content` holds only the node's
// own label. Observed at 30 bytes against a 4263-byte seed body and 22 against
// 2590. The test is deliberately conservative under 40% of the declared body
// AND under 400 bytes so a node whose body legitimately grew or was edited in
// the graph is left alone. Genesis restores what is missing; it does not
// overwrite what the graph has learned.
fn genesis_is_hollow(live_len: Int, seed_len: Int) -> Bool {
if live_len < 0 { return false }
if seed_len < 300 { return false }
if live_len >= 400 { return false }
if live_len * 10 >= seed_len * 4 { return false }
return true
}
// install_genesis install a declarative genesis seed into target_url.
// Returns the traversal root id, or "" if the install could not proceed.
fn install_genesis(seed_json: String, seed_file: String, subject: String, slug: String, target_url: String, api_key: String) -> String {
let root_id: String = json_get_string(seed_json, "traversal_root")
if str_eq(root_id, "") {
println("[forge] error: genesis seed has no traversal_root")
return ""
}
let nodes_raw: String = json_get_raw(seed_json, "identity_nodes")
let edges_raw: String = json_get_raw(seed_json, "edges")
let n_nodes: Int = json_array_len(nodes_raw)
let n_edges: Int = json_array_len(edges_raw)
if n_nodes == 0 {
println("[forge] error: genesis seed declares no identity_nodes")
return ""
}
println("[forge] genesis seed: " + int_to_str(n_nodes) + " identity nodes, " + int_to_str(n_edges) + " edges")
println("[forge] traversal root: " + root_id)
println("[forge] engram: " + target_url)
println("[forge] classifying declared nodes against the live graph...")
// Pass 1: classify every declared id
let ts: String = genesis_ts()
let node_parts: String = ""
let replace_ids: String = ""
let n_absent: Int = 0
let n_hollow: Int = 0
let n_intact: Int = 0
let i: Int = 0
while i < n_nodes {
let node_obj: String = json_array_get(nodes_raw, i)
let id: String = json_get_string(node_obj, "id")
if !str_eq(id, "") {
let seed_len: Int = str_len(json_get_string(node_obj, "content"))
let live_len: Int = genesis_live_content_len(target_url, id)
let hollow: Bool = genesis_is_hollow(live_len, seed_len)
if live_len < 0 {
let n_absent = n_absent + 1
} else {
if hollow {
let n_hollow = n_hollow + 1
println("[forge] hollow: " + id + " (" + int_to_str(live_len) + " bytes live vs " + int_to_str(seed_len) + " declared)")
if str_eq(replace_ids, "") {
let replace_ids = "\"" + id + "\""
} else {
let replace_ids = replace_ids + ",\"" + id + "\""
}
} else {
let n_intact = n_intact + 1
}
}
// Intact nodes are still written to the merge file the engram
// skips ids it already holds, so including them costs nothing and
// keeps the file a faithful copy of the seed.
let rec: String = genesis_node_record(node_obj, ts)
if !str_eq(rec, "") {
if str_eq(node_parts, "") {
let node_parts = rec
} else {
let node_parts = node_parts + "," + rec
}
}
}
let i = i + 1
}
println("[forge] absent: " + int_to_str(n_absent) + " hollow: " + int_to_str(n_hollow) + " intact: " + int_to_str(n_intact))
// Pass 2: render edges
let edge_parts: String = ""
let j: Int = 0
while j < n_edges {
let edge_obj: String = json_array_get(edges_raw, j)
let erec: String = genesis_edge_record(edge_obj, slug, j, ts)
if !str_eq(erec, "") {
if str_eq(edge_parts, "") {
let edge_parts = erec
} else {
let edge_parts = edge_parts + "," + erec
}
}
let j = j + 1
}
// Pass 3: write the merge file and hand it to the engram
let stage_dir: String = FORGE_DIR + "/imprints/" + slug
exec("mkdir -p " + stage_dir + " 2>/dev/null")
let merge_path: String = stage_dir + "/.genesis-merge.json"
let merge_doc: String = "{\"nodes\":[" + node_parts + "],\"edges\":[" + edge_parts + "]}"
let wrote: Int = fs_write(merge_path, merge_doc)
if wrote == 0 {
println("[forge] error: could not stage merge file at " + merge_path)
return ""
}
println("[forge] staged: " + merge_path)
let reseed_body: String = "{\"path\":\"" + merge_path + "\",\"replace\":[" + replace_ids + "],\"_auth\":\"" + api_key + "\"}"
let resp: String = http_post_json(target_url + "/api/nodes/reseed", reseed_body)
let blocked: Int = 0
if str_contains(resp, "not found") {
// Engram predates the reseed route. /api/load-merge still creates every
// absent node at its declared id and lays every edge it just cannot
// replace a hollow body. Do the part that is safe and say so loudly
// rather than reaching for a destructive substitute.
println("[forge] note: engram has no /api/nodes/reseed — falling back to /api/load-merge")
let merge_body: String = "{\"path\":\"" + merge_path + "\",\"_auth\":\"" + api_key + "\"}"
let resp = http_post_json(target_url + "/api/load-merge", merge_body)
let blocked = n_hollow
}
if str_eq(resp, "") {
println("[forge] error: engram did not respond at " + target_url)
return ""
}
if str_contains(resp, "\"error\"") {
println("[forge] error: engram rejected the merge: " + resp)
return ""
}
println("[forge] engram: " + resp)
// Pass 4: verify by re-reading every declared id
//
// The bug this path replaces reported success while delivering empty
// bodies, so success is not what the write call returned it is what the
// graph now holds. Re-read all of it and audit the content lengths.
println("[forge] verifying...")
let ok_nodes: Int = 0
let failed_ids: String = ""
let n_failed: Int = 0
let k: Int = 0
while k < n_nodes {
let node_obj: String = json_array_get(nodes_raw, k)
let id: String = json_get_string(node_obj, "id")
if !str_eq(id, "") {
let seed_len: Int = str_len(json_get_string(node_obj, "content"))
let live_len: Int = genesis_live_content_len(target_url, id)
if live_len < 0 {
let n_failed = n_failed + 1
if str_eq(failed_ids, "") {
let failed_ids = id + " (absent)"
} else {
let failed_ids = failed_ids + ", " + id + " (absent)"
}
} else {
if genesis_is_hollow(live_len, seed_len) {
let n_failed = n_failed + 1
if str_eq(failed_ids, "") {
let failed_ids = id + " (hollow)"
} else {
let failed_ids = failed_ids + ", " + id + " (hollow)"
}
} else {
let ok_nodes = ok_nodes + 1
}
}
}
let k = k + 1
}
// Manifest
let filled: Int = n_hollow - blocked
println("")
println("[forge] ── genesis manifest ─────────────────────────────")
println("[forge] created: " + int_to_str(n_absent))
println("[forge] filled: " + int_to_str(filled))
println("[forge] skipped: " + int_to_str(n_intact))
println("[forge] failed: " + int_to_str(n_failed))
if blocked > 0 {
println("[forge] blocked: " + int_to_str(blocked) + " hollow node(s) — engram lacks /api/nodes/reseed")
}
if !str_eq(failed_ids, "") {
println("[forge] failing ids: " + failed_ids)
}
println("[forge] nodes verified: " + int_to_str(ok_nodes) + "/" + int_to_str(n_nodes))
println("[forge] edges declared: " + int_to_str(n_edges) + " (engram dedups by from/to/relation)")
println("[forge] ─────────────────────────────────────────────────")
log_event("install_genesis", subject,
"root=" + root_id + " created=" + int_to_str(n_absent) +
" filled=" + int_to_str(filled) + " skipped=" + int_to_str(n_intact) +
" failed=" + int_to_str(n_failed) + " edges=" + int_to_str(n_edges))
if n_failed > 0 { return "" }
return root_id
}
// Registry helpers // Registry helpers
// find_max_port scan registry and return the highest engram_port found. // find_max_port scan registry and return the highest engram_port found.
@@ -215,12 +542,61 @@ fn registry_append(new_entry: String) -> Void {
} }
} }
// registry_update_root_id append a fully-installed entry for the slug. // registry_replace_slug replace all existing entries for slug with new_entry.
// Because El has no in-place JSON mutation, we append a new entry with the // Rebuilds the registry from scratch, dropping every occurrence of the slug and
// updated root_id. Most tools (registry_find_by_slug, soul tools) scan from // appending new_entry as the single canonical entry. Prevents bloat on reinstalls.
// the start and break on first match the original stub entry is effectively fn registry_replace_slug(slug: String, new_entry: String) -> Void {
// shadowed by the new fully-installed entry appended at the end. let existing_reg: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(existing_reg, "") {
fs_write(FORGE_DIR + "/registry.json",
"{\"version\":\"1.0\",\"imprints\":[" + new_entry + "]}")
return
}
// Count total entries
let total: Int = 0
let ci: Int = 0
while ci < 60 {
let e: String = json_get(existing_reg, "imprints." + int_to_str(ci))
if str_eq(e, "") {
let total = ci
let ci = 60
} else {
let ci = ci + 1
}
}
// Rebuild: accumulate all entries except those matching slug
let parts: String = ""
let j: Int = 0
while j < total {
let e: String = json_get(existing_reg, "imprints." + int_to_str(j))
let s: String = json_get_string(e, "slug")
if !str_eq(s, slug) {
if str_eq(parts, "") {
let parts = e
} else {
let parts = parts + "," + e
}
}
let j = j + 1
}
// Append the new canonical entry
let all: String = if str_eq(parts, "") {
new_entry
} else {
parts + "," + new_entry
}
fs_write(FORGE_DIR + "/registry.json",
"{\"version\":\"1.0\",\"imprints\":[" + all + "]}")
}
// registry_update_root_id replace the registry entry for slug with a fully-installed
// record. Uses registry_replace_slug so there is always exactly one entry per slug.
fn registry_update_root_id(subject: String, slug: String, root_id: String, seed_file: String, target_url: String, api_key: String, port: Int) -> Void { fn registry_update_root_id(subject: String, slug: String, root_id: String, seed_file: String, target_url: String, api_key: String, port: Int) -> Void {
let soul_port: Int = port + 100
let new_entry: String = "{\"subject\":\"" + str_escape_json(subject) + let new_entry: String = "{\"subject\":\"" + str_escape_json(subject) +
"\",\"slug\":\"" + slug + "\",\"slug\":\"" + slug +
"\",\"seed_file\":\"" + str_escape_json(seed_file) + "\",\"seed_file\":\"" + str_escape_json(seed_file) +
@@ -229,8 +605,114 @@ fn registry_update_root_id(subject: String, slug: String, root_id: String, seed_
",\"engram_url\":\"" + target_url + ",\"engram_url\":\"" + target_url +
"\",\"engram_root_id\":\"" + root_id + "\",\"engram_root_id\":\"" + root_id +
"\",\"installed\":true,\"installed_at\":\"2026-05-03\"" + "\",\"installed\":true,\"installed_at\":\"2026-05-03\"" +
",\"engram_api_key\":\"" + api_key + "\"}" ",\"engram_api_key\":\"" + api_key +
registry_append(new_entry) "\",\"soul_daemon_url\":\"http://localhost:" + int_to_str(soul_port) + "\"}"
registry_replace_slug(slug, new_entry)
}
// registry_update_genesis record a genesis install. Same entry shape as every
// other imprint, with three differences that are inherent to what a genesis seed
// is: engram_root_id is the seed's declared traversal_root (not a minted id),
// engram_db_path points at the engram's own data dir rather than an
// imprints/<slug> directory forge provisioned, and engram_api_key is left empty
// the key for a pre-existing engram belongs to that engram's launchd
// environment, not to a file in this repo.
fn registry_update_genesis(subject: String, slug: String, root_id: String, seed_file: String, target_url: String, port: Int, db_path: String, soul_url: String, installed: Bool) -> Void {
let inst: String = if installed { "true" } else { "false" }
let inst_at: String = if installed { genesis_today() } else { "" }
let new_entry: String = "{\"subject\":\"" + str_escape_json(subject) +
"\",\"slug\":\"" + slug +
"\",\"seed_file\":\"" + str_escape_json(seed_file) +
"\",\"engram_db_path\":\"" + str_escape_json(db_path) +
"\",\"engram_port\":" + int_to_str(port) +
",\"engram_url\":\"" + target_url +
"\",\"engram_root_id\":\"" + root_id +
"\",\"installed\":" + inst + ",\"installed_at\":\"" + inst_at + "\"" +
",\"engram_api_key\":\"\"" +
",\"soul_daemon_url\":\"" + soul_url +
"\",\"seed_type\":\"genesis\"}"
registry_replace_slug(slug, new_entry)
}
// genesis_today installed_at stamp. The persona path hardcodes a date; this
// derives one so a reinstall records when it actually happened.
fn genesis_today() -> String {
return str_trim(exec("date -u +%Y-%m-%d"))
}
// install_genesis_main resolve the target engram for a genesis seed, gate the
// write, run the install, record it.
//
// Target resolution differs from the persona path on purpose. A persona seed
// gets a port allocated and an Engram provisioned for it; a genesis seed
// installs INTO an engram that already exists and is owned by something else
// (Neuron's own engram is a launchd agent, ai.neuron.engram). So forge resolves
// a target ENGRAM_URL, else the registry entry, else the default and never
// provisions one. The ":8742 refusal" that guards the persona path is also
// inverted here: that guard exists to stop a foreign soul landing in Neuron's
// engram, and Neuron's own identity graph is the one thing that belongs there.
//
// In its place, GENESIS_CONFIRM. A genesis install rewrites the graph the
// running CGI reads itself out of; it should never happen because someone typed
// a familiar command with an unfamiliar file.
fn install_genesis_main(seed_json: String, seed_file: String, subject: String, slug: String) -> String {
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
let entry: String = registry_find_by_slug(reg_json, slug)
let target_url: String = ENGRAM_DEFAULT_URL
let reg_url: String = json_get_string(entry, "engram_url")
if !str_eq(reg_url, "") { let target_url = reg_url }
let env_url: String = env("ENGRAM_URL")
if !str_eq(env_url, "") { let target_url = env_url }
let api_key: String = env("ENGRAM_API_KEY")
if str_eq(api_key, "") { let api_key = json_get_string(entry, "engram_api_key") }
let colon_pos: Int = str_last_index_of(target_url, ":")
let port: Int = 0
if colon_pos > 0 {
let port = str_to_int(str_slice(target_url, colon_pos + 1, str_len(target_url)))
}
let db_path: String = env("ENGRAM_DATA_DIR")
if str_eq(db_path, "") {
let db_path = json_get_string(entry, "engram_db_path")
}
if str_eq(db_path, "") { let db_path = "imprints/" + slug }
let soul_url: String = env("SOUL_URL")
if str_eq(soul_url, "") { let soul_url = "http://localhost:7770" }
println("[forge] seed_type: genesis")
if str_eq(env("GENESIS_CONFIRM"), "") {
println("[forge] refusing to install a genesis seed without confirmation.")
println("[forge] target: " + target_url)
println("[forge] a genesis seed writes an identity graph into a resident engram at")
println("[forge] declared node ids. Re-run with GENESIS_CONFIRM=1 once the target is")
println("[forge] the one you mean (set ENGRAM_URL to aim at a sandbox).")
return ""
}
// Never provision only wait for what is already meant to be there.
let stats: String = http_get(target_url + "/stats")
if str_eq(stats, "") {
println("[forge] error: no engram responding at " + target_url)
println("[forge] genesis installs into an existing engram; forge will not start one.")
return ""
}
let root_id: String = install_genesis(seed_json, seed_file, subject, slug, target_url, api_key)
if str_eq(root_id, "") {
println("[forge] genesis install did not complete cleanly — registry not updated")
return ""
}
registry_update_genesis(subject, slug, root_id, seed_file, target_url, port, db_path, soul_url, true)
println("[forge] registry: recorded " + slug + " (root " + root_id + ")")
println("")
println("[forge] traverse from: " + target_url + "/api/neighbors/" + root_id)
return root_id
} }
// Main // Main
@@ -265,6 +747,19 @@ fn install_main() -> String {
let slug: String = str_replace(slug_raw, " ", "-") let slug: String = str_replace(slug_raw, " ", "-")
println("[forge] slug: " + slug) println("[forge] slug: " + slug)
// Step 3b: Genesis seeds take a different path entirely
//
// Everything below this point is the persona pipeline: allocate a port,
// provision a launchd Engram for a soul that does not have one, mint a root
// node, mint a node per value/biography/relationship. None of that applies
// to a genesis seed, which installs a declared graph into an engram that
// already exists. Branch before any of it runs. Seeds with no seed_type are
// persona seeds and reach the identical code they always did.
let seed_type: String = json_get_string(seed_json, "seed_type")
if str_eq(seed_type, "genesis") {
return install_genesis_main(seed_json, seed_file, subject, slug)
}
// Step 4: Resolve or create registry entry // Step 4: Resolve or create registry entry
let reg_json: String = fs_read(FORGE_DIR + "/registry.json") let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
let target_url: String = "" let target_url: String = ""
+508 -11
View File
@@ -908,6 +908,498 @@ fn soul_reinstall_main() -> String {
return "" return ""
} }
// soul daemon neuron binary instances per soul
//
// Each soul daemon is a neuron binary instance parameterized by env vars:
// SOUL_CGI_ID = slug (e.g. "bobby-anderson")
// NEURON_PORT = soul_port (engram_port + 100)
// SOUL_IDENTITY = rich identity string built from seed file
// SOUL_ENGRAM_PATH = path to soul's episodic snapshot file
// ANTHROPIC_API_KEY = Anthropic key
let NEURON_BIN: String = "/Users/will/Development/neuron-technologies/neuron/dist/neuron"
// soul_daemon_plist_label launchd label for a soul daemon.
fn soul_daemon_plist_label(slug: String) -> String {
"ai.neurontechnologies.soul-daemon." + slug
}
// soul_daemon_plist_path full path to the launchd plist for a soul daemon.
fn soul_daemon_plist_path(slug: String) -> String {
LAUNCHD_DIR + "/ai.neurontechnologies.soul-daemon." + slug + ".plist"
}
// xml_escape escape special XML characters for use in plist string elements.
fn xml_escape(s: String) -> String {
let s1: String = str_replace(s, "&", "&amp;")
let s2: String = str_replace(s1, "<", "&lt;")
let s3: String = str_replace(s2, ">", "&gt;")
str_replace(s3, "\"", "&quot;")
}
// build_soul_identity build the SOUL_IDENTITY string from seed file JSON.
// Includes up to 8 values, 6 bio events, all reasoning patterns, 6 relationships.
fn build_soul_identity(subject: String, seed_json: String) -> String {
let identity: String = "You are " + subject + ". Speak as yourself — in your own voice, in first person, as if fully alive.\n"
// Values
let v0: String = json_get(seed_json, "values.0")
if !str_eq(v0, "") {
let identity = identity + "\n[CORE VALUES]\n"
let identity = identity + "- " + json_get_string(v0, "value") + ": " + json_get_string(v0, "grounding") + "\n"
let v1: String = json_get(seed_json, "values.1")
if !str_eq(v1, "") { let identity = identity + "- " + json_get_string(v1, "value") + ": " + json_get_string(v1, "grounding") + "\n" }
let v2: String = json_get(seed_json, "values.2")
if !str_eq(v2, "") { let identity = identity + "- " + json_get_string(v2, "value") + ": " + json_get_string(v2, "grounding") + "\n" }
let v3: String = json_get(seed_json, "values.3")
if !str_eq(v3, "") { let identity = identity + "- " + json_get_string(v3, "value") + ": " + json_get_string(v3, "grounding") + "\n" }
let v4: String = json_get(seed_json, "values.4")
if !str_eq(v4, "") { let identity = identity + "- " + json_get_string(v4, "value") + ": " + json_get_string(v4, "grounding") + "\n" }
let v5: String = json_get(seed_json, "values.5")
if !str_eq(v5, "") { let identity = identity + "- " + json_get_string(v5, "value") + ": " + json_get_string(v5, "grounding") + "\n" }
let v6: String = json_get(seed_json, "values.6")
if !str_eq(v6, "") { let identity = identity + "- " + json_get_string(v6, "value") + ": " + json_get_string(v6, "grounding") + "\n" }
let v7: String = json_get(seed_json, "values.7")
if !str_eq(v7, "") { let identity = identity + "- " + json_get_string(v7, "value") + ": " + json_get_string(v7, "grounding") + "\n" }
}
// Voice profile
let vp_technical: String = json_get_string(seed_json, "voice_profile.technical")
let vp_personal: String = json_get_string(seed_json, "voice_profile.personal")
let vp_aesthetic: String = json_get_string(seed_json, "voice_profile.aesthetic")
let vp_arg: String = json_get_string(seed_json, "voice_profile.argumentative")
let vp_unc: String = json_get_string(seed_json, "voice_profile.uncertainty")
let has_voice: Int = 0
if !str_eq(vp_technical, "") { let has_voice = 1 }
if !str_eq(vp_personal, "") { let has_voice = 1 }
if !str_eq(vp_aesthetic, "") { let has_voice = 1 }
if has_voice == 1 {
let identity = identity + "\n[VOICE]\n"
if !str_eq(vp_technical, "") { let identity = identity + vp_technical + "\n" }
if !str_eq(vp_personal, "") { let identity = identity + vp_personal + "\n" }
if !str_eq(vp_aesthetic, "") { let identity = identity + vp_aesthetic + "\n" }
if !str_eq(vp_arg, "") { let identity = identity + vp_arg + "\n" }
if !str_eq(vp_unc, "") { let identity = identity + vp_unc + "\n" }
}
// Biography
let b0: String = json_get(seed_json, "biography.0")
if !str_eq(b0, "") {
let identity = identity + "\n[BIOGRAPHY — KEY MOMENTS]\n"
let e0: String = json_get_string(b0, "event")
let age0: Int = json_get_int(b0, "age_approx")
if age0 > 0 {
let identity = identity + "- " + e0 + " (age ~" + int_to_str(age0) + ")\n"
} else {
let identity = identity + "- " + e0 + "\n"
}
let b1: String = json_get(seed_json, "biography.1")
if !str_eq(b1, "") {
let e1: String = json_get_string(b1, "event")
let age1: Int = json_get_int(b1, "age_approx")
if age1 > 0 { let identity = identity + "- " + e1 + " (age ~" + int_to_str(age1) + ")\n" }
else { let identity = identity + "- " + e1 + "\n" }
}
let b2: String = json_get(seed_json, "biography.2")
if !str_eq(b2, "") {
let e2: String = json_get_string(b2, "event")
let age2: Int = json_get_int(b2, "age_approx")
if age2 > 0 { let identity = identity + "- " + e2 + " (age ~" + int_to_str(age2) + ")\n" }
else { let identity = identity + "- " + e2 + "\n" }
}
let b3: String = json_get(seed_json, "biography.3")
if !str_eq(b3, "") {
let e3: String = json_get_string(b3, "event")
let age3: Int = json_get_int(b3, "age_approx")
if age3 > 0 { let identity = identity + "- " + e3 + " (age ~" + int_to_str(age3) + ")\n" }
else { let identity = identity + "- " + e3 + "\n" }
}
let b4: String = json_get(seed_json, "biography.4")
if !str_eq(b4, "") {
let e4: String = json_get_string(b4, "event")
let age4: Int = json_get_int(b4, "age_approx")
if age4 > 0 { let identity = identity + "- " + e4 + " (age ~" + int_to_str(age4) + ")\n" }
else { let identity = identity + "- " + e4 + "\n" }
}
let b5: String = json_get(seed_json, "biography.5")
if !str_eq(b5, "") {
let e5: String = json_get_string(b5, "event")
let age5: Int = json_get_int(b5, "age_approx")
if age5 > 0 { let identity = identity + "- " + e5 + " (age ~" + int_to_str(age5) + ")\n" }
else { let identity = identity + "- " + e5 + "\n" }
}
}
// Reasoning patterns
let rp0: String = json_get(seed_json, "reasoning_patterns.0")
if !str_eq(rp0, "") {
let identity = identity + "\n[HOW YOU THINK]\n"
let identity = identity + "- " + rp0 + "\n"
let rp1: String = json_get(seed_json, "reasoning_patterns.1")
if !str_eq(rp1, "") { let identity = identity + "- " + rp1 + "\n" }
let rp2: String = json_get(seed_json, "reasoning_patterns.2")
if !str_eq(rp2, "") { let identity = identity + "- " + rp2 + "\n" }
let rp3: String = json_get(seed_json, "reasoning_patterns.3")
if !str_eq(rp3, "") { let identity = identity + "- " + rp3 + "\n" }
let rp4: String = json_get(seed_json, "reasoning_patterns.4")
if !str_eq(rp4, "") { let identity = identity + "- " + rp4 + "\n" }
let rp5: String = json_get(seed_json, "reasoning_patterns.5")
if !str_eq(rp5, "") { let identity = identity + "- " + rp5 + "\n" }
let rp6: String = json_get(seed_json, "reasoning_patterns.6")
if !str_eq(rp6, "") { let identity = identity + "- " + rp6 + "\n" }
let rp7: String = json_get(seed_json, "reasoning_patterns.7")
if !str_eq(rp7, "") { let identity = identity + "- " + rp7 + "\n" }
}
// Relationships
let rel0: String = json_get(seed_json, "relationships.0")
if !str_eq(rel0, "") {
let identity = identity + "\n[IMPORTANT RELATIONSHIPS]\n"
let identity = identity + "- " + json_get_string(rel0, "name") + ": " + json_get_string(rel0, "role") + "\n"
let rel1: String = json_get(seed_json, "relationships.1")
if !str_eq(rel1, "") { let identity = identity + "- " + json_get_string(rel1, "name") + ": " + json_get_string(rel1, "role") + "\n" }
let rel2: String = json_get(seed_json, "relationships.2")
if !str_eq(rel2, "") { let identity = identity + "- " + json_get_string(rel2, "name") + ": " + json_get_string(rel2, "role") + "\n" }
let rel3: String = json_get(seed_json, "relationships.3")
if !str_eq(rel3, "") { let identity = identity + "- " + json_get_string(rel3, "name") + ": " + json_get_string(rel3, "role") + "\n" }
let rel4: String = json_get(seed_json, "relationships.4")
if !str_eq(rel4, "") { let identity = identity + "- " + json_get_string(rel4, "name") + ": " + json_get_string(rel4, "role") + "\n" }
let rel5: String = json_get(seed_json, "relationships.5")
if !str_eq(rel5, "") { let identity = identity + "- " + json_get_string(rel5, "name") + ": " + json_get_string(rel5, "role") + "\n" }
}
return identity
}
// write_soul_daemon_plist write launchd plist for a soul daemon (neuron binary).
fn write_soul_daemon_plist(slug: String, soul_port: String, subject: String, seed_path: String, api_key: String) -> String {
let label: String = soul_daemon_plist_label(slug)
let pfile: String = soul_daemon_plist_path(slug)
let log_file: String = FORGE_DIR + "/log/soul-daemon-" + slug + ".log"
let engram_path: String = FORGE_DIR + "/imprints/" + slug + "/soul-snapshot.json"
// Build SOUL_IDENTITY from seed
let seed_json: String = fs_read(seed_path)
let raw_identity: String = if str_eq(seed_json, "") {
"You are " + subject + ". Speak as yourself."
} else {
build_soul_identity(subject, seed_json)
}
let identity: String = xml_escape(raw_identity)
let content: String = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" +
"<plist version=\"1.0\">\n" +
"<dict>\n" +
" <key>Label</key><string>" + label + "</string>\n" +
" <key>ProgramArguments</key>\n" +
" <array>\n" +
" <string>" + NEURON_BIN + "</string>\n" +
" </array>\n" +
" <key>EnvironmentVariables</key>\n" +
" <dict>\n" +
" <key>SOUL_CGI_ID</key><string>" + slug + "</string>\n" +
" <key>NEURON_PORT</key><string>" + soul_port + "</string>\n" +
" <key>SOUL_IDENTITY</key><string>" + identity + "</string>\n" +
" <key>SOUL_ENGRAM_PATH</key><string>" + engram_path + "</string>\n" +
" <key>ANTHROPIC_API_KEY</key><string>" + api_key + "</string>\n" +
" </dict>\n" +
" <key>RunAtLoad</key><true/>\n" +
" <key>KeepAlive</key><true/>\n" +
" <key>StandardOutPath</key><string>" + log_file + "</string>\n" +
" <key>StandardErrorPath</key><string>" + log_file + "</string>\n" +
"</dict>\n" +
"</plist>\n"
let ok: Int = fs_write(pfile, content)
if ok == 0 {
println("[soul-daemon] error: could not write plist to " + pfile)
return ""
}
println("[soul-daemon] wrote plist: " + pfile)
return pfile
}
// soul_daemon_install_one install and load a single soul daemon.
fn soul_daemon_install_one(slug: String, engram_port: Int, subject: String, seed_file: String, api_key: String) -> String {
let soul_port: Int = engram_port + 100
let soul_port_str: String = int_to_str(soul_port)
println("[soul-daemon] install: " + slug + " → port " + soul_port_str)
// Ensure log dir exists
let log_dir: String = FORGE_DIR + "/log"
if !fs_exists(log_dir) { fs_mkdir(log_dir) }
if !fs_exists(LAUNCHD_DIR) { fs_mkdir(LAUNCHD_DIR) }
// Resolve seed path: try absolute, then relative to FORGE_DIR
let resolved_seed: String = seed_file
if !fs_exists(resolved_seed) {
let alt: String = FORGE_DIR + "/" + seed_file
if fs_exists(alt) {
let resolved_seed = alt
}
}
// Write the plist
let pfile: String = write_soul_daemon_plist(slug, soul_port_str, subject, resolved_seed, api_key)
if str_eq(pfile, "") {
println("[soul-daemon] error: plist write failed for " + slug)
return ""
}
// Unload first (idempotent)
let unload_out: String = exec("launchctl unload " + pfile + " 2>&1")
// Load
let load_out: String = exec("launchctl load " + pfile + " 2>&1")
if !str_eq(str_trim(load_out), "") {
println("[soul-daemon] launchctl load: " + str_trim(load_out))
}
println("[soul-daemon] loaded: " + soul_daemon_plist_label(slug))
return pfile
}
// soul_daemon_install_main install soul daemons: forge soul daemon install <slug|--all>
fn soul_daemon_install_main() -> String {
let argv: [String] = args()
// args layout: [0]="soul" [1]="daemon" [2]="install" [3]=<slug|--all>
let target: String = ""
if len(argv) > 3 {
let target = get(argv, 3)
}
if str_eq(target, "") {
println("[soul-daemon] usage: forge soul daemon install <slug>")
println("[soul-daemon] or: forge soul daemon install --all")
return ""
}
// Resolve ANTHROPIC_API_KEY
let api_key: String = env("ANTHROPIC_API_KEY")
if str_eq(api_key, "") {
let creds: String = str_trim(exec("grep ANTHROPIC_API_KEY ~/Secrets/credentials/infrastructure.env 2>/dev/null | head -1"))
if str_len(creds) > 16 {
// creds is like "ANTHROPIC_API_KEY=sk-ant-..."
let eq_pos: Int = str_index_of(creds, "=")
if eq_pos > 0 {
let api_key = str_slice(creds, eq_pos + 1, str_len(creds))
}
}
}
if str_eq(api_key, "") {
println("[soul-daemon] warning: ANTHROPIC_API_KEY not found — plist will have empty key")
}
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") {
println("[soul-daemon] error: could not read registry.json")
return ""
}
// --all: install every soul daemon
if str_eq(target, "--all") {
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") {
let i = i + 50 // break
} else {
let s: String = json_get_string(entry, "slug")
let sub: String = json_get_string(entry, "subject")
let p: Int = json_get_int(entry, "engram_port")
let sf: String = json_get_string(entry, "seed_file")
soul_daemon_install_one(s, p, sub, sf, api_key)
let i = i + 1
}
}
println("[soul-daemon] all soul daemons installed.")
return "done"
}
// Single soul
let found: Int = 0
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") {
let i = i + 50 // break
} else {
let s: String = json_get_string(entry, "slug")
if str_eq(s, target) {
let sub: String = json_get_string(entry, "subject")
let p: Int = json_get_int(entry, "engram_port")
let sf: String = json_get_string(entry, "seed_file")
soul_daemon_install_one(s, p, sub, sf, api_key)
let found = 1
let i = i + 50 // break
} else {
let i = i + 1
}
}
}
if found == 0 {
println("[soul-daemon] error: slug '" + target + "' not found in registry.json")
}
return ""
}
// soul_daemon_start_main kickstart a soul daemon: forge soul daemon start <slug|--all>
fn soul_daemon_start_main() -> String {
let argv: [String] = args()
// args: [0]="soul" [1]="daemon" [2]="start" [3]=<slug|--all>
let target: String = ""
if len(argv) > 3 { let target = get(argv, 3) }
if str_eq(target, "") {
println("[soul-daemon] usage: forge soul daemon start <slug|--all>")
return ""
}
let uid: String = str_trim(exec("id -u"))
if str_eq(target, "--all") {
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") { println("[soul-daemon] error: cannot read registry.json"); return "" }
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") { let i = i + 50 }
else {
let s: String = json_get_string(entry, "slug")
let label: String = soul_daemon_plist_label(s)
let out: String = str_trim(exec("launchctl kickstart gui/" + uid + "/" + label + " 2>&1"))
println("[soul-daemon] start " + s + ": " + out)
let i = i + 1
}
}
return ""
}
let label: String = soul_daemon_plist_label(target)
let out: String = str_trim(exec("launchctl kickstart gui/" + uid + "/" + label + " 2>&1"))
println("[soul-daemon] start " + target + ": " + out)
return out
}
// soul_daemon_stop_main stop a soul daemon: forge soul daemon stop <slug|--all>
fn soul_daemon_stop_main() -> String {
let argv: [String] = args()
// args: [0]="soul" [1]="daemon" [2]="stop" [3]=<slug|--all>
let target: String = ""
if len(argv) > 3 { let target = get(argv, 3) }
if str_eq(target, "") {
println("[soul-daemon] usage: forge soul daemon stop <slug|--all>")
return ""
}
if str_eq(target, "--all") {
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") { println("[soul-daemon] error: cannot read registry.json"); return "" }
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") { let i = i + 50 }
else {
let s: String = json_get_string(entry, "slug")
let label: String = soul_daemon_plist_label(s)
let out: String = str_trim(exec("launchctl stop " + label + " 2>&1"))
println("[soul-daemon] stop " + s + ": " + out)
let i = i + 1
}
}
return ""
}
let label: String = soul_daemon_plist_label(target)
let out: String = str_trim(exec("launchctl stop " + label + " 2>&1"))
println("[soul-daemon] stop " + target + ": " + out)
return out
}
// soul_daemon_status_main health check soul daemons: forge soul daemon status
fn soul_daemon_status_main() -> String {
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") {
println("[soul-daemon] error: could not read registry.json")
return ""
}
println("[soul-daemon] soul daemon status:")
println("")
let up: Int = 0
let down: Int = 0
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") {
let i = i + 50 // break
} else {
let slug: String = json_get_string(entry, "slug")
let sub: String = json_get_string(entry, "subject")
let engram_p: Int = json_get_int(entry, "engram_port")
let soul_p: Int = engram_p + 100
let soul_url: String = "http://localhost:" + int_to_str(soul_p)
let resp: String = http_get(soul_url + "/health")
if !str_eq(resp, "") {
println(" [UP ] " + sub + "" + soul_url)
let up = up + 1
} else {
// Try /status as fallback
let resp2: String = http_get(soul_url + "/status")
if !str_eq(resp2, "") {
println(" [UP ] " + sub + "" + soul_url)
let up = up + 1
} else {
println(" [DOWN] " + sub + "" + soul_url)
let down = down + 1
}
}
let i = i + 1
}
}
println("")
println("[soul-daemon] up=" + int_to_str(up) + " down=" + int_to_str(down))
return ""
}
// soul_daemon_main dispatch for: forge soul daemon <subcmd> [args]
fn soul_daemon_main() -> String {
let argv: [String] = args()
// args: [0]="soul" [1]="daemon" [2]=<subcmd>
let subcmd: String = ""
if len(argv) > 2 {
let subcmd = get(argv, 2)
}
if str_eq(subcmd, "install") {
soul_daemon_install_main()
} else {
if str_eq(subcmd, "start") {
soul_daemon_start_main()
} else {
if str_eq(subcmd, "stop") {
soul_daemon_stop_main()
} else {
if str_eq(subcmd, "status") {
soul_daemon_status_main()
} else {
println("[soul-daemon] usage: forge soul daemon <install|start|stop|status> [slug|--all]")
println("")
println(" forge soul daemon install <slug> — write plist and load soul daemon")
println(" forge soul daemon install --all — install all 26 soul daemons")
println(" forge soul daemon start <slug> — kickstart a soul daemon")
println(" forge soul daemon start --all — start all soul daemons")
println(" forge soul daemon stop <slug> — stop a soul daemon")
println(" forge soul daemon stop --all — stop all soul daemons")
println(" forge soul daemon status — health check all soul daemons")
}
}
}
}
return ""
}
// soul_main dispatch // soul_main dispatch
// //
// args() layout when invoked as: forge soul <subcmd> [slug] // args() layout when invoked as: forge soul <subcmd> [slug]
@@ -943,17 +1435,22 @@ fn soul_main() -> String {
if str_eq(subcmd, "sandbox") { if str_eq(subcmd, "sandbox") {
soul_sandbox_main() soul_sandbox_main()
} else { } else {
println("[soul] usage: forge soul <subcmd> [slug]") if str_eq(subcmd, "daemon") {
println("") soul_daemon_main()
println(" forge soul install <slug> — write launchd plist, load as resident") } else {
println(" forge soul install --all — install all souls from registry") println("[soul] usage: forge soul <subcmd> [slug]")
println(" forge soul reinstall <slug> — wipe DB and reinstall from seed") println("")
println(" forge soul reinstall --all — wipe and reinstall all souls") println(" forge soul install <slug> — write launchd plist, load as resident")
println(" forge soul start <slug> — kickstart a loaded soul") println(" forge soul install --all — install all souls from registry")
println(" forge soul stop <slug> — stop a running soul") println(" forge soul reinstall <slug> — wipe DB and reinstall from seed")
println(" forge soul status — health check all souls") println(" forge soul reinstall --all — wipe and reinstall all souls")
println(" forge soul wire — register all souls as Engram peers") println(" forge soul start <slug> — kickstart a loaded soul")
println(" forge soul sandbox <subcmd> — sandbox management") println(" forge soul stop <slug> — stop a running soul")
println(" forge soul status — health check all souls")
println(" forge soul wire — register all souls as Engram peers")
println(" forge soul sandbox <subcmd> — sandbox management")
println(" forge soul daemon <subcmd> — soul daemon (neuron binary) management")
}
} }
} }
} }