The El Architecture

El is a concept-oriented language. This is the architecture that claim commits it to — what is built, what is measured, and what still has no home.

Working document · no sacred cows · self-hosting, so nothing here is fixed

01The primitive is the concept

Language families are named for their primitive. Procedural — procedures. Object-oriented — objects. Functional — functions. Logic — predicates. Every one of them is oriented toward a representation of a concept: the shape a concept gets flattened into so a machine can hold it.

El's primitive is the concept itself. That is why it is the first of its family and intended as the last — once the primitive is the concept, there is no further rung to climb to.

The consequence is architectural rather than stylistic:

A concept with no home in the language does not disappear. It becomes C, or it becomes a convention.

Both forms are measurable. As C: 20,504 lines of el_runtime.c, against 9,089 lines for the entire self-hosting language — the shim is 2.3× the language it serves, and ~47% of it is engram code that already has six sibling files. As convention, from lang/spec/language.md §18.0 — "these are not four problems, they are one absence, four times":

ConcernFragments intoThe convention it became
Process identity0 guards"check nothing is already running first"
Configuration20 env vars"remember the right default here"
Durability62 sites"after you mutate, remember to persist"
Request auth10 routes"check the token in this handler too"
Index-after-append9 of 9 failed"after you append, remember to index"

The last row is the strongest available evidence about this class of convention: it failed at every single site. A count is what appears where a concept has no home; the size of the count is how far the fragmentation got, not how hard the problem is.

02Geometry is a first-class value — and what follows

This is the enabling primitive. Everything else in the architecture is downstream of it.

Geometry is an El value, alongside Int, String, List, Map — bound, passed, returned, composed, carrying its own width. Not a library type, not a handle into a store, not a serialization format. Meaning is a value the language computes with directly.

let g: Geometry = geometry_new(4)
fn tone_realizer(signal: String) -> Geometry { … }

