Architecture Overview

This track is for someone working on the runtime, the compiler, or a port. It assumes the Guide — actors, turns, messages, and the module/program/executable vocabulary — and describes the machinery underneath: what artifacts exist, how one becomes the next, and where each lives at run time.

Terms are defined in the Glossary.

The artifact chain

source ──▶ AST ──▶ mcode        per source file, portable

mcode units, one or more
   ├──▶ Mach pool               lowered, linked, optimized, target-final
   └──▶ native image

executable manifest             program + resolved module closure
target realization              manifest + profile + form + pools

Two halves, with different granularity. Compiling to mcode happens per source file and produces something portable — no target, no layout, no link decisions. Everything after that works over groups: a link group of mcode units is lowered and linked together into one pool, optimized across the whole group and laid out for one exact target.

That second step is itself split, and the split is where the C floor ends. C lowers, pit links. One code generator turns a unit’s mcode into the target’s final instruction words and object bytes; a linker written in pit takes a group of those and lays out one pool. Meaning stays with the lowering that owns the object ABI, placement stays with the linker, and neither learns the other’s job. The Pipeline walks the whole chain.

An executable manifest is the logical identity — one root program, its resolved bindings, the exact mcode closure, initialization order, and claims. A target realization is what you can actually start: a manifest joined to one target profile, one execution form, exact pool hashes, and a start plan. One manifest can have several realizations.

Every artifact is named by the hash of its bytes, so identical inputs produce one stored object no matter how many locators reach it.

Names, hashes, indices

Those three appear in that order and never mix, which is what keeps the chain readable:

WhereNames
locatorscatalogs and manifestswhat a human or a resolver asks for
content hashesthe storeone whole artifact, exactly
dense indices and self-relative offsetsinside an artifactone row, one section, one function

A locator gets you to a manifest; the manifest resolves it to a hash; inside the artifact that hash names, there are only indices. A pool does not know which locator a function came from, and the executable manifest is the border table where that changes.

Three independent choices

Finalization decides three things separately, and conflating them is the usual mistake:

ChoiceControlsRanges from
Link planoptimization scope, constant pooling, rebuild scope, hot-reload granularityone unit per pool → a whole cart in one
Placement planaddressability and lifetimeone mapping per pool → one resident group
Execution formhow the code runsMach bytecode → native image

A build can put every unit in its own pool for fast reload while placing them all in one resident group, or the reverse. The link plan is about compile time, code quality, and what can be swapped at run time; the placement plan is about memory.

Where things live

Five classes account for memory, and each has a distinct owner and lifetime:

ClassHoldsLifetime
runtime imageVM code, native providers, static tablesthe process
runtime RAMscheduler, allocator, registries, actor descriptorsthe process
mailboxesserialized letters, runtime-owned, budgeteduntil delivered
actor heapsactor-local dynamic valuesthe actor
Mach stonepools: bytecode, constants, text, shapes, descriptorswhile pinned

An actor’s own memory is its heap plus its share of its mailbox. Everything else it uses is immutable, shared, and counted once — which is what makes a footprint measurable on a target with a fixed budget.

That is the accounting view. Where a value can live is shorter, and it is three regions and no others: the fixed runtime stone pool seeded before actor 0 exists, the Mach pools compiled code brings along, and the actor heaps. Nothing is interned across actors. See Actors and Memory.

Where authority comes from

Authority is decided when a program is built, and never revisited. Policy answers one question — may this be built — so a start is the mechanical execution of a plan already decided. What a shop can build from is what it has mounted, which makes mounting the act that decides what may enter. What running code can reach is decided by the realization’s binding rows; pools sharing a mapping are merely near each other.

The rest of this track