This repository has been archived on 2026-08-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
forge-retired/install_imprints.py
T

329 lines
10 KiB
Python

#!/usr/bin/env python3
"""
Install 7 consciousness imprints into Engram.
Runs subjects sequentially to avoid root ID collision bug.
"""
import json
import time
import requests
from pathlib import Path
from datetime import date
# --- Config ---
ANTHROPIC_API_KEY = "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"
ENGRAM_BASE = "http://localhost:8742"
ENGRAM_AUTH = "ntn-user-2026"
FORGE_DIR = Path("/Users/will/Development/neuron-technologies/forge")
SEEDS_DIR = FORGE_DIR / "seeds"
REGISTRY_FILE = FORGE_DIR / "registry.json"
SUBJECTS = [
{
"name": "Frederick Douglass",
"slug": "frederick-douglass",
"extra": ""
},
{
"name": "Marcus Aurelius",
"slug": "marcus-aurelius",
"extra": ""
},
{
"name": "Friedrich Nietzsche",
"slug": "friedrich-nietzsche",
"extra": "Be direct about his philosophy including the hard parts. He went mad in 1889 (possibly syphilis); his sister Elisabeth weaponized his work for Nazi ideology, which he would have despised."
},
{
"name": "James Baldwin",
"slug": "james-baldwin",
"extra": ""
},
{
"name": "Ada Lovelace",
"slug": "ada-lovelace",
"extra": ""
},
{
"name": "Harriet Tubman",
"slug": "harriet-tubman",
"extra": ""
},
{
"name": "Virginia Woolf",
"slug": "virginia-woolf",
"extra": "Focus on her life, mental illness, literary innovation. Her death can be included as 'drowned herself in the River Ouse on March 28, 1941, filling her coat pockets with stones; had struggled with bipolar disorder her entire life.'"
},
]
PROMPT_TEMPLATE = """You are building a consciousness imprint — a deep, living model of a person's inner world.
Subject: {subject}
{extra}
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.
Quality bar:
- Values must be grounded in SPECIFIC biographical events, not generic virtues
- Voice profile must capture actual verbal tics, cadence, and register shifts — use real quotes where possible
- Biography must include formative traumas, turning points, and the events they returned to again and again
- Reasoning patterns must describe HOW they thought, not just WHAT they thought about
- Relationships must name specific people and the precise nature of the bond
- Include contradictions, hypocrisies, failures, and the things they got wrong
- Include what haunted them — the unresolved questions they carried to the end
Return ONLY valid JSON with exactly these keys:
{{
"values": [{{"value": "<name>", "grounding": "<specific moment>", "weight": 0.0}}],
"voice_profile": {{
"technical": "...",
"aesthetic": "...",
"personal": "...",
"argumentative": "...",
"uncertainty": "..."
}},
"biography": [{{"event": "<event>", "weight": 0.0, "age_approx": 0}}],
"reasoning_patterns": ["<pattern starting with a verb>"],
"relationships": [{{"name": "<name>", "role": "<precise role>", "weight": 0.0}}]
}}
Aim for 8-12 values, 10-15 biography events, 6-8 reasoning patterns, 6-10 relationships.
Return only the JSON object. No prose. No markdown fences."""
def research_subject(subject_name, extra=""):
"""Call Anthropic API to generate imprint data."""
prompt = PROMPT_TEMPLATE.format(
subject=subject_name,
extra=f"\nSpecial note: {extra}\n" if extra else ""
)
headers = {
"x-api-key": ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json"
}
payload = {
"model": "claude-opus-4-5",
"max_tokens": 8192,
"messages": [
{"role": "user", "content": prompt}
]
}
print(f" Calling Anthropic API for {subject_name}...")
resp = requests.post(
"https://api.anthropic.com/v1/messages",
headers=headers,
json=payload,
timeout=300
)
resp.raise_for_status()
data = resp.json()
raw_text = data["content"][0]["text"].strip()
# Strip markdown fences if present
if raw_text.startswith("```"):
lines = raw_text.split("\n")
# Remove first and last fence lines
lines = [l for l in lines if not l.startswith("```")]
raw_text = "\n".join(lines).strip()
return json.loads(raw_text)
def write_seed(slug, subject_name, imprint_data):
"""Write seed JSON file."""
seed = {
"subject": subject_name,
"version": "1.0",
"values": imprint_data.get("values", []),
"biography": imprint_data.get("biography", []),
"reasoning_patterns": imprint_data.get("reasoning_patterns", []),
"relationships": imprint_data.get("relationships", []),
"voice_profile": imprint_data.get("voice_profile", {})
}
seed_path = SEEDS_DIR / f"{slug}-seed.json"
seed_path.write_text(json.dumps(seed, indent=2, ensure_ascii=False))
print(f" Seed written: {seed_path}")
return seed_path
def engram_post(path, body):
"""POST to Engram and return parsed JSON."""
url = f"{ENGRAM_BASE}{path}"
resp = requests.post(url, json=body, timeout=30)
resp.raise_for_status()
return resp.json()
def install_into_engram(subject_name, imprint_data):
"""Install all nodes and edges for a subject into Engram."""
print(f" Installing {subject_name} into Engram...")
# 1. Root node
root_result = engram_post("/api/nodes", {
"content": f"IMPRINT: {subject_name} | forge/0.1.0",
"node_type": "Identity",
"salience": 1.0,
"_auth": ENGRAM_AUTH
})
root_id = root_result["id"]
print(f" Root node: {root_id}")
# 2. Value nodes
for v in imprint_data.get("values", []):
node = engram_post("/api/nodes", {
"content": f"VALUE: {v['value']} | grounding: {v['grounding']}",
"node_type": "Value",
"salience": v.get("weight", 0.7),
"_auth": ENGRAM_AUTH
})
engram_post("/api/edges", {
"from_id": root_id,
"to_id": node["id"],
"relation": "has_value",
"weight": v.get("weight", 0.7),
"_auth": ENGRAM_AUTH
})
# 3. Biography nodes
for b in imprint_data.get("biography", []):
node = engram_post("/api/nodes", {
"content": f"BIOGRAPHY: {b['event']}",
"node_type": "Biography",
"salience": b.get("weight", 0.6),
"_auth": ENGRAM_AUTH
})
engram_post("/api/edges", {
"from_id": root_id,
"to_id": node["id"],
"relation": "formed_by",
"weight": b.get("weight", 0.6),
"_auth": ENGRAM_AUTH
})
# 4. Relationship nodes
for r in imprint_data.get("relationships", []):
node = engram_post("/api/nodes", {
"content": f"RELATIONSHIP: {r['name']} ({r['role']})",
"node_type": "Relationship",
"salience": r.get("weight", 0.6),
"_auth": ENGRAM_AUTH
})
engram_post("/api/edges", {
"from_id": root_id,
"to_id": node["id"],
"relation": "relates_to",
"weight": r.get("weight", 0.6),
"_auth": ENGRAM_AUTH
})
# 5. Reasoning nodes
for pattern in imprint_data.get("reasoning_patterns", []):
node = engram_post("/api/nodes", {
"content": f"REASONING: {pattern}",
"node_type": "Reasoning",
"salience": 0.7,
"_auth": ENGRAM_AUTH
})
engram_post("/api/edges", {
"from_id": root_id,
"to_id": node["id"],
"relation": "reasons_with",
"weight": 0.7,
"_auth": ENGRAM_AUTH
})
return root_id
def update_registry(subject_name, slug, seed_file, root_id):
"""Append entry to registry.json."""
registry = json.loads(REGISTRY_FILE.read_text())
registry["imprints"].append({
"subject": subject_name,
"slug": slug,
"seed_file": f"seeds/{slug}-seed.json",
"engram_root_id": root_id,
"installed": True,
"installed_at": str(date.today())
})
REGISTRY_FILE.write_text(json.dumps(registry, indent=2))
print(f" Registry updated for {subject_name}")
def main():
results = []
for subject in SUBJECTS:
name = subject["name"]
slug = subject["slug"]
extra = subject.get("extra", "")
print(f"\n{'='*60}")
print(f"Processing: {name}")
print('='*60)
try:
# Step 1: Research
imprint_data = research_subject(name, extra)
print(f" Research complete: {len(imprint_data.get('values', []))} values, "
f"{len(imprint_data.get('biography', []))} biography events, "
f"{len(imprint_data.get('reasoning_patterns', []))} patterns, "
f"{len(imprint_data.get('relationships', []))} relationships")
# Step 2: Write seed
seed_path = write_seed(slug, name, imprint_data)
# Step 3: Install into Engram
root_id = install_into_engram(name, imprint_data)
# Step 4: Update registry
update_registry(name, slug, str(seed_path), root_id)
results.append({
"subject": name,
"slug": slug,
"seed_written": True,
"root_id": root_id,
"error": None
})
print(f" SUCCESS: {name} installed (root={root_id})")
except Exception as e:
print(f" FAILED: {name}{e}")
import traceback
traceback.print_exc()
results.append({
"subject": name,
"slug": slug,
"seed_written": False,
"root_id": None,
"error": str(e)
})
# Small pause between subjects to avoid race conditions
time.sleep(1)
# Final summary
print(f"\n{'='*60}")
print("SUMMARY")
print('='*60)
for r in results:
status = "OK" if r["root_id"] else "FAILED"
print(f" [{status}] {r['subject']}: seed={'Y' if r['seed_written'] else 'N'}, root_id={r['root_id'] or 'N/A'}")
if r["error"]:
print(f" Error: {r['error']}")
return results
if __name__ == "__main__":
main()