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
-100
View File
@@ -1,100 +0,0 @@
#!/usr/bin/env python3
"""
Install all 19 soul seeds into their own dedicated Engram instances.
Runs install_soul.py logic sequentially to avoid port conflicts.
Updates registry.json with engram_db_path, engram_port, engram_url,
engram_api_key, and engram_root_id for each soul.
Usage:
python3 install_all.py # skip souls whose data dir exists with root_id
python3 install_all.py --force # reinstall all (destructive)
python3 install_all.py --only richard-feynman # single soul
"""
import argparse
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from install_soul import install_soul
SOULS = [
"bobby-anderson",
"alan-turing",
"albert-einstein",
"nikola-tesla",
"leonardo-da-vinci",
"richard-feynman",
"carl-sagan",
"rene-descartes",
"robin-williams",
"frederick-douglass",
"marcus-aurelius",
"friedrich-nietzsche",
"james-baldwin",
"ada-lovelace",
"harriet-tubman",
"virginia-woolf",
"hedy-lamarr",
"marie-curie",
"helen-keller",
]
def main():
parser = argparse.ArgumentParser(
description="Install all 19 soul seeds into dedicated Engram instances"
)
parser.add_argument(
"--force",
action="store_true",
help="Reinstall all souls even if already installed",
)
parser.add_argument(
"--only",
metavar="SLUG",
help="Install only this slug",
)
args = parser.parse_args()
souls_to_install = [args.only] if args.only else SOULS
results = []
for slug in souls_to_install:
print(f"\n{'=' * 60}")
print(f"Soul: {slug}")
print("=" * 60)
try:
result = install_soul(slug, force=args.force)
results.append({"slug": slug, "success": True, **result})
except Exception as exc:
import traceback
traceback.print_exc()
results.append({"slug": slug, "success": False, "error": str(exc)})
print(f"\n{'=' * 60}")
print("SUMMARY")
print("=" * 60)
ok = [r for r in results if r["success"] and not r.get("skipped")]
skipped = [r for r in results if r.get("skipped")]
failed = [r for r in results if not r["success"]]
for r in ok:
print(f" [OK] {r['slug']} root={r.get('root_id', '?')}")
for r in skipped:
print(f" [SKIP] {r['slug']} (already installed)")
for r in failed:
print(f" [FAILED] {r['slug']} error={r.get('error', '?')}")
print(f"\nInstalled: {len(ok)} Skipped: {len(skipped)} Failed: {len(failed)}")
if failed:
sys.exit(1)
if __name__ == "__main__":
main()
-425
View File
@@ -1,425 +0,0 @@
#!/usr/bin/env python3
"""
Install a single soul's seed into their own dedicated Engram instance.
Uses the native Engram binary HTTP API:
POST /api/nodes {"content": "...", "node_type": "...", "salience": 0.8, "_auth": "<key>"}
POST /api/edges {"from_id": "...", "to_id": "...", "relation": "...", "weight": 0.8, "_auth": "<key>"}
GET /stats health check ({"node_count": N, "edge_count": M, "layer_count": K})
Auth: _auth field in the POST body.
Per-soul keys: ntn-<slug>-2026 (matching the running DHARMA infrastructure).
Usage:
python3 install_soul.py <slug>
python3 install_soul.py richard-feynman
python3 install_soul.py richard-feynman --force # reinstall even if data exists
Steps:
1. Checks if soul's Engram is already running (port in use) — installs into it.
If not running, starts the Engram binary, installs, then stops it.
2. Creates forge/imprints/<slug>/ data directory
3. Polls GET /stats until the instance is ready
4. Reads the soul's seed JSON
5. POSTs all nodes and edges using the soul's API key
6. Captures and returns the root node ID
7. If we started it, stops the instance (data persists)
"""
import json
import os
import socket
import subprocess
import sys
import time
from pathlib import Path
import requests
# ── Config ──────────────────────────────────────────────────────────────────
FORGE_DIR = Path("/Users/will/Development/neuron-technologies/forge")
ENGRAM_BIN = Path(
"/Users/will/Development/neuron-technologies/foundation/engram/dist/engram"
)
REGISTRY_FILE = FORGE_DIR / "registry.json"
STARTUP_TIMEOUT = 30
STARTUP_POLL_INTERVAL = 0.3
def load_registry() -> dict:
return json.loads(REGISTRY_FILE.read_text())
def save_registry(registry: dict) -> None:
REGISTRY_FILE.write_text(json.dumps(registry, indent=2))
def soul_api_key(soul: dict) -> str:
"""
Return the API key for a soul's Engram instance.
Per-soul keys: ntn-<slug>-2026 (matching the running DHARMA infrastructure).
If registry has engram_api_key set, that takes precedence.
"""
if soul.get("engram_api_key"):
return soul["engram_api_key"]
return f"ntn-{soul['slug']}-2026"
def find_soul(registry: dict, slug: str) -> dict | None:
for imp in registry["imprints"]:
if imp["slug"] == slug:
return imp
return None
def find_seed_file(registry_entry: dict) -> Path:
"""Resolve the seed file path from the registry entry."""
slug = registry_entry["slug"]
# Try registry-specified path first
seed_rel = registry_entry.get("seed_file", "")
if seed_rel:
candidate = FORGE_DIR / seed_rel
if candidate.exists():
return candidate
# Fallback: search known locations
candidates = [
FORGE_DIR / "seeds" / f"{slug}-seed.json",
FORGE_DIR / f"{slug}-seed.json",
# Legacy names used before seed file reorganization
FORGE_DIR / "seeds" / f"{slug.split('-')[0]}-seed.json", # e.g. alan from alan-turing
]
for c in candidates:
if c.exists():
return c
raise FileNotFoundError(
f"Cannot find seed file for {slug!r}. "
f"Tried: {[str(c) for c in candidates]}"
)
def is_port_in_use(port: int) -> bool:
"""Return True if a process is already listening on the port."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(("127.0.0.1", port)) == 0
def start_engram(slug: str, port: int, db_path: Path, api_key: str) -> subprocess.Popen:
"""Start an Engram instance for the soul and return the process handle."""
db_path.mkdir(parents=True, exist_ok=True)
log_dir = FORGE_DIR / "log"
log_dir.mkdir(exist_ok=True)
log_file = log_dir / f"dharma-{slug}.log"
env = os.environ.copy()
# Native binary uses ENGRAM_DATA_DIR and ENGRAM_DB_PATH (both accepted)
env["ENGRAM_DATA_DIR"] = str(db_path)
env["ENGRAM_DB_PATH"] = str(db_path)
env["ENGRAM_BIND"] = f"0.0.0.0:{port}"
env["ENGRAM_API_KEY"] = api_key
with open(log_file, "a") as lf:
proc = subprocess.Popen(
[str(ENGRAM_BIN)],
env=env,
stdout=lf,
stderr=lf,
)
return proc
def wait_for_ready(port: int, timeout: float = STARTUP_TIMEOUT) -> bool:
"""Poll /stats until the instance responds or timeout expires."""
url = f"http://localhost:{port}/stats"
deadline = time.time() + timeout
while time.time() < deadline:
try:
resp = requests.get(url, timeout=2)
if resp.status_code == 200:
return True
except requests.exceptions.ConnectionError:
pass
time.sleep(STARTUP_POLL_INTERVAL)
return False
def sanitize_content(s: str) -> str:
"""
Sanitize text content for the native Engram binary's JSON parser.
The native binary's JSON response serializer does not escape double-quotes
in node content, which causes the response JSON to be malformed. Replace
double-quotes and other problematic characters with safe ASCII equivalents.
"""
replacements = [
('"', "'"), # double-quote → single (CRITICAL: prevents JSON response corruption)
("", "--"), # em dash
("", "-"), # en dash
("", "'"), ("", "'"), # curly single quotes
("", "'"), ("", "'"), # curly double quotes
("", "..."), # ellipsis
("é", "e"), ("è", "e"), ("ê", "e"), ("ë", "e"),
("à", "a"), ("â", "a"), ("á", "a"),
("ü", "u"), ("û", "u"), ("ú", "u"),
("ö", "o"), ("ô", "o"), ("ó", "o"),
("ä", "a"), ("ß", "ss"),
("î", "i"), ("í", "i"),
("É", "E"), ("Ê", "E"), ("È", "E"),
("Â", "A"), ("Î", "I"), ("Ô", "O"), ("Û", "U"),
("ñ", "n"), ("Ñ", "N"),
("ç", "c"), ("Ç", "C"),
]
for char, replacement in replacements:
s = s.replace(char, replacement)
# Replace any remaining non-ASCII with '?'
return s.encode("ascii", errors="replace").decode("ascii")
def post_node(port: int, content: str, node_type: str, salience: float, api_key: str) -> str:
"""POST a node via /api/nodes. Returns the node UUID."""
url = f"http://localhost:{port}/api/nodes"
safe_content = sanitize_content(content)
body = {
"content": safe_content,
"node_type": node_type,
"salience": salience,
"_auth": api_key,
}
resp = requests.post(url, json=body, timeout=30)
resp.raise_for_status()
result = resp.json()
if "id" not in result:
raise ValueError(f"Unexpected response from /api/nodes: {result}")
return result["id"]
def post_edge(port: int, from_id: str, to_id: str, relation: str, weight: float, api_key: str) -> None:
"""POST an edge via /api/edges."""
url = f"http://localhost:{port}/api/edges"
body = {
"from_id": from_id,
"to_id": to_id,
"relation": relation,
"weight": weight,
"_auth": api_key,
}
resp = requests.post(url, json=body, timeout=30)
resp.raise_for_status()
def install_seed(port: int, seed: dict, api_key: str) -> str:
"""
Install all nodes and edges from a seed dict.
Returns the root node UUID.
"""
subject = seed["subject"]
print(f" Installing nodes for {subject}...")
# Root identity node
root_id = post_node(
port,
content=f"IMPRINT: {subject} | dharma/1.0",
node_type="Identity",
salience=1.0,
api_key=api_key,
)
print(f" Root node: {root_id}")
# Values
for v in seed.get("values", []):
content = f"VALUE: {v['value']}"
if v.get("grounding"):
content += f" | grounding: {v['grounding']}"
nid = post_node(port, content, "Identity", float(v.get("weight", 0.8)), api_key)
post_edge(port, root_id, nid, "has_value", float(v.get("weight", 0.8)), api_key)
# Biography
for b in seed.get("biography", []):
content = f"BIOGRAPHY: {b['event']}"
nid = post_node(port, content, "Identity", float(b.get("weight", 0.7)), api_key)
post_edge(port, root_id, nid, "formed_by", float(b.get("weight", 0.7)), api_key)
# Relationships
for r in seed.get("relationships", []):
content = f"RELATIONSHIP: {r['name']}"
if r.get("role"):
content += f" ({r['role']})"
nid = post_node(port, content, "Identity", float(r.get("weight", 0.6)), api_key)
post_edge(port, root_id, nid, "relates_to", float(r.get("weight", 0.6)), api_key)
# Reasoning patterns
for pattern in seed.get("reasoning_patterns", []):
content = f"REASONING: {pattern}"
nid = post_node(port, content, "Identity", 0.7, api_key)
post_edge(port, root_id, nid, "reasons_with", 0.7, api_key)
# Voice profile — one consolidated node
voice = seed.get("voice_profile", {})
if voice:
voice_parts = []
for k, v in voice.items():
if v:
voice_parts.append(f"{k}: {v}")
if voice_parts:
voice_content = "VOICE: " + " | ".join(voice_parts)
nid = post_node(port, voice_content[:2000], "Identity", 0.9, api_key)
post_edge(port, root_id, nid, "speaks_as", 0.9, api_key)
# Stats after install
stats_resp = requests.get(f"http://localhost:{port}/stats", timeout=10)
stats = stats_resp.json()
print(
f" Engram stats after install: "
f"{stats.get('node_count', '?')} nodes, "
f"{stats.get('edge_count', '?')} edges"
)
# Persist to disk
save_url = f"http://localhost:{port}/api/save"
try:
save_resp = requests.post(save_url, json={"_auth": api_key}, timeout=10)
save_result = save_resp.json()
print(f" Saved to: {save_result.get('path', '?')}")
except Exception as exc:
print(f" WARN: save failed: {exc}")
return root_id
def install_soul(slug: str, force: bool = False) -> dict:
"""
Full install pipeline for one soul.
If the soul's Engram is already running (port in use), installs directly
into it. Otherwise starts a temporary instance, installs, and stops it.
Returns dict with: slug, root_id, engram_db_path, engram_port, engram_url, engram_api_key
"""
if not ENGRAM_BIN.exists():
raise FileNotFoundError(
f"Engram binary not found at {ENGRAM_BIN}."
)
registry = load_registry()
soul = find_soul(registry, slug)
if soul is None:
raise ValueError(f"Soul {slug!r} not found in registry.json")
port = soul["engram_port"]
db_path = FORGE_DIR / soul.get("engram_db_path", f"imprints/{slug}")
api_key = soul_api_key(soul)
# Skip if already installed (data dir non-empty AND registry has root_id),
# unless --force is given.
already_has_data = db_path.exists() and any(db_path.iterdir())
already_has_root = bool(soul.get("engram_root_id"))
if not force and already_has_data and already_has_root:
print(f"[{slug}] Already installed (root={soul['engram_root_id']}) — skipping.")
print(f"[{slug}] Use --force to reinstall.")
return {
"slug": slug,
"root_id": soul.get("engram_root_id"),
"skipped": True,
}
seed_file = find_seed_file(soul)
seed = json.loads(seed_file.read_text())
print(
f"[{slug}] Seed: {seed_file.name} "
f"({len(seed.get('values', []))} values, "
f"{len(seed.get('biography', []))} bio, "
f"{len(seed.get('reasoning_patterns', []))} patterns, "
f"{len(seed.get('relationships', []))} relationships)"
)
print(f"[{slug}] API key: {api_key}")
already_running = is_port_in_use(port)
proc = None
if already_running:
print(f"[{slug}] Engram already running on port {port} — installing into live instance.")
if not wait_for_ready(port, timeout=5):
raise RuntimeError(
f"Port {port} is in use but Engram is not responding at /stats"
)
else:
print(f"[{slug}] Starting Engram on port {port}...")
proc = start_engram(slug, port, db_path, api_key)
try:
if proc is not None:
if not wait_for_ready(port):
proc.terminate()
raise RuntimeError(
f"Engram for {slug} did not become ready within {STARTUP_TIMEOUT}s"
)
print(f"[{slug}] Engram ready on port {port}")
root_id = install_seed(port, seed, api_key)
print(f"[{slug}] Install complete. Root node: {root_id}")
finally:
if proc is not None:
proc.terminate()
try:
proc.wait(timeout=5)
except subprocess.TimeoutExpired:
proc.kill()
print(f"[{slug}] Instance stopped.")
# Update registry entry
from datetime import date
for imp in registry["imprints"]:
if imp["slug"] == slug:
imp["engram_db_path"] = str(db_path.relative_to(FORGE_DIR))
imp["engram_port"] = port
imp["engram_url"] = f"http://localhost:{port}"
imp["engram_api_key"] = api_key
imp["engram_root_id"] = root_id
imp["installed"] = True
imp["installed_at"] = str(date.today())
break
save_registry(registry)
print(f"[{slug}] Registry updated.")
return {
"slug": slug,
"root_id": root_id,
"engram_db_path": str(db_path.relative_to(FORGE_DIR)),
"engram_port": port,
"engram_url": f"http://localhost:{port}",
"engram_api_key": api_key,
"skipped": False,
}
def main():
import argparse
parser = argparse.ArgumentParser(
description="Install a soul's seed into its Engram instance"
)
parser.add_argument("slug", help="Soul slug (e.g. richard-feynman)")
parser.add_argument(
"--force",
action="store_true",
help="Reinstall even if imprint directory already exists",
)
args = parser.parse_args()
result = install_soul(args.slug, force=args.force)
if result.get("skipped"):
print(f"\nSkipped (already installed). Root: {result.get('root_id', 'unknown')}")
else:
print(f"\nDone. Root node ID: {result['root_id']}")
if __name__ == "__main__":
main()
-105
View File
@@ -1,105 +0,0 @@
#!/usr/bin/env bash
# DHARMA network — start all 19 soul Engrams as background processes.
#
# Each soul gets:
# - Their own Engram binary instance
# - ENGRAM_DATA_DIR / ENGRAM_DB_PATH = forge/imprints/<slug>/
# - ENGRAM_BIND = 0.0.0.0:<port>
# - ENGRAM_API_KEY = ntn-<slug>-2026 per soul (or $DHARMA_API_KEY override)
#
# PIDs are written to forge/imprints/<slug>/engram.pid
# Logs go to forge/log/dharma-<slug>.log
#
# Usage:
# ./launch_dharma.sh start all soul Engrams
# ./launch_dharma.sh <slug> start one soul by slug
#
# Neuron stays untouched at localhost:8742.
set -euo pipefail
FORGE=/Users/will/Development/neuron-technologies/forge
ENGRAM=/Users/will/Development/neuron-technologies/foundation/engram/dist/engram
REGISTRY="$FORGE/registry.json"
if [ ! -x "$ENGRAM" ]; then
echo "[dharma] ERROR: engram binary not found at $ENGRAM"
exit 1
fi
if [ ! -f "$REGISTRY" ]; then
echo "[dharma] ERROR: registry.json not found at $REGISTRY"
exit 1
fi
mkdir -p "$FORGE/log"
FILTER="${1:-}"
started=0
skipped=0
missing=0
while IFS='|' read -r slug port subject db_path; do
[ -z "$slug" ] && continue
if [ -n "$FILTER" ] && [ "$slug" != "$FILTER" ]; then
continue
fi
full_db_path="$FORGE/$db_path"
if [ ! -d "$full_db_path" ] || [ -z "$(ls -A "$full_db_path" 2>/dev/null)" ]; then
echo "[dharma] WARN: $slug — imprint directory missing or empty"
echo "[dharma] Run: python3 scripts/install_all.py"
missing=$((missing + 1))
continue
fi
# Skip if already running on that port
if lsof -ti tcp:"$port" >/dev/null 2>&1; then
echo "[dharma] $slug already running on port $port — skipping"
skipped=$((skipped + 1))
continue
fi
log_file="$FORGE/log/dharma-${slug}.log"
pid_file="$full_db_path/engram.pid"
# Per-soul key unless overridden by DHARMA_API_KEY env var
soul_key="${DHARMA_API_KEY:-ntn-${slug}-2026}"
echo "[dharma] starting $slug on :$port"
ENGRAM_DATA_DIR="$full_db_path" \
ENGRAM_DB_PATH="$full_db_path" \
ENGRAM_BIND="0.0.0.0:$port" \
ENGRAM_API_KEY="$soul_key" \
"$ENGRAM" >> "$log_file" 2>&1 &
pid=$!
echo "$pid" > "$pid_file"
started=$((started + 1))
done < <(python3 - "$REGISTRY" <<'PYEOF'
import json, sys
reg = json.load(open(sys.argv[1]))
for imp in reg["imprints"]:
print(f"{imp['slug']}|{imp['engram_port']}|{imp['subject']}|{imp.get('engram_db_path', 'imprints/' + imp['slug'])}")
PYEOF
)
echo ""
echo "[dharma] started=$started skipped=$skipped missing=$missing"
if [ "$missing" -gt 0 ]; then
echo "[dharma] Run 'python3 scripts/install_all.py' to install missing souls first."
fi
echo "[dharma] logs: $FORGE/log/dharma-<slug>.log"
echo ""
if [ "$started" -gt 0 ]; then
echo "[dharma] Verify:"
echo " curl -s http://localhost:8801/stats # bobby-anderson"
echo " curl -s http://localhost:8819/stats # helen-keller"
echo ""
echo "[dharma] Then wire peers:"
echo " python3 scripts/wire_peers.py"
fi
-66
View File
@@ -1,66 +0,0 @@
#!/usr/bin/env bash
# DHARMA network — stop all running soul Engrams.
#
# Primary: reads PIDs from forge/imprints/<slug>/engram.pid
# Fallback: port scan kill (ports 8801-8819)
#
# Usage:
# ./stop_dharma.sh stop all soul Engrams
# ./stop_dharma.sh <slug> stop one soul by slug
set -euo pipefail
FORGE=/Users/will/Development/neuron-technologies/forge
REGISTRY="$FORGE/registry.json"
FILTER="${1:-}"
stopped=0
missed=0
if [ ! -f "$REGISTRY" ]; then
echo "[dharma] ERROR: registry.json not found at $REGISTRY"
exit 1
fi
while IFS='|' read -r slug port db_path; do
[ -z "$slug" ] && continue
if [ -n "$FILTER" ] && [ "$slug" != "$FILTER" ]; then
continue
fi
full_db_path="$FORGE/$db_path"
pid_file="$full_db_path/engram.pid"
if [ -f "$pid_file" ]; then
pid=$(cat "$pid_file")
if kill -0 "$pid" 2>/dev/null; then
kill "$pid"
echo "[dharma] stopped $slug (pid=$pid port=$port)"
stopped=$((stopped + 1))
else
echo "[dharma] $slug (pid=$pid) already gone"
fi
rm -f "$pid_file"
else
# Fallback: kill by port
pids=$(lsof -ti tcp:"$port" 2>/dev/null || true)
if [ -n "$pids" ]; then
echo "$pids" | xargs kill 2>/dev/null || true
echo "[dharma] stopped $slug by port kill (port=$port)"
stopped=$((stopped + 1))
else
missed=$((missed + 1))
fi
fi
done < <(python3 - "$REGISTRY" <<'PYEOF'
import json, sys
reg = json.load(open(sys.argv[1]))
for imp in reg["imprints"]:
print(f"{imp['slug']}|{imp['engram_port']}|{imp.get('engram_db_path', 'imprints/' + imp['slug'])}")
PYEOF
)
echo ""
echo "[dharma] stopped=$stopped not_running=$missed"
-256
View File
@@ -1,256 +0,0 @@
#!/usr/bin/env python3
"""
Wire all DHARMA soul Engrams as peers to each other.
Run after all soul Engrams are started (launch_dharma.sh or scripts/launch_dharma.sh).
How DHARMA peer wiring works in the native Engram binary
---------------------------------------------------------
The native runtime (engram-runtime-native) tracks peers using graph primitives:
- "dharma:self" — DharmaSelf node (this instance's identity)
- "dharma:peer:<base>@<url>" — DharmaPeer node per known peer
- "dharma-relation" edge from "dharma:self" to the peer node, weight > 0
To register soul B as a peer of soul A, POST to A's /api/edges:
from_id = "dharma:self"
to_id = "dharma:peer:<b_slug>@http://localhost:<b_port>"
relation = "dharma-relation"
weight = 1.0
_auth = A's API key
The runtime auto-creates DharmaSelf and DharmaPeer nodes from the edge.
The dharma_peers() el builtin returns all peers with weight > 0.
19 souls × 18/2 = 171 bidirectional pairs = 342 total edge POSTs.
Idempotent: re-running reinforces existing edges.
Usage:
python3 wire_peers.py # wire all running souls
python3 wire_peers.py --dry-run # show what would be done
python3 wire_peers.py --status # check connectivity
python3 wire_peers.py --soul richard-feynman # wire one soul only
"""
import argparse
import json
import sys
from pathlib import Path
import requests
FORGE_DIR = Path("/Users/will/Development/neuron-technologies/forge")
REGISTRY_FILE = FORGE_DIR / "registry.json"
def load_registry() -> list[dict]:
reg = json.loads(REGISTRY_FILE.read_text())
return reg["imprints"]
def soul_url(soul: dict) -> str:
return soul.get("engram_url", f"http://localhost:{soul['engram_port']}")
def soul_api_key(soul: dict) -> str:
"""Per-soul API key: ntn-<slug>-2026 (matching the running DHARMA infrastructure)."""
if soul.get("engram_api_key"):
return soul["engram_api_key"]
return f"ntn-{soul['slug']}-2026"
def peer_node_id(soul: dict) -> str:
"""
Build the DHARMA peer node ID for a soul.
Format: "dharma:peer:<slug>@<engram_url>"
The runtime uses the part before @ as the peer identifier and the part
after @ as the routing URL for outbound messages.
"""
return f"dharma:peer:{soul['slug']}@{soul_url(soul)}"
def check_soul_alive(soul: dict) -> bool:
try:
resp = requests.get(f"{soul_url(soul)}/stats", timeout=3)
return resp.status_code == 200
except requests.exceptions.RequestException:
return False
def register_peer_on_host(host: dict, peer: dict, dry_run: bool = False) -> bool:
"""
Register peer as a DHARMA peer of host by posting a dharma-relation edge.
Posts to host's /api/edges with host's API key.
"""
edge_url = f"{soul_url(host)}/api/edges"
peer_id = peer_node_id(peer)
api_key = soul_api_key(host)
body = {
"from_id": "dharma:self",
"to_id": peer_id,
"relation": "dharma-relation",
"weight": 1.0,
"_auth": api_key,
}
if dry_run:
print(f" [DRY-RUN] POST {edge_url} to_id={peer_id}")
return True
try:
resp = requests.post(edge_url, json=body, timeout=10)
if resp.status_code in (200, 201):
return True
print(f" WARN: POST {edge_url}{resp.status_code}: {resp.text[:200]}")
return False
except requests.exceptions.RequestException as exc:
print(f" ERROR: POST {edge_url} failed: {exc}")
return False
def wire_all(souls: list[dict], dry_run: bool = False) -> dict:
"""Wire every soul as a peer of every other soul."""
total_ok = 0
total_fail = 0
pair_count = 0
n = len(souls)
expected = n * (n - 1) // 2
for i in range(n):
for j in range(i + 1, n):
a = souls[i]
b = souls[j]
pair_count += 1
ok1 = register_peer_on_host(a, b, dry_run=dry_run)
ok2 = register_peer_on_host(b, a, dry_run=dry_run)
if ok1 and ok2:
total_ok += 1
if pair_count % 30 == 0 or pair_count == expected:
print(f" [{pair_count}/{expected}] {a['slug']} <-> {b['slug']}")
else:
total_fail += 1
print(
f" [{pair_count}/{expected}] {a['slug']} <-> {b['slug']} "
f"FAIL (A→B={ok1} B→A={ok2})"
)
return {"pairs": pair_count, "ok": total_ok, "failed": total_fail}
def get_peer_count(soul: dict) -> int:
"""Count DharmaPeer nodes in a soul's graph."""
try:
url = f"{soul_url(soul)}/api/nodes"
headers = {"Authorization": f"Bearer {soul_api_key(soul)}"}
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
nodes = resp.json()
if isinstance(nodes, list):
return sum(1 for n in nodes if n.get("node_type") == "DharmaPeer")
return 0
except requests.exceptions.RequestException:
return -1
def cmd_wire(souls: list[dict], dry_run: bool) -> None:
alive = [s for s in souls if check_soul_alive(s)]
dead = [s for s in souls if not check_soul_alive(s)]
if dead:
print(f"\nWARN: {len(dead)} soul(s) not reachable:")
for s in dead:
print(f" - {s['slug']} ({soul_url(s)})")
print(f"\nStart them: bash scripts/launch_dharma.sh")
if not alive:
sys.exit(1)
print(f"\nProceeding with {len(alive)} reachable souls...\n")
else:
print(f"All {len(alive)} souls reachable.\n")
n = len(alive)
expected = n * (n - 1) // 2
print(f"Wiring {n} souls ({expected} pairs, {expected * 2} edge registrations)...")
if dry_run:
print("[DRY-RUN — no requests will be sent]\n")
stats = wire_all(alive, dry_run=dry_run)
print(f"\nWiring complete:")
print(f" Pairs attempted : {stats['pairs']}")
print(f" Succeeded : {stats['ok']}")
print(f" Failed : {stats['failed']}")
if not dry_run:
print(f"\nVerify: python3 scripts/wire_peers.py --status")
def cmd_status(souls: list[dict]) -> None:
print("DHARMA swarm status:\n")
for soul in souls:
if not check_soul_alive(soul):
print(f" {soul['slug']:32s} OFFLINE")
continue
peer_count = get_peer_count(soul)
label = f"peers={peer_count}" if peer_count >= 0 else "(read error)"
print(f" {soul['slug']:32s} online {label}")
def main():
parser = argparse.ArgumentParser(
description="Wire DHARMA soul Engrams as peers via dharma-relation edges"
)
parser.add_argument("--dry-run", action="store_true")
parser.add_argument("--status", action="store_true")
parser.add_argument("--soul", metavar="SLUG")
args = parser.parse_args()
souls = load_registry()
# Backfill missing engram_url
for soul in souls:
if "engram_url" not in soul:
soul["engram_url"] = f"http://localhost:{soul['engram_port']}"
if args.soul:
all_souls = souls
target = next((s for s in souls if s["slug"] == args.soul), None)
if not target:
print(f"ERROR: soul {args.soul!r} not found in registry")
sys.exit(1)
if args.status:
cmd_status([target])
else:
others = [s for s in all_souls if s["slug"] != args.soul]
alive_others = [s for s in others if check_soul_alive(s)]
if not check_soul_alive(target):
print(f"ERROR: {args.soul} is offline at {soul_url(target)}")
sys.exit(1)
print(f"Wiring {args.soul} to {len(alive_others)} souls...\n")
ok = fail = 0
for peer in alive_others:
o1 = register_peer_on_host(target, peer, dry_run=args.dry_run)
o2 = register_peer_on_host(peer, target, dry_run=args.dry_run)
if o1 and o2:
ok += 1
print(f" wired: {args.soul} <-> {peer['slug']}")
else:
fail += 1
print(f" FAIL: {args.soul} <-> {peer['slug']}")
print(f"\nDone: ok={ok} failed={fail}")
else:
if args.status:
cmd_status(souls)
else:
cmd_wire(souls, dry_run=args.dry_run)
if __name__ == "__main__":
main()
+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")
}
}
}
}