170 lines
8.6 KiB
Markdown
170 lines
8.6 KiB
Markdown
# Capsules Load Definitions Only — Design Doc
|
|
|
|
**Date:** 2026-07-09 (rev a)
|
|
**Branch:** `lithosananke`
|
|
**Status:** RETRACTED (2026-07-10). This doc's entire premise — that
|
|
`capsule_exec_payload` should stop writing a capsule's `Block N` content
|
|
to the literal block N — is wrong. Captain Bob's direct correction:
|
|
*"all capsule does is LOAD a block with a given Block xxxxx header to
|
|
THAT BLOCK. that's all. They are not ordered in the capsule necessarily."*
|
|
This doc was implemented (commit `e1c3ac01`) and then reverted (commits
|
|
`43d81d49`/`548062ab`) once the correction landed; three-arch Tripod
|
|
acceptance re-confirmed identical `dict_hash` with the original mechanism
|
|
restored (`ee91280d`). `write_ramdrive_block` and its call site are back
|
|
exactly as they were. Kept as a record of a wrong turn, per this repo's
|
|
revision-history convention, not deleted. **Do not implement anything in
|
|
this doc.** See `CAPSULE-BLOCK-PERSISTENCE-BOUNDARY-FINDING-20260709.md`
|
|
for the corrected, closed status of the underlying finding.
|
|
**Author:** Captain Bob / Claude Code
|
|
|
|
---
|
|
|
|
## Problem, restated from the finding doc
|
|
|
|
`capsule_exec_payload()` (`src/starkernel/capsule/capsule_loader.c:448`)
|
|
does two things per parsed block, not one:
|
|
|
|
```
|
|
1. write_ramdrive_block(current_block_num, block_start, block_len); /* line 484 */
|
|
2. exec_block_with_retry(vm, block_start, block_len, current_block_num);
|
|
```
|
|
|
|
Step 2 is what a capsule loader is for: interpret the block's FORTH text,
|
|
compile words into the dictionary. Step 1 is not — it writes the block's
|
|
raw content into the live block-device LBN space, keyed by the literal
|
|
number in the capsule's own `Block N` source header, with no boundary
|
|
check. `CAPSULE-BLOCK-PERSISTENCE-BOUNDARY-FINDING-20260709.md` documents
|
|
the consequence: every capsule numbered `4000+` (most of them) has that
|
|
write land on Artemis's real disk once attached, entirely outside
|
|
Artemis's own allocator's knowledge.
|
|
|
|
## Confirmed direction
|
|
|
|
> "let the capsules load definitions only. persistence needed to message
|
|
> will sit and compudynamics will provide the where. logical blocks will
|
|
> start to put the rest of this together"
|
|
|
|
Three separate claims, each addressed below:
|
|
|
|
## 1. Capsules load definitions only
|
|
|
|
Step 1 (`write_ramdrive_block`) is removed from `capsule_exec_payload`.
|
|
A capsule's `Block N` headers go back to being pure source-file
|
|
organization — the `mkcapsule --lint` format check (≤64 chars/line, ≤16
|
|
lines/block) and `MANIFEST.md`/`BLOCK_MAP.md`'s content-addressed
|
|
bookkeeping — with no runtime persistence meaning. Capsule execution
|
|
becomes exactly what the function's own header comment already claims
|
|
for step 2 alone: interpret the payload bytes directly, no block device
|
|
touched.
|
|
|
|
This is a clean removal, not a guess dressed as one — checked, not
|
|
assumed:
|
|
|
|
- `write_ramdrive_block()` itself (`capsule_loader.c:146`) becomes dead
|
|
code once its one call site is gone, along with the unused
|
|
`CAPSULE_RAM_OFFSET` macro (`capsule_loader.c:51`) whose comment
|
|
already described a scheme (`dest = source - CAPSULE_RAM_OFFSET`) the
|
|
code never actually implemented.
|
|
- `capsule_clear_blocks()` (`capsule_loader.c:514`) exists only to undo
|
|
step 1's write — its two call sites (`capsule_exec_init`,
|
|
`capsule_loader.c:569`; the post-Mama-birth cleanup in
|
|
`kernel_main.c:570`) become no-ops on nothing and should go too.
|
|
- `capsule_load_blocks()` (`capsule_loader.c:192`) — a second, separate
|
|
function that also calls `write_ramdrive_block` — has **zero callers
|
|
anywhere in the codebase** (verified: `grep -rn
|
|
"capsule_load_blocks(" src/` matches only its own definition and
|
|
header declaration). Already-dead code, not something this change
|
|
orphans.
|
|
- No capsule in the current corpus calls the real FORTH `LOAD` word
|
|
against a capsule-written block number — verified by grepping every
|
|
`.4th` file under `capsules/` for `LOAD`; the only matches are
|
|
substrings inside unrelated word names (`FLEET-DOE-WORKLOAD`,
|
|
`LOAD-DOE`). The "so FORTH can call `LOAD N` later if needed"
|
|
capability the removed comment describes has no real consumer today.
|
|
|
|
Net effect: `capsule_exec_payload` shrinks to the execute-only loop;
|
|
nothing in the current capsule corpus observably changes behavior,
|
|
because nothing currently depends on the write it's losing.
|
|
|
|
## 2. Persistence, when actually needed, is placed — not addressed by convention
|
|
|
|
A capsule defining `MSG-ALLOC` no longer implies anything about where a
|
|
message physically lives. When an entity genuinely needs to persist
|
|
(a Hermes message, eventually), **compudynamics decides the placement** —
|
|
the same role `capsule_vm_physics.c` already plays for VM heat: a live
|
|
mechanism making a runtime decision, not a number an author typed into a
|
|
`.4th` file.
|
|
|
|
This is new scope for compudynamics, not a capability it has today —
|
|
worth stating plainly rather than implying otherwise.
|
|
`include/compudynamics.h`/`src/compudynamics.c` currently expose tuning
|
|
values (`CDTuning` via `cd_tuning_word()`/`cd_tuning_vm()`), not block
|
|
placement or allocation. Extending it to decide *where* a persisted
|
|
entity lands is follow-on design work, not yet specified — see Open
|
|
questions.
|
|
|
|
## 3. Logical blocks are the layer that ties it together
|
|
|
|
Captain Bob named this as the piece that "puts the rest of this
|
|
together" but did not specify a mechanism, and this doc does not invent
|
|
one. What's already on record, factually, from prior design work:
|
|
|
|
- `HERMES-MESSAGE-BLOCK-STORAGE-DESIGN-20260708.md` and
|
|
`ARTEMIS-BLOCK-PHYSICS-DESIGN-20260708.md` both name "Logical BAM" —
|
|
per-VM normalization of physical block-heat accounting so a VM
|
|
participates correctly in fleet-wide heat conservation — as a real,
|
|
already-deferred gap (`ARTEMIS-BAM-ACCEPTANCE-20260703.md`'s Phase 1
|
|
acceptance left it explicitly unbuilt for Artemis).
|
|
- The storage doc's confirmed simplification was that Physical BAM and
|
|
Logical BAM "will look like the same mechanism right now" — a
|
|
deliberate non-split, not a permanent one.
|
|
|
|
This session's direction reopens that simplification: "logical blocks"
|
|
now sounds like the addressing layer between "an entity needs to live
|
|
somewhere" and "here is the physical LBN," which is a bigger role than
|
|
"normalization for fleet conservation" alone. **Whether that's the same
|
|
logical-block concept wearing a larger hat, or something adjacent, is
|
|
not yet settled — flagged as the central open question below, not
|
|
guessed at.**
|
|
|
|
## What this doc does NOT do
|
|
|
|
- Does not implement the `write_ramdrive_block` removal. That's a small,
|
|
well-scoped follow-on change (delete one call, its now-dead callee, the
|
|
two `capsule_clear_blocks` call sites, and the already-dead
|
|
`capsule_load_blocks`) — but still a code change, held per standing
|
|
instruction until asked for.
|
|
- Does not specify how compudynamics decides placement, or what a
|
|
"logical block" concretely is as data or as an API. Both are named
|
|
directions, not designed mechanisms.
|
|
- Does not revise `HERMES-MESSAGE-BLOCK-STORAGE-DESIGN-20260708.md` in
|
|
full — its storage-tiering discussion (own RAM blocks → own ramdrive
|
|
blocks → own appended disk, no cross-VM coupling) is not contradicted
|
|
by this doc, only its specific "claim a `Block N` range" mechanism,
|
|
which no longer applies once capsules stop writing blocks at all. A
|
|
fuller rewrite of that doc is follow-on work once compudynamics
|
|
placement and logical blocks are designed enough to describe how
|
|
Hermes's messages actually get placed.
|
|
|
|
## Open questions
|
|
|
|
1. **What compudynamics-driven placement actually looks like** — an
|
|
allocator interface, a heat-driven selection among candidate blocks,
|
|
something else. Not specified here.
|
|
2. **What a "logical block" is, concretely** — an addressing indirection
|
|
(logical ID → physical LBN, resolved at access time), a renamed
|
|
Logical BAM, or a new layer distinct from both. Not specified here.
|
|
3. **Whether removing `write_ramdrive_block` has any effect on parity
|
|
logging or dict-hash determinism** — `capsule_birth_mama`/
|
|
`capsule_birth_baby` log `post_dict_hash` after execution
|
|
(`capsule_birth.c:377, 462`), which only depends on step 2 (dictionary
|
|
state), not step 1 (block-device writes) — so removal should be
|
|
parity-neutral, but this wants confirming against a real three-arch
|
|
run when the change is actually made, not asserted here.
|
|
4. **Whether `MANIFEST.md`/`BLOCK_MAP.md`'s block-numbering conventions
|
|
need to change** once `Block N` carries no persistence meaning — the
|
|
`4000+` numbering could stay as pure namespace (no reason to renumber
|
|
just because the aliasing risk is gone), or get simplified now that
|
|
nothing constrains it to a real device's address space. Not decided
|
|
here.
|