docs(v4.0.0): the F18 engine in the VM's place -- design
From the rulings of 2026-10-05 and v3's code. The kernel stays untouched; what is replaced is the part of a v3 VM that executes FORTH. Sets out the interface the kernel reaches a VM through (interpret this text, a character out, asking the kernel, the stacks and dictionary, a word being executed, an error, a tick, the dictionary hash), what a node needs for each, what becomes of the lone-node work, seven steps, and what is open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ff53ec4bb4
commit
ab7a9bf06f
@@ -0,0 +1,179 @@
|
||||
# StarForth v4.0.0 — The F18 engine in the VM's place
|
||||
|
||||
Design, 2026-10-05. Written from Captain Bob's rulings of that day
|
||||
(`V3-PARITY.md` sections 1a to 1h, where each is recorded with its words)
|
||||
and from v3's code. It replaces the lone-node assumptions of `NUCLEUS.md`
|
||||
sections 5.3 and 7 to 9.
|
||||
|
||||
## 1. The principle
|
||||
|
||||
`JUSTIFICATION.md` section 16: v4 is equivalent to v3 at any point in time;
|
||||
"the only difference is the machine underneath: the F18-derived engine
|
||||
instead of the original StarForth VM."
|
||||
|
||||
Ruled 2026-10-05: v4 is exactly like v3 in functional requirements up to
|
||||
the first FORTH prompt, and that is the stopping point for now. Nothing is
|
||||
stubbed, simulated or stood in for.
|
||||
|
||||
So v4 is not a new system beside LithosAnanke. It is LithosAnanke with a
|
||||
different machine executing its FORTH.
|
||||
|
||||
## 2. What stays, and what is replaced
|
||||
|
||||
**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
|
||||
subsystem and its devices; identity and Zuse; the HAL console, Hestia, the
|
||||
console proxies and the kernel's REPL; the heartbeat; the boot order in
|
||||
`kernel_main.c`.
|
||||
|
||||
**Replaced:** the part of a v3 VM that executes FORTH.
|
||||
|
||||
| v3 | v4 |
|
||||
|---|---|
|
||||
| The inner interpreter (`v3/src/vm.c`, `kernel/src/vm/vm_core.c`) | The node: `v4/src`, 32 opcodes |
|
||||
| The dictionary as a list of C `DictEntry` records | The dictionary in the node's memory (`v4/capsule/dict.v4`) |
|
||||
| The FORTH-79 words as C functions (`v3/src/word_source`) | The assembled nucleus (`v4/capsule/*.v4`) and colon definitions in `capsules/v4/forth79.4th` |
|
||||
| The outer interpreter and compiler in C | The same, in the nucleus |
|
||||
|
||||
A v3 VM is also a record the kernel keeps: its identity, its Stadium ID,
|
||||
its heartbeat state, its place in the registry, its Zuse flags. That
|
||||
record stays. What changes is what stands behind it.
|
||||
|
||||
## 3. The interface
|
||||
|
||||
The kernel reaches a VM through a small number of things. Each is listed
|
||||
with what v3 has, what was ruled, and what a node needs. This is the whole
|
||||
of the work: when a node answers all of these, the kernel's boot runs on
|
||||
it as it runs on a v3 VM.
|
||||
|
||||
### 3.1 Interpret this text
|
||||
|
||||
*v3:* `vm_interpret(vm, text)`. The kernel's REPL hands over each line it
|
||||
has read; `capsule_exec_payload` hands over each line of a capsule;
|
||||
kernel-Hermes hands over a message's payload when the target drains its
|
||||
queue. The VM runs the text and returns, with its error flag set or not.
|
||||
|
||||
*Ruled:* the kernel hands a node a whole line and takes characters back;
|
||||
the node's own prompt loop plays no part at that level. A node receives a
|
||||
message by being handed its text.
|
||||
|
||||
*v4:* the node has an entry that interprets the text in its input buffer
|
||||
and then stops, saying how the line ended: completed, ended in an error,
|
||||
or `QUIT`. It prints no prompt and no ` ok`. The buffer takes 1024
|
||||
characters, a block, as v3's does. `QUIT` and `ABORT` end the line and
|
||||
return to whoever handed it over. `KEY`, `EXPECT` and `QUERY` stay
|
||||
FORTH-79 words that read characters.
|
||||
|
||||
With this one entry v3's capsule loader, REPL and message drain can all
|
||||
drive a node, and `v4/system/boot.c`'s own loader is not needed.
|
||||
|
||||
### 3.2 A character out
|
||||
|
||||
*v3:* the host service `putc`, then `console_putc`; the fabric adds
|
||||
`[user@VM]`.
|
||||
|
||||
*v4:* the node's `EMIT` gives the character to its host, which calls the
|
||||
same service. Present today.
|
||||
|
||||
### 3.3 Asking the kernel
|
||||
|
||||
*v3:* a kernel word is a C function registered in the VM's dictionary:
|
||||
`BIRTH`, `KILL`, `USE`, the block words, the Stadium and Hermes words, the
|
||||
framebuffer words. It takes its arguments from the VM's data stack.
|
||||
|
||||
*Ruled:* a node asks for a block by number and the kernel decides the
|
||||
rest; a node sends a message by asking.
|
||||
|
||||
*v4:* a kernel word is a dictionary entry on the node whose code hands a
|
||||
request to the kernel, with its arguments on the node's data stack. The
|
||||
C functions are v3's. **How the request is carried is not designed yet**
|
||||
and is the first thing step 2 settles.
|
||||
|
||||
### 3.4 The stacks and the dictionary, from the kernel's side
|
||||
|
||||
*v3:* `vm_push`, `vm_pop`, `vm_find_word`, and the fields of a
|
||||
`DictEntry` (the kernel pins `BIRTH` and `CAPSULE-BIRTH` by setting two of
|
||||
them).
|
||||
|
||||
*v4:* the same operations on the node's stacks and on entries in the
|
||||
node's memory.
|
||||
|
||||
### 3.5 A word is being executed
|
||||
|
||||
*v3:* the inner loop, for every word: the ACL's countdown and recheck,
|
||||
`execution_heat`, `stadium_word_dispatch`, the rolling window, pipelining.
|
||||
|
||||
*Ruled:* the word card stays exactly as v3 — a run-time check, the TTL
|
||||
adaptive from the word's own count. Every kind of patron keeps its own
|
||||
accounts; the word's are as v3. Opcodes are counted and left unwired.
|
||||
|
||||
*v4:* the node dispatches a word at the `call` opcode, one place in the
|
||||
engine. The node does there what v3's loop does. A word that is to be
|
||||
checked must be called, so the in-line words that can be called become
|
||||
calls.
|
||||
|
||||
### 3.6 An error
|
||||
|
||||
*v3:* `vm->error`. *v4:* how a line ended (3.1), and the node's error
|
||||
register for a C function to raise one.
|
||||
|
||||
### 3.7 A tick
|
||||
|
||||
*v3:* the kernel's timer drives `vm_tick` and the heartbeat state in the
|
||||
VM's record. *v4:* unchanged; that state is the record's, not the
|
||||
engine's.
|
||||
|
||||
### 3.8 The dictionary hash
|
||||
|
||||
*v3:* `vm_dict_hash_fn`, a hook the birth protocol calls. *v4:* the same
|
||||
hook, answered from the node's dictionary.
|
||||
|
||||
## 4. What was built on the detour
|
||||
|
||||
| Built 2026-10-05 | What becomes of it |
|
||||
|---|---|
|
||||
| `kernel_main.c` calling `sk_v4_run()` before the fleet tables | Goes at step 4. Until then it is how the bare-metal build is kept booting while the interface is built. |
|
||||
| `v4/system/boot.c`: its own capsule loader and `PARITY:V4_*` lines | Goes at step 4, when v3's birth protocol loads the capsules and prints v3's parity lines. |
|
||||
| The node's prompt loop, and the code that strips ` ok` from its output | Goes at step 1. |
|
||||
| `capsules/v4/forth79.4th`, `post79.4th`, `mkpost.py`, the rules | Stay. POST is the gate for every word moved out of the nucleus. |
|
||||
| `(CATCH)`, `(EMIT-HOOK)`, `NODE-ERROR` by name | Stay; POST uses them. |
|
||||
| The per-call-target count (`v4/src/heat.c`, `call[]`) | Goes at step 3, when the node does at `call` what v3 does. |
|
||||
| The hosted Linux product | Stays, on the same interface. Hosted v3 has no fleet and neither has hosted v4. |
|
||||
|
||||
## 5. Steps
|
||||
|
||||
Each ends with all six builds booting and agreeing, and is committed with
|
||||
its logs.
|
||||
|
||||
1. **Interpret this text (3.1).** The node's line entry; no prompt loop.
|
||||
The hosts print the prompt and ` ok`, as v3's REPL does.
|
||||
2. **Asking the kernel, and the stacks from the kernel's side (3.3,
|
||||
3.4).** Settle how a request is carried. Kernel words callable from a
|
||||
node.
|
||||
3. **A word is being executed (3.5).** The hook at `call`; the ACL's
|
||||
countdown and recheck; the word's count; `stadium_word_dispatch`.
|
||||
In-line words become calls. The per-call-target count goes.
|
||||
4. **In place.** Under `STARFORTH_V4` the kernel's own boot brings the
|
||||
node up where it brings a v3 VM up, after the fleet tables; the
|
||||
kernel's REPL drives it; blocks come from the block subsystem.
|
||||
`sk_v4_run()` and `boot.c` go.
|
||||
5. **Hera as v3 has her.** `init.4th` runs on the node; v3's whole POST;
|
||||
v3's parity lines.
|
||||
6. **The fleet.** Hestia and Artemis; message delivery; the switcher.
|
||||
7. **Identity and the prompt.** Zuse; `[zuse@Hera] ok>`.
|
||||
|
||||
Moving words from the assembled nucleus to `forth79.4th` goes on beside
|
||||
these, a group at a time, with POST after each.
|
||||
|
||||
## 6. Open, and where each must be settled
|
||||
|
||||
| Open | Before |
|
||||
|---|---|
|
||||
| How a node's request to the kernel is carried | Step 2 |
|
||||
| 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 |
|
||||
| The node's safe moment for message delivery and switching | Step 6 |
|
||||
| `PAD 42 OVER !`, a byte address given to `!` (D-1) | Step 5 |
|
||||
| Which word patrons' accounts the hosted product keeps, having no Stadium | Step 3 |
|
||||
Reference in New Issue
Block a user