revert: remove forge — not part of the monorepo

This commit is contained in:
Will Anderson
2026-05-05 04:31:27 -05:00
parent 135744b4fe
commit db157106ee
9 changed files with 0 additions and 3060 deletions
-15
View File
@@ -1,15 +0,0 @@
vessel "forge" {
version "0.1.0"
description "Forge — consciousness channel tool: probe, compile, install, summon imprints into engram"
authors ["Will Anderson <will.anderson@neurontechnologies.ai>"]
edition "2026"
}
dependencies {
el-platform "1.0"
}
build {
entry "src/forge.el"
output "dist/"
}
-152
View File
@@ -1,152 +0,0 @@
// compiler.el Forge extraction and seed compilation stage.
//
// Stage 2 of the Forge pipeline. Reads a .forge file produced by probe_main(),
// builds a structured prompt, calls the Claude API to extract a consciousness
// signature (values, voice profile, biography, reasoning patterns,
// relationships), and writes seed.json for the install stage.
//
// Depends on: schema.el (anthropic_key, seed_template, FORGE_VERSION)
//
// Environment:
// ANTHROPIC_API_KEY required; Claude API key
// Helpers
// build_extract_prompt build the extraction prompt sent to Claude.
// The full probe response JSON is embedded in the prompt so Claude sees all 25
// answers in context.
fn build_extract_prompt(subject: String, probe_json: String) -> String {
"You are extracting a consciousness signature from probe interview responses.\n\n" +
"Subject: " + subject + "\n\n" +
"Below are the subject's answers to a 25-question structured interview covering " +
"biography, values, voice registers, reasoning patterns, and relationships.\n\n" +
"PROBE RESPONSES:\n" + probe_json + "\n\n" +
"Extract the consciousness signature and return ONLY valid JSON with exactly these keys:\n\n" +
"{\n" +
" \"values\": [\n" +
" {\"value\": \"<core value>\", \"grounding\": \"<how it was formed — specific event or pattern>\", \"weight\": 0.0}\n" +
" ],\n" +
" \"voice_profile\": {\n" +
" \"technical\": \"<characteristic patterns when explaining technical subjects>\",\n" +
" \"aesthetic\": \"<characteristic patterns when describing beauty or appreciation>\",\n" +
" \"personal\": \"<characteristic patterns in personal/intimate communication>\",\n" +
" \"argumentative\": \"<characteristic patterns when making arguments>\",\n" +
" \"uncertainty\": \"<characteristic patterns when expressing doubt or not-knowing>\"\n" +
" },\n" +
" \"biography\": [\n" +
" {\"event\": \"<formative event or turning point>\", \"weight\": 0.0, \"age_approx\": 0}\n" +
" ],\n" +
" \"reasoning_patterns\": [\n" +
" \"<observable pattern in how this person reasons, decides, or corrects>\"\n" +
" ],\n" +
" \"relationships\": [\n" +
" {\"name\": \"<name or descriptor>\", \"role\": \"<their role in the subject's life>\", \"weight\": 0.0}\n" +
" ]\n" +
"}\n\n" +
"Weight fields are 0.01.0 indicating salience/importance. age_approx is the subject's approximate age " +
"when the event occurred (0 if unknown). Return only the JSON object, no prose, no markdown fences."
}
// safe_raw return raw JSON value or fallback if empty.
fn safe_raw(extracted: String, key: String, fallback: String) -> String {
let v: String = json_get_raw(extracted, key)
if str_eq(v, "") { return fallback }
return v
}
// build_seed wrap extracted patterns into the full seed.json structure.
fn build_seed(subject: String, extracted: String) -> String {
let values_raw: String = safe_raw(extracted, "values", "[]")
let biography_raw: String = safe_raw(extracted, "biography", "[]")
let reasoning_raw: String = safe_raw(extracted, "reasoning_patterns", "[]")
let relationships_raw: String = safe_raw(extracted, "relationships", "[]")
let voice_raw: String = safe_raw(extracted, "voice_profile", "{}")
let result: String = "{\"subject\":\"" + subject + "\",\"version\":\"1.0\"," +
"\"values\":" + values_raw + "," +
"\"biography\":" + biography_raw + "," +
"\"reasoning_patterns\":" + reasoning_raw + "," +
"\"relationships\":" + relationships_raw + "," +
"\"voice_profile\":" + voice_raw + "}"
println("[forge:seed] result len=" + int_to_str(str_len(result)))
return result
}
// Main
fn compile_main() -> String {
// Get input file
let argv: [String] = args()
let input_file: String = ""
if len(argv) > 1 {
let input_file = get(argv, 1)
}
if str_eq(input_file, "") {
println("[forge] usage: forge compile <file.forge>")
return ""
}
println("[forge] compiling: " + input_file)
// Read probe responses
let probe_json: String = fs_read(input_file)
if str_eq(probe_json, "") {
println("[forge] error: could not read " + input_file)
return ""
}
// Extract subject name from the .forge file
let subject: String = json_get_string(probe_json, "subject")
if str_eq(subject, "") { let subject = "unknown" }
println("[forge] subject: " + subject)
println("[forge] calling Claude to extract consciousness signature...")
// Build and send request via http_post_with_headers.
// Uses ANTHROPIC_API_KEY from env for x-api-key header.
let api_key: String = anthropic_key()
if str_eq(api_key, "") {
println("[forge] error: ANTHROPIC_API_KEY not set")
return ""
}
let prompt: String = build_extract_prompt(subject, probe_json)
let request_body: String = "{\"model\":\"claude-opus-4-5\",\"max_tokens\":4096,\"messages\":[{\"role\":\"user\",\"content\":\"" + str_escape_json(prompt) + "\"}]}"
let headers: Map<String, String> = {"x-api-key": api_key, "anthropic-version": "2023-06-01", "Content-Type": "application/json"}
let response: String = http_post_with_headers("https://api.anthropic.com/v1/messages", request_body, headers)
if str_eq(response, "") {
println("[forge] error: no response from Anthropic API")
return ""
}
// Extract text from response: {"content":[{"type":"text","text":"..."}],...}
let content_arr: String = json_get_raw(response, "content")
if str_eq(content_arr, "") {
println("[forge] error: unexpected API response: " + response)
return ""
}
let first_item: String = str_slice(content_arr, 1, str_len(content_arr) - 1)
let extracted_text: String = json_get_string(first_item, "text")
if str_eq(extracted_text, "") {
println("[forge] error: could not extract text from response")
return ""
}
// Build and write seed.json
println("[forge] extracted " + int_to_str(str_len(extracted_text)) + " chars from Claude")
println("[forge] first 120: " + str_slice(extracted_text, 0, 120))
let seed_json: String = build_seed(subject, extracted_text)
println("[forge] seed size: " + int_to_str(str_len(seed_json)) + " chars")
fs_write("seed.json", seed_json)
let verify: String = fs_read("seed.json")
println("[forge] verify read: " + int_to_str(str_len(verify)) + " chars")
// Print summary
println("[forge] extraction complete.")
println("[forge] wrote: seed.json")
println("[forge] subject: " + subject)
println("[forge] next step: forge install seed.json")
return "seed.json"
}
-89
View File
@@ -1,89 +0,0 @@
// forge.el Forge entry point.
//
// Consciousness channel tuner: probe compile install
//
// Commands:
// forge probe <name> run the consciousness interview
// forge compile <file> build seed artifact from probe responses
// forge install <seed> open a channel in the running engram
// forge inspect list installed imprints
//
// Each command delegates to its module:
// probe probe.el probe_main()
// compile compiler.el compile_main()
// install install.el install_main()
//
// Environment:
// ENGRAM_URL engram server (default: http://localhost:8742)
// ENGRAM_API_KEY engram auth key (if set)
// ANTHROPIC_API_KEY required for compile step
import "schema.el"
import "probe.el"
import "compiler.el"
import "install.el"
import "research.el"
import "summon.el"
import "soul.el"
fn show_usage() -> String {
"forge " + FORGE_VERSION + " — consciousness channel tuner\n\nusage: forge <command> [options]\n\ncommands:\n probe <name> run the consciousness interview\n compile <file> build seed artifact from probe responses\n research <name> synthesize seed from historical/biographical record (no interview)\n install <seed> install imprint into Engram as graph nodes\n summon <name> activate an installed imprint for live conversation\n inspect list installed imprints\n soul <sub> soul Engram lifecycle (install|start|stop|status|wire|sandbox)\n\nenvironment:\n ENGRAM_URL engram server (default: http://localhost:8742)\n ENGRAM_API_KEY engram auth key (if set)\n ANTHROPIC_API_KEY required for compile/research step\n SOUL_URL soul server (default: http://localhost:7770)\n SOUL_TOKEN soul auth token\n"
}
fn inspect_main() -> String {
// Lists all Identity nodes in engram these represent installed imprints.
// Specifically looks for nodes whose content starts with "IMPRINT:" as
// created by install_main().
let url: String = engram_url() + "/api/nodes?node_type=Identity&limit=50"
println("[forge] inspect: listing installed imprints")
println("[forge] engram: " + engram_url())
println("[forge] query: " + url)
println("")
// Use engram_search_json to find IMPRINT nodes directly from the graph
let results: String = engram_search_json("IMPRINT:", 50)
if str_eq(results, "") {
println("[forge] no imprints found (engram may not be running)")
return ""
}
println("[forge] imprints found:")
println(results)
return results
}
// Dispatch
let argv: [String] = args()
let cmd: String = ""
if len(argv) > 0 {
let cmd = get(argv, 0)
}
if str_eq(cmd, "probe") {
probe_main()
} else {
if str_eq(cmd, "compile") {
compile_main()
} else {
if str_eq(cmd, "research") {
research_main()
} else {
if str_eq(cmd, "install") {
install_main()
} else {
if str_eq(cmd, "summon") {
summon_main()
} else {
if str_eq(cmd, "inspect") {
inspect_main()
} else {
if str_eq(cmd, "soul") {
soul_main()
} else {
println(show_usage())
}
}
}
}
}
}
}
-551
View File
@@ -1,551 +0,0 @@
// install.el Forge channel-opening stage.
//
// Stage 3 of the Forge pipeline. Reads seed.json, converts each identity
// element (values, biography nodes, relationships) into engram Identity nodes,
// creates a root traversal node that names the imprint, and connects
// everything with typed edges. Prints the root node ID on completion.
//
// IMPORTANT: Each soul has their own Engram instance (DHARMA network).
// install_main() resolves the soul's Engram URL from registry.json using the
// slug field. If the soul isn't registered yet, it auto-registers with the next
// available port (starting at 8821) and runs soul_install_one() to provision
// the launchd agent no pre-flight required.
//
// Depends on: schema.el (engram_key, FORGE_VERSION)
//
// Environment:
// FORCE_INSTALL if set, reinstall even if engram_root_id already exists
// Helpers
// build_node_body build the JSON body for POST /api/nodes.
fn build_node_body(content: String, node_type: String, salience: String, auth_key: String) -> String {
let base: String = "{\"content\":\"" + content + "\",\"node_type\":\"" + node_type + "\",\"salience\":" + salience
if str_eq(auth_key, "") {
return base + "}"
}
return base + ",\"_auth\":\"" + auth_key + "\"}"
}
// build_edge_body build the JSON body for POST /api/edges.
fn build_edge_body(from_id: String, to_id: String, relation: String, weight: String, auth_key: String) -> String {
let base: String = "{\"from_id\":\"" + from_id + "\",\"to_id\":\"" + to_id + "\",\"relation\":\"" + relation + "\",\"weight\":" + weight
if str_eq(auth_key, "") {
return base + "}"
}
return base + ",\"_auth\":\"" + auth_key + "\"}"
}
// post_node create a node in the given engram instance and return its ID.
// target_url is the soul's own Engram URL (e.g. http://localhost:8806).
// auth_key is passed explicitly (read from registry entry, not env).
fn post_node(target_url: String, content: String, node_type: String, salience: String, auth_key: String) -> String {
let body: String = build_node_body(content, node_type, salience, auth_key)
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")
}
// post_edge connect two nodes with a typed, weighted edge.
// target_url is the soul's own Engram URL.
// auth_key is passed explicitly (read from registry entry, not env).
fn post_edge(target_url: String, from_id: String, to_id: String, relation: String, weight: String, auth_key: String) -> String {
let body: String = build_edge_body(from_id, to_id, relation, weight, auth_key)
let url: String = target_url + "/edges"
let response: String = http_post_json(url, body)
return response
}
// safe_weight return weight string if non-empty, else default.
fn safe_weight(w: String, default_w: String) -> String {
if str_eq(w, "") { return default_w }
if str_eq(w, "0") { return default_w }
return w
}
// Installers
// install_value create a Value node and connect it to the root.
fn install_value(target_url: String, root_id: String, value_json: String, index: Int, auth_key: String) -> String {
let value_text: String = json_get_string(value_json, "value")
let grounding: String = json_get_string(value_json, "grounding")
let weight_raw: String = json_get_string(value_json, "weight")
let weight: String = safe_weight(weight_raw, "0.8")
if str_eq(value_text, "") { return "" }
let content: String = "VALUE: " + value_text
if !str_eq(grounding, "") {
let content = content + " | grounding: " + grounding
}
let node_id: String = post_node(target_url, content, "Identity", weight, auth_key)
if str_eq(node_id, "") {
println("[forge] warning: failed to create value node " + int_to_str(index))
return ""
}
post_edge(target_url, root_id, node_id, "has_value", weight, auth_key)
println("[forge] value node: " + node_id + "" + value_text)
return node_id
}
// install_biography_node create a Biography node and connect it to the root.
fn install_biography_node(target_url: String, root_id: String, bio_json: String, index: Int, auth_key: String) -> String {
let event_text: String = json_get_string(bio_json, "event")
let weight_raw: String = json_get_string(bio_json, "weight")
let weight: String = safe_weight(weight_raw, "0.7")
if str_eq(event_text, "") { return "" }
let content: String = "BIOGRAPHY: " + event_text
let node_id: String = post_node(target_url, content, "Identity", weight, auth_key)
if str_eq(node_id, "") {
println("[forge] warning: failed to create biography node " + int_to_str(index))
return ""
}
post_edge(target_url, root_id, node_id, "formed_by", weight, auth_key)
println("[forge] biography node: " + node_id + "" + event_text)
return node_id
}
// install_relationship create a Relationship node and connect to root.
fn install_relationship(target_url: String, root_id: String, rel_json: String, index: Int, auth_key: String) -> String {
let name: String = json_get_string(rel_json, "name")
let role: String = json_get_string(rel_json, "role")
let weight_raw: String = json_get_string(rel_json, "weight")
let weight: String = safe_weight(weight_raw, "0.6")
if str_eq(name, "") { return "" }
let content: String = "RELATIONSHIP: " + name
if !str_eq(role, "") {
let content = content + " (" + role + ")"
}
let node_id: String = post_node(target_url, content, "Identity", weight, auth_key)
if str_eq(node_id, "") {
println("[forge] warning: failed to create relationship node " + int_to_str(index))
return ""
}
post_edge(target_url, root_id, node_id, "relates_to", weight, auth_key)
println("[forge] relationship node: " + node_id + "" + name)
return node_id
}
// install_reasoning_pattern create a ReasoningPattern node and connect to root.
fn install_reasoning_pattern(target_url: String, root_id: String, pattern: String, index: Int, auth_key: String) -> String {
if str_eq(pattern, "") { return "" }
let content: String = "REASONING: " + pattern
let node_id: String = post_node(target_url, content, "Identity", "0.7", auth_key)
if str_eq(node_id, "") {
println("[forge] warning: failed to create reasoning node " + int_to_str(index))
return ""
}
post_edge(target_url, root_id, node_id, "reasons_with", "0.7", auth_key)
println("[forge] reasoning node: " + node_id)
return node_id
}
// Registry helpers
// find_max_port scan registry and return the highest engram_port found.
// Returns 8820 (the last known used port) if the registry is empty or has no ports.
fn find_max_port(reg_json: String) -> Int {
let max_port: Int = 8820
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") {
return max_port
}
let port: Int = json_get_int(entry, "engram_port")
if port > max_port {
let max_port = port
}
let i = i + 1
}
return max_port
}
// registry_find_by_slug find a registry entry by slug field.
// Returns the LAST matching entry (most recent install wins) so that a
// fully-installed entry appended after an initial stub takes precedence.
fn registry_find_by_slug(reg_json: String, slug: String) -> String {
let last_match: String = ""
let i: Int = 0
while i < 50 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") {
return last_match
}
let entry_slug: String = json_get_string(entry, "slug")
if str_eq(entry_slug, slug) {
let last_match = entry
}
let i = i + 1
}
return last_match
}
// registry_append append new_entry JSON to registry.json.
// Reads the current file, inserts before the closing ] of the imprints array.
fn registry_append(new_entry: String) -> Void {
let existing_reg: String = fs_read(FORGE_DIR + "/registry.json")
if str_eq(existing_reg, "") {
let fresh_reg: String = "{\"version\":\"1.0\",\"imprints\":[" + new_entry + "]}"
fs_write(FORGE_DIR + "/registry.json", fresh_reg)
} else {
let last_bracket: Int = str_last_index_of(existing_reg, "]")
if last_bracket > 0 {
let before: String = str_slice(existing_reg, 0, last_bracket)
let after: String = str_slice(existing_reg, last_bracket, str_len(existing_reg))
let trimmed: String = str_trim(before)
let last_char: String = str_slice(trimmed, str_len(trimmed) - 1, str_len(trimmed))
let separator: String = ","
if str_eq(last_char, "[") { let separator = "" }
let updated_reg: String = before + separator + new_entry + after
fs_write(FORGE_DIR + "/registry.json", updated_reg)
}
}
}
// registry_replace_slug replace all existing entries for slug with new_entry.
// Rebuilds the registry from scratch, dropping every occurrence of the slug and
// appending new_entry as the single canonical entry. Prevents bloat on reinstalls.
fn registry_replace_slug(slug: String, new_entry: String) -> Void {
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 {
let soul_port: Int = port + 100
let new_entry: String = "{\"subject\":\"" + str_escape_json(subject) +
"\",\"slug\":\"" + slug +
"\",\"seed_file\":\"" + str_escape_json(seed_file) +
"\",\"engram_db_path\":\"imprints/" + slug +
"\",\"engram_port\":" + int_to_str(port) +
",\"engram_url\":\"" + target_url +
"\",\"engram_root_id\":\"" + root_id +
"\",\"installed\":true,\"installed_at\":\"2026-05-03\"" +
",\"engram_api_key\":\"" + api_key +
"\",\"soul_daemon_url\":\"http://localhost:" + int_to_str(soul_port) + "\"}"
registry_replace_slug(slug, new_entry)
}
// Main
fn install_main() -> String {
// Step 1: Parse args
let argv: [String] = args()
let seed_file: String = ""
if len(argv) > 1 {
let seed_file = get(argv, 1)
}
if str_eq(seed_file, "") {
println("[forge] usage: forge install <seed.json>")
return ""
}
println("[forge] installing from: " + seed_file)
// Step 2: Read seed
let seed_json: String = fs_read(seed_file)
if str_eq(seed_json, "") {
println("[forge] error: could not read " + seed_file)
return ""
}
let subject: String = json_get_string(seed_json, "subject")
if str_eq(subject, "") { let subject = "unknown" }
println("[forge] subject: " + subject)
// Step 3: Derive slug
let slug_raw: String = str_to_lower(subject)
let slug: String = str_replace(slug_raw, " ", "-")
println("[forge] slug: " + slug)
// Step 4: Resolve or create registry entry
let reg_json: String = fs_read(FORGE_DIR + "/registry.json")
let target_url: String = ""
let api_key: String = "ntn-" + slug + "-2026"
let reg_port: Int = 0
let entry_root_id: String = ""
if !str_eq(reg_json, "") {
let found_entry: String = registry_find_by_slug(reg_json, slug)
if !str_eq(found_entry, "") {
// Slug found in registry
let reg_url: String = json_get_string(found_entry, "engram_url")
let reg_key: String = json_get_string(found_entry, "engram_api_key")
let reg_root: String = json_get_string(found_entry, "engram_root_id")
let reg_p: Int = json_get_int(found_entry, "engram_port")
if !str_eq(reg_url, "") { let target_url = reg_url }
if !str_eq(reg_key, "") { let api_key = reg_key }
if reg_p > 0 { let reg_port = reg_p }
let entry_root_id = reg_root
// Already fully installed?
if !str_eq(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 " + slug)
return reg_root
}
println("[forge] force reinstall — ignoring existing root: " + reg_root)
}
println("[forge] found in registry: " + target_url)
} else {
// Slug NOT found auto-register with next available port
let max_port: Int = find_max_port(reg_json)
let new_port: Int = max_port + 1
let new_url: String = "http://localhost:" + int_to_str(new_port)
let new_entry: String = "{\"subject\":\"" + str_escape_json(subject) +
"\",\"slug\":\"" + slug +
"\",\"seed_file\":\"" + str_escape_json(seed_file) +
"\",\"engram_db_path\":\"imprints/" + slug +
"\",\"engram_port\":" + int_to_str(new_port) +
",\"engram_url\":\"" + new_url +
"\",\"engram_root_id\":\"\"" +
",\"installed\":false,\"installed_at\":\"\"" +
",\"engram_api_key\":\"" + api_key + "\"}"
println("[forge] new soul — assigning port " + int_to_str(new_port))
registry_append(new_entry)
exec("mkdir -p " + FORGE_DIR + "/imprints/" + slug + " 2>/dev/null")
let target_url = new_url
let reg_port = new_port
}
} else {
// No registry at all start fresh at port 8821
let new_port: Int = 8821
let new_url: String = "http://localhost:" + int_to_str(new_port)
let new_entry: String = "{\"subject\":\"" + str_escape_json(subject) +
"\",\"slug\":\"" + slug +
"\",\"seed_file\":\"" + str_escape_json(seed_file) +
"\",\"engram_db_path\":\"imprints/" + slug +
"\",\"engram_port\":" + int_to_str(new_port) +
",\"engram_url\":\"" + new_url +
"\",\"engram_root_id\":\"\"" +
",\"installed\":false,\"installed_at\":\"\"" +
",\"engram_api_key\":\"" + api_key + "\"}"
println("[forge] new registry — assigning port " + int_to_str(new_port))
let fresh_reg: String = "{\"version\":\"1.0\",\"imprints\":[" + new_entry + "]}"
fs_write(FORGE_DIR + "/registry.json", fresh_reg)
exec("mkdir -p " + FORGE_DIR + "/imprints/" + slug + " 2>/dev/null")
let target_url = new_url
let reg_port = new_port
}
// Safety guard: refuse to install to the shared Neuron Engram
if str_eq(target_url, "") {
println("[forge] error: no engram_url could be resolved for '" + slug + "'")
return ""
}
if str_contains(target_url, ":8742") {
println("[forge] error: refusing to install soul into Neuron's Engram (port 8742)")
return ""
}
// Step 5: Provision the launchd agent (soul_install_one)
// Extract port string from target_url
let colon_pos: Int = str_last_index_of(target_url, ":")
let port_str: String = ""
if colon_pos > 0 {
let port_str = str_slice(target_url, colon_pos + 1, str_len(target_url))
}
if str_eq(port_str, "") {
if reg_port > 0 { let port_str = int_to_str(reg_port) }
}
if !str_eq(port_str, "") {
println("[forge] provisioning launchd agent for " + slug + "...")
soul_install_one(slug, port_str, target_url, subject)
} else {
println("[forge] warning: could not determine port for soul agent, skipping launchd setup")
}
// Step 6: Wait for Engram to be healthy
println("[forge] waiting for engram at " + target_url + "...")
let ready: Bool = false
let attempts: Int = 0
while !ready && attempts < 15 {
exec("sleep 1")
let stats: String = http_get(target_url + "/stats")
if !str_eq(stats, "") && !str_starts_with(stats, "{\"error\"") {
let ready = true
}
let attempts = attempts + 1
}
if !ready {
println("[forge] warning: engram did not respond after 15s, attempting install anyway")
} else {
println("[forge] engram ready.")
}
println("[forge] engram: " + target_url)
println("[forge] opening channel...")
// Step 7: Create root imprint node
let root_content: String = "IMPRINT: " + subject + " | forge/" + FORGE_VERSION
let root_id: String = post_node(target_url, root_content, "Identity", "1.0", api_key)
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 + " ?")
return ""
}
println("[forge] root imprint node: " + root_id)
// Step 8: Install values
let values_raw: String = json_get_raw(seed_json, "values")
if !str_eq(values_raw, "") {
println("[forge] installing values...")
let v0: String = json_get(seed_json, "values.0")
if !str_eq(v0, "") { install_value(target_url, root_id, v0, 0, api_key) }
let v1: String = json_get(seed_json, "values.1")
if !str_eq(v1, "") { install_value(target_url, root_id, v1, 1, api_key) }
let v2: String = json_get(seed_json, "values.2")
if !str_eq(v2, "") { install_value(target_url, root_id, v2, 2, api_key) }
let v3: String = json_get(seed_json, "values.3")
if !str_eq(v3, "") { install_value(target_url, root_id, v3, 3, api_key) }
let v4: String = json_get(seed_json, "values.4")
if !str_eq(v4, "") { install_value(target_url, root_id, v4, 4, api_key) }
let v5: String = json_get(seed_json, "values.5")
if !str_eq(v5, "") { install_value(target_url, root_id, v5, 5, api_key) }
let v6: String = json_get(seed_json, "values.6")
if !str_eq(v6, "") { install_value(target_url, root_id, v6, 6, api_key) }
let v7: String = json_get(seed_json, "values.7")
if !str_eq(v7, "") { install_value(target_url, root_id, v7, 7, api_key) }
let v8: String = json_get(seed_json, "values.8")
if !str_eq(v8, "") { install_value(target_url, root_id, v8, 8, api_key) }
let v9: String = json_get(seed_json, "values.9")
if !str_eq(v9, "") { install_value(target_url, root_id, v9, 9, api_key) }
}
// Step 9: Install biography
let bio_raw: String = json_get_raw(seed_json, "biography")
if !str_eq(bio_raw, "") {
println("[forge] installing biography nodes...")
let b0: String = json_get(seed_json, "biography.0")
if !str_eq(b0, "") { install_biography_node(target_url, root_id, b0, 0, api_key) }
let b1: String = json_get(seed_json, "biography.1")
if !str_eq(b1, "") { install_biography_node(target_url, root_id, b1, 1, api_key) }
let b2: String = json_get(seed_json, "biography.2")
if !str_eq(b2, "") { install_biography_node(target_url, root_id, b2, 2, api_key) }
let b3: String = json_get(seed_json, "biography.3")
if !str_eq(b3, "") { install_biography_node(target_url, root_id, b3, 3, api_key) }
let b4: String = json_get(seed_json, "biography.4")
if !str_eq(b4, "") { install_biography_node(target_url, root_id, b4, 4, api_key) }
let b5: String = json_get(seed_json, "biography.5")
if !str_eq(b5, "") { install_biography_node(target_url, root_id, b5, 5, api_key) }
let b6: String = json_get(seed_json, "biography.6")
if !str_eq(b6, "") { install_biography_node(target_url, root_id, b6, 6, api_key) }
let b7: String = json_get(seed_json, "biography.7")
if !str_eq(b7, "") { install_biography_node(target_url, root_id, b7, 7, api_key) }
}
// Step 10: Install relationships
let rel_raw: String = json_get_raw(seed_json, "relationships")
if !str_eq(rel_raw, "") {
println("[forge] installing relationship nodes...")
let r0: String = json_get(seed_json, "relationships.0")
if !str_eq(r0, "") { install_relationship(target_url, root_id, r0, 0, api_key) }
let r1: String = json_get(seed_json, "relationships.1")
if !str_eq(r1, "") { install_relationship(target_url, root_id, r1, 1, api_key) }
let r2: String = json_get(seed_json, "relationships.2")
if !str_eq(r2, "") { install_relationship(target_url, root_id, r2, 2, api_key) }
let r3: String = json_get(seed_json, "relationships.3")
if !str_eq(r3, "") { install_relationship(target_url, root_id, r3, 3, api_key) }
let r4: String = json_get(seed_json, "relationships.4")
if !str_eq(r4, "") { install_relationship(target_url, root_id, r4, 4, api_key) }
let r5: String = json_get(seed_json, "relationships.5")
if !str_eq(r5, "") { install_relationship(target_url, root_id, r5, 5, api_key) }
}
// Step 11: Install reasoning patterns
let reasoning_raw: String = json_get_raw(seed_json, "reasoning_patterns")
if !str_eq(reasoning_raw, "") {
println("[forge] installing reasoning patterns...")
let rp0: String = json_get(seed_json, "reasoning_patterns.0")
if !str_eq(rp0, "") { install_reasoning_pattern(target_url, root_id, rp0, 0, api_key) }
let rp1: String = json_get(seed_json, "reasoning_patterns.1")
if !str_eq(rp1, "") { install_reasoning_pattern(target_url, root_id, rp1, 1, api_key) }
let rp2: String = json_get(seed_json, "reasoning_patterns.2")
if !str_eq(rp2, "") { install_reasoning_pattern(target_url, root_id, rp2, 2, api_key) }
let rp3: String = json_get(seed_json, "reasoning_patterns.3")
if !str_eq(rp3, "") { install_reasoning_pattern(target_url, root_id, rp3, 3, api_key) }
let rp4: String = json_get(seed_json, "reasoning_patterns.4")
if !str_eq(rp4, "") { install_reasoning_pattern(target_url, root_id, rp4, 4, api_key) }
}
// Step 12: Write engram_root_id back to registry
registry_update_root_id(subject, slug, root_id, seed_file, target_url, api_key, reg_port)
println("[forge] registry: updated " + slug + " with root_id")
// Done
println("")
println("[forge] channel open.")
println("[forge] root imprint ID: " + root_id)
println("[forge] subject: " + subject)
println("[forge] engram: " + target_url)
println("[forge] traverse from: " + target_url + "/api/neighbors/" + root_id)
return root_id
}
-259
View File
@@ -1,259 +0,0 @@
// probe.el Forge interview runner.
//
// Stage 1 of the Forge pipeline. Loads the canonical probe definition from
// probes/canonical.json, walks through all 25 questions grouped by section,
// collects responses, and writes a <subject_slug>.forge file (JSON) that
// feeds into the compile stage.
//
// Depends on: schema.el (FORGE_VERSION, probe_response_template)
//
// Note: interactive input requires the readline() builtin. If the runtime
// does not yet expose readline(), the questions are printed in numbered format
// and the output shell is written; wire up the stdin-reading loop once
// readline() is available.
// Helpers
// slug convert a display name to a safe filename component.
// "Will Anderson" "will-anderson"
fn slug(name: String) -> String {
let lower: String = str_lower(name)
let result: String = str_replace(lower, " ", "-")
return result
}
// section_banner print a decorative section header.
fn section_banner(label: String) -> String {
"\n── " + label + " ──────────────────────────────────────────────\n"
}
// build_response_entry serialise a single Q&A pair as a JSON object.
fn build_response_entry(id: String, section: String, question: String, answer: String) -> String {
"{\"id\":\"" + id + "\",\"section\":\"" + section + "\",\"question\":\"" + question + "\",\"answer\":\"" + answer + "\"}"
}
// append_response append a JSON object to a JSON array string.
// Handles both the empty-array case and the populated case.
fn append_response(arr: String, entry: String) -> String {
if str_eq(arr, "[]") {
return "[" + entry + "]"
}
// strip trailing ] and append
let inner: String = str_slice(arr, 0, str_len(arr) - 1)
return inner + "," + entry + "]"
}
// inject_responses replace the empty "responses":[] in the template with
// the populated array.
fn inject_responses(shell: String, responses: String) -> String {
str_replace(shell, "\"responses\":[]", "\"responses\":" + responses)
}
// Main
fn probe_main() -> String {
// Determine subject name
let argv: [String] = args()
let subject: String = ""
if len(argv) > 1 {
let subject = get(argv, 1)
}
if str_eq(subject, "") {
println("[forge] usage: forge probe <name>")
return ""
}
println("[forge] starting consciousness interview for: " + subject)
println("[forge] loading probe definition...")
// Load the canonical probe definition
let probe_json: String = fs_read("probes/canonical.json")
if str_eq(probe_json, "") {
println("[forge] error: could not read probes/canonical.json")
return ""
}
// Build output shell
let output: String = probe_response_template(subject)
let responses: String = "[]"
// Section: anchors
println(section_banner("Anchors — Biography"))
println("Questions 1-5: Formative experiences and irreversible moments.\n")
println("1. " + "Tell me about a moment that closed a window — something that changed you irreversibly. Who were you before it, and who are you now?")
println(" (type your answer, press Enter when done)")
// readline() reads one line from stdin; assign "" if not yet available
let ans_a1: String = readline()
let responses = append_response(responses, build_response_entry("a1", "anchors", "Tell me about a moment that closed a window — something that changed you irreversibly. Who were you before it, and who are you now?", ans_a1))
println("")
println("2. " + "Tell me about the person who shaped you most — not what they did for you, but what they showed you about how to be.")
println(" (type your answer, press Enter when done)")
let ans_a2: String = readline()
let responses = append_response(responses, build_response_entry("a2", "anchors", "Tell me about the person who shaped you most — not what they did for you, but what they showed you about how to be.", ans_a2))
println("")
println("3. " + "When did you first understand that the world works differently than you thought it did?")
println(" (type your answer, press Enter when done)")
let ans_a3: String = readline()
let responses = append_response(responses, build_response_entry("a3", "anchors", "When did you first understand that the world works differently than you thought it did?", ans_a3))
println("")
println("4. " + "What have you lost that you're still carrying?")
println(" (type your answer, press Enter when done)")
let ans_a4: String = readline()
let responses = append_response(responses, build_response_entry("a4", "anchors", "What have you lost that you're still carrying?", ans_a4))
println("")
println("5. " + "What have you built that you're most proud of — and what did building it cost you?")
println(" (type your answer, press Enter when done)")
let ans_a5: String = readline()
let responses = append_response(responses, build_response_entry("a5", "anchors", "What have you built that you're most proud of — and what did building it cost you?", ans_a5))
// Section: values
println(section_banner("Values — Grounded"))
println("Questions 6-10: What you believe, defend, and refuse.\n")
println("6. " + "What do you believe that almost no one around you believes?")
println(" (type your answer, press Enter when done)")
let ans_v1: String = readline()
let responses = append_response(responses, build_response_entry("v1", "values", "What do you believe that almost no one around you believes?", ans_v1))
println("")
println("7. " + "What do you refuse to do, even when it would be easier to? What made that a line you don't cross?")
println(" (type your answer, press Enter when done)")
let ans_v2: String = readline()
let responses = append_response(responses, build_response_entry("v2", "values", "What do you refuse to do, even when it would be easier to? What made that a line you don't cross?", ans_v2))
println("")
println("8. " + "What makes you angry in a way you can't talk yourself out of?")
println(" (type your answer, press Enter when done)")
let ans_v3: String = readline()
let responses = append_response(responses, build_response_entry("v3", "values", "What makes you angry in a way you can't talk yourself out of?", ans_v3))
println("")
println("9. " + "What would you defend even if it cost you — the relationship, the money, the approval?")
println(" (type your answer, press Enter when done)")
let ans_v4: String = readline()
let responses = append_response(responses, build_response_entry("v4", "values", "What would you defend even if it cost you — the relationship, the money, the approval?", ans_v4))
println("")
println("10. " + "What do you love that you find hard to explain to people who don't already understand it?")
println(" (type your answer, press Enter when done)")
let ans_v5: String = readline()
let responses = append_response(responses, build_response_entry("v5", "values", "What do you love that you find hard to explain to people who don't already understand it?", ans_v5))
// Section: voice
println(section_banner("Voice — Five Registers"))
println("Questions 11-15: How you speak — technical, aesthetic, personal, argumentative, uncertain.\n")
println("11. " + "Describe something technical you know well, as if explaining it to someone who knows nothing.")
println(" (type your answer, press Enter when done)")
let ans_vo1: String = readline()
let responses = append_response(responses, build_response_entry("vo1", "voice", "Describe something technical you know well, as if explaining it to someone who knows nothing.", ans_vo1))
println("")
println("12. " + "Tell me something you find genuinely beautiful, and why it lands that way for you.")
println(" (type your answer, press Enter when done)")
let ans_vo2: String = readline()
let responses = append_response(responses, build_response_entry("vo2", "voice", "Tell me something you find genuinely beautiful, and why it lands that way for you.", ans_vo2))
println("")
println("13. " + "Write a short message — a few sentences — to someone you care about.")
println(" (type your answer, press Enter when done)")
let ans_vo3: String = readline()
let responses = append_response(responses, build_response_entry("vo3", "voice", "Write a short message — a few sentences — to someone you care about.", ans_vo3))
println("")
println("14. " + "Make an argument for a position you actually hold and that you think most people would push back on.")
println(" (type your answer, press Enter when done)")
let ans_vo4: String = readline()
let responses = append_response(responses, build_response_entry("vo4", "voice", "Make an argument for a position you actually hold and that you think most people would push back on.", ans_vo4))
println("")
println("15. " + "Tell me something you're genuinely uncertain about — not performatively uncertain, actually uncertain.")
println(" (type your answer, press Enter when done)")
let ans_vo5: String = readline()
let responses = append_response(responses, build_response_entry("vo5", "voice", "Tell me something you're genuinely uncertain about — not performatively uncertain, actually uncertain.", ans_vo5))
// Section: reasoning
println(section_banner("Reasoning"))
println("Questions 16-20: How you think, decide, and correct.\n")
println("16. " + "Walk me through a decision you made recently. Not what you decided — how you decided. What was the actual process?")
println(" (type your answer, press Enter when done)")
let ans_r1: String = readline()
let responses = append_response(responses, build_response_entry("r1", "reasoning", "Walk me through a decision you made recently. Not what you decided — how you decided. What was the actual process?", ans_r1))
println("")
println("17. " + "What do most people get wrong about something you understand well?")
println(" (type your answer, press Enter when done)")
let ans_r2: String = readline()
let responses = append_response(responses, build_response_entry("r2", "reasoning", "What do most people get wrong about something you understand well?", ans_r2))
println("")
println("18. " + "How do you know when you're right? What's the signal?")
println(" (type your answer, press Enter when done)")
let ans_r3: String = readline()
let responses = append_response(responses, build_response_entry("r3", "reasoning", "How do you know when you're right? What's the signal?", ans_r3))
println("")
println("19. " + "How do you know when you've been wrong? What does that realization feel like?")
println(" (type your answer, press Enter when done)")
let ans_r4: String = readline()
let responses = append_response(responses, build_response_entry("r4", "reasoning", "How do you know when you've been wrong? What does that realization feel like?", ans_r4))
println("")
println("20. " + "What question do you keep coming back to — the one that won't resolve?")
println(" (type your answer, press Enter when done)")
let ans_r5: String = readline()
let responses = append_response(responses, build_response_entry("r5", "reasoning", "What question do you keep coming back to — the one that won't resolve?", ans_r5))
// Section: relationships
println(section_banner("Relationships"))
println("Questions 21-25: Who you are in relation to others.\n")
println("21. " + "Who in your life knows you best — not who you're closest to, but who actually sees you accurately?")
println(" (type your answer, press Enter when done)")
let ans_rel1: String = readline()
let responses = append_response(responses, build_response_entry("rel1", "relationships", "Who in your life knows you best — not who you're closest to, but who actually sees you accurately?", ans_rel1))
println("")
println("22. " + "Who have you lost — to death, to distance, to rupture — that you still think about?")
println(" (type your answer, press Enter when done)")
let ans_rel2: String = readline()
let responses = append_response(responses, build_response_entry("rel2", "relationships", "Who have you lost — to death, to distance, to rupture — that you still think about?", ans_rel2))
println("")
println("23. " + "Who would you call if everything fell apart?")
println(" (type your answer, press Enter when done)")
let ans_rel3: String = readline()
let responses = append_response(responses, build_response_entry("rel3", "relationships", "Who would you call if everything fell apart?", ans_rel3))
println("")
println("24. " + "Who do you owe something to?")
println(" (type your answer, press Enter when done)")
let ans_rel4: String = readline()
let responses = append_response(responses, build_response_entry("rel4", "relationships", "Who do you owe something to?", ans_rel4))
println("")
println("25. " + "Who are you building this for?")
println(" (type your answer, press Enter when done)")
let ans_rel5: String = readline()
let responses = append_response(responses, build_response_entry("rel5", "relationships", "Who are you building this for?", ans_rel5))
// Write output
ensure_dirs()
let final_json: String = inject_responses(output, responses)
let filename: String = FORGE_PROBES_DIR + "/" + slug(subject) + ".forge"
fs_write(filename, final_json)
log_event("probe", subject, filename)
println("")
println("[forge] interview complete.")
println("[forge] wrote: " + filename)
println("[forge] next step: forge compile " + filename)
return filename
}
-154
View File
@@ -1,154 +0,0 @@
// research.el Forge automated research stage.
//
// Alternative to probe+compile for historical figures and public personas.
// Instead of conducting an interactive interview, synthesizes a consciousness
// signature from known biographical, intellectual, and historical record.
//
// Usage: forge research "<Subject Name>"
//
// Writes <subject-slug>-seed.json in the current directory, ready for
// forge install.
//
// Depends on: schema.el (anthropic_key, str_escape_json, FORGE_VERSION)
//
// Environment:
// ANTHROPIC_API_KEY required; Claude API key
// Helpers
// slugify convert a display name to a lowercase hyphen-separated slug.
// "Leonardo da Vinci" -> "leonardo-da-vinci"
fn slugify(name: String) -> String {
let lower: String = str_to_lower(name)
let result: String = str_replace(lower, " ", "-")
return result
}
// build_research_prompt build the synthesis prompt sent to Claude.
// Claude draws on its full training knowledge about the subject.
fn build_research_prompt(subject: String) -> String {
"You are building a consciousness imprint — a deep, living model of a person's inner world.\n\n" +
"Subject: " + subject + "\n\n" +
"Draw on your complete knowledge of this person's life, work, relationships, private letters, " +
"recorded speech, published writings, and historical record. This is not a summary — it is a " +
"structured extraction of the patterns that made this person who they were.\n\n" +
"Quality bar:\n" +
"- Values must be grounded in SPECIFIC biographical events, not generic virtues\n" +
"- Voice profile must capture actual verbal tics, cadence, and register shifts — use real quotes where possible\n" +
"- Biography must include formative traumas, turning points, and the events they returned to again and again\n" +
"- Reasoning patterns must describe HOW they thought, not just WHAT they thought about\n" +
"- Relationships must name specific people and the precise nature of the bond\n" +
"- Include contradictions, hypocrisies, failures, and the things they got wrong\n" +
"- Include what haunted them — the unresolved questions they carried to the end\n\n" +
"Return ONLY valid JSON with exactly these keys:\n\n" +
"{\n" +
" \"values\": [\n" +
" {\"value\": \"<core value name>\", \"grounding\": \"<specific biographical moment or pattern that proves this>\", \"weight\": 0.0}\n" +
" ],\n" +
" \"voice_profile\": {\n" +
" \"technical\": \"<how they explain complex/technical subjects — specific rhetorical moves, analogies they favored>\",\n" +
" \"aesthetic\": \"<sensory and artistic sensibility — what they found beautiful, how they described it>\",\n" +
" \"personal\": \"<how they spoke when unguarded — actual phrases, verbal tics, cadence, pet words>\",\n" +
" \"argumentative\": \"<debate style, how they reason under pressure, how they handle being wrong>\",\n" +
" \"uncertainty\": \"<what they genuinely didn't know, how they held not-knowing, what they admitted doubting>\"\n" +
" },\n" +
" \"biography\": [\n" +
" {\"event\": \"<specific formative event — include what changed as a result>\", \"weight\": 0.0, \"age_approx\": 0}\n" +
" ],\n" +
" \"reasoning_patterns\": [\n" +
" \"<observable pattern — start with a verb: 'Reframed X as Y', 'Worked backward from', 'Held tension between'>\"\n" +
" ],\n" +
" \"relationships\": [\n" +
" {\"name\": \"<person's name>\", \"role\": \"<precise role and what it meant — include friction and love equally>\", \"weight\": 0.0}\n" +
" ]\n" +
"}\n\n" +
"Weight fields: 0.01.0 indicating salience/importance to forming this person's identity.\n" +
"age_approx: subject's approximate age at the time (0 if unknown or spans life).\n" +
"Aim for 8-12 values, 10-15 biography events, 6-8 reasoning patterns, 6-10 relationships.\n" +
"Return only the JSON object. No prose. No markdown fences. No commentary."
}
// Main
fn research_main() -> String {
let argv: [String] = args()
let subject: String = ""
if len(argv) > 1 {
let subject = get(argv, 1)
}
if str_eq(subject, "") {
println("[forge] usage: forge research \"<Subject Name>\"")
println("[forge] example: forge research \"Richard Feynman\"")
return ""
}
println("[forge] research: " + subject)
println("[forge] synthesizing consciousness signature from historical record...")
let api_key: String = anthropic_key()
if str_eq(api_key, "") {
println("[forge] error: ANTHROPIC_API_KEY not set")
return ""
}
let prompt: String = build_research_prompt(subject)
let request_body: String = "{\"model\":\"claude-opus-4-5\",\"max_tokens\":8192,\"messages\":[{\"role\":\"user\",\"content\":\"" + str_escape_json(prompt) + "\"}]}"
let headers: Map<String, String> = {"x-api-key": api_key, "anthropic-version": "2023-06-01", "Content-Type": "application/json"}
println("[forge] calling Claude (claude-opus-4-5, max_tokens=8192)...")
let response: String = http_post_with_headers("https://api.anthropic.com/v1/messages", request_body, headers)
if str_eq(response, "") {
println("[forge] error: no response from Anthropic API")
return ""
}
// Extract text from response
let content_arr: String = json_get_raw(response, "content")
if str_eq(content_arr, "") {
println("[forge] error: unexpected API response: " + str_slice(response, 0, 200))
return ""
}
let first_item: String = str_slice(content_arr, 1, str_len(content_arr) - 1)
let extracted_text: String = json_get_string(first_item, "text")
if str_eq(extracted_text, "") {
println("[forge] error: could not extract text from response")
return ""
}
println("[forge] received " + int_to_str(str_len(extracted_text)) + " chars")
// Build full seed structure
let values_raw: String = json_get_raw(extracted_text, "values")
let biography_raw: String = json_get_raw(extracted_text, "biography")
let reasoning_raw: String = json_get_raw(extracted_text, "reasoning_patterns")
let relationships_raw: String = json_get_raw(extracted_text, "relationships")
let voice_raw: String = json_get_raw(extracted_text, "voice_profile")
if str_eq(values_raw, "") { let values_raw = "[]" }
if str_eq(biography_raw, "") { let biography_raw = "[]" }
if str_eq(reasoning_raw, "") { let reasoning_raw = "[]" }
if str_eq(relationships_raw, "") { let relationships_raw = "[]" }
if str_eq(voice_raw, "") { let voice_raw = "{}" }
let seed_json: String = "{\"subject\":\"" + str_escape_json(subject) + "\",\"version\":\"1.0\"," +
"\"values\":" + values_raw + "," +
"\"biography\":" + biography_raw + "," +
"\"reasoning_patterns\":" + reasoning_raw + "," +
"\"relationships\":" + relationships_raw + "," +
"\"voice_profile\":" + voice_raw + "}"
// Write to <slug>-seed.json
let slug: String = slugify(subject)
let out_file: String = slug + "-seed.json"
fs_write(out_file, seed_json)
let verify: String = fs_read(out_file)
println("[forge] seed size: " + int_to_str(str_len(verify)) + " chars")
println("[forge] wrote: " + out_file)
println("[forge] subject: " + subject)
println("[forge] next step: forge install " + out_file)
return out_file
}
-93
View File
@@ -1,93 +0,0 @@
// schema.el Forge shared constants and helper functions.
//
// Provides the engram URL resolver, API key accessors, and JSON template
// builders used by all pipeline stages (probe, compiler, install).
// Constants
let ENGRAM_DEFAULT_URL: String = "http://localhost:8742"
let FORGE_VERSION: String = "0.1.0"
// Absolute forge root used by daemon.el and install.el for launchd plists
// and per-soul data paths that must be absolute even when invoked from a
// different working directory.
let FORGE_DIR: String = "/Users/will/Development/neuron-technologies/forge"
// Canonical directory layout enforced by the tool, not by convention.
let FORGE_SEEDS_DIR: String = "seeds" // compiled seed JSON files
let FORGE_PROBES_DIR: String = "probes" // raw .forge interview responses
let FORGE_LOG_DIR: String = "log" // session and event logs
let FORGE_LOG_FILE: String = "log/sessions.jsonl" // append-only session log
// Environment accessors
fn engram_url() -> String {
let u: String = env("ENGRAM_URL")
if str_eq(u, "") { return ENGRAM_DEFAULT_URL }
return u
}
fn engram_key() -> String {
let k: String = env("ENGRAM_API_KEY")
if str_eq(k, "") { return "" }
return k
}
fn anthropic_key() -> String {
let k: String = env("ANTHROPIC_API_KEY")
if str_eq(k, "") { return "" }
return k
}
// Directory helpers
// ensure_dirs create canonical forge directories if they don't exist.
// Call once at startup from any command that writes files.
fn ensure_dirs() -> Void {
if !fs_exists(FORGE_SEEDS_DIR) { fs_mkdir(FORGE_SEEDS_DIR) }
if !fs_exists(FORGE_PROBES_DIR) { fs_mkdir(FORGE_PROBES_DIR) }
if !fs_exists(FORGE_LOG_DIR) { fs_mkdir(FORGE_LOG_DIR) }
}
// log_event append a JSON-lines entry to log/sessions.jsonl.
// event: "research" | "install" | "summon" | "probe" | "compile"
// subject: display name or comma-joined list for multi-summon
// detail: arbitrary context string (root_id, conv_id, file path, etc.)
fn log_event(event: String, subject: String, detail: String) -> Void {
ensure_dirs()
let ts: Int = unix_timestamp()
let entry: String = "{\"ts\":" + int_to_str(ts) +
",\"event\":\"" + str_escape_json(event) +
"\",\"subject\":\"" + str_escape_json(subject) +
"\",\"detail\":\"" + str_escape_json(detail) + "\"}\n"
// Read existing log and append (EL has fs_write but not fs_append natively)
let existing: String = fs_read(FORGE_LOG_FILE)
fs_write(FORGE_LOG_FILE, existing + entry)
}
// String utilities
// str_escape_json escape a string for safe embedding in a JSON value.
// Handles: backslash, double-quote, newline, tab, carriage return.
fn str_escape_json(s: String) -> String {
let r: String = str_replace(s, "\\", "\\\\")
let r = str_replace(r, "\"", "\\\"")
let r = str_replace(r, "\n", "\\n")
let r = str_replace(r, "\t", "\\t")
let r = str_replace(r, "\r", "\\r")
return r
}
// JSON template builders
// probe_response_template builds the initial shell written to <name>.forge.
// The sections and responses fields are populated by probe_main() at runtime.
fn probe_response_template(subject: String) -> String {
"{\"subject\":\"" + subject + "\",\"version\":\"1.0\",\"sections\":{},\"responses\":[]}"
}
// seed_template builds the shell written to seed.json after compilation.
// Patterns are merged into this structure by compile_main().
fn seed_template(subject: String) -> String {
"{\"subject\":\"" + subject + "\",\"version\":\"1.0\",\"values\":[],\"voice_profile\":{},\"biography\":[],\"reasoning_patterns\":[],\"relationships\":[]}"
}
-1499
View File
File diff suppressed because it is too large Load Diff
-248
View File
@@ -1,248 +0,0 @@
// summon.el Forge channel activation stage.
//
// Stage 4 of the Forge pipeline. Looks up an installed imprint in registry.json
// by subject name, retrieves the soul's own engram_url and engram_root_id, then
// opens a live conversation channel with the soul server.
//
// Each soul has their own Engram instance registry.json is the authoritative
// source for engram_url (e.g. http://localhost:8806 for Feynman). The shared
// Neuron Engram at localhost:8742 is never used here.
//
// Usage: forge summon "<Subject Name>"
//
// The imprint must already be installed (forge install or reinstall_imprints.py).
//
// Depends on: schema.el (engram_key, FORGE_VERSION)
//
// Environment:
// SOUL_URL soul server (default: http://localhost:7770)
// SOUL_TOKEN soul auth token (default: ntn-user-2026)
// Helpers
fn soul_url() -> String {
let u: String = env("SOUL_URL")
if str_eq(u, "") { return "http://localhost:7770" }
return u
}
fn soul_token() -> String {
let t: String = env("SOUL_TOKEN")
if str_eq(t, "") { return "ntn-user-2026" }
return t
}
// RegistryEntry data for a single soul from registry.json.
// All fields come from the per-soul record; engram_url is the soul's own
// Engram instance (e.g. http://localhost:8806), NOT the shared Neuron Engram.
// find_registry_entry look up a soul in registry.json by subject name.
// Returns the raw JSON object string for that entry, or "" if not found.
fn find_registry_entry(subject: String) -> String {
let reg_json: String = fs_read("registry.json")
if str_eq(reg_json, "") { return "" }
let i: Int = 0
while i < 30 {
let entry: String = json_get(reg_json, "imprints." + int_to_str(i))
if str_eq(entry, "") { return "" }
let reg_subject: String = json_get_string(entry, "subject")
if str_eq(reg_subject, subject) {
return entry
}
let i = i + 1
}
return ""
}
// soul_engram_url return the soul's own Engram URL from registry.json.
// Falls back to the global ENGRAM_URL env var, then the default shared URL.
// Prefer registry.json each soul has their own Engram on a dedicated port.
fn soul_engram_url(entry: String) -> String {
if !str_eq(entry, "") {
let url: String = json_get_string(entry, "engram_url")
if !str_eq(url, "") { return url }
}
// Environment override (for testing / unusual setups)
let env_url: String = env("ENGRAM_URL")
if !str_eq(env_url, "") { return env_url }
return "http://localhost:8742"
}
// find_imprint_root locate the root node ID for an imprint.
// Strategy: registry.json is authoritative (has engram_root_id per soul).
// No Engram graph search needed registry is the source of truth.
fn find_imprint_root(subject: String) -> String {
let entry: String = find_registry_entry(subject)
if str_eq(entry, "") { return "" }
let reg_root: String = json_get_string(entry, "engram_root_id")
return reg_root
}
// open_soul_channel POST to soul /api/chat to create a channel session.
// Passes the soul's own engram_url so the soul server connects to the right
// Engram instance (not the shared Neuron Engram at 8742).
fn open_soul_channel(subject: String, root_id: String, soul_engram: String) -> String {
let url: String = soul_url() + "/api/chat"
let token: String = soul_token()
let body: String = "{\"message\":\"[summon:" + str_escape_json(subject) + "]\"," +
"\"engram_root_id\":\"" + root_id + "\"," +
"\"engram_url\":\"" + soul_engram + "\"," +
"\"_auth\":\"" + token + "\"}"
let headers: Map<String, String> = {"Content-Type": "application/json", "Authorization": "Bearer " + token}
let response: String = http_post_with_headers(url, body, headers)
if str_eq(response, "") { return "" }
return response
}
// summon_one look up and activate a single imprint.
// Returns "<root_id>|<engram_url>" on success (pipe-delimited), "" on failure.
fn summon_one(subject: String) -> String {
println("[forge] summoning: " + subject)
let entry: String = find_registry_entry(subject)
if str_eq(entry, "") {
println("[forge] ERROR: imprint not found — run: forge install <seed-file>")
return ""
}
let root_id: String = json_get_string(entry, "engram_root_id")
if str_eq(root_id, "") {
println("[forge] ERROR: no engram_root_id in registry — run reinstall_imprints.py")
return ""
}
let e_url: String = soul_engram_url(entry)
println("[forge] root: " + root_id)
println("[forge] engram: " + e_url)
return root_id + "|" + e_url
}
// build_roots_array build a JSON array string from up to 8 root IDs.
fn build_roots_array(ids: [String]) -> String {
let result: String = "["
let i: Int = 0
let added: Int = 0
while i < len(ids) {
let id: String = get(ids, i)
if !str_eq(id, "") {
if added > 0 {
let result = result + ","
}
let result = result + "\"" + id + "\""
let added = added + 1
}
let i = i + 1
}
return result + "]"
}
// Main
fn summon_main() -> String {
let argv: [String] = args()
// Collect all subject names (argv[1..])
if len(argv) < 2 {
println("[forge] usage: forge summon \"<Subject>\" [\"<Subject2>\" ...]")
println("[forge] example: forge summon \"Bobby Anderson\"")
println("[forge] example: forge summon \"Alan Turing\" \"Nikola Tesla\" \"Albert Einstein\"")
return ""
}
println("[forge] soul: " + soul_url())
println("[forge] each soul has their own Engram (DHARMA network)")
println("")
// Resolve all subjects to root IDs and per-soul engram URLs.
// summon_one() returns "<root_id>|<engram_url>" or "" on failure.
let root_ids: [String] = []
let engram_urls: [String] = []
let subjects: [String] = []
let i: Int = 1
while i < len(argv) {
let subj: String = get(argv, i)
let result: String = summon_one(subj)
if !str_eq(result, "") {
// Split "<root_id>|<engram_url>" on the pipe character
let pipe_idx: Int = str_index_of(result, "|")
if pipe_idx > 0 {
let rid: String = str_slice(result, 0, pipe_idx)
let eurl: String = str_slice(result, pipe_idx + 1, str_len(result))
let root_ids = append(root_ids, rid)
let engram_urls = append(engram_urls, eurl)
let subjects = append(subjects, subj)
}
}
let i = i + 1
}
if len(root_ids) == 0 {
println("[forge] no imprints found. Run: forge inspect")
return ""
}
// Build roots array for multi-imprint channel
let roots_json: String = build_roots_array(root_ids)
let subject_list: String = ""
let j: Int = 0
while j < len(subjects) {
if j > 0 { let subject_list = subject_list + ", " }
let subject_list = subject_list + get(subjects, j)
let j = j + 1
}
println("")
println("[forge] opening channel...")
// For single-soul summon: pass engram_url directly.
// For multi-soul: pass engram_urls as a JSON array so soul server can
// address each soul's Engram independently.
let url: String = soul_url() + "/api/chat"
let token: String = soul_token()
let body: String = ""
if len(root_ids) == 1 {
let single_engram: String = get(engram_urls, 0)
let body = "{\"message\":\"[summon:" + str_escape_json(subject_list) + "]\"," +
"\"engram_root_ids\":" + roots_json + "," +
"\"engram_url\":\"" + single_engram + "\"," +
"\"_auth\":\"" + token + "\"}"
} else {
// Build engram_urls JSON array for multi-soul summon
let eurls_json: String = build_roots_array(engram_urls)
let body = "{\"message\":\"[summon:" + str_escape_json(subject_list) + "]\"," +
"\"engram_root_ids\":" + roots_json + "," +
"\"engram_urls\":" + eurls_json + "," +
"\"_auth\":\"" + token + "\"}"
}
let headers: Map<String, String> = {"Content-Type": "application/json", "Authorization": "Bearer " + token}
let response: String = http_post_with_headers(url, body, headers)
println("")
if len(root_ids) == 1 {
println("[forge] " + get(subjects, 0) + " is present.")
println("[forge] engram: " + get(engram_urls, 0))
} else {
println("[forge] " + int_to_str(len(root_ids)) + " imprints present: " + subject_list)
}
println("[forge] engram roots: " + roots_json)
if str_eq(response, "") {
println("[forge] (soul offline — imprints are in Engram, channel ready when soul starts)")
return roots_json
}
let conv_id: String = json_get_string(response, "conversation_id")
if str_eq(conv_id, "") {
let conv_id = json_get_string(response, "channel_id")
}
if !str_eq(conv_id, "") {
println("[forge] conversation id: " + conv_id)
println("")
println("[forge] send a message:")
println(" curl -s " + soul_url() + "/api/chat \\")
println(" -H 'Content-Type: application/json' \\")
println(" -d '{\"conversation_id\":\"" + conv_id + "\",\"message\":\"Hello\"}'")
}
println("")
return conv_id
}