remove Python/bash scripts, add forge soul reinstall command

- Delete scripts/ (Python/bash superseded by native El forge commands)
- install.el: fix /api/nodes → /nodes, /api/edges → /edges (Engram has no /api prefix)
- install.el: add FORCE_INSTALL env var to bypass already-installed check
- install.el: remove all python3/launch_dharma.sh references
- soul.el: add soul_reinstall_one() and forge soul reinstall <slug|--all>
  Wipes engram DB, restarts launchd agent, waits for startup, runs install
This commit is contained in:
Will Anderson
2026-05-03 03:12:45 -05:00
parent cbeb9c02eb
commit 97f3a3ff88
7 changed files with 163 additions and 981 deletions
+14 -10
View File
@@ -10,8 +10,8 @@
// engram_url field (e.g. http://localhost:8806 for Feynman). It NEVER writes
// to the shared Neuron Engram at localhost:8742.
//
// The soul's Engram must already be running (launch_dharma.sh) before
// installing. For bulk reinstall use: python3 reinstall_imprints.py
// The soul's Engram must already be running as a launchd agent before
// installing. For reinstall: forge soul reinstall <slug>
//
// Depends on: schema.el (engram_key, FORGE_VERSION)
//
@@ -43,7 +43,7 @@ fn build_edge_body(from_id: String, to_id: String, relation: String, weight: Str
fn post_node(target_url: String, content: String, node_type: String, salience: String) -> String {
let key: String = engram_key()
let body: String = build_node_body(content, node_type, salience, key)
let url: String = target_url + "/api/nodes"
let url: String = target_url + "/nodes"
let response: String = http_post_json(url, body)
if str_eq(response, "") { return "" }
return json_get_string(response, "id")
@@ -54,7 +54,7 @@ fn post_node(target_url: String, content: String, node_type: String, salience: S
fn post_edge(target_url: String, from_id: String, to_id: String, relation: String, weight: String) -> String {
let key: String = engram_key()
let body: String = build_edge_body(from_id, to_id, relation, weight, key)
let url: String = target_url + "/api/edges"
let url: String = target_url + "/edges"
let response: String = http_post_json(url, body)
return response
}
@@ -199,9 +199,13 @@ fn install_main() -> String {
if str_eq(reg_subject, subject) {
let reg_root: String = json_get_string(reg_entry, "engram_root_id")
if !str_eq(reg_root, "") {
println("[forge] already installed — root: " + reg_root)
println("[forge] skip. to reinstall: python3 reinstall_imprints.py --slug <slug>")
return reg_root
let force: String = env("FORCE_INSTALL")
if str_eq(force, "") {
println("[forge] already installed — root: " + reg_root)
println("[forge] to reinstall: forge soul reinstall " + str_lower(str_replace(subject, " ", "-")))
return reg_root
}
println("[forge] force reinstall — ignoring existing root: " + reg_root)
}
let reg_url: String = json_get_string(reg_entry, "engram_url")
if !str_eq(reg_url, "") {
@@ -226,12 +230,12 @@ fn install_main() -> String {
// Safety guard: refuse to install to the shared Neuron Engram
if str_eq(target_url, "") {
println("[forge] error: no engram_url found for '" + subject + "' in registry.json")
println("[forge] ensure registry.json has an engram_url entry, or run reinstall_imprints.py")
println("[forge] ensure registry.json has an engram_url entry, or run forge soul reinstall &lt;slug&gt;")
return ""
}
if str_contains(target_url, ":8742") {
println("[forge] error: refusing to install soul into Neuron's Engram (port 8742)")
println("[forge] start the DHARMA network first: ./launch_dharma.sh")
println("[forge] start the DHARMA network first: ./forge soul start &lt;slug&gt;")
println("[forge] then retry. Each soul needs their own Engram instance.")
return ""
}
@@ -245,7 +249,7 @@ fn install_main() -> String {
if str_eq(root_id, "") {
println("[forge] error: failed to create root imprint node")
println("[forge] is the soul's Engram running at " + target_url + " ?")
println("[forge] start it with: ./launch_dharma.sh")
println("[forge] start it with: ./forge soul start &lt;slug&gt;")
return ""
}
+149 -19
View File
@@ -784,6 +784,130 @@ fn soul_sandbox_main() -> String {
return ""
}
// soul_reinstall_one wipe and reinstall a single soul
//
// 1. stop the launchd agent (launchctl stop)
// 2. delete the engram DB directory (rm -rf)
// 3. kickstart the launchd agent (launchctl kickstart)
// 4. wait up to 10s for the Engram to respond on /stats
// 5. run install_main() against this soul's engram_url + seed_file
//
// slug: e.g. "kal-el"
fn soul_reinstall_one(slug: String) -> String {
println("[soul] reinstalling: " + slug)
// Look up soul in registry
let reg_json: String = fs_read("registry.json")
if str_eq(reg_json, "") {
println("[soul] error: cannot read registry.json")
return ""
}
let entry: String = ""
let ri: Int = 0
while ri < 30 {
let e: String = json_get(reg_json, "imprints." + int_to_str(ri))
if str_eq(e, "") { let ri = ri + 30 }
else {
let s: String = json_get_string(e, "slug")
if str_eq(s, slug) { let entry = e; let ri = ri + 30 }
else { let ri = ri + 1 }
}
}
if str_eq(entry, "") {
println("[soul] error: slug not found in registry: " + slug)
return ""
}
let engram_url: String = json_get_string(entry, "engram_url")
let seed_file: String = json_get_string(entry, "seed_file")
let db_path: String = json_get_string(entry, "engram_db_path")
let label: String = "ai.neurontechnologies.soul." + slug
let uid: String = str_trim(exec("id -u"))
// Step 1: stop
println("[soul] stopping launchd agent...")
exec("launchctl stop " + label + " 2>/dev/null")
exec("sleep 1")
// Step 2: wipe DB
if !str_eq(db_path, "") {
println("[soul] wiping engram DB: " + db_path)
exec("rm -rf " + db_path)
}
// Step 3: kickstart
println("[soul] starting fresh engram...")
exec("launchctl kickstart gui/" + uid + "/" + label + " 2>/dev/null")
// Step 4: wait for Engram (poll /stats up to 10s)
let ready: Bool = false
let attempts: Int = 0
while !ready && attempts < 10 {
exec("sleep 1")
let stats: String = http_get(engram_url + "/stats")
if !str_eq(stats, "") && !str_starts_with(stats, "{\"error\"") {
let ready = true
}
let attempts = attempts + 1
}
if !ready {
println("[soul] warning: engram did not respond after 10s, proceeding anyway")
} else {
println("[soul] engram ready")
}
// Step 5: clear registry engram_root_id so install proceeds (not skipped)
// We write a temp registry update by patching the registry in place.
// Easiest: just set ENGRAM_URL env and call install directly via HTTP.
// The install.el skips if engram_root_id is set in registry so we must
// call the Engram directly to create nodes.
//
// For now: install by calling install_main() is not possible from soul.el
// since it's a separate compiled unit. Instead we call forge install via exec.
let api_key: String = "ntn-" + slug + "-2026"
let forge_cmd: String = "ENGRAM_URL=" + engram_url + " ENGRAM_API_KEY=" + api_key
+ " FORCE_INSTALL=1 ./dist/forge install " + seed_file + " 2>&1"
println("[soul] installing seed: " + seed_file)
let install_out: String = exec(forge_cmd)
println(install_out)
return "done"
}
// soul_reinstall_main dispatch `forge soul reinstall <slug|--all>`
fn soul_reinstall_main() -> String {
let argv: [String] = args()
let target: String = ""
if len(argv) > 2 { let target = get(argv, 2) }
if str_eq(target, "") {
println("[soul] usage: forge soul reinstall <slug>")
println(" forge soul reinstall --all")
return ""
}
if str_eq(target, "--all") {
println("[soul] reinstalling all souls...")
let reg_json: String = fs_read("registry.json")
if str_eq(reg_json, "") { println("[soul] error: cannot read registry.json"); return "" }
let i: Int = 0
while i < 30 {
let e: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(e, "") { let i = i + 30 }
else {
let s: String = json_get_string(e, "slug")
if !str_eq(s, "") { soul_reinstall_one(s) }
let i = i + 1
}
}
println("[soul] reinstall complete.")
return ""
}
soul_reinstall_one(target)
return ""
}
// soul_main dispatch
//
// args() layout when invoked as: forge soul <subcmd> [slug]
@@ -801,30 +925,36 @@ fn soul_main() -> String {
if str_eq(subcmd, "install") {
soul_install_main()
} else {
if str_eq(subcmd, "start") {
soul_start_main()
if str_eq(subcmd, "reinstall") {
soul_reinstall_main()
} else {
if str_eq(subcmd, "stop") {
soul_stop_main()
if str_eq(subcmd, "start") {
soul_start_main()
} else {
if str_eq(subcmd, "status") {
soul_status_main()
if str_eq(subcmd, "stop") {
soul_stop_main()
} else {
if str_eq(subcmd, "wire") {
soul_wire_main()
if str_eq(subcmd, "status") {
soul_status_main()
} else {
if str_eq(subcmd, "sandbox") {
soul_sandbox_main()
if str_eq(subcmd, "wire") {
soul_wire_main()
} else {
println("[soul] usage: forge soul <install|start|stop|status|wire|sandbox> [slug]")
println("")
println(" forge soul install <slug> — write launchd plist, load soul as resident")
println(" forge soul install --all — install all souls from registry")
println(" forge soul start <slug> — kickstart a loaded soul")
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 (create|list|join|close|status)")
if str_eq(subcmd, "sandbox") {
soul_sandbox_main()
} else {
println("[soul] usage: forge soul <subcmd> [slug]")
println("")
println(" forge soul install <slug> — write launchd plist, load as resident")
println(" forge soul install --all — install all souls from registry")
println(" forge soul reinstall <slug> — wipe DB and reinstall from seed")
println(" forge soul reinstall --all — wipe and reinstall all souls")
println(" forge soul start <slug> — kickstart a loaded soul")
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")
}
}
}
}