feat(v4.0.0): the node tells its kernel of its words; the boot seals the system

ENGINE.md 3b, the node's side of ruling A (a word's code is the node's, its
accounts the kernel's).

- dict.v4, system.v4: (WORD-DEFINED) ( xt -- ) is run when an entry is
  made, (WORD-FORGOTTEN) ( w -- ) when FORGET or COLD removes entries; with
  0 there no one is told, as on the hosted product
- test_host_quit.c: a kernel that keeps the list of words and is checked to
  hold exactly the node's dictionary after definitions, a vocabulary, an
  abandoned definition, FORGET, a refused FORGET and COLD; KERNEL-WORD
  called from the prompt and from a definition

Fixed, found while writing that test: since the capsules moved from build
time to boot time (294e6946), what COLD returns to and FORGET protects was
still the nucleus alone, so COLD lost U*, U/MOD and BYE and FORGET U* was
allowed.  The boot now seals the system when it has loaded it
(v4_image_seal), and hosted-check checks COLD, the capsule word after it,
the refused FORGET and BYE.

Verified: make -C v4 test passes at both widths (1283 checks in
test_host_quit.c); hosted-check passes on three ISAs; clean qemu with
STARFORTH_V4=1 on amd64, aarch64 and riscv64 passes POST, and COLD, U*
after it, FORGET U* (refused), an unserved kernel word and BYE typed at
each prompt are answered correctly (logs/20261005-193045, -193307, -193636).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-05 19:38:40 -04:00
co-authored by Claude Opus 5.5
parent e8e8ea13ea
commit 25fc5fd5e3
16 changed files with 609 additions and 15 deletions
+7
View File
@@ -69,3 +69,10 @@ int v4_line_status(const v4_node *n, const v4_image *im)
{
return (int)n->mem[im->line_status];
}
void v4_image_seal(v4_node *n, const v4_image *im)
{
n->mem[im->boot_cells] = n->mem[im->dp];
n->mem[im->boot_cells + 1] = n->mem[im->latest];
n->mem[im->fence] = (n->mem[im->dp] + 3) / 4;
}