bigmerge 3fcc36c2f1
El SDK CI - dev / build-and-test (pull_request) Failing after 14m58s
runtime: transduction is a language concern, so move it into the language
#141 let signal enter as geometry and it worked, but it was placed at the
CONSUMER and said so in its own commit message. This is the correction.

Three defects, all of them placement:

1. It sat in the engram. Ingest is a LANGUAGE concern — every el program
   touching any modality needs it, and the engram is merely one el program
   that happens to hold a graph. The geometry surface is now defined in
   el_runtime.c immediately ABOVE the engram section and depends on nothing
   inside it. Delete the entire engram and geometry still enters el.

2. It marshalled the vector as a hex STRING, because el had no first-class
   geometry value — which reintroduced text as the TRANSPORT medium one layer
   below the problem being fixed. Geometry is now an el value: a magic-tagged
   heap object carried in el_val_t, same discipline as List/Map. Hex survives
   only as an adapter at the edge, which is all an encoding should ever be.

3. It needed an arbitrary `dim <= 8192` bound purely to size an allocation
   from a caller's CLAIM about a string's length. A value carries its own
   width, so the width is derived and never asserted. The bound is gone, not
   raised — there is nothing left to validate.

Language surface, none of it engram-prefixed: geometry_new / _dim / _is /
_get / _set / _norm / _free, geometry_from_f32le_hex + geometry_to_f32le_hex
as the wire adapters, realizer_register(modality, fn_name), realizer_has, and
transduce(signal, modality) -> Geometry.

REALIZERS ARE DECLARABLE IN EL. This is the part that makes the move real
rather than nominal: registration resolves a name with dlsym against the
running binary, the identical mechanism http_set_handler already relies on,
because every el `fn name(...)` compiles to a global C symbol with that exact
name. So an ordinary el function IS a realizer and a new modality needs no
runtime patch. Verified end to end in lang/examples/transduce.el: an el-defined
tone_realizer is registered by name, transduce dispatches to it, and the
signal demonstrably reaches it (distinct signals produce distinct geometry).

A modality with no realizer transduces to NOTHING. There is deliberately no
built-in realizer, not even for text — silently embedding a description of a
signal and calling that perception is the exact defect this ends.

engram/src/server.el is migrated: POST /api/nodes decodes "emb" hex exactly
once, at the edge, into a Geometry, and everything below that line moves
geometry. The wire is unchanged because production clients speak it. "dim" is
now an ASSERTION about the vector, not the source of its width; disagreement
is a rejected ingest, not a silent reinterpretation.

#141's engram_node_set_emb becomes a DEPRECATED WRAPPER over
geometry_from_f32le_hex + node_attach_geometry — kept only because the runtime
ships as an SDK asset and a downstream binary may link the symbol. Its exact
contract, negative cases included, is preserved and re-verified.

ingest.el's `fn transduce` is renamed transduce_manifold. Mechanically it had
to yield the name (duplicate C symbol, a hard compile error, measured). But it
was never signal->geometry: it chunks already-extracted content into a node+edge
manifold, one layer up, and had taken the name belonging to the primitive
underneath it. Behaviour unchanged.

PROPERTIES FROM #141 PRESERVED, each re-measured on a scratch engram (:8971,
never prod :8742):
  - off-dimension vectors stored but NOT indexed — the HNSW build loop still
    filters on n->emb_dim == dim at four sites, so a 64-dim voice vector is
    durable and addressable without perturbing the 768-dim canonical index
  - geometry makes a node ineligible for embed_backfill: after backfill the
    64-dim voice node was still 64-dim while the text control acquired 768
  - the create response reports whether geometry landed, and the node document
    always emits emb_dim and embedded

Read-back with control and negatives, all verified against a PID-confirmed
fresh binary: geometry node emb_dim=64 embedded=true / emb_set=1; text-only
control emb_dim=0 embedded=false / emb_set=0; malformed hex, ragged length,
and dim-disagreement each emb_set=0.

