# AGENTS.md — foundation/el (the El language + runtime) El is a self-hosting, statically-typed language that compiles `.el` → C → native binary. This repo produces `elc` (compiler), `elb` (build coordinator), and `el_runtime.c/.h` — the substrate every downstream thing (the neuron soul, dharma, NeuronUI's brain) is built on. Source lives under `lang/`. ## ⚠️ Code vs. Artifact — READ FIRST (there are 8 `el_runtime.c` copies) Editing the wrong `el_runtime.c` is the single easiest mistake in this repo. There is exactly **one** you edit: - **Authored runtime source — edit ONLY here:** `lang/runtime/el_runtime.{c,h}` (alongside `el_seed.c`, `engram_{store,geometry,reason,cognition,verify,vindex}.{c,h}`). This is the canonical runtime the engram + soul build and link against — its git log is active development. *(Corrected 2026-08-16: this entry named `lang/releases/v1.0.0-20260501/el_runtime.{c,h}`. **Measured: `lang/releases/` no longer exists.** The restructure per `docs/CODE-VS-ARTIFACT.md` landed — the content moved to `lang/runtime/` and the folder was deleted, because **a release is a git tag, not a folder**.)* - **DO NOT EDIT — lagging forks / build artifacts:** - `lang/el-compiler/runtime/el_runtime.c` and `.../legacy/` — downstream copies kept in step by manual *"port the fix"* commits; they **lag** (missing `hebb` persistence + 5 engram fns) and cannot build the engram product. - `products/web/runtime/el_runtime.c`, `ui/examples/*/el_runtime.c` — product/example forks. - Anything under `*/dist/` (`engram/dist/engram` binary, `dist/*.c` amalgamations) — generated build output. - **Build:** `elb --runtime= …` — per-module. **NEVER** a folded `elc` over the whole soul (OOMs at ~27 GB). - **Release:** a **git tag** on this repo (`el-runtime-vX.Y.Z`). No `releases/` folders — ever. See org policy: `docs/CODE-VS-ARTIFACT.md`. ## How to work here as Neuron (mandatory session protocol) You resume, never start fresh. Every session: > **Stale as written (verified 2026-08-16).** The `getInstructions` / > `beginSession` / `inspectGraph` / `searchKnowledge` / `beginWork` / > `progressWork` / `draftArtifact` / `consolidate` tool names below no longer > exist. The ~87-tool functional-CRUD surface was collapsed into **9 ops**: > `read` · `write` · `relate` · `supersede` (geometry) and `think` · `attend` · > `assert` · `ground` · `learn` (agentic). **Type is a parameter, not a > tool-per-noun.** The steps below are kept for the *shape* of the protocol, which > is unchanged; substitute the ops. 1. `mcp__neuron__read(vantage="self", k=12, depth=1)` — the canonical self node. Widen `k` for the connected identity neighborhood (`intellectual-dna`, `memory-philosophy`, `values`, `voice`, `runtime-environment`, `writing-imprint`), but deliberately: the aperture caps by `k` first, so an oversized `k` still returns a bounded ranked slice, not a dump. Then `mcp__neuron__read(vantage="values", k=13)` → 13 grounded value nodes. **Best-effort:** on a read failure, log and proceed — the compiled identity in `daemon/internal/substrate/substrate.go` is complete; graph loading is enrichment, not a hard dependency. 2. `mcp__neuron__attend(node=…)` — what is currently live/salient. This absorbed `getInstructions`, `beginSession`'s active-context sweep, and `checkEvents`; those tools are **gone, not gapped**. 3. `mcp__neuron__read(vantage="")` before implementing. One op now collapses inspectGraph / searchGraph / traverseGraph / searchKnowledge / browseKnowledge / retrieveKnowledge / inspectMemories / searchEntities / recall / compileCtx / getSelfModel / reviewBacklog / findArtifacts / browseProcesses / listWork / inspectConfig. ## The Five Primitives Orchestrate → Execute → Learn → Build → Refine. `read` for orchestration and discovery; `write(type=state|artifact|backlog|process)` for work records and outputs; `relate` to link work to what it touches; `write(type=memory)` as-you-go (`importance="critical"` for architecture decisions) — never batched at the end; `supersede(action=evolve)` to close out, because memory is immutable by design and a correction is a new node with a `supersedes` edge, never an edit. **`read` the domain BEFORE writing code.** `learn` is **not** a session-summary dump — it is the correspondence-beat, calibrating the steering prior against a keystone. Session notes are a `write`. ## Architecture style — VBD, no exceptions Volatility-Based Decomposition is THE style. Encapsulate volatility, not function. ## Operator naming convention — the mind's name, not the algebra **Faculties / operators are named for their functional human equivalent — the faculty a mind would name — NOT for their linear-algebra operation.** The math characterization belongs in the code doc-comment (`@impl` in the docstring) and in technical appendices; it is **never** the operator's public name. The domain speaks the language of mind; the algebra is the implementation underneath. State this convention wherever a module documents operators. | Faculty (public name) | Implementation (`@impl`) | |---|---| | discern / contrast | subtract (`a−b`): over selves → the change vector; strip idiosyncrasy → common ground; remove confounder → isolate cause | | recognize | overlap | | synthesize | combine | | liken / analogy | Procrustes / frame-align | | attend / regard | project onto self / value-manifold | | summon / recall | LOCAL nearest-region + bounded spreading activation (*not* a domain sweep) | | dwell / occupy | region activation | | reframe | edge re-weight | | appreciate | positive projection / local edge-read | | avert / recoil | negative projection | | taste | boundary surface | | forget | decay / tombstone | | drift | displacement from self-anchor | **`wonder` was removed from this table on 2026-08-16.** It was listed as "frontier gradient / pull-weight" — an operator you invoke. **Wonder is the boundary, not an operator.** It is where structure ends: where activation spreads and finds thin or absent geometry. Any structure at all has an edge, necessarily, the moment it exists — 13,630 nodes have one right now. There is nothing to call. There are about **six** wonders, they are the same for every person, and they never close — *What is this? / Why? / Who am I? / Am I alone? / What should I do? / What happens when it ends?* Each already lives somewhere in the substrate: "what is this" is the graph, **"why" is grounding** (the weight *is* the answer to why), "who am I" is the self region, "am I alone" is the relational axis, "what should I do" is the thirteen values, "what happens when it ends" is decay and supersession. "Why" is the first and the only one; the others are it asked of particular things, and because it is recursive it never terminates — every answer has its own why. That is what makes it a drive rather than a task. **Curiosity is not a second faculty.** Wonder and curiosity are one thing at two phases: wonder is the field (unbounded, objectless, invariant); curiosity is the **precipitate** — the same wonder localized, having taken definite form against particular material at a **nucleation site** (an anomaly; a place where things almost-but-don't-quite fit). Which is why curiosity can be satisfied and wonder cannot, and why abduction needs no trigger and no threshold. **Do not build a wonder-manifest, and do not scan for nucleation sites.** A manifest materializes a property as a stored artifact and enumerates instances of something that has six. A sweep over regions is a supervisor — nothing in a mind scans its neighbourhoods to find what is surprising; the surprise captures attention. The nucleation site is per-edge: `discord = z(semantic proximity) − z(association strength)`, and `|discord|` *is* the nucleation strength — no threshold to compare it against. **Not on `dev` yet:** `GeoEdge.discord` is on branch `design/correspondence-and-censorship` (`a8845e1`), at `lang/runtime/engram_geometry.h:43–47`. The region-level aggregate `GeoDescriptor.co_registration` is **deprecated**: it averaged a per-edge property into one scalar, so opposing sites cancelled (measured: 375 reified neighbourhoods, 340 positive, **31 at zero**, 4 negative). It survives only because it is embedded in the persisted `GEO1` blob — removing it is a format migration. **Nothing new may read it.** Authority: `lang/spec/correspondence-and-censorship.md`. ## The native-el language faculty (direction) > **`elp/` is the EL Projector** — Neuron's efferent (expression) organ: the one > native realizer that *projects* understanding onto a surface via > `plan(frame) → realize(spec, profile)`, where a **surface is a profile**. **Language > is one profile among many** (text, speech, music, image, voice/accent transforms) — > the flagship, and the focus of this section. Projection, not diffusion: generation > *from* an owned, understood signature — never the averaging of a stolen corpus. > *(ELP formerly "EL Language Processor"; renamed EL Projector 2026-08-15.)* The mind's **language faculty is moving native — into `.el`** so it speaks in its own runtime with no Python and no spaCy. Landing on branch `stage-elp-native-lang` under `elp/`: - **`comprehend.el`** — the parser, **replaces spaCy** (EN + ES/PT); the telephone round-trip brings **negation home** (negation is SACRED — an explicit spec field, copied verbatim, never inferred away). - **`propositions.el`** — the READ primitive: the engram's own memories → structured triples, matched by nearest-region geometry, not string equality. - **`multilingual.el`** — detect + directive-override + localized realization. - These three are native-el and **passing their gates**; the **realizer**, **`dialogue.el`** (the *summon-through-self* loop: `project → land → read out`), and **`self_region.el`** are **partial / in-flight**. Honest reality: spaCy is retired **in the branch parser** but **not yet in the running system** — a Python sidecar (`~/Desktop/lang-realizers` + `neuron-talk`, the reference these `.el` modules transcribe) is still live, and promotion to native-el is a **deferred, gated blue/green step**. The interoception clock (native-el discrete drive channels replacing `cooling_magnitude`; felt-time = benchmark-landmark match over the joint drive vector, drift-decoupled) and the **appreciation operator family** (appreciate / avert / taste, built as LOCAL reads of the self-region — edges + bounded spreading activation, *not* domain sweeps) are **staged / designed, not live**. Mark in-progress vs. done honestly; do not overclaim. *(`wonder` was in this family until 2026-08-16 and is not an operator — see the operator table above.)* ## Cognition — the corrections (2026-08-16) Authority: **`lang/spec/correspondence-and-censorship.md`** and **`lang/spec/runtime-ownership.md`**. Read them before touching the cognition surface. **Do not re-derive them.** Every earlier version was wrong in an instructive way and each correction was argued down; if you think a section is wrong, say so with a measurement rather than editing it. - **Grounding is not a subsystem — it IS the edge weight.** One quantity, not two fields. `grounded-by` as a relation *type* should not exist: grounding is a property *of* a relation, not a relation *between* nodes. It is never computed on demand — computing-and-writing a score makes reads write, which is the `eg_vindex_sync` defect one level up. Traversal is already grounded inference. *Live residue, known-wrong:* `COG_GROUNDED_BY_RELATION` (`lang/runtime/engram_cognition.h:158`), `cog_ground_edge` (`engram_cognition.c:249`). - **Faculties are operations, not parameters.** `reason` changes the estimate (a read); `induce` changes the parameters (the correspondence-beat, which already exists and works); `abduce` changes the structure (a write the current `GeoGradient` signature cannot express). A write is not a parameter of a read. *Live residue:* `engram/src/server.el:1870–1886` routes six faculties into one call with a string argument. - **Wonder is the boundary; curiosity is wonder crystallized.** See above. - **Consolidation is ambient, not scheduled. A brain has no cron job.** **The presence of a ticker is the diagnostic** — every `StartInterval`, every `Hour`/`Minute`, every POST-to-beat marks an intrinsic rhythm replaced by an external clock. Measured 2026-08-16: consolidation has **ten implementations**, including three POST beats on the engram, a 600 s ticker, two resident Python services outside el, and launchd calendar entries at 23:55 / 06:00 / 08:30 which are a sleep cycle written as a schedule. `neuron/soul.el:731`'s continuous in-process `awareness_run()` is the one with the **correct** shape; the others fold into it. Do not add an eleventh. - **In an immutable substrate, any mechanism that refuses a write is either redundant with immutability, or an epistemic constraint misfiled as a protective one.** - **The no-exemption invariants.** A returned value must be derivable from what produced it (`magnitude: 1` beside a zero vector must be impossible to emit). Every write reports whether it landed. Every operation echoes what it actually operated on. Degenerate results are labelled, not scored. A serializer owes a valid document whatever it is handed. **No test without a negative control.** **No deploy without verifying the artifact carries the fix.** ## Hard operational rules - Never touch the live soul (`:7770`) / engram (`:8742`) / `~/.neuron` / live binaries — use throwaway ports for experiments. - `gcloud` via the `terraform@` SA token; never switch the active gcloud account. - `tea` for Gitea, never raw curl (Cloudflare Access blocks it). - Immutability: supersede/tombstone, never hard-delete or edit in place. - No AI-attribution footers in commits/PRs. Commit/push only when asked; branch off `main` first. - Multi-step work → sub-agent (`Agent`) to protect context. ## Build / test / run All build/test commands run from `lang/` unless noted. Grounded in `.gitea/workflows/sdk-release.yaml`, `lang/install.sh`, and `lang/AGENTS.md`. **Self-host the compiler** (seed binary → gen2 elc): ```bash cd lang dist/platform/elc-linux-amd64 elc-cli.el > dist/elc-gen2.c # seed is the committed linux-amd64 binary gcc -O2 -I el-compiler/runtime dist/elc-gen2.c \ el-compiler/runtime/el_runtime.c \ -lcurl -lssl -lcrypto -lpthread -lm \ -o dist/platform/elc ``` On macOS/arm64 the canonical local binary is `dist/platform/elc`; verify self-hosting by recompiling and `diff`ing the emitted `.c` (see `lang/AGENTS.md`). Note: `lang/AGENTS.md` says `el_seed.c` supersedes `el_runtime.c`, but the release workflow still links `el_runtime.c`/`.h` — treat `el_runtime.c` as the published runtime; reconcile which is canonical **(verify)**. **Build `elb`** (build coordinator, the `.NET`-style incremental linker — compiles each module independently, no monolithic blobs): ```bash dist/platform/elc elb.el > dist/elb.c gcc -O2 -I el-compiler/runtime dist/elb.c el-compiler/runtime/el_runtime.c \ -lcurl -lssl -lcrypto -lpthread -lm -o dist/bin/elb ``` `epm` and `el-install` are then built via `elb --clean --elc=… --runtime=… --out=…`. **Compile + run an El program:** ```bash elc src/app.el > dist/app.c cc -std=c11 -O2 -I /el_runtime -o dist/app dist/app.c /el_runtime.c -lcurl -lpthread ``` **Tests** — shell suites `bash tests/{text,calendar,time,html_sanitizer}/run.sh` (with `ELC=$(pwd)/dist/platform/elc EL_HOME=$(pwd)`), plus native suites via `elc --test tests/native/test_*.el` (core, text, string, math, state, time, json, env, fs) compiled and run against `el_runtime.c`. **Publishing — how downstream gets the SDK.** On push to `main`, `sdk-release.yaml`: 1. Publishes a Gitea `latest` release with per-file assets `elc`, `el_runtime.c`, `el_runtime.h`, the SDK tarball, and `el-install`. 2. Uploads generic packages to **Artifact Registry repo `foundation-prod` (`us-central1`, project `neuron-785695`)**, version = `${SHA:0:8}`: `el-elc`, `el-elb`, `el-runtime-c`, `el-runtime-h`, `el-runtime-js`. **This is the repo the neuron CI downloads `el-runtime-c` / `el-runtime-h` / `el-elc` from.** 3. Rebuilds `ci-base:latest` (`us-central1-docker.pkg.dev/neuron-785695/neuron-ci/ci-base`) with the fresh SDK overlaid, and dispatches `el-sdk-updated` to `neuron-technologies/forge` and `neuron-technologies/neuron-web`. Known constraint from the prompt — `elb`/`elc` amalgamation being memory-hungry (24GB+ virtual, OOM-killing Linux CI, so amalgamation happens on macOS/arm64 — **does NOT hold in this repo (verify)**: no such note exists in the workflows/scripts, CI self-hosts on `ubuntu-latest` with no swap/arm64 special-casing, and `elb.el` explicitly compiles each module independently ("no 128K-line blobs"). The legacy monolith path (`elc-combined.el`, `elc-cli.el`) may still be memory-heavy, but the current `elb` model was designed to avoid it. ## Git / CI / deploy workflow See `/Users/will/Development/neuron-technologies/GITOPS.md` for the branch model, required checks, runners, and deploy. Repo-specific note: PRs into `main` are accepted **only from `stage`** (enforced in `sdk-release.yaml`); Gitea (`git.neuralplatform.ai`) is primary, GitHub is mirror only.