Phase 8: zuse cert storage moved out of the dictionary (fuse-blow install)

Found that a pinned CONSTANT is not actually tamper-proof: ACL-PIN only
blocks redefinition, not a >BODY-then-store on the word's existing data
field. Moves the Zuse cert value into C-only VM struct fields
(zuse_cert_lo/hi + zuse_cert_installed fuse bit) with a one-time
vm_zuse_cert_install() and read-only ZUSE-CERT-LO@/HI@/INSTALLED? FORTH
accessors, closing the tamper path structurally instead of by convention.
Deletes the now-insecure ZUSE-CERT-LO/HI CONSTANT words from zuse.4th.

vm_zuse_cert_install() has no caller yet -- the real mint flow (Milestone
6 CA, the MINT word) is still open; this is storage + accessors only, not
a stand-in mint. Documented in FABRIC-3.md. Verified: hosted build clean,
mkcapsule --lint clean (31/31), clean boot to ok> on amd64/aarch64/riscv64
with Stadium conservation intact and no panics.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U14ET9CWAtbQMbYqomKgXd
This commit is contained in:
Robert Allan James
2026-08-26 13:58:22 -04:00
co-authored by Claude Sonnet 5
parent 4dd1321ea4
commit 6f5605d479
14 changed files with 27217 additions and 10 deletions
+30
View File
@@ -316,6 +316,36 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
**Still open, not attempted:** the mint-then-pin boot-sequence fix itself, the `MINT` word,
and the Zuse recovery path.
**Correction, supersedes the "reuse `acl_pinned`" resolution above (2026-08-26): a pinned
`CONSTANT` is not actually tamper-proof.** `ACL-PIN`/`acl_pinned` only guards against
*redefinition* — `vm_create_word()`'s pin check blocks a second `: ZUSE-CERT-LO ... ;`, but
nothing stops `' ZUSE-CERT-LO >BODY !` from overwriting the same word's data field in place.
A `CONSTANT`'s value lives in its data field, so the earlier design left the cert mutable
from FORTH despite being "pinned." Found while starting the mint-then-pin boot-sequence fix
itself; fixing that gap came first since building a real mint flow on top of a tamperable
store would just re-open the hole later.
**Fixed (2026-08-26): moved cert storage out of the dictionary entirely.** New
`VM` struct fields (`include/vm.h`): `zuse_cert_lo`/`zuse_cert_hi` (the cert value) +
`zuse_cert_installed` (one-time fuse bit). New `vm_zuse_cert_install(vm, lo, hi)`
(`src/vm.c`) — C-only, no FORTH word wraps it, returns `-1` on a second call rather than
silently re-installing (a second call is a caller bug, not a runtime condition to recover
from). No FORTH store word exists or should exist for these fields, closing the `>BODY`
path structurally rather than by convention. Three new read-only C primitives
(`src/word_source/starforth_words.c`, same shape as the existing `HEARTBEAT-TICKS@`):
`ZUSE-CERT-LO@`, `ZUSE-CERT-HI@`, `ZUSE-CERT-INSTALLED?`. `capsules/zuse.4th`'s old
`ZUSE-CERT-LO`/`HI` `CONSTANT` words (and `ACL-ZUSE-BOOT`'s two now-pointless `ACL-PIN`
calls on them) deleted outright rather than left as dead/insecure scaffolding — `mkcapsule
--lint` clean (31/31) after the edit. `vm_zuse_cert_install()` has no caller yet: the real
mint flow still doesn't exist (Milestone 6 CA + the `MINT` word are both still open), and
calling it with a placeholder value would just be a stub wearing the shape of a fix — so
this stays an honest, complete slice (storage + read accessors) with the actual mint-then-
pin sequence still explicitly open, not faked. **Verified:** hosted `make` build clean,
zero warnings; clean boot to `ok>` on all three architectures (amd64/aarch64/riscv64),
Stadium conservation intact (43691/21845/65536) on all three, no panics or guest errors.
ACL is opt-in (`init.4th`'s `S" ACL.4th" EXEC` commented out by default) so the new words
weren't exercised live from the REPL this pass — compile/lint/boot verification only.
### From FABRIC-2.md §X, Milestone 5 — Console/VM key-match binding
- [ ] Settle the still-open question: reuse `ACL-PIN`/`acl_allow` directly, or build a