Two compiler landmines found by reading the generated C rather than trusting a
successful build, both documented at their sites: elc lowers `a == b` to
str_eq unless both operand NAMES are in the per-function int-name set (which
does NOT propagate into nested if-expression blocks — the first cut would have
strcmp'd two integers as pointers on the first geometry-bearing request), and
`+` lowers to string concat when either operand is a user-defined call.
2026-08-16 11:37:27 -05:00

El

A self-hosting, statically-typed language that compiles to C — built around a graph-native runtime instead of a database driver.

El is the execution substrate for the Neuron agent runtime, the DHARMA network, and the Engram knowledge graph. This repository is the monorepo for the whole stack: the language itself, the graph memory engine it's built to talk to natively, and the tools (package manager, IDE, UI framework, diagramming) built on top of it.


Why El exists

Every other language treats persistent, associative state as something you reach for through a driver — a SQL client, an ORM, a Redis library bolted on from outside. El inverts that: graph operations (engram_*) are runtime primitives, on the same footing as string or list operations. There is no separate database driver because the database is not separate.

El has four defining properties:

  1. Self-hosting compiler. The compiler (lexer.el, parser.el, codegen.el, compiler.el) is written in El. It compiles El source to C, which cc compiles against a fixed runtime into a native binary. A Rust genesis compiler bootstrapped the first iteration; the self-hosted binary at lang/dist/platform/elc has been the canonical compiler ever since — every binary in dist/platform/ was produced by an earlier version of itself compiling el-compiler/src/. The chain is auditable: source is the ground truth, not the binary. See lang/BOOTSTRAP.md for the full recovery path if that binary is ever lost.
  2. C compilation target. Every compiled program is plain C11. Every El value is el_val_t (int64_t); strings are heap pointers cast through it. Functions become C functions; top-level statements become main().
  3. Graph-native runtime. The runtime provides first-class graph operations over an in-process Engram store — no separate DB driver, no ORM.
  4. DHARMA-aware identity. A cgi block declares a program's DHARMA identity at compile time. The runtime resolves identity before user code runs, so dharma_* calls have a stable principal and channel surface throughout.

Architecture map

                     ┌─────────────┐
                     │    lang     │   El compiler + C runtime
                     │ (El itself) │   everything below is written in it,
                     └──────┬──────┘   or compiles down through it
                            │
              ┌─────────────┼─────────────┐
              │             │             │
       ┌──────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
       │   engram   │ │    epm    │ │    ide    │
       │ graph/mem  │ │  package  │ │  editor + │
       │  substrate │ │  manager  │ │    LSP    │
       └──────┬─────┘ └───────────┘ └───────────┘
              │
      ┌───────┼────────────────┬─────────────────────┐
      │       │                │                     │
┌─────▼───┐ ┌─▼──────────┐  ┌──▼──────────┐    ┌─────▼──────┐
│   elp   │ │ ql         │  │  ui         │    │   arbor    │
│  NLG /  │ │engram-el.  │  |spreading-   │    |arbor       │
│ 31 langs│ │studio+tests│  |activation UI│    |diagram lang│
└─────────┘ └────────────┘  └─────────────┘    └────────────┘

lang is the foundation — the compiler and C runtime everything else builds on. engram is the graph-native memory/state engine that gives El its identity (property 3 above). Everything else is either a tool for working with El (epm, ide) or a system built on top of Engram's graph model (elp, ql, ui, arbor).


Repository layout

lang/ — the El language

The compiler and runtime. Self-hosting: elc-cli.elcompiler.ellexer.el / parser.el / codegen.el / codegen-js.el, textually inlined and compiled in one pass. Compiles to C11 and links against el-compiler/runtime/el_seed.c, a hand-maintained OS-boundary layer (libcurl HTTP, pthreads, filesystem, arena allocation) — everything else in the runtime is native El (runtime/*.el).

Two layers to know: El programs (.el files — where nearly all work belongs) and the C seed (el_seed.c — edit only for genuine OS-level access; never re-implement what El can already express).

Current status (single source of truth: lang/spec/language.md): lexer/parser/codegen and the C runtime's core (I/O, strings, math, lists, maps, filesystem, args) are implemented. In flight: % operator, match-statement codegen, ? nil-propagation, cgi block parsing + DHARMA identity resolution, VBD role enforcement (@manager/@engine/@accessor), the real engram_* and dharma_* runtimes (currently stubs), and libcurl-backed http_get/http_post/http_serve. Bitwise operators, ??, and as casts are explicitly not in this language.

Key docs: AGENTS.md (agent-facing orientation), BOOTSTRAP.md (compiler recovery from scratch), spec/language.md, spec/codegen-js.md.

engram/ — graph intelligence substrate

A local-first memory substrate for accumulating intelligence, and the reason El's runtime doesn't need a database driver. Rust core (engram-core, engram-ffi) exposed to El and other languages (Kotlin, TypeScript/WASM, Go bindings).

The model: retrieval is spreading activation, not query. You name seed nodes and a query embedding; activation propagates outward through weighted edges, attenuating multiplicatively per hop (strength = parent_strength × edge_weight × target_salience × cosine_sim), gets pruned below a threshold, and the top-N nodes by activation strength come back. Storage and retrieval are the same structure — the way long-term potentiation works in biological memory, not the way a relational or vector database works.

Nodes live in four tiers (Working / Episodic / Semantic / Procedural, mirroring prefrontal / hippocampal / neocortical / cerebellar memory) and migrate between them based on salience decayimportance × recency-decay × log(activation_count). Forgetting is adaptive pruning, not a bug: unreinforced memories stop competing for attention without being deleted.

Backed by sled (embedded, local-first, no daemon) with flat cosine scan for vector search — deliberately simple until scale demands an HNSW layer. Full API and design rationale in engram/README.md.

elp/ — Engram Language Protocol

Bidirectional engine mapping between Engram semantic forms and natural-language surface text, across 31 languages — from Spanish and Japanese through historical/liturgical languages (Old Norse, Sanskrit, Sumerian, Coptic, Akkadian, Ge'ez). Compilation order runs language-profile + vocabulary → per-language morphology-*grammarrealizersemanticselp. This is what lets an Engram graph node round-trip to and from readable text in any of those languages.

epm/ — El Package Manager

Manages vessels (El's package unit): publish, install, resolve dependencies. Vessels are stored in Engram as graph nodes, not files in a registry index — epm reads the local manifest.el, talks to Engram over HTTP, and writes resolved vessels to .epm/vessels/. Source: registry.el, install.el, update.el, manifest.el.

ide/ — El IDE

Three vessels: el-ide-server (HTTP backend — file ops, build/run, LSP bridge, plugin host, settings), el-lsp (the language server — completion, hover, diagnostics, outline, format, type graph), and el-plugin-host (first-party plugin lifecycle: install/remove/enable/disable). ide/projects/ and ide/examples/ hold sample projects, including the canonical hello-friends first-program walkthrough.

ql/ — engram-el

The El-native integration layer for a live Engram server — not a library (no importable modules, no build artifact), a set of standalone .el programs run directly via el run-file. Three components: Studio (studio/studio.el, a full terminal graph explorer), a Hebbian field-model proof of concept, and El builtin / LLM-builtin smoke test suites. This is the reference for correct patterns when an El program uses Engram as its substrate. Spec: ql/spec/elql.md.

ui/ — el-ui

A frontend framework where component state is an Engram graph and reactivity is spreading activation — not virtual-DOM diffing (React), Proxy-based dependency tracking (Vue), or compile-time analysis (Svelte). Re-renders are activated and propagated the same way associative memory retrieval works in engram/.

~15 vessels covering the full frontend surface: el-platform (env/fs/network/clock abstraction), el-config, el-html (SSR emit primitives), el-layout, el-style (design tokens/themes), el-i18n, el-auth / el-identity (JWT, sessions, OAuth PKCE — Engram-native), el-services (REST/gRPC/WebSocket bindings), el-aop (@authenticate/@authorize/@cache/@rate_limit decorators), el-secrets, el-graph (graph rendering/editor), el-publish (App Store / Play Store automation), and el-ui-compiler (El→JS component compiler; currently a stub pending a JS backend in elc). Spec: ui/spec/framework.md.

arbor/ — diagram language

A .arbor diagram language and toolchain: arbor-core (NodeId/shape/edge-kind types), arbor-parse (recursive-descent parser), arbor-diagram (IR + Mermaid serializer + architecture-diagram builders), arbor-layout (hierarchical layout — rank assignment, positioning, group bounds), arbor-render (SVG renderer), arbor-cli. (The architecture map above is the kind of diagram this is for.)


Getting started

Install the El SDK from the latest release:

bash lang/install.sh
# EL_VERSION=v1.0.0   bash lang/install.sh   # pin a specific release tag
# EL_PREFIX=/opt/el   bash lang/install.sh   # custom install prefix

Or build the compiler from source and verify the self-hosting chain:

cd lang
./dist/platform/elc elc-cli.el > elc-new.c
cc -std=c11 -I el-compiler/runtime -lcurl -lpthread \
   -o dist/platform/elc-new \
   elc-new.c el-compiler/runtime/el_seed.c

# Confirm the new binary reproduces itself exactly
./dist/platform/elc-new elc-cli.el > elc-verify.c
diff elc-new.c elc-verify.c   # should be identical

mv dist/platform/elc-new dist/platform/elc

Run your first program:

./lang/dist/platform/elc lang/examples/hello.el > hello.c
cc -std=c11 -I lang/el-compiler/runtime -lcurl -lpthread \
   -o hello hello.c lang/el-compiler/runtime/el_seed.c
./hello

More examples in lang/examples/, including a full starter project at lang/examples/hello-project/.

If the compiler binary is ever lost or corrupted, lang/BOOTSTRAP.md is the authoritative recovery path.


Development workflow

Branching follows dev → stage → main: work lands on dev, promotes to stage for integration testing, and is promoted to main for release (visible directly in the git history of this repo). CI is defined per-subproject under .gitea/workflows/lang/epm/ide share the root pipeline; engram and ql carry their own (ci-dev, ci-stage, and a release workflow each).

  • Language/runtime specs live at */spec/*.md (lang/spec/, ql/spec/, ui/spec/) and are the single source of truth for implemented-vs-planned status — code and docs are expected to agree with the spec's status markers, not the other way around.
  • Agent-facing orientation guides live at */AGENTS.md (currently lang/AGENTS.md); more subprojects may grow their own as they need agent-specific conventions documented.
  • Tagged releases live under lang/releases/, each with its own RELEASE.md.

Status

This is an actively developed, internal monorepo — not yet published under an open license. Treat everything here as proprietary to Neuron Technologies unless told otherwise.

S
Description
The Engram programming language — types as knowledge nodes, quantum-sealed prod target
Readme
211 MiB
2026-07-22 22:02:53 +00:00
Languages
Emacs Lisp 95.1%
C 3.9%
HTML 0.3%
Python 0.2%
Shell 0.2%
Other 0.1%