MACHINE.md stands: v3 goes after parity; Hera, Hermes, Artemis (and Hestia) are kernel functions. ENGINE.md section 2 amended with the rulings, section 6's step-3 rows struck (R2). The step 4 plan rewritten: Part A (hook at call, called in-line words) and Phases 1-8 to parity. No identity thumbdrive, headless; work goes ahead only with Zuse attached. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
14 KiB
ENGINE Step 4, revised under MACHINE.md: v4 in the kernel's boot — Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans (Captain Bob prefers native execution). Steps use checkbox (
- [ ]) syntax for tracking.
Goal: On bare metal, v4 boots in the kernel's boot, not before it: the kernel brings up its
own services, then the v4 system, then does what v3 does before its first prompt, through the
kernel and the nodes, never through a v3 VM. When v4 is shown at parity, v3 leaves the build
(MACHINE.md §5.1, §6 step 6, §7 item 3).
What changed (RULED 2026-10-20, Captain Bob): "MACHINE.md stands; v3 goes after parity; Hera,
Hermes, Artemis are now all kernel." The first version of this plan followed ENGINE.md §2: a
node behind each v3 VM record, a third interpreter file answering v3's engine functions, v3's C
words served to nodes, the Tripod and kernel-Hermes kept. That is withdrawn. Nothing is put behind a
v3 VM; v3 is kept only as the reference until parity.
Spec: docs/v4.0.0/MACHINE.md (governs), ENGINE.md §3, 3a, 3b, 3d and §5 step 3 (stand where
they do not conflict), V3-PARITY.md §1 to §1j (what v3 does before its prompt; the yardstick),
MESH.md §9 and §9a (the kernel's registry, births, KILL).
Global Constraints
- Branch
StarForth-v4.0.0, main checkout. Never create a branch, never stash, never--no-verify. - Commit with
G="git -c filter.lfs.process= -c filter.lfs.clean=cat -c filter.lfs.smudge=cat -c filter.lfs.required=false"; push withPATH="$PATH:/usr/share/gitkraken/resources/app.asar.unpacked/git/libexec/git-core" $G push -q origin StarForth-v4.0.0. Messages endCo-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>. - v4 = v3 up to the first prompt; nothing stubbed, simulated or stood in for (
ENGINE.md1). - The engine in
v4/srcstays free of anything specific to StarForth or the kernel (ENGINE.md3d). - A node may be stopped between any two instruction words (
ENGINE.md3a). - v3 stays in the tree and
system=v3still boots until parity is shown; nothing in v3's own path changes (MACHINE.md§7 item 3). v3 is not part of acceptance. - Compose in FORTH first; a kernel request only for what only the kernel can do.
- Never apply a fix that is not in this plan; report it.
- Suite per task:
make -C v4 test test-32 sanitize hosted-check. - Acceptance per kernel-affecting increment:
make ARCH=<isa> clean qemuon amd64, aarch64, riscv64, one at a time, foreground, took>,PARITY:V4_POST ... fail=0,POST: PASSED, equaldict_hash;make -C v4 test-320 failures; logs committed.
What becomes of the first plan's rulings
| First plan | Now | |
|---|---|---|
| R1 | MESH inc 2, then this | Done (6cb8f128). |
| R2 | Step 3: hook at call; EXECUTE calls; all in-line words but >R R> R@ I J LEAVE called |
Stands (Part A). |
| R3 | Third interpreter file replaces vm_core.c; system= goes |
Gone. No v3 function is answered by a node, so both systems link as today; system= and STARFORTH_V4=0 go with v3 at the end (§5.1). |
| R4 | v3 C words on a node by stack copy and copy helpers | Gone. v3's C words are not served to nodes. |
| R5 | Every v3 C word a node lacks becomes a KERNEL-WORD served by v3's function |
Replaced by Q3. |
| R6 | v3's POST run on the node, failures listed | Replaced by Q5. |
| R7 | A node behind each VM the boot births | Gone. The fleet is the nodes' (MESH 8 and 9); Hera, Hermes and Artemis are the kernel's. |
Rulings (Captain Bob)
RULED 2026-10-20: "yes, Q1-Q5 as recommended", recorded in ENGINE.md §2 and MACHINE.md §5.1
(Task 0). And with it: "go ahead only if zuse thumbdrive is attached so you have zuse. no identity
thumb drive equals headless. when a thumb drive is inserted, only then is there an identity and a
console." So no task's acceptance boot is run without Zuse: the Zuse thumbdrive is attached and
minted, and the boot recognises it. Today it does not: the drive QEMU attaches by default,
disk/thumbdrives/zuse-thumb-ident.img, is all zeros (bleached, e56974e0), and the v4 boot reads
no thumbdrive and prints its prompt with no identity. See "The identity gate" below.
Q1. What "Hera, Hermes, Artemis are kernel" means in v4. Recommend: each is a function of the kernel, not a VM or node with a capsule of its own:
- Hera — process management: the registry, births,
NODE-KILL/SLEEP/WAKEand who may ask (v4/src/manage.c, already the kernel's, MESH 9a.4). The first node, which the kernel makes and POSTs and whose prompt the console shows, keeps the name Hera, as[zuse@Hera] ok>needs, and is the root of the birth graph;hera.4th's words stay the commands she types. - Hermes — messaging: the wires and the kernel's serving of them (
v4/src/wire.c,message.c, the GONE the kernel tells). Not v3'skernel_hermes.c. - Artemis — storage: the kernel serving blocks (
v4/system/blocks.con the block subsystem), the disk's genesis signature, and the owner's word that the disk may be formatted (ENGINE.mdstep 7). No Artemis capsule.
Q2. Hestia. Not named in the ruling. v3's Hestia is a VM owning console policy (V3-PARITY.md
1b). Recommend: the same as the other three — the console is the kernel's (HAL, REPL), with no
Hestia node.
Q3. Which of v3's kernel code survives v3. MACHINE.md §5.1 sends kernel/src/vm/,
kernel/src/capsule/ and v3/src out of the kernel. Some of what lives there does not touch a v3
VM at all: the Stadium (stadium.c, stadium_words.c, stadium_blocks.c, keyed by VMUuid),
the heartbeat (kernel/src/heartbeat.c), the block subsystem (v3/src/block_subsystem.c, which
v4 already uses), the capsule directory and its signatures, the disk signature, and the identity code
(Zuse, mint, WIREBIND, kernel/src/crypto).
Recommend: these are the kernel's and stay, moved out of v3's directories when v3 goes, keyed by
node number where they are keyed by VM today. What goes is what is a v3 VM: vm_core.c, arena.c,
capsule_birth.c, mama_forth_words.c, kernel_hermes.c, sessions and switcher as they hold
VM *, the C ACL fields, v3/src's interpreter and C words. If not: each of those services is
rewritten for v4 before parity, which is most of the kernel.
Q4. Where a v4 word's accounts are kept (ruling "A", V3-PARITY.md 1j: code the node's,
accounts the kernel's, joined by word ID). "A" named v3's DictEntry, which goes with v3.
Recommend: the kernel keeps, per node and word ID, a record of its own with the account fields
DictEntry has (execution_heat, the physics record, the four ACL fields, the transition metrics,
the word ID), and the Stadium's word layer is fed from it (stadium_word_dispatch takes a VM ID and
a word ID, not a DictEntry). The physics loops (v3/src/physics_*, rolling_window_of_truth.c,
inference_engine.c, ssm_jacquard.c) walk DictEntry lists today; each is ported to the record
when its turn comes (Phase 7).
Q5. The words v3 has and a node lacks, and the yardstick. v3 has 526 words before its prompt;
a node has 317. Recommend: each missing word is written in FORTH in the layer MACHINE.md §3
gives it (forth79.4th, starforth.4th, a system capsule), or is a kernel request where only the
kernel can do it (blocks, births, the Stadium, identity, the framebuffer). v3's POST is the measure:
each module's cases are added to v4/system/post_cases.c (by mkpost.py, from the v3 binary) when
its words land, and must pass. Parity is v3's whole POST passing on v4 plus the boot of
V3-PARITY.md §1, rows 1 to 12, done by v4's means.
The identity gate (2026-10-20)
v3 as built: with no identity drive the kernel waits headless (sk_repl_headless_wait,
kernel_main.c), servicing the heartbeat and watching USB; capsule_zuse_boot_try_attach
recognises Zuse's drive when it arrives, and only then is there a prompt ([zuse@Hera] ok>).
The v4 boot does none of this. Until it does, the condition for going ahead cannot be met by any
boot. Two things are needed, and are put to Captain Bob:
- A minted Zuse drive. Re-minting the committed images is his call; a scratch copy can be
minted by a v3 boot (
ZUSEDISK=<scratch>/zuse.img, genesis minted on first boot) without touching the committed one. - The gate on v4: the headless wait and Zuse's recognition, done by the kernel for the v4 boot, ahead of Part A, moved forward from Phase 6.
Phases
Each phase is its own plan, written when the one before it is accepted. Each ends with full acceptance. Only Part A is written in tasks below; it does not depend on Q1 to Q5.
| Phase | What | V3-PARITY.md §1 rows |
|---|---|---|
| A | ENGINE.md step 3, engine side: the hook at call; EXECUTE and the in-line words called |
(3, 8: the hook they need) |
| 1 | v4 in the kernel's boot. sk_v4_run() before everything goes. The kernel's order runs as v3's does: hardware, the Stadium, the heartbeat, then the v4 system on the first node (Hera) with POST, then the devices (PCI, the disk), then the kernel's REPL hands lines to Hera. The registry and births (manage.c) come into the kernel build: MESH step 9. |
1, 2, 5, 6, 9 |
| 2 | Word accounts at call (Q4): the kernel's record per word; at each call, execution_heat, stadium_word_dispatch, the ACL countdown. |
3 (part), 8 (part) |
| 3 | init.4th (MACHINE.md §6 step 3) and starforth.4th: the StarForth words, with their POST modules. |
4 (part), 7 |
| 4 | ACL: ACL.4th on v4, the word card from Phase 2, BIRTH and CAPSULE-BIRTH pinned; the ACL module of POST. |
8 |
| 5 | Artemis, the kernel's: the disk's genesis signature, formatting by the owner's word, writes. | 6, 10 (Artemis) |
| 6 | Identity and the prompt: Zuse, the thumbdrive, WIREBIND, EJECT; the banner; [zuse@Hera] ok>. |
11, 12 |
| 7 | Physics on the word records: decay, rolling window, pipelining, inference, L8; the physics-freeze and inference POST modules. v3's whole POST passes: parity. | 3, 4 |
| 8 | v3 leaves the build (MACHINE.md §6 step 6). |
— |
Review Focus
- A word called through
EXECUTEfrom inside a definition must be seen by the hook exactly once, and the definition must go on after it. Pinned in A2. >R ... R>around a call (the six in-line words beside called ones): a called word must not disturb a return-stack value the caller pushed. Pinned in A2.- The 32-bit build: the call hook and the called in-line words at 32-bit cells give the same results. Covered by
test-32in every task. - A definition that runs past the end of its text while the hook is set (an abandoned definition): the hook sees no call into it. Pinned in A2.
- Speed: every in-line word becoming a call slows the node; POST and the depth sweep must still finish under QEMU TCG in the time the acceptance boots allow. Measured in A2 (boot time before and after recorded in the commit message).
Part A — ENGINE.md step 3, engine side
Task 0: Record the rulings
Files: docs/v4.0.0/ENGINE.md (§2, §3c, §5 steps 3 and 4, §6), docs/v4.0.0/MACHINE.md (§5.1).
- Step 1: Write the 2026-10-20 ruling and the approved Q1 to Q5 into
ENGINE.mdandMACHINE.md§5.1, with Captain Bob's words and the date; strike §6's three rows settled by R2. - Step 2: Commit
docs(v4): ENGINE step 4 under MACHINE.md.
Task A1: A generic hook at call
Files: Modify v4/src/exec.c (V4_OP_CALL), v4/include/v4/exec.h; v4/src/heat.c, v4/include/v4/heat.h (the per-call-target count goes, ENGINE.md 4, V3-PARITY.md 2.7). Test: v4/tests/test_exec.c.
Interfaces: Produces typedef void (*v4_call_hook)(void *ctx, v4_node *n, v4_cell target); and, in v4_exec_state, v4_call_hook on_call; void *on_call_ctx;. Called at V4_OP_CALL after the return address is pushed, before n->p moves. NULL = no hook.
- Step 1: Failing test
test_call_hook_sees_every_call: a programme calling three routines, one twice; the hook records the four targets in order; withon_call = NULLthe result is the same. - Step 2:
make -C v4 test— FAIL (noon_call). - Step 3: Add the hook; remove
v4_heat_on_call,call[], the freeze mask andv4_heat_call_*, and their tests. - Step 4: Suite passes at both widths and under sanitizers;
hosted-checkunchanged. - Step 5: Commit
feat(v4): a hook at call, for whoever runs the node. (No boot change: nothing sets the hook on bare metal yet. One amd64 boot to confirm POST 538/538 and the samedict_hash.)
Task A2: Words that are checked are called
Files: Modify capsules/v4/sys/compile.f18 ((CALL,) and the in-line table), the .f18 file that defines EXECUTE. Test: v4/tests/test_host_compile.c; the 538 POST cases; test_host_depth.c.
Interfaces: Consumes A1's hook (the test sets it to observe).
- Step 1: Failing tests
inline_words_are_called(for each callable in-line word ofV3-PARITY.md1f, a definition using it produces a call the hook sees),residue_stays_inline(>R R> R@ I J LEAVEcompile in line),execute_passes_the_hook(' DUP EXECUTEseen once; Review Focus 1, from inside a definition that goes on after),rstack_kept_across_call(Review Focus 2),abandoned_definition_not_called(Review Focus 4). - Step 2: Run — FAIL.
- Step 3: The compiler's in-line table becomes the six;
EXECUTEcalls the xt. Regenerate the maps (make -C v4 sysmap). - Step 4: Suite passes; POST 538/538; record the new
dict_hash(equal at both widths' products as before). - Step 5: Full acceptance (three boots, test-32; boot times before and after, Review Focus 5); commit
feat(v4): every word but the six is called, so it can be checked, then the logs.
Phase 1's plan is written when Part A is accepted and Q1 to Q5 are ruled.