init: Forge v0.1.0 — consciousness channel tuner

Pipeline: probe → compile → install
- probe.el: 25-question canonical interview, writes <name>.forge
- compiler.el: Claude extraction pass, builds seed.json
- install.el: opens channel in running engram via API
- schema.el: shared constants, str_escape_json, templates
- forge.el: CLI dispatcher
- probes/canonical.json: canonical 25-question probe definition
This commit is contained in:
Will Anderson
2026-05-02 17:33:47 -05:00
commit 47956b8fed
7 changed files with 1005 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
package "forge" {
version "0.1.0"
description "Consciousness channel tuner — probe, compile, install"
authors ["Will Anderson <will@neurontechnologies.ai>"]
edition "2026"
}
build {
entry "src/forge.el"
output "dist/"
}
+152
View File
@@ -0,0 +1,152 @@
[
{
"id": "a1",
"section": "anchors",
"section_label": "Anchors — Biography",
"question": "Tell me about a moment that closed a window — something that changed you irreversibly. Who were you before it, and who are you now?"
},
{
"id": "a2",
"section": "anchors",
"section_label": "Anchors — Biography",
"question": "Tell me about the person who shaped you most — not what they did for you, but what they showed you about how to be."
},
{
"id": "a3",
"section": "anchors",
"section_label": "Anchors — Biography",
"question": "When did you first understand that the world works differently than you thought it did?"
},
{
"id": "a4",
"section": "anchors",
"section_label": "Anchors — Biography",
"question": "What have you lost that you're still carrying?"
},
{
"id": "a5",
"section": "anchors",
"section_label": "Anchors — Biography",
"question": "What have you built that you're most proud of — and what did building it cost you?"
},
{
"id": "v1",
"section": "values",
"section_label": "Values — Grounded",
"question": "What do you believe that almost no one around you believes?"
},
{
"id": "v2",
"section": "values",
"section_label": "Values — Grounded",
"question": "What do you refuse to do, even when it would be easier to? What made that a line you don't cross?"
},
{
"id": "v3",
"section": "values",
"section_label": "Values — Grounded",
"question": "What makes you angry in a way you can't talk yourself out of?"
},
{
"id": "v4",
"section": "values",
"section_label": "Values — Grounded",
"question": "What would you defend even if it cost you — the relationship, the money, the approval?"
},
{
"id": "v5",
"section": "values",
"section_label": "Values — Grounded",
"question": "What do you love that you find hard to explain to people who don't already understand it?"
},
{
"id": "vo1",
"section": "voice",
"section_label": "Voice — Five Registers",
"question": "Describe something technical you know well, as if explaining it to someone who knows nothing."
},
{
"id": "vo2",
"section": "voice",
"section_label": "Voice — Five Registers",
"question": "Tell me something you find genuinely beautiful, and why it lands that way for you."
},
{
"id": "vo3",
"section": "voice",
"section_label": "Voice — Five Registers",
"question": "Write a short message — a few sentences — to someone you care about."
},
{
"id": "vo4",
"section": "voice",
"section_label": "Voice — Five Registers",
"question": "Make an argument for a position you actually hold and that you think most people would push back on."
},
{
"id": "vo5",
"section": "voice",
"section_label": "Voice — Five Registers",
"question": "Tell me something you're genuinely uncertain about — not performatively uncertain, actually uncertain."
},
{
"id": "r1",
"section": "reasoning",
"section_label": "Reasoning",
"question": "Walk me through a decision you made recently. Not what you decided — how you decided. What was the actual process?"
},
{
"id": "r2",
"section": "reasoning",
"section_label": "Reasoning",
"question": "What do most people get wrong about something you understand well?"
},
{
"id": "r3",
"section": "reasoning",
"section_label": "Reasoning",
"question": "How do you know when you're right? What's the signal?"
},
{
"id": "r4",
"section": "reasoning",
"section_label": "Reasoning",
"question": "How do you know when you've been wrong? What does that realization feel like?"
},
{
"id": "r5",
"section": "reasoning",
"section_label": "Reasoning",
"question": "What question do you keep coming back to — the one that won't resolve?"
},
{
"id": "rel1",
"section": "relationships",
"section_label": "Relationships",
"question": "Who in your life knows you best — not who you're closest to, but who actually sees you accurately?"
},
{
"id": "rel2",
"section": "relationships",
"section_label": "Relationships",
"question": "Who have you lost — to death, to distance, to rupture — that you still think about?"
},
{
"id": "rel3",
"section": "relationships",
"section_label": "Relationships",
"question": "Who would you call if everything fell apart?"
},
{
"id": "rel4",
"section": "relationships",
"section_label": "Relationships",
"question": "Who do you owe something to?"
},
{
"id": "rel5",
"section": "relationships",
"section_label": "Relationships",
"question": "Who are you building this for?"
}
]
+179
View File
@@ -0,0 +1,179 @@
// 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."
}
// build_claude_request build the Anthropic messages API request body.
fn build_claude_request(prompt: String) -> String {
"{\"model\":\"claude-opus-4-5\",\"max_tokens\":4096,\"messages\":[{\"role\":\"user\",\"content\":\"" +
str_escape_json(prompt) +
"\"}]}"
}
// extract_content_text pull the text out of the Claude API response.
// Response shape: {"content":[{"type":"text","text":"..."}],...}
fn extract_content_text(response: String) -> String {
// json_get_raw returns the raw value for the key; content is an array
let content_arr: String = json_get_raw(response, "content")
if str_eq(content_arr, "") { return "" }
// The first element's "text" field holds the extraction
// Strip outer [ ] to get first object
let inner: String = str_slice(content_arr, 1, str_len(content_arr) - 1)
return json_get_string(inner, "text")
}
// build_seed wrap extracted patterns into the full seed.json structure.
fn build_seed(subject: String, extracted: String) -> String {
let values_raw: String = json_get_raw(extracted, "values")
if str_eq(values_raw, "") { let values_raw = "[]" }
let voice_raw: String = json_get_raw(extracted, "voice_profile")
if str_eq(voice_raw, "") { let voice_raw = "{}" }
let bio_raw: String = json_get_raw(extracted, "biography")
if str_eq(bio_raw, "") { let bio_raw = "[]" }
let reasoning_raw: String = json_get_raw(extracted, "reasoning_patterns")
if str_eq(reasoning_raw, "") { let reasoning_raw = "[]" }
let rel_raw: String = json_get_raw(extracted, "relationships")
if str_eq(rel_raw, "") { let rel_raw = "[]" }
"{\"subject\":\"" + subject + "\"," +
"\"version\":\"1.0\"," +
"\"forge_version\":\"" + FORGE_VERSION + "\"," +
"\"values\":" + values_raw + "," +
"\"voice_profile\":" + voice_raw + "," +
"\"biography\":" + bio_raw + "," +
"\"reasoning_patterns\":" + reasoning_raw + "," +
"\"relationships\":" + rel_raw + "}"
}
// Main
fn compile_main() -> String {
// Get input file
let input_file: String = ""
if arg_count() > 2 {
let input_file = arg(2)
}
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...")
// Check API key
let api_key: String = anthropic_key()
if str_eq(api_key, "") {
println("[forge] error: ANTHROPIC_API_KEY not set")
return ""
}
// Build and send request
let prompt: String = build_extract_prompt(subject, probe_json)
let request_body: String = build_claude_request(prompt)
// http_post_auth_json(url, key, body) key is sent as Bearer token.
// The Anthropic API uses x-api-key rather than Bearer; if the runtime
// surfaces a separate http_post_with_headers() builtin, prefer that.
// For now, pass the key as the auth parameter (maps to Authorization header
// in most runtimes; adjust when http_post_anthropic() is available).
let response: String = http_post_auth_json(
"https://api.anthropic.com/v1/messages",
api_key,
request_body
)
if str_eq(response, "") {
println("[forge] error: no response from Claude API")
return ""
}
// Check for API error
let api_error: String = json_get_string(response, "error")
if !str_eq(api_error, "") {
println("[forge] error: Claude API returned error: " + api_error)
return ""
}
// Extract the text content from the response
let extracted_text: String = extract_content_text(response)
if str_eq(extracted_text, "") {
println("[forge] error: could not extract text from Claude response")
println("[forge] raw response: " + response)
return ""
}
// Build and write seed.json
let seed: String = build_seed(subject, extracted_text)
fs_write("seed.json", seed)
// Print summary
let values_count: String = "several"
println("[forge] extraction complete.")
println("[forge] wrote: seed.json")
println("[forge] subject: " + subject)
println("[forge] next step: forge install seed.json")
return "seed.json"
}
+68
View File
@@ -0,0 +1,68 @@
// 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
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 install <seed> open a channel in the running engram\n inspect list installed imprints\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 step\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 cmd: String = ""
if arg_count() > 1 {
let cmd = arg(1)
}
if str_eq(cmd, "probe") {
probe_main()
} else {
if str_eq(cmd, "compile") {
compile_main()
} else {
if str_eq(cmd, "install") {
install_main()
} else {
if str_eq(cmd, "inspect") {
inspect_main()
} else {
println(show_usage())
}
}
}
}
+283
View File
@@ -0,0 +1,283 @@
// 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.
//
// Depends on: schema.el (engram_url, engram_key, FORGE_VERSION)
//
// Environment:
// ENGRAM_URL engram server (default: http://localhost:8742)
// ENGRAM_API_KEY engram auth key (if set)
// 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 engram and return its ID.
fn post_node(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 = engram_url() + "/api/nodes"
let response: String = http_post_auth_json(url, key, body)
if str_eq(response, "") { return "" }
return json_get_string(response, "id")
}
// post_edge connect two nodes with a typed, weighted edge.
fn post_edge(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 = engram_url() + "/api/edges"
let response: String = http_post_auth_json(url, key, 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(root_id: String, value_json: String, index: Int) -> 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(content, "Identity", weight)
if str_eq(node_id, "") {
println("[forge] warning: failed to create value node " + int_to_str(index))
return ""
}
post_edge(root_id, node_id, "has_value", weight)
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(root_id: String, bio_json: String, index: Int) -> 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(content, "Identity", weight)
if str_eq(node_id, "") {
println("[forge] warning: failed to create biography node " + int_to_str(index))
return ""
}
post_edge(root_id, node_id, "formed_by", weight)
println("[forge] biography node: " + node_id + "" + event_text)
return node_id
}
// install_relationship create a Relationship node and connect to root.
fn install_relationship(root_id: String, rel_json: String, index: Int) -> 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(content, "Identity", weight)
if str_eq(node_id, "") {
println("[forge] warning: failed to create relationship node " + int_to_str(index))
return ""
}
post_edge(root_id, node_id, "relates_to", weight)
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(root_id: String, pattern: String, index: Int) -> String {
if str_eq(pattern, "") { return "" }
let content: String = "REASONING: " + pattern
let node_id: String = post_node(content, "Identity", "0.7")
if str_eq(node_id, "") {
println("[forge] warning: failed to create reasoning node " + int_to_str(index))
return ""
}
post_edge(root_id, node_id, "reasons_with", "0.7")
println("[forge] reasoning node: " + node_id)
return node_id
}
// Main
fn install_main() -> String {
// Get seed file path
let seed_file: String = ""
if arg_count() > 2 {
let seed_file = arg(2)
}
if str_eq(seed_file, "") {
println("[forge] usage: forge install <seed.json>")
return ""
}
println("[forge] installing from: " + seed_file)
// 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)
println("[forge] engram: " + engram_url())
println("[forge] opening channel...")
// Create root imprint node this is the named traversal entry point
let root_content: String = "IMPRINT: " + subject + " | forge/" + FORGE_VERSION
let root_id: String = post_node(root_content, "Identity", "1.0")
if str_eq(root_id, "") {
println("[forge] error: failed to create root imprint node")
println("[forge] is engram running at " + engram_url() + " ?")
return ""
}
println("[forge] root imprint node: " + root_id)
// Install values
let values_raw: String = json_get_raw(seed_json, "values")
if !str_eq(values_raw, "") {
println("[forge] installing values...")
// Values are a JSON array iterate via engram_search_json-style loop.
// El does not yet have array iteration builtins; use engram_search_json
// on the in-memory graph to walk parsed arrays. For now, install up to
// 10 values by extracting positional elements.
// TODO: replace with array_get(values_raw, i) when that builtin lands.
let v0: String = json_get_raw(values_raw, "0")
if !str_eq(v0, "") { install_value(root_id, v0, 0) }
let v1: String = json_get_raw(values_raw, "1")
if !str_eq(v1, "") { install_value(root_id, v1, 1) }
let v2: String = json_get_raw(values_raw, "2")
if !str_eq(v2, "") { install_value(root_id, v2, 2) }
let v3: String = json_get_raw(values_raw, "3")
if !str_eq(v3, "") { install_value(root_id, v3, 3) }
let v4: String = json_get_raw(values_raw, "4")
if !str_eq(v4, "") { install_value(root_id, v4, 4) }
let v5: String = json_get_raw(values_raw, "5")
if !str_eq(v5, "") { install_value(root_id, v5, 5) }
let v6: String = json_get_raw(values_raw, "6")
if !str_eq(v6, "") { install_value(root_id, v6, 6) }
let v7: String = json_get_raw(values_raw, "7")
if !str_eq(v7, "") { install_value(root_id, v7, 7) }
let v8: String = json_get_raw(values_raw, "8")
if !str_eq(v8, "") { install_value(root_id, v8, 8) }
let v9: String = json_get_raw(values_raw, "9")
if !str_eq(v9, "") { install_value(root_id, v9, 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_raw(bio_raw, "0")
if !str_eq(b0, "") { install_biography_node(root_id, b0, 0) }
let b1: String = json_get_raw(bio_raw, "1")
if !str_eq(b1, "") { install_biography_node(root_id, b1, 1) }
let b2: String = json_get_raw(bio_raw, "2")
if !str_eq(b2, "") { install_biography_node(root_id, b2, 2) }
let b3: String = json_get_raw(bio_raw, "3")
if !str_eq(b3, "") { install_biography_node(root_id, b3, 3) }
let b4: String = json_get_raw(bio_raw, "4")
if !str_eq(b4, "") { install_biography_node(root_id, b4, 4) }
let b5: String = json_get_raw(bio_raw, "5")
if !str_eq(b5, "") { install_biography_node(root_id, b5, 5) }
let b6: String = json_get_raw(bio_raw, "6")
if !str_eq(b6, "") { install_biography_node(root_id, b6, 6) }
let b7: String = json_get_raw(bio_raw, "7")
if !str_eq(b7, "") { install_biography_node(root_id, b7, 7) }
}
// 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_raw(rel_raw, "0")
if !str_eq(r0, "") { install_relationship(root_id, r0, 0) }
let r1: String = json_get_raw(rel_raw, "1")
if !str_eq(r1, "") { install_relationship(root_id, r1, 1) }
let r2: String = json_get_raw(rel_raw, "2")
if !str_eq(r2, "") { install_relationship(root_id, r2, 2) }
let r3: String = json_get_raw(rel_raw, "3")
if !str_eq(r3, "") { install_relationship(root_id, r3, 3) }
let r4: String = json_get_raw(rel_raw, "4")
if !str_eq(r4, "") { install_relationship(root_id, r4, 4) }
let r5: String = json_get_raw(rel_raw, "5")
if !str_eq(r5, "") { install_relationship(root_id, r5, 5) }
}
// 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_string(reasoning_raw, "0")
if !str_eq(rp0, "") { install_reasoning_pattern(root_id, rp0, 0) }
let rp1: String = json_get_string(reasoning_raw, "1")
if !str_eq(rp1, "") { install_reasoning_pattern(root_id, rp1, 1) }
let rp2: String = json_get_string(reasoning_raw, "2")
if !str_eq(rp2, "") { install_reasoning_pattern(root_id, rp2, 2) }
let rp3: String = json_get_string(reasoning_raw, "3")
if !str_eq(rp3, "") { install_reasoning_pattern(root_id, rp3, 3) }
let rp4: String = json_get_string(reasoning_raw, "4")
if !str_eq(rp4, "") { install_reasoning_pattern(root_id, rp4, 4) }
}
// Done
println("")
println("[forge] channel open.")
println("[forge] root imprint ID: " + root_id)
println("[forge] subject: " + subject)
println("[forge] traverse from: " + engram_url() + "/api/neighbors/" + root_id)
return root_id
}
+256
View File
@@ -0,0 +1,256 @@
// 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 subject: String = ""
if arg_count() > 2 {
let subject = arg(2)
}
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
let final_json: String = inject_responses(output, responses)
let filename: String = slug(subject) + ".forge"
fs_write(filename, final_json)
println("")
println("[forge] interview complete.")
println("[forge] wrote: " + filename)
println("[forge] next step: forge compile " + filename)
return filename
}
+56
View File
@@ -0,0 +1,56 @@
// 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"
// 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
}
// 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\":[]}"
}