docs(v4.0.0): v4 against v3 up to the first prompt; row 3, physics and heat

Measures v4 against the ruling of 2026-10-05: v4 is exactly like v3 in
functional requirements up to the first FORTH prompt.  Twelve things v3 does
before its prompt, and what v4 does of each.  Row 3 in full: what v3 does
for every executed word and on every heartbeat tick, what a v4 node has,
what the v4 design documents say instead, the three places they conflict
with the ruling, and what each answer would take.  Lists the stand-ins
found in v4.  Proposes; decides nothing; nothing in it has been built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-05 16:40:41 -04:00
co-authored by Claude Opus 5.5
parent 2930349bbf
commit 2abaf51aee
+213
View File
@@ -0,0 +1,213 @@
# StarForth v4.0.0 — Parity with v3 up to the first prompt
Started 2026-10-05. This file measures v4 against one ruling:
> v4 is exactly like v3 in functional requirements up to the first FORTH
> prompt. That is the stopping point for now. (Captain Bob, 2026-10-05)
and a second, given the same day:
> I would never stub, simulate or develop outside of functional,
> as-intended code. Piecemeal is how errors and intent get hidden.
It records what v3 does, where in v3's code, what v4 does today, and what
has to be ruled before v4 can do the same. It proposes; it decides nothing.
Nothing described here as missing has been built.
## 1. What v3 does before its first prompt
From the bare-metal boot log `logs/20261003-100613/amd64/`, in order, after
the kernel's M0–M6 hardware milestones:
| # | v3 | v4 today |
|---|---|---|
| 1 | Stadium allocated (cells, 50 VM slots); switch-signal and kernel-Hermes channel tables | Missing |
| 2 | VM arena; 530 words registered | One node; 295 assembled words and 2 from the capsule |
| 3 | Physics live whenever a word executes: per-word heat, decay, rolling window, pipelining, L8 mode selector (61 mode changes during POST), heartbeat | Missing; see section 2 |
| 4 | POST: 1050 tests, every module (FORTH-79, StarForth extensions, ACL, Mama, Q48, inference, physics freeze) | 550 cases, FORTH-79 Required Word Set only |
| 5 | `PARITY:M7.1a` word count, here, latest, dictionary hash; `PARITY:OK`; `POST: PASSED` | Present, as `PARITY:V4_*` |
| 6 | PCI; virtio-blk attached; Artemis genesis signature | Missing. Blocks are a RAM array |
| 7 | Mama init capsule `init.4th`: signature checked, executed, `PARITY:MAMA_INIT` | v4 loads its own two capsules the same way; not `init.4th` |
| 8 | ACL: `BIRTH` and `CAPSULE-BIRTH` pinned strict | Missing. The ACL words are assembled but not loaded |
| 9 | Heartbeat running; Stadium conservation checks; quota and kernel-Hermes self-tests | Missing |
| 10 | Hestia born, then Artemis (disk formatted, self-test, K figures), each with `PARITY:BIRTH` | Missing. One node, no fleet |
| 11 | Kernel-Hermes fleet self-tests; USB mass storage; Zuse genesis minted on the thumbdrive | Missing |
| 12 | Banner with versions; `[zuse@Hera] ok>` | `ok>` alone |
Rows 1, 6, 9, 10 and 11 are messaging, blocks and the console's wider
setting. They are to be discussed before anything is written about them.
Section 2 is row 3.
## 2. Row 3: physics and per-word heat
### 2.1 What v3 does
**For every word a definition executes** — the inner loop,
`kernel/src/vm/vm_core.c:757-880`, and the same on the interpreter's path at
`:1053-1110`:
1. **Decay (Loop #3).** The word's heat is reduced by the ticks since it was
last touched times the decay slope, in Q48.16
(`physics_metadata_apply_linear_decay`, `v3/src/physics_metadata.c`). Not
for a frozen word, and not while L8 has gated Loop #3 off.
2. **Heat (Loop #1).** The word's `execution_heat` is raised by one.
3. **Stadium.** The word's ID, the VM's ID and the tick go to the Stadium's
conserved heat wire (`stadium_word_dispatch`).
4. **Rolling window (Loop #2).** The word's ID is recorded
(`rolling_window_record_execution`).
5. **Pipelining (Loop #4).** The transition from the previous word is
recorded, the most likely next word is worked out, and a likely one is
promoted to the hot-words cache.
6. **ACL.** The word's TTL is counted down, or the word rechecked at zero; a
denied word stops the definition.
7. The word runs. Then its physics record is touched (temperature, time) and
the heartbeat's count of words executed is raised.
**On every heartbeat tick** — `kernel/src/vm/vm_runtime.c`, driven by the
timer interrupt: `vm_tick`; the window tuner (Loop #5, `:158`); the slope
validator (Loop #6, `:228`); background decay (`:355`); the L8 mode update
(`:400`), which turns loops on and off; the inference engine (`:579`); and a
published snapshot.
**What each word carries** — `DictEntry`, `v3/include/vm.h:342-358`:
`execution_heat`; a `DictPhysics` record (temperature, last decay tick, mass,
state flags); a pointer to its transition metrics; a stable `word_id`; the
four ACL fields; and the `WORD_FROZEN` and `WORD_PINNED` flags.
All of this is running before the first prompt. POST itself executes under
it.
### 2.2 What v4 has
- A v4 word is native code. Executing one is the `call` opcode going to its
address. There is no inner loop, so there is no place in software where
v3's seven steps could happen.
- Short words are not called at all. `DUP`, `+`, `@`, `>R` and about fifty
others are compiled in line as opcodes (`header DUP inline`,
`v4/capsule/forth.v4`). At run time nothing says "this was `DUP`".
- The engine counts three things as instructions retire (`v4/src/exec.c`):
each opcode's count (32 counters), the anti-clock, and a count for each
call target.
- **The call-target count is a stand-in, by its own account.** It is a C
array beside the node, 4096 entries, written 2026-10-02
(`v4/src/heat.c`). A call to an address of 4096 or above is silently not
counted. The nucleus runs to about word 6300 and capsule definitions start
at 8192, so some assembled words and every capsule word get nothing. No
FORTH word can read it: `ACL-HEAT@` returns 0 (`v4/capsule/acl.v4:80`).
- A dictionary entry is three cells before the code — flags, name, link
(`v4/capsule/dict.v4`). It has no heat, no physics record, no word ID.
- There is no decay, rolling window, pipelining, inference, L8, heartbeat
or Stadium wire on the node.
### 2.3 What the v4 design documents say
The documents ruled on 2026-10-01 do not say "as v3". They say:
- `JUSTIFICATION.md` section 4, item 4: "Compudynamics as a side effect of
execution. Heat counters, the anti-clock, and the heartbeat are driven by
instruction retirement in hardware. They cost no instructions."
- `DECOMPOSITION.md` section 1.4: "every `call` increments the heat counter
of its target".
- `DECOMPOSITION.md` section 7: registers `HEAT-OP[0..31]`,
`HEAT-CALL[...]`, `ANTICLOCK`, `HEARTBEAT`, `GOV-*`.
- `DECOMPOSITION.md` sections 5.19 and 5.23 use the words "heat table" for
`HEAT-CALL` (`ENTROPY@`, `FREEZE-WORD`).
- D-6, **deferred**: "Which heat structures exist in hardware: per-opcode
counters only, or also per-call-target and word-to-word transition
counters. … The golden model implements per-opcode and per-call-target
heat in the meantime."
- Section 5.22: the six `PIPELINING-*` words are retired, to return "if D-6
adds transition counters". Section 5.21: the hot-words cache words are
retired as having no equivalent on a node.
So the 4096-entry array is the "in the meantime" of D-6, and "heat table"
is these documents' own term.
### 2.4 The conflict
Today's ruling and those documents do not say the same thing, in three
places. Each needs a ruling; none is mine to settle.
**A. Where a word's heat is kept.** v3: in the word's own dictionary entry.
The documents: in the node, as a register indexed by call target.
**B. What counts as a word.** v3 counts every execution of `DUP` as
`DUP`'s. v4 compiles `DUP` in line; what is counted is the `dup` opcode,
and a word built of several opcodes in line (`2DUP` is `over over`) leaves
no count of its own. v3's per-word heat for these words cannot be had from
a v4 node as it compiles now.
**C. Which loops exist.** v3 runs all seven and L8 before the prompt. The
documents retire Loop #4 (pipelining) and the hot-words cache, and leave
the rest to registers whose behaviour is not written down beyond their
names.
### 2.5 What each answer would take
Offered so that the ruling can be made knowing its cost. Not a plan.
**If heat is kept as v3 keeps it (A, v3's way).** Each entry gains cells
before its code, beside flags, name and link: heat, last-decay tick, word
ID, and what of `DictPhysics` is kept. `dict.v4`'s entry words, the header
macro of the text assembler and every assembled `header` line account for
them. The node, on `call`, finds the entry from the target address and does
steps 1 to 5 of section 2.1. Heat is then ordinary memory: `HEAT@` is a
fetch, and it is inside the dictionary, so the dictionary hash either
covers it or is defined to skip it, as v3's canonical hash skips it.
**If heat is kept as the documents have it (A, the node's way).** The
call-target counts become part of the node, cover every address of it, and
are readable through `HEAT-CALL` as a memory-mapped register, which needs
D-4, the memory map, settled. This is not "as v3" in where heat lives; it
is in what is counted.
**B either way.** Three ways, and they are not equivalent:
1. In-line words are counted by opcode: `DUP`'s heat is `HEAT-OP[dup]`.
Words that are more than one opcode in line have no heat. Not as v3.
2. Nothing is compiled in line except what must be (`>R`, `R>`, `R@`, `I`,
`J`, `LEAVE`: a call would bury the return address). Every other word is
called and so counted. As v3 for those words; slower, and the six that
must stay in line are still uncounted.
3. The compiler lays down a marker the node counts and does not execute.
That is a new opcode or a new use of one, which is a change to the
instruction set.
**C.** For each of Loops #2 to #7 and L8: where its state lives, what
advances it, and what the heartbeat is on a node that has no timer of its
own (v3's is the kernel's timer interrupt; the documents' is "in the
fabric"). v3's code for each is the reference: `rolling_window_of_truth.c`,
`physics_pipelining_metrics.c`, `inference_engine.c`, `ssm_jacquard.c`,
`vm_runtime.c`.
### 2.6 What depends on this
- **Decomposition.** Moving a word from assembler to a colon definition
does not change how it is called, but it turns in-line opcodes into
calls, which changes what is counted under every answer to B. It should
wait for B.
- **ACL.** v3's TTL comes from heat (`ACL-TTL-COMPUTE`). With `ACL-HEAT@`
returning 0 every word has the same TTL. Row 8 waits for A.
- **POST's other 500 cases** (row 4) include the physics-freeze and
inference modules, which test words that read and write heat.
- **K.** Nothing computes K on v4. It is a figure over heat; it waits for A
and C.
## 3. Stand-ins in v4, as found 2026-10-05
Each describes itself as one. None has been changed.
| What | Where | Says of itself |
|---|---|---|
| Per-call-target heat | `v4/src/heat.c`, `v4/include/v4/heat.h` | "in the meantime" (D-6) |
| `ACL-HEAT@` | `v4/capsule/acl.v4:80` | returns 0; "not readable from a programme yet" |
| Console | `v4/include/v4/node.h:136`, `:156` | "the model stands in for the console" until the mesh exists |
| Block storage | `v4/include/v4/node.h:248`, D-19 | "the model stands in" until the mesh carries the storage service |
| Memory map | `v4/tests/host_map.h`, D-4 deferred | a test header the product image is built from |
| CA public key | `v4/capsule/ACL.fth:40` | "placeholders, as in v3" |
| Address-dependent POST cases | `v4/tools/post79_rules.py`, `ADDRESS` | check how many values are left, not which |
`NUCLEUS.md` section 3 puts Q48, logging, ACL and the StarForth extensions
out of scope until FORTH-79 is accepted. Under the ruling at the head of
this file they are in scope, since v3 has them before its prompt. That
section is to be corrected once the rows above are ruled.