Landed 2026-08-16 (#141, #144), and the spec is explicit that it belongs to the language rather than the graph: "neither is engram-specific — any program touching any modality needs them; the engram is merely one El program that happens to hold a graph."

Five things follow, and together they are the concept-oriented claim made operational:

A declaration can name a region, not a shape

If meaning is a value, a name can be bound to a position rather than a struct. cat is not a fixed record; it is a region that resolves against the engram and the surrounding code. cat among animals and cat among shell utilities are different concepts without a namespace, because they are in different neighbourhoods and the distance says so.

Checking is grounding, not unification

If a declaration names a region, then verifying a use is asking whether the geometry supports it — a question about position and distance, not about matching a declared shape. This is why §2.3's "a type checker is planned" is likely the wrong name for the missing piece, and naming it wrong would build the wrong thing.

Dispatch is position, not a tag

A vtable is a finite set of discrete labels fixed at link time. A region admits graded membership and an open set. So transduce(signal, modality) asks the caller to supply what the signal already carries — what a thing is falls out of where it lands. The modality parameter is a kind-tag, and a registry keyed on it is a lookup table doing by string what geometry does by nearness.

Types are discovered, not declared

Reification crystallizes a densely co-wired neighbourhood into a first-class node — the neighbourhood is the name that was missing. Every other family requires a human to see the abstraction in advance and write class Foo. Here the instances arrive and the type falls out, by measurement rather than by insight.

Enumeration becomes unnecessary

Five ingest functions differ only in how bytes are acquired — one operation wearing five surfaces. 356 branches in engram_activate_inner are not 356 behaviours. Cyclomatic complexity is a count of the places comprehension ran out and was replaced by an if; where the concept is expressible, the count collapses instead of being redistributed.

03The shape of the language

Geometry first-class gives El three layers, and it holds all three — which is why there is no separate database driver and no impedance boundary to manage.

afferent

Transduce

Signal in, geometry out. Decomposition into components and relations — never conversion to a point. Realizers are ordinary El functions, so a new modality never requires a runtime patch.

substrate

Geometry

Meaning as position; relation as distance. Held as values in the language and persisted in the graph. One coordinate system, so entities are commensurable and the operators compose.

efferent

Realize

plan(frame) → realize(spec, profile), where a surface is a profile. Text, speech, music, image are profiles of one projection — and so is source code.

The efferent side is why the recursive property below is possible at all: if source is a surface, then emitting a corrected file is projection, and the file becomes an artifact of the geometry rather than the thing you edit.

04Decomposition is by faculty

Not by file, module, or subsystem — by what the system does.

Each faculty is a concept. Where it has no home in El it leaks: into C, into a Swift binary, into a shell script with a curl timeout, into a convention nobody performs. State below is measured, not asserted.

FacultyStateMeasuredWhere it leaked
Ingest take indead2 min → 0 nodesseparate process uploading bytes over HTTP to a process with direct fs access; five functions where there is one
Recall rememberdeadself ranked 8thlexical substring scan; empty on 23 of 24 multi-token queries
Transduce perceivedead1 node, 0 edgesintake flattens signal to a point; realized:false; caller must declare the modality
Think reasondeaddirection [0,0,…]null gradient from any anchor and any faculty, byte-identical; confidence at the uninformed prior
Realize expresspartial13-word lexiconorgan was 939 lines of Swift beside the language; voice read from a file path
Body substratepartialCC 356 / 1,626 lnengram_activate_inner — recall itself, 356 unexamined paths
Persist endurelive13,562 / 13,562works — every signal placed in geometry at intake, no backlog

05The recursive property

El's compiler is written in El. Every concept the language gains, the compiler can then be written in — so the tool improves the tool, and codegen.el at 4,661 lines gets shorter as the language gets better at expressing what it does. The fixpoint — stage2 ≡ stage3, byte-identical — makes each turn provable rather than hopeful, and the verifier answers in 2.9s.

This sets the ordering criterion, and it is not size of payoff:

Order by leverage on the next iteration. Which concept, added to El, most increases the ability to add the following one?

A small early gain that compounds beats a large one that does not. And it bounds itself correctly — unbounded in depth, bounded in rate, because nothing lands that the compiler and the fixpoint have not passed.

06What has no home yet

Reserved in the lexer, no parse form. These are not a feature backlog — they are the concepts the architecture above requires and does not yet hold, which is why each is currently a convention or a block of C.

ReservedConceptCurrently lives as
retry · times · fallback · reasonresiliencea shell script with a 10s curl timeout; 254 restarts in 3 days
requires · deploy · to · via · targetdeploymentYAML in another repository
sealedcapability scopeconsent checks written by hand
protocol · implone operation, many realizationsfive ingest functions; eight faculty routes on one builtin
activate · whereretrievaltraversals written by hand
test · seed · assertverificationa framework; 5 of 13 native suites failing
parallel · traceconcurrencypthreads in C

Plus, from the spec's own status: annotations parsed and skipped, match parsed and emitting nothing, ? a no-op, % unlexed, structs as ElMap, enums as strings, selective import unenforced.

07Open

What does a declaration bind to, exactly?If cat names a region that shifts and completes against context, what is written at the declaration site and what is resolved at use? This is the centre and it is unspecified.
Is the faculty list right?Seven, derived from what broke. Derived-from-failure is a biased sample — it finds what is loud, not what is absent. Which faculty is missing entirely and therefore never failed?
Which concept has the highest leverage on the next turn?The prologue/epilogue seam (§19.3 names it as the prerequisite; its stated blocker has expired; it collapses 62 + 10 convention sites), protocol/impl, or resolution itself. The §05 criterion should decide this, not preference.
What seam makes cognition non-optional?"Use the ops" is itself a convention — present every turn, enforced by nothing, ~100% failure across a full session. A stronger instruction is still a convention. What makes reasoning outside the substrate fail, the way @manager makes dharma_emit outside the boundary a compile error rather than a lint?

Every number here is measured or quoted from lang/spec/language.md. Nothing is inferred and presented as fact. El is self-hosting: all of this can change and be rebuilt.