docs(v4): ENGINE step 4 under MACHINE.md; Q1-Q5 and the identity gate ruled
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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d6eab090b4
commit
eef6c15c28
+43
-3
@@ -20,6 +20,46 @@ different machine executing its FORTH.
|
||||
|
||||
## 2. What stays, and what is replaced
|
||||
|
||||
> **Amended 2026-10-20 (Captain Bob): "MACHINE.md stands; v3 goes after parity; Hera, Hermes,
|
||||
> Artemis are now all kernel."** This section was written 2026-10-05, before `MACHINE.md`
|
||||
> (2026-10-15). Where they disagree, `MACHINE.md` §5.1 governs: once v4 is at parity, v3 leaves
|
||||
> every build, and with it the v3 VM, the Tripod, kernel-Hermes, the C ACL and the v3 PKI words.
|
||||
> So the design below — a node behind each v3 `VM` record, v3's interpreter functions answered by
|
||||
> a node (3c), v3's C words serving a node, the Tripod and kernel-Hermes kept — is withdrawn. Hera,
|
||||
> Hermes and Artemis are functions of the kernel, not VMs. v3 stays in the tree as the reference
|
||||
> until parity (`MACHINE.md` §7 item 3). What v4 does instead is
|
||||
> `plans/2026-10-20-engine-step4-node-in-the-vms-place.md`. Kept below as written.
|
||||
>
|
||||
> **Ruled the same day ("yes, Q1-Q5 as recommended"):**
|
||||
> 1. **Hera, Hermes and Artemis are functions of the kernel.** Hera is process management: the
|
||||
> registry, births, `NODE-KILL`, `NODE-SLEEP`, `NODE-WAKE` and who may ask (`v4/src/manage.c`).
|
||||
> The first node, which the kernel makes and POSTs, keeps the name Hera and is the root of the
|
||||
> birth graph. Hermes is messaging: the wires and the kernel's serving of them (`v4/src/wire.c`,
|
||||
> `message.c`), not `kernel_hermes.c`. Artemis is storage: the kernel serving blocks
|
||||
> (`v4/system/blocks.c`), the disk's genesis signature, and the owner's word that the disk may
|
||||
> be formatted. None has a capsule of its own.
|
||||
> 2. **Hestia likewise:** the console is the kernel's (HAL, REPL); there is no Hestia node.
|
||||
> 3. **What survives v3:** the kernel services that do not touch a v3 `VM` (the Stadium, the
|
||||
> heartbeat, the block subsystem, the capsule directory and its signatures, the disk signature,
|
||||
> the identity code: Zuse, mint, `WIREBIND`, `kernel/src/crypto`) stay, moved out of v3's
|
||||
> directories when v3 goes and keyed by node where they are keyed by VM today. What is a v3 VM
|
||||
> goes: `vm_core.c`, `arena.c`, `capsule_birth.c`, `mama_forth_words.c`, `kernel_hermes.c`,
|
||||
> sessions and the switcher as they hold `VM *`, the C ACL fields, `v3/src`'s interpreter and C
|
||||
> words.
|
||||
> 4. **A word's accounts** (ruling "A", `V3-PARITY.md` 1j) are kept by the kernel in a record of its
|
||||
> own per node and word ID, with the account fields `DictEntry` has; the Stadium's word layer is
|
||||
> fed from it. The physics loops are ported to it in their turn.
|
||||
> 5. **The words a node lacks** are written in FORTH in the layer `MACHINE.md` §3 gives them, or are
|
||||
> kernel requests where only the kernel can do it. v3's POST is the measure: each module's cases
|
||||
> join `v4/system/post_cases.c` when its words land. Parity is v3's whole POST passing on v4 and
|
||||
> the boot of `V3-PARITY.md` §1 done by v4's means.
|
||||
>
|
||||
> **And, the same day: "no identity thumb drive equals headless. When a thumb drive is inserted,
|
||||
> only then is there an identity and a console."** As v3 (`sk_repl_headless_wait`, `kernel_main.c`):
|
||||
> with no identity drive the system runs headless, with no prompt; a console and an identity exist
|
||||
> only once a drive is inserted. Work goes ahead only with the Zuse thumbdrive attached, so that
|
||||
> there is Zuse.
|
||||
|
||||
**Stays, untouched:** everything the kernel does. The Stadium and each
|
||||
patron's own accounts; sessions; the switcher; kernel-Hermes; the capsule
|
||||
directory, birth protocol, hashing, signing and parity; the block
|
||||
@@ -425,9 +465,9 @@ these, a group at a time, with POST after each.
|
||||
|
||||
| Open | Before |
|
||||
|---|---|
|
||||
| How the node tells a dictionary entry from a bare address at `call` | Step 3 |
|
||||
| `EXECUTE`, which enters a word by a return | Step 3 |
|
||||
| `>R R> R@ I J LEAVE`, which cannot be called | Step 3 |
|
||||
| ~~How the node tells a dictionary entry from a bare address at `call`~~ Ruled 2026-10-20: the kernel's table of entry addresses, filled by `(WORD-DEFINED)`, emptied by `(WORD-FORGOTTEN)`; a target not in it is a bare routine | Step 3 |
|
||||
| ~~`EXECUTE`, which enters a word by a return~~ Ruled 2026-10-20: `EXECUTE` calls the xt | Step 3 |
|
||||
| ~~`>R R> R@ I J LEAVE`, which cannot be called~~ Ruled 2026-10-20: they stay in line and are checked when the definition holding them is compiled; every other in-line word is called | Step 3 |
|
||||
| Who decides which node runs next, and when: Hera, by compudynamics; preemptive and cooperative | Step 7 |
|
||||
| The node's safe moment for message delivery and switching | Step 7 |
|
||||
| `PAD 42 OVER !`, a byte address given to `!` (D-1) | Step 6 |
|
||||
|
||||
@@ -222,6 +222,13 @@ v3 goes from every build as though it never existed:
|
||||
The Tripod, kernel-Hermes, the C ACL and the v3 PKI words go with it. v4 has rebuilt only the
|
||||
start of the Tripod (`hera.4th`).
|
||||
|
||||
**Ruled 2026-10-20 (Captain Bob): "MACHINE.md stands; v3 goes after parity; Hera, Hermes, Artemis
|
||||
are now all kernel."** This section governs where `ENGINE.md` §2 disagrees. Hera, Hermes, Artemis
|
||||
and Hestia are functions of the kernel, not VMs or nodes; the kernel services that do not touch a
|
||||
v3 `VM` (the Stadium, the heartbeat, the block subsystem, the capsule and disk signatures, the
|
||||
identity code) stay, moved out of v3's directories. `ENGINE.md` §2 records the rulings in full,
|
||||
with the one on identity: no identity thumbdrive, headless; a console only once one is inserted.
|
||||
|
||||
POST needs nothing from v3 at run time. `post_cases.c` is committed. `mkpost.py` needs a v3
|
||||
binary only to write the cases again.
|
||||
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
# 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 with `PATH="$PATH:/usr/share/gitkraken/resources/app.asar.unpacked/git/libexec/git-core" $G push -q origin StarForth-v4.0.0`. Messages end `Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>`.
|
||||
- v4 = v3 up to the first prompt; nothing stubbed, simulated or stood in for (`ENGINE.md` 1).
|
||||
- The engine in `v4/src` stays free of anything specific to StarForth or the kernel (`ENGINE.md` 3d).
|
||||
- A node may be stopped between any two instruction words (`ENGINE.md` 3a).
|
||||
- v3 stays in the tree and `system=v3` still 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 qemu` on amd64, aarch64,
|
||||
riscv64, one at a time, foreground, to `ok>`, `PARITY:V4_POST ... fail=0`, `POST: PASSED`, equal
|
||||
`dict_hash`; `make -C v4 test-32` 0 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`/`WAKE` and 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's `kernel_hermes.c`.
|
||||
- **Artemis** — storage: the kernel serving blocks (`v4/system/blocks.c` on the block subsystem),
|
||||
the disk's genesis signature, and the owner's word that the disk may be formatted (`ENGINE.md`
|
||||
step 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:
|
||||
1. **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.
|
||||
2. **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
|
||||
|
||||
1. **A word called through `EXECUTE` from inside a definition** must be seen by the hook exactly once, and the definition must go on after it. Pinned in A2.
|
||||
2. **`>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.
|
||||
3. **The 32-bit build**: the call hook and the called in-line words at 32-bit cells give the same results. Covered by `test-32` in every task.
|
||||
4. **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.
|
||||
5. **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.md` and `MACHINE.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; with `on_call = NULL` the result is the same.
|
||||
- [ ] **Step 2:** `make -C v4 test` — FAIL (no `on_call`).
|
||||
- [ ] **Step 3:** Add the hook; remove `v4_heat_on_call`, `call[]`, the freeze mask and `v4_heat_call_*`, and their tests.
|
||||
- [ ] **Step 4:** Suite passes at both widths and under sanitizers; `hosted-check` unchanged.
|
||||
- [ ] **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 same `dict_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 of `V3-PARITY.md` 1f, a definition using it produces a call the hook sees), `residue_stays_inline` (`>R R> R@ I J LEAVE` compile in line), `execute_passes_the_hook` (`' DUP EXECUTE` seen 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; `EXECUTE` calls 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.
|
||||
Reference in New Issue
Block a user