~226 lines of architecture documentation that were written, left uncommitted in the working tree, and nearly lost. None of it was on main. Recovered from a stash taken while merging tonight's fixes. Substantive content, not notes: - Peer import-of-understanding PROVEN by execution. A exported a skill-geometry; on the receiver `think` went "geometry unavailable" -> operable. Cosine 1.0 on both the raw-geometry and text/dharma-bus transports, bidirectional. The mind-not-paste evidence: n_support 27 on source vs 3 on receiver, i.e. the imported geometry wires into the host manifold rather than sitting inert. Honest boundary recorded too: proven between forks sharing one embedder, UNTESTED cross-embedder. - "Teacher" renamed GUIDE, and the distinction is load-bearing: its output is grounded/verified before trust. A teacher you believe; a guide you check. - Layers are named persistent relational neighborhoods, not storage tiers, with their own growth and threshold-lock policy (note->canonical maturation lifted from single nodes to a region). - The consciousness theories (Global Workspace, IIT's Phi, attention-schema, higher-order thought, active inference, interoception) read as geometric LENSES over one manifold rather than competing mechanisms. Functional problems fall out; the hard problem explicitly not claimed solved. - Growth is bounded/logistic, not geometric — exponential growth is the cancer shape. Two-rate discipline: explore fast in local geometry, grow the engram slowly by verifier-gated merge. - Orchestration as a geometric operation: critical path as geodesic, float as displacement, @manager compiles the work-graph. Single-writer enforced by capability (Rule 4). - The decorated seam, the API surface collapse to geometry ops, and the distributed-self thesis — each tiered honestly against what is actually proven vs staged vs unbuilt. Also gitignores dist-fresh/ (regenerate scratch dir, a build artifact). Not included from the same stash: awareness.elh and dist/elp-c-decls.h, which are generated artifacts now gitignored per #154/#158.
11 KiB
Neuron — Runtime & Deployment
Process/port topology, the end-to-end MCP request path, local vs GKE blue/green production, and a high-level view of secrets/config. Grounded in
entrypoint.sh,scripts/blue-green-deploy.sh, the k8s manifests underinfrastructure/platform/k8s/neuron-mcp/, and.gitea/workflows/.
Process & port topology
A running neuron is two processes in one container: the soul and the engram,
started by entrypoint.sh.
container (one pod)
┌──────────────────────────────────────────────────────────┐
│ entrypoint.sh │
│ 1. start engram (background) ── listens :8742 │
│ 2. wait /health up to 60s │
│ 3. exec soul (PID 1 foreground) ── listens :7770 │
│ │
│ soul :7770 ──HTTP──► engram :8742 │
│ (ENGRAM_URL=http://localhost:8742, HTTP mode) │
│ │
│ /data (PVC mount) ◄── engram snapshot.json │
└──────────────────────────────────────────────────────────┘
entrypoint.shstarts engram withENGRAM_BIND=:8742andENGRAM_DATA_DIR=/data, pollshttp://localhost:8742/health(up to 60s; Autopilot cold starts are slow), thenexecs the soul.SOUL_ENGRAM_PATHis deliberately unset soENGRAM_URLtriggers HTTP mode (soul talks to engram over localhost HTTP, not an in-process embed).- EL HTTP runtime is tuned down for co-located calls:
EL_HTTP_TIMEOUT_MS=10000,EL_HTTP_CONNECT_TIMEOUT_MS=3000(entrypoint.sh).
Full port map
| Port | Process | Role | Source |
|---|---|---|---|
| 7779 | mcp-proxy | MCP client entry; byte-forward + retry | mcp-proxy/src/main.el |
| 17779 | mcp-wrapper | MCP JSON-RPC ⇄ soul REST; tool catalog | mcp-wrapper/src/main.el |
| 7770 | soul | HTTP cognitive API + handle_request |
NEURON_PORT, deployment-blue.yaml |
| 8742 | engram | graph store HTTP | entrypoint.sh, server.el:711 |
| 7771 | neuron-connectd | MCP connector bridges | routes.el connectd_* |
Local vs prod, an important distinction. The proxy → wrapper chain is the
local developer adapter: a stdio MCP client (Claude Code) needs to reach an
HTTP soul, so the proxy/wrapper translate and add resilience. In production,
the neuron-mcp Kubernetes Service is a ClusterIP that targets the soul's
:7770 directly (service.yaml) — external access is "to be wired via
Cloudflare Tunnel later" (annotation, same file). So in prod the MCP/HTTP
boundary is the soul's own HTTP surface; the proxy/wrapper are not (yet) in the
cluster path. (inference from the ClusterIP-only Service + the local-only
proxy/wrapper binaries.)
The MCP request path (end to end)
A single tools/call from an MCP client, local topology:
client proxy :7779 wrapper :17779 soul :7770 engram :8742
│ JSON-RPC │ │ │ │
│ tools/call ─────────► │ forward+retry │ │ │
│ │ ─────────────────► │ map tool→REST │ │
│ │ │ ─── HTTP POST ────► │ handle_request │
│ │ │ /api/neuron/... │ → handle_api_* │
│ │ │ │ engram_* builtin │
│ │ │ │ ── (HTTP mode) ───► │ activate/search/
│ │ │ │ │ save
│ │ │ │ ◄─── nodes/edges ── │
│ │ │ ◄── JSON result ── │ │
│ │ │ fire_activation │ │
│ │ │ /recall warm-up ─► soul (side effect) │
│ ◄──── result ──────── │ ◄───────────────── │ │ │
Responsibilities per hop, and the volatility each isolates (VBD reading):
- proxy — transport resilience. Isolates client connection volatility (drops, retries, health) from everything above. No MCP semantics.
- wrapper — protocol translation. Isolates the MCP protocol from the soul:
owns
initialize/tools/list/tools/call, the ~90-tool catalog, anddispatch_tool_call. Also fires thefire_activation/recallside effect so tool use warms working memory. - soul — cognition.
handle_requestdispatch →handle_api_*→ engram builtins. In HTTP mode it reaches engram over localhost; otherwise embedded. - engram — the graph. Spreading activation, Hebbian edges, snapshot persistence.
For the user-facing chat pipeline (not tool calls), /api/chat enters
layered_cycle (soul.el) — L1 safety → L2 stewardship → L3 imprint — described
in 02-components.md §3c.
Production: GKE blue/green
Neuron prod runs on GKE cluster neuron-platform (Autopilot, us-central1),
namespace neuron-prod. Two Deployments, neuron-mcp-blue and
neuron-mcp-green, share one Service selector that names the active slot.
- Deployments (
deployment-blue.yaml/deployment-green.yaml): one containersoul, image pinned by digest (not:latest) so Argo CD can't drift the active slot to an untested build (see the pin comment indeployment-blue.yaml).strategy: Recreate— the PVC is RWO so only one pod can hold it at a time. Probes hit/healthon:7770. - Service (
service.yaml): ClusterIPneuron-mcp, port 7770 → 7770,selector: {app: neuron-mcp, slot: blue}. The blue/green script patchesslot. - Storage (
pvc.yaml):neuron-engram-data,standard-rwo(pd-balanced), 10Gi, RWO. Engram data is the singlesnapshot.json(~8MB active). - The swap (
scripts/blue-green-deploy.sh): (1) set image on the target slot; (2) scale target to 1, wait for rollout; (3) patch the Service selector to the new slot (traffic flip); (4) scale the old slot to 0. Imperativekubectlfor the live swap, then git-update the Argo manifests so a sync doesn't revert replica counts. - Backup (
backup-cronjob.yaml): every 15 min, tar/data→ GCS, keep 96.
Resource sizing (learned the hard way)
deployment-blue.yaml documents the memory history in comments: idle soul RSS
~860Mi; the beginSession call (loads memories + backlog + preferences) spikes
past 1Gi and OOM-killed the pod mid-request (client socket closed). Current
setting: requests = limits = 2Gi, cpu 250m/1000m. This is why the cognitive
API projects/compacts payloads so aggressively (doc 02 §2, doc 01 axis 1) — the
memory ceiling is real and close.
CI/CD
Two Gitea Actions workflows (.gitea/workflows/), serialized on a single GCE
runner (concurrency: neuron-runner).
ci.yaml(push/PR tomain):- build: free disk → checkout → install gcc/libcurl/gcloud → download
el-runtime-c/el-runtime-hfrom Artifact Registryfoundation-prod(elc/elbintentionally not downloaded) → compile the committeddist/soul.cdirectly:cc -O2 -DHAVE_CURL dist/soul.c el_runtime.c -lssl -lcrypto -lcurl -lpthread -lm -o dist/neuron→strip -s→ smoke testdist/neuron --help→ publishneuron-soul@<sha8>to AR (push only). - deploy (push-to-main only): auth GCP →
get-credentials neuron-platform→ determine idle slot (the deployment at 0 replicas) → prepare artifacts (soul binary +elc+ runtime for the Docker build) → clone the engram repo into./engram/(Dockerfile builds engram from source) →docker build+pushneuron-soul:<sha>→scripts/blue-green-deploy.sh --image --slot→ git-push updated infra manifests →kubectl rollout status→ verifyneuron-mcpendpoints.
- build: free disk → checkout → install gcc/libcurl/gcloud → download
deploy-gke.yaml(workflow_dispatchonly, slot defaultgreen) — manual rollback / forced-slot deploy without a rebuild; same auth → slot → docker → blue-green → manifest-sync → verify steps.
The Docker image (Dockerfile) is a two-stage build: stage 1 compiles
engram/src/server.el → engram.c → engram binary via elc + cc; stage 2
is an Ubuntu 24.04 runtime (GLIBC 2.39 satisfies both binaries) with soul +
engram + entrypoint.sh.
Config & secrets (high level)
Runtime configuration is injected as environment, sourced from a Kubernetes
Secret neuron-soul-secrets via ExternalSecret (ESO → GCP Secret Manager,
Workload Identity — no key files). From deployment-blue.yaml:
| Env | Meaning |
|---|---|
NEURON_PORT |
soul HTTP port (7770) |
NEURON_LLM_0_URL / _KEY / _FORMAT |
primary LLM endpoint (Anthropic format) |
SOUL_CGI_ID / SOUL_IDENTITY |
CGI id + identity seed (→ seed_persona_from_env, soul.el:250) |
NEURON_TOKEN |
auth token (present in env; note the HTTP dispatch does not currently check it — doc 01 Divergence 3) |
NEURON_API_URL |
self-callback URL (http://neuron-mcp.neuron-prod.svc.cluster.local:7770) |
ENGRAM_URL / ENGRAM_DATA_DIR |
http://localhost:8742 / /data |
There is also an in-graph config surface: ConfigEntry nodes read/written by
inspect_config / tune_config (neuron-api.el:616-653) — runtime-tunable
persona/behavior keys stored in the engram rather than the environment.
Operational note to flag. The
deployment-blue.yamlimage pin comment (dated Jul 2026) records that:latestresolved to an untested build lacking amem_save/genesis-SIGSEGV fix, which is why the active slot is pinned to a digest. Any promotion must (a) rebuild a good soul and (b) update the digest in git so Argo CD andblue-green-deploy.shagree. (state as-of the manifests read; verify current slot before deploying.)
Performance & retrieval cost (MEASURED, 2026-08-14; ANN index PLANNED)
Measured envelope of a live mind, and where the time goes:
- Working footprint: a live mind is ~1 GB resident.
- Retrieval is the bottleneck. Retrieval today does brute-force cosine over
all nodes — ~330 ms at ~13k nodes — and that scan dominates request
latency (the geometric-retrieval path of
03§Retrieval /06§2.5 improved quality, not the scan cost). - Planned fix — an HNSW approximate-nearest-neighbour index (backlog
d3d0d644): turns the linear scan into ≈O(D·log N), so a 100× larger graph costs ≈1.5× rather than ≈100×. PLANNED, not built — brute-force is the live behavior; do not present the ANN speedup as shipped.