feat(v4.0.0): the nucleus is a capsule, sent to a node born empty

MESH.md step 2.  A capsule of F18 code is the words a neighbour writes to a
node's port: for each stretch of memory, "@p a! @p push", the address and
count, "@p !+ unext" and the words; then a jump to the start.  A node born
empty executes that from its port, so it needs nothing in it beforehand.

- capsule.h/.c: v4_capsule_write, any node's memory as such a capsule
- mkimage writes the nucleus so, to capsules/v4/nucleus-64.f18, and the
  addresses a host needs as a C file; the memory image is no longer linked
  into either product
- mkcapsule is unchanged: the nucleus capsule is a built file kept under
  capsules/, as BLOCK_MAP.md is, and is baked, hashed and signed with the
  rest
- boot: the node is born empty (v4_image_born); the nucleus capsule is
  found, its hash and signature checked, and given to the node a word at a
  time as it reads its port; PARITY:V4_NUCLEUS carries its name and hash

Verified: test_fabric.c (59 checks, both widths, and under ASan and UBSan):
a memory with a programme and scattered words arrives word for word in an
empty node and runs.  The nucleus capsule rebuilds byte for byte.
hosted-check passes on three ISAs; clean qemu with STARFORTH_V4=1 on amd64,
aarch64 and riscv64 takes the nucleus in, passes POST (550 of 550) and
answers lines typed at each prompt (logs/20261006-102421, -102706,
-103048).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-06 10:33:15 -04:00
co-authored by Claude Opus 5.5
parent 9af442f793
commit 42610e844f
17 changed files with 718 additions and 88 deletions
+29 -8
View File
@@ -149,14 +149,15 @@ to 8 and are made of capsule code and of the host that owns the devices.
## 5. A capsule of F18 code, and how an empty node takes it in
**Proposal.** A capsule of F18 code is words of memory and where they go:
runs of `(address, count, the words)`, and the address to start at. The
nucleus image `mkimage` writes today is this already, as a C file linked
into the binary; it becomes a capsule in the capsule directory, with a
name, a hash and a signature like any other. (`mkcapsule` takes what is
under `capsules/`; the nucleus is built, not written. How a built file
enters the directory is to be settled when this is reached, and reported
before it is done, since `mkcapsule` is v3's tool too.)
**As built.** A capsule of F18 code is not a format a node has to
understand. It is the words a neighbour writes to the node's port, in the
order they are written: for each stretch of memory that is not zero the
two instruction words below with their address and count and then the
words themselves, and at the end a jump to where to start. The file is
those words, each in a cell's bytes, low byte first, and its hash is the
hash of exactly what is sent. The nucleus is one, in the capsule directory
with a name, a hash and a signature like any other. `mkcapsule` was not
changed: the nucleus capsule is a built file kept under `capsules/v4/`.
A neighbour puts it into an empty node by writing to the port between
them, and the node executes what arrives (4.1). For each run it sends
@@ -264,6 +265,26 @@ Each is tested, committed and pushed before the next.
(`logs/20261006-074907`, `-075150`, `-075532`).
2. **The nucleus as a capsule, and an empty node made a StarForth node
through its port (section 5).**
**Done 2026-10-06.** `v4/src/capsule.c`, `v4_capsule_write`: any
node's memory as the words to send an empty node. `mkimage` writes the
nucleus so, to `capsules/v4/nucleus-64.f18`, a built file kept in the
tree as `BLOCK_MAP.md` is; `mkcapsule` is unchanged and bakes, hashes
and signs it with the rest. The boot's node is born empty
(`v4_image_born`) and is given the nucleus a word at a time as it reads
its port, after the capsule's hash and signature are checked
(`v4/system/boot.c`). Nothing of the nucleus is linked into either
product any more. `test_fabric.c`: a memory with a programme and words
here and there arrives word for word and runs. Both products boot so:
`hosted-check` on three ISAs; `logs/20261006-102421`, `-102706`,
`-103048`.
**What a newborn node still has from its host:** the registers the
nucleus expects — the console's three, the two stack registers, the
error register, the fault table's address, the storage registers — are
attached by the host when the node is born, from the description
`mkimage` writes. They are the node's hardware as the golden model has
it, at addresses the memory map (D-4, still open) will fix. The console
and storage ones go when those become devices on ports (steps 3 and
6).
3. **Messages (section 6):** a StarForth node that reads messages when
idle; the console as a device; a line typed is a message.
4. **Finding the way (section 7).**