This repository has been archived on 2026-08-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
forge-retired/src/soul.el
T
Will Anderson d09f7ec409 rename kal-el → superman; fix registry duplicates, use ENGRAM_DATA_DIR
- Renamed soul slot 20 from Kal-El to Superman (new seed, new slug)
- Cleared stale duplicate entries that forge reinstall was appending
- Updated all 20 engram_root_ids to reflect fresh reinstall
- soul.el plist generator already fixed to emit ENGRAM_DATA_DIR
2026-05-03 03:25:06 -05:00

966 lines
37 KiB
EmacsLisp

// soul.el Soul Engram lifecycle management.
//
// Manages launchd-resident DHARMA soul Engrams on macOS.
//
// Commands:
// forge soul install <slug> write launchd plist, load soul as resident
// forge soul start <slug> launchctl kickstart the soul
// forge soul stop <slug> launchctl stop the soul
// forge soul status health check all souls
// forge soul wire register all soul Engrams as peers to each other
// forge soul sandbox create <name> <s1> <s2> create a named sandbox with participants
// forge soul sandbox list list all sandboxes
// forge soul sandbox join <id> <slug> add a soul to an existing sandbox
// forge soul sandbox close <id> close sandbox and write record
// forge soul sandbox status <id> show sandbox state
//
// Depends on: schema.el (FORGE_VERSION, engram_key, str_escape_json, log_event)
// Constants
// (FORGE_DIR is defined in schema.el)
let ENGRAM_BIN: String = "/Users/will/Development/neuron-technologies/foundation/engram/dist/engram"
let LAUNCHD_DIR: String = "/Users/will/Library/LaunchAgents"
let DHARMA_API_KEY: String = "ntn-dharma-2026"
// plist generation
// plist_label launchd label for a soul slug.
fn plist_label(slug: String) -> String {
"ai.neurontechnologies.soul." + slug
}
// plist_path full path to the launchd plist file for a soul.
fn plist_path(slug: String) -> String {
LAUNCHD_DIR + "/ai.neurontechnologies.soul." + slug + ".plist"
}
// write_soul_plist generate and write the launchd plist for a soul.
// Returns the path written, or "" on failure.
fn write_soul_plist(slug: String, port: String, db_path: String, subject: String) -> String {
let label: String = plist_label(slug)
let plist_file: String = plist_path(slug)
let log_file: String = FORGE_DIR + "/log/" + slug + ".log"
let soul_api_key: String = "ntn-" + slug + "-2026"
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>" + ENGRAM_BIN + "</string>\n" +
" </array>\n" +
" <key>EnvironmentVariables</key>\n" +
" <dict>\n" +
" <key>ENGRAM_DATA_DIR</key><string>" + db_path + "</string>\n" +
" <key>ENGRAM_BIND</key><string>0.0.0.0:" + port + "</string>\n" +
" <key>ENGRAM_API_KEY</key><string>" + soul_api_key + "</string>\n" +
" <key>ENGRAM_PEER_NAME</key><string>" + str_escape_json(subject) + "</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(plist_file, content)
if ok == 0 {
println("[soul] error: could not write plist to " + plist_file)
return ""
}
println("[soul] wrote plist: " + plist_file)
return plist_file
}
// launchctl helpers
// launchctl_load load (register + start) a plist via launchctl.
fn launchctl_load(plist_file: String) -> String {
let out: String = exec("launchctl load " + plist_file + " 2>&1")
return str_trim(out)
}
// launchctl_unload unload a plist via launchctl.
fn launchctl_unload(plist_file: String) -> String {
let out: String = exec("launchctl unload " + plist_file + " 2>&1")
return str_trim(out)
}
// launchctl_kickstart start a loaded soul via its label.
fn launchctl_kickstart(slug: String) -> String {
let label: String = plist_label(slug)
let out: String = exec("launchctl kickstart gui/$(id -u)/" + label + " 2>&1")
return str_trim(out)
}
// launchctl_stop stop a running soul (does not unload, KeepAlive will restart).
fn launchctl_stop(slug: String) -> String {
let label: String = plist_label(slug)
let out: String = exec("launchctl stop " + label + " 2>&1")
return str_trim(out)
}
// soul_is_up returns true if the soul's Engram responds to /stats.
fn soul_is_up(engram_url: String) -> Bool {
let resp: String = http_get(engram_url + "/stats")
if str_eq(resp, "") { return false }
return true
}
// Registry helpers
// count_souls returns number of imprints in registry.json.
fn count_souls(reg_json: String) -> Int {
let n: 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, "") {
return n
}
let n = n + 1
let i = i + 1
}
return n
}
// soul install
// soul_install_one install a single soul as a launchd agent.
// Creates the imprints dir, ensures the Engram runs (starts temp if needed),
// writes the plist and loads it.
fn soul_install_one(slug: String, port: String, engram_url: String, subject: String) -> String {
println("[soul] install: " + slug + " → port " + port)
// Ensure dirs exist
let db_path: String = FORGE_DIR + "/imprints/" + slug
let log_dir: String = FORGE_DIR + "/log"
if !fs_exists(db_path) { fs_mkdir(db_path) }
if !fs_exists(log_dir) { fs_mkdir(log_dir) }
if !fs_exists(LAUNCHD_DIR) { fs_mkdir(LAUNCHD_DIR) }
// Write plist
let pfile: String = write_soul_plist(slug, port, db_path, subject)
if str_eq(pfile, "") {
println("[soul] error: plist write failed for " + slug)
return ""
}
// Unload first in case it was already loaded (idempotent)
launchctl_unload(pfile)
// Load
let load_out: String = launchctl_load(pfile)
if !str_eq(load_out, "") {
println("[soul] launchctl load: " + load_out)
}
println("[soul] loaded: " + plist_label(slug))
log_event("soul_install", subject, "port=" + port + " plist=" + pfile)
return pfile
}
fn soul_install_main() -> String {
let argv: [String] = args()
// args() layout: [0]="soul" [1]="install" [2]=<slug>
let slug: String = ""
if len(argv) > 2 {
let slug = get(argv, 2)
}
if str_eq(slug, "") {
println("[soul] usage: forge soul install <slug>")
println("[soul] or: forge soul install --all")
return ""
}
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") {
println("[soul] error: could not read registry.json")
return ""
}
// --all: install every soul in the registry
if str_eq(slug, "--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 p: String = int_to_str(json_get_int(entry, "engram_port"))
let u: String = json_get_string(entry, "engram_url")
let sub: String = json_get_string(entry, "subject")
soul_install_one(s, p, u, sub)
let i = i + 1
}
}
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, slug) {
let p: String = int_to_str(json_get_int(entry, "engram_port"))
let u: String = json_get_string(entry, "engram_url")
let sub: String = json_get_string(entry, "subject")
soul_install_one(s, p, u, sub)
let found = 1
let i = i + 50 // break
} else {
let i = i + 1
}
}
}
if found == 0 {
println("[soul] error: slug '" + slug + "' not found in registry.json")
}
return ""
}
// soul start / stop
fn soul_start_main() -> String {
let argv: [String] = args()
// args() layout: [0]="soul" [1]="start" [2]=<slug>
let slug: String = ""
if len(argv) > 2 {
let slug = get(argv, 2)
}
if str_eq(slug, "") {
println("[soul] usage: forge soul start <slug>")
return ""
}
let out: String = launchctl_kickstart(slug)
println("[soul] start " + slug + ": " + out)
return out
}
fn soul_stop_main() -> String {
let argv: [String] = args()
// args() layout: [0]="soul" [1]="stop" [2]=<slug>
let slug: String = ""
if len(argv) > 2 {
let slug = get(argv, 2)
}
if str_eq(slug, "") {
println("[soul] usage: forge soul stop <slug>")
return ""
}
let out: String = launchctl_stop(slug)
println("[soul] stop " + slug + ": " + out)
return out
}
// soul status
fn soul_status_main() -> String {
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") {
println("[soul] error: could not read registry.json")
return ""
}
println("[soul] DHARMA soul 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 url: String = json_get_string(entry, "engram_url")
let sub: String = json_get_string(entry, "subject")
let port: String = int_to_str(json_get_int(entry, "engram_port"))
if soul_is_up(url) {
println(" [UP ] " + sub + "" + url)
let up = up + 1
} else {
println(" [DOWN] " + sub + "" + url)
let down = down + 1
}
let i = i + 1
}
}
println("")
println("[soul] up=" + int_to_str(up) + " down=" + int_to_str(down))
return ""
}
// soul wire
//
// Registers every soul as a peer in every other soul's Engram.
// POST /sync/peers with a Peer JSON object.
//
// Peer format (from engram-sync/src/types.rs):
// { "id": <uuid>, "name": <string>, "address": <url>, "api_key": <string>,
// "sync_tiers": ["Semantic"], "last_sync_at": 0, "trusted": true }
fn make_peer_json(peer_id: String, name: String, address: String, api_key: String) -> String {
"{\"id\":\"" + peer_id + "\",\"name\":\"" + str_escape_json(name) +
"\",\"address\":\"" + address +
"\",\"api_key\":\"" + api_key +
"\",\"sync_tiers\":[\"Semantic\"],\"last_sync_at\":0,\"trusted\":true}"
}
fn soul_wire_main() -> String {
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(reg_json, "") {
println("[soul] error: could not read registry.json")
return ""
}
println("[soul] wiring peers — registering all souls as peers to each other...")
println("")
// Collect all soul entries (up to 50)
// For each soul A, register all other souls B as peers of A
let registered: Int = 0
let failed: Int = 0
let i: Int = 0
while i < 50 {
let entry_a: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry_a, "") {
let i = i + 50 // break
} else {
let slug_a: String = json_get_string(entry_a, "slug")
let url_a: String = json_get_string(entry_a, "engram_url")
let key_a: String = "ntn-" + slug_a + "-2026"
// Register all other souls as peers of soul A
let j: Int = 0
while j < 50 {
let entry_b: String = json_get(reg_json, "imprints." + int_to_str(j))
if str_eq(entry_b, "") {
let j = j + 50 // break
} else {
let slug_b: String = json_get_string(entry_b, "slug")
if !str_eq(slug_a, slug_b) {
let url_b: String = json_get_string(entry_b, "engram_url")
let sub_b: String = json_get_string(entry_b, "subject")
let key_b: String = "ntn-" + slug_b + "-2026"
// Generate a deterministic peer ID from slug_b
let peer_id: String = uuid_v4()
let peer_json: String = make_peer_json(peer_id, sub_b, url_b, key_b)
let headers: String = "{\"Authorization\":\"Bearer " + key_a + "\",\"Content-Type\":\"application/json\"}"
let headers_map: String = headers // pass as json string for http_post_with_headers
// Build a Map for headers
let hdrs = el_map_new(2, "Authorization", "Bearer " + key_a, "Content-Type", "application/json")
let resp: String = http_post_with_headers(url_a + "/sync/peers", peer_json, hdrs)
if str_eq(resp, "") {
let failed = failed + 1
} else {
let registered = registered + 1
}
}
let j = j + 1
}
}
let i = i + 1
}
}
println("[soul] wire complete: registered=" + int_to_str(registered) + " failed=" + int_to_str(failed))
return ""
}
// Sandbox helpers
//
// Sandboxes are bounded collaboration spaces for a subset of DHARMA souls.
// Each sandbox is persisted as FORGE_DIR/sandboxes/<id>.json.
//
// JSON structure:
// { "id": "sb-<uuid>", "name": "...", "created_at": <ts>,
// "status": "active"|"closed", "participants": [...],
// "topic": "...", "working_memory": [], "record": [] }
let FORGE_SANDBOXES_DIR: String = FORGE_DIR + "/sandboxes"
// sandbox_path full path to a sandbox JSON file.
fn sandbox_path(id: String) -> String {
FORGE_SANDBOXES_DIR + "/" + id + ".json"
}
// sandbox_ensure_dir create sandboxes dir if absent.
fn sandbox_ensure_dir() -> Void {
if !fs_exists(FORGE_SANDBOXES_DIR) { fs_mkdir(FORGE_SANDBOXES_DIR) }
}
// sandbox_new_json build a fresh sandbox JSON string.
fn sandbox_new_json(id: String, name: String, topic: String, participants_json: String) -> String {
let ts: Int = unix_timestamp()
"{\"id\":\"" + id + "\",\"name\":\"" + str_escape_json(name) +
"\",\"created_at\":" + int_to_str(ts) +
",\"status\":\"active\"" +
",\"participants\":" + participants_json +
",\"topic\":\"" + str_escape_json(topic) + "\"" +
",\"working_memory\":[]" +
",\"record\":[]}"
}
// sandbox_read read and return a sandbox JSON, or "" if not found.
fn sandbox_read(id: String) -> String {
let path: String = sandbox_path(id)
if !fs_exists(path) { return "" }
fs_read(path)
}
// sandbox_write persist a sandbox JSON.
fn sandbox_write(id: String, json: String) -> Int {
sandbox_ensure_dir()
fs_write(sandbox_path(id), json)
}
// sandbox_build_participants_json build a JSON array string from a list of slugs.
// Reads up to 20 slugs from args starting at position `start`.
fn sandbox_build_participants_json(argv: [String], start: Int) -> String {
let arr: String = "["
let first: Int = 1
let i: Int = start
while i < len(argv) {
let slug: String = get(argv, i)
if !str_eq(slug, "") {
if first == 0 {
let arr = arr + ","
}
let arr = arr + "\"" + str_escape_json(slug) + "\""
let first = 0
}
let i = i + 1
}
arr + "]"
}
// sandbox_participants_count count participants in a sandbox JSON.
// NOTE: participants is a string array must use json_get(), not json_get_string().
fn sandbox_participants_count(sandbox_json: String) -> Int {
let n: Int = 0
let i: Int = 0
while i < 50 {
let p: String = json_get(sandbox_json, "participants." + int_to_str(i))
if str_eq(p, "") {
return n
}
let n = n + 1
let i = i + 1
}
return n
}
// sandbox_list_ids return a newline-separated list of sandbox IDs by scanning sandboxes dir.
// We use exec + ls because El has no readdir builtin.
fn sandbox_list_ids() -> String {
sandbox_ensure_dir()
let out: String = exec("ls " + FORGE_SANDBOXES_DIR + " 2>/dev/null")
return str_trim(out)
}
// forge soul sandbox create
fn soul_sandbox_create_main() -> String {
// args layout: [0]="soul" [1]="sandbox" [2]="create" [3]=<name> [4..]=<slug>...
let argv: [String] = args()
let name: String = ""
if len(argv) > 3 {
let name = get(argv, 3)
}
if str_eq(name, "") {
println("[sandbox] usage: forge soul sandbox create <name> [slug1 slug2 ...]")
return ""
}
let participants_json: String = sandbox_build_participants_json(argv, 4)
// Derive topic from name (placeholder; can be overridden later via join/edit)
let topic: String = name
let id: String = "sb-" + uuid_v4()
let json: String = sandbox_new_json(id, name, topic, participants_json)
sandbox_ensure_dir()
let ok: Int = sandbox_write(id, json)
if ok == 0 {
println("[sandbox] error: could not write sandbox file")
return ""
}
println("[sandbox] created: " + id)
println("[sandbox] name: " + name)
println("[sandbox] file: " + sandbox_path(id))
log_event("sandbox_create", name, "id=" + id + " participants=" + participants_json)
return id
}
// forge soul sandbox list
fn soul_sandbox_list_main() -> String {
sandbox_ensure_dir()
let listing: String = sandbox_list_ids()
if str_eq(listing, "") {
println("[sandbox] no sandboxes found")
return ""
}
println("[sandbox] active sandboxes:")
println("")
// Each line is a filename like "sb-<uuid>.json"
// We split by newline by iterating: exec ls outputs one file per line
// We use a simple approach: re-read each file by constructing the path
let files_out: String = exec("ls " + FORGE_SANDBOXES_DIR + "/*.json 2>/dev/null")
let files: String = str_trim(files_out)
if str_eq(files, "") {
println("[sandbox] no sandboxes found")
return ""
}
// Parse line-by-line via exec + while loop using index
// El has no split(), so we iterate using exec to list files individually
let count: Int = 0
let i: Int = 0
// We use a trick: exec "ls -1" and parse each file
// Since El has no string split, we re-use the file listing via a numbered approach
let num_files_str: String = str_trim(exec("ls " + FORGE_SANDBOXES_DIR + "/*.json 2>/dev/null | wc -l"))
let num_files: Int = str_to_int(num_files_str)
while i < num_files {
let file_path_raw: String = str_trim(exec("ls " + FORGE_SANDBOXES_DIR + "/*.json 2>/dev/null | sed -n '" + int_to_str(i + 1) + "p'"))
if !str_eq(file_path_raw, "") {
let sb_json: String = fs_read(file_path_raw)
if !str_eq(sb_json, "") {
let sb_id: String = json_get_string(sb_json, "id")
let sb_name: String = json_get_string(sb_json, "name")
let sb_status: String = json_get_string(sb_json, "status")
let sb_ts: Int = json_get_int(sb_json, "created_at")
let n_parts: Int = sandbox_participants_count(sb_json)
println(" [" + sb_status + "] " + sb_id + " " + sb_name + " (" + int_to_str(n_parts) + " participants) created=" + int_to_str(sb_ts))
let count = count + 1
}
}
let i = i + 1
}
if count == 0 {
println("[sandbox] no sandboxes found")
}
return ""
}
// forge soul sandbox join
fn soul_sandbox_join_main() -> String {
// args: [0]="soul" [1]="sandbox" [2]="join" [3]=<id> [4]=<slug>
let argv: [String] = args()
let id: String = ""
let slug: String = ""
if len(argv) > 3 { let id = get(argv, 3) }
if len(argv) > 4 { let slug = get(argv, 4) }
if str_eq(id, "") || str_eq(slug, "") {
println("[sandbox] usage: forge soul sandbox join <sandbox-id> <slug>")
return ""
}
let sb_json: String = sandbox_read(id)
if str_eq(sb_json, "") {
println("[sandbox] error: sandbox not found: " + id)
return ""
}
let status: String = json_get_string(sb_json, "status")
if str_eq(status, "closed") {
println("[sandbox] error: sandbox is closed: " + id)
return ""
}
// Check if slug already present
let already: Int = 0
let i: Int = 0
while i < 50 {
let p: String = json_get(sb_json, "participants." + int_to_str(i))
if str_eq(p, "") {
let i = i + 50 // break
} else {
if str_eq(p, slug) {
let already = 1
let i = i + 50 // break
} else {
let i = i + 1
}
}
}
if already == 1 {
println("[sandbox] " + slug + " is already a participant in " + id)
return ""
}
// Build new participants array by appending
let n: Int = sandbox_participants_count(sb_json)
let new_parts: String = "["
let j: Int = 0
while j < n {
let p: String = json_get(sb_json, "participants." + int_to_str(j))
if j > 0 { let new_parts = new_parts + "," }
let new_parts = new_parts + "\"" + str_escape_json(p) + "\""
let j = j + 1
}
if n > 0 { let new_parts = new_parts + "," }
let new_parts = new_parts + "\"" + str_escape_json(slug) + "\""
let new_parts = new_parts + "]"
// Reconstruct sandbox JSON with updated participants
let sb_id: String = json_get_string(sb_json, "id")
let sb_name: String = json_get_string(sb_json, "name")
let sb_ts: Int = json_get_int(sb_json, "created_at")
let sb_topic: String = json_get_string(sb_json, "topic")
let updated: String = "{\"id\":\"" + str_escape_json(sb_id) +
"\",\"name\":\"" + str_escape_json(sb_name) +
"\",\"created_at\":" + int_to_str(sb_ts) +
",\"status\":\"active\"" +
",\"participants\":" + new_parts +
",\"topic\":\"" + str_escape_json(sb_topic) + "\"" +
",\"working_memory\":[]" +
",\"record\":[]}"
sandbox_write(id, updated)
println("[sandbox] " + slug + " joined sandbox " + id)
log_event("sandbox_join", sb_name, "id=" + id + " slug=" + slug)
return ""
}
// forge soul sandbox close
fn soul_sandbox_close_main() -> String {
// args: [0]="soul" [1]="sandbox" [2]="close" [3]=<id>
let argv: [String] = args()
let id: String = ""
if len(argv) > 3 { let id = get(argv, 3) }
if str_eq(id, "") {
println("[sandbox] usage: forge soul sandbox close <sandbox-id>")
return ""
}
let sb_json: String = sandbox_read(id)
if str_eq(sb_json, "") {
println("[sandbox] error: sandbox not found: " + id)
return ""
}
let status: String = json_get_string(sb_json, "status")
if str_eq(status, "closed") {
println("[sandbox] sandbox already closed: " + id)
return ""
}
let sb_id: String = json_get_string(sb_json, "id")
let sb_name: String = json_get_string(sb_json, "name")
let sb_ts: Int = json_get_int(sb_json, "created_at")
let sb_topic: String = json_get_string(sb_json, "topic")
let close_ts: Int = unix_timestamp()
// Rebuild participants array
let n: Int = sandbox_participants_count(sb_json)
let parts_json: String = "["
let j: Int = 0
while j < n {
let p: String = json_get(sb_json, "participants." + int_to_str(j))
if j > 0 { let parts_json = parts_json + "," }
let parts_json = parts_json + "\"" + str_escape_json(p) + "\""
let j = j + 1
}
let parts_json = parts_json + "]"
// Write closed record with closed_at timestamp
let closed: String = "{\"id\":\"" + str_escape_json(sb_id) +
"\",\"name\":\"" + str_escape_json(sb_name) +
"\",\"created_at\":" + int_to_str(sb_ts) +
",\"closed_at\":" + int_to_str(close_ts) +
",\"status\":\"closed\"" +
",\"participants\":" + parts_json +
",\"topic\":\"" + str_escape_json(sb_topic) + "\"" +
",\"working_memory\":[]" +
",\"record\":[{\"ts\":" + int_to_str(close_ts) + ",\"event\":\"sandbox_closed\",\"by\":\"forge\"}]}"
sandbox_write(id, closed)
println("[sandbox] closed: " + id + " (" + sb_name + ")")
println("[sandbox] record: " + sandbox_path(id))
log_event("sandbox_close", sb_name, "id=" + id + " closed_at=" + int_to_str(close_ts))
return ""
}
// forge soul sandbox status
fn soul_sandbox_status_main() -> String {
// args: [0]="soul" [1]="sandbox" [2]="status" [3]=<id>
let argv: [String] = args()
let id: String = ""
if len(argv) > 3 { let id = get(argv, 3) }
if str_eq(id, "") {
println("[sandbox] usage: forge soul sandbox status <sandbox-id>")
return ""
}
let sb_json: String = sandbox_read(id)
if str_eq(sb_json, "") {
println("[sandbox] error: sandbox not found: " + id)
return ""
}
let sb_id: String = json_get_string(sb_json, "id")
let sb_name: String = json_get_string(sb_json, "name")
let sb_status: String = json_get_string(sb_json, "status")
let sb_ts: Int = json_get_int(sb_json, "created_at")
let sb_topic: String = json_get_string(sb_json, "topic")
let n: Int = sandbox_participants_count(sb_json)
println("[sandbox] " + sb_id)
println(" name: " + sb_name)
println(" status: " + sb_status)
println(" topic: " + sb_topic)
println(" created: " + int_to_str(sb_ts))
println(" participants (" + int_to_str(n) + "):")
let k: Int = 0
while k < n {
let p: String = json_get(sb_json, "participants." + int_to_str(k))
println(" - " + p)
let k = k + 1
}
return ""
}
// forge soul sandbox dispatch
fn soul_sandbox_main() -> String {
// args: [0]="soul" [1]="sandbox" [2]=<subcmd> ...
let argv: [String] = args()
let subcmd: String = ""
if len(argv) > 2 {
let subcmd = get(argv, 2)
}
if str_eq(subcmd, "create") {
soul_sandbox_create_main()
} else {
if str_eq(subcmd, "list") {
soul_sandbox_list_main()
} else {
if str_eq(subcmd, "join") {
soul_sandbox_join_main()
} else {
if str_eq(subcmd, "close") {
soul_sandbox_close_main()
} else {
if str_eq(subcmd, "status") {
soul_sandbox_status_main()
} else {
println("[sandbox] usage: forge soul sandbox <create|list|join|close|status> [args]")
println("")
println(" forge soul sandbox create <name> [slug1 slug2 ...] — create sandbox")
println(" forge soul sandbox list — list all sandboxes")
println(" forge soul sandbox join <id> <slug> — add soul to sandbox")
println(" forge soul sandbox close <id> — close and record sandbox")
println(" forge soul sandbox status <id> — show sandbox state")
}
}
}
}
}
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]
// args()[0] = "soul"
// args()[1] = <subcmd> e.g. "install"
// args()[2] = [slug] e.g. "bobby-anderson"
fn soul_main() -> String {
let argv: [String] = args()
let subcmd: String = ""
if len(argv) > 1 {
let subcmd = get(argv, 1)
}
if str_eq(subcmd, "install") {
soul_install_main()
} else {
if str_eq(subcmd, "reinstall") {
soul_reinstall_main()
} else {
if str_eq(subcmd, "start") {
soul_start_main()
} else {
if str_eq(subcmd, "stop") {
soul_stop_main()
} else {
if str_eq(subcmd, "status") {
soul_status_main()
} else {
if str_eq(subcmd, "wire") {
soul_wire_main()
} else {
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")
}
}
}
}
}
}
}
return ""
}