97 lines
3.5 KiB
Markdown
97 lines
3.5 KiB
Markdown
---
|
|
id: LSN-0004
|
|
ticket: legacy-runtime-learn-import
|
|
title: Historical Cartridge Boot Protocol and Manifest Authority
|
|
created: 2026-03-27
|
|
tags: [migration, tech-debt]
|
|
---
|
|
|
|
# Historical Cartridge Boot Protocol and Manifest Authority
|
|
|
|
Status: pedagogical / historical
|
|
Normative anchors:
|
|
- [`../specs/13-cartridge.md`](../../specs/13-cartridge.md)
|
|
- [`../specs/12-firmware-pos-and-prometeuhub.md`](../../specs/12-firmware-pos-and-prometeuhub.md)
|
|
- [`../specs/14-boot-profiles.md`](../../specs/14-boot-profiles.md)
|
|
|
|
This document records the historical rationale behind removing `entrypoint` from the cartridge manifest and moving cartridge boot authority into the executable artifact itself.
|
|
|
|
It is not a normative contract. The current contract lives in the specs above.
|
|
|
|
## Core Shift
|
|
|
|
The older runtime model treated `entrypoint` as cartridge metadata:
|
|
|
|
- `manifest.json` declared the callable to run;
|
|
- loader and cartridge DTOs propagated that string;
|
|
- VM initialization accepted textual resolution;
|
|
- runtime state tracked the current entrypoint as if boot authority were part of runtime metadata.
|
|
|
|
The newer model treats boot as executable protocol:
|
|
|
|
- the cartridge artifact itself defines the physical boot target;
|
|
- the executable entrypoint is always `func_id = 0`;
|
|
- firmware selects the cartridge, but not the callable inside it;
|
|
- nominal exports may still exist, but they do not decide boot.
|
|
|
|
## Why The Old Model Was Weak
|
|
|
|
The manifest-driven model created duplicate authority between compiler and runtime.
|
|
|
|
That duplication had three concrete effects:
|
|
|
|
- it let the manifest override what should have been fixed by the compiled artifact;
|
|
- it mixed symbolic, numeric, and fallback boot paths in the VM;
|
|
- it made boot failures less deterministic and less explainable.
|
|
|
|
In practice, the machine was carrying too much flexibility at the exact boundary where it needed a single source of truth.
|
|
|
|
## Why `func_id = 0` Became The Right Boundary
|
|
|
|
Boot is not user-facing metadata. It is part of executable structure.
|
|
|
|
By fixing boot at `func_id = 0`, the machine gets:
|
|
|
|
- one authority for startup;
|
|
- a simpler cartridge manifest;
|
|
- a more deterministic VM initialization path;
|
|
- clearer failure semantics when the artifact is malformed.
|
|
|
|
This also keeps the cartridge manifest focused on package metadata such as identity, version, mode, and capabilities, instead of turning it into an execution control surface.
|
|
|
|
## What Stayed Flexible
|
|
|
|
This change did not ban nominal exports from the bytecode image.
|
|
|
|
Exports still make sense for:
|
|
|
|
- linking;
|
|
- introspection;
|
|
- debug-oriented naming.
|
|
|
|
What changed is narrower and more important:
|
|
|
|
- exports are no longer boot authority.
|
|
|
|
## Runtime Consequence
|
|
|
|
Once boot became protocol-driven, the runtime was simplified:
|
|
|
|
- `entrypoint` disappeared from cartridge manifest and loader types;
|
|
- VM initialization stopped accepting textual boot resolution;
|
|
- runtime state no longer needed to track `current_entrypoint` for cartridge startup;
|
|
- the stress cartridge generator was updated to emit the new manifest shape.
|
|
|
|
The canonical initialization failure remained `VmInitError::EntrypointNotFound`, but its meaning hardened to "protocol boot target is absent or invalid".
|
|
|
|
## Historical Trace
|
|
|
|
This model was closed through the historical pipeline:
|
|
|
|
- agenda `025`
|
|
- decision `025`
|
|
- PR `025` for spec propagation
|
|
- PR `026` for runtime propagation
|
|
|
|
Those working artifacts were intentionally pruned after implementation so that `agendas/`, `decisions/`, and `pull-requests/` remain focused on live work.
|