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:
| Where | Names | |
|---|---|---|
| locators | catalogs and manifests | what a human or a resolver asks for |
| content hashes | the store | one whole artifact, exactly |
| dense indices and self-relative offsets | inside an artifact | one 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:
| Choice | Controls | Ranges from |
|---|---|---|
| Link plan | optimization scope, constant pooling, rebuild scope, hot-reload granularity | one unit per pool → a whole cart in one |
| Placement plan | addressability and lifetime | one mapping per pool → one resident group |
| Execution form | how the code runs | Mach 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:
| Class | Holds | Lifetime |
|---|---|---|
| runtime image | VM code, native providers, static tables | the process |
| runtime RAM | scheduler, allocator, registries, actor descriptors | the process |
| mailboxes | serialized letters, runtime-owned, budgeted | until delivered |
| actor heaps | actor-local dynamic values | the actor |
| Mach stone | pools: bytecode, constants, text, shapes, descriptors | while 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
- The Pipeline — source to cart as one chain, and where pressing happens
- Actors and Memory — heaps, pools, views and bindings, placement
- The Executable as an Array — the three entry kinds, slots,
$image - Booting — the C floor, the fixed header, and the boot actor
- Capabilities — endowments, the gate, the C floor
- Providers and Lanes — how a native provider delivers its work
- Security and Threat Model — what is defended, and what is not
- Build and Artifacts — mcode, pools, hashing, profiles
- Packages and Distribution — manifests, locks, shipping
- Nightly Distribution — tested CI artifacts, compatibility, and Gitea publication
- Assets — how non-code files are addressed and reached
- Cartridges — sealed stores, placement plans, and ROMs
- Recipes — the file that is a target, and how a build selects one
- Target Profiles — the levers, and what enters the stamp
- The Target Matrix — worked recipes for machines pit has been built for
- Consoles and Constrained Targets — floating point, budgets, banking
- Building C — cake, the runtime builder, the extension spec
- Debugging — the four debugging endowments, origin maps, hot reload