MINT: add a FORTH-79/83-standard-words-only lockdown personality

Captain Bob, 2026-09-07: "starting with that 00 user we created, we're
going to give access only to FORTH 79 and 83 standard words. everything
else is locked down."

New capsules/acl-std79.4th (blocks 4023-4047): walks a VM's own
dictionary (>LINK/LINK> traversal, same as ACL-INIT-PRIMITIVES/WORDS
already use) and permanently denies+pins every word not on an explicit
FORTH-79/83 allowlist, extracted from the real registered word set
(stack_words.c through control_words.c), not recited from memory.
Deliberately excludes, beyond plain non-standard words: BYE (100% ACL
bypass to the emergency console -- "needs more discussion, exclude for
now"), COLD/WARM/REBOOT/SAVE-SYSTEM (system lifecycle), the block/screen
editor L/S/SHOW/EDIT/UPDATE/SAVE-BUFFERS (lets a session rewrite
persistent block/capsule content, defeating the lockdown even though
nominally standard), BLK-ACL-*/BLK-OWNER@ (StarForth-specific), and
FORGET/FENCE (flagged as an unrestricted superpower word, 2026-09-03
audit). Keeps WORDS/VLIST/SEE (introspection only -- ACL is enforced
per-target-word at execution time regardless of how an XT was
obtained) and the parenthesized control-flow runtime primitives
((BRANCH) etc. -- IF/DO/LOOP compile calls to these; denying them
breaks ordinary control flow, not security).

MintPersonality enum (capsule_mint.h) lets capsule_mint_identity()
select which personality-source template gets written to a new
identity's devblock -- MINT_PERSONALITY_DEFAULT (unchanged) or
MINT_PERSONALITY_STD79_LOCKDOWN (EXECs acl-std79.4th then
ACL-LOCKDOWN-STD79 as the VM's own last bootstrap step). The actual
restriction logic stays entirely in FORTH per .claude/CLAUDE.md's
Word-Level ACL System rules ("ACL policy belongs in ACL.4th, never in
C") -- capsule_mint.c only picks which few-line bootstrap stub to
write. MINT's own stack signature gains a trailing restrict? flag;
capsule_zuse_boot.c's genesis mint (Zuse herself) explicitly passes
MINT_PERSONALITY_DEFAULT -- the superuser is never restricted.

Two real bugs found and fixed live during testing, both the same class
of self-referential fault: ACL-LOCKDOWN-STD79's own walk loop calls
ACL-STD79-ALLOWED?/ACL-STD79-LIST/ACL-ALLOW!/ACL-PIN on every single
iteration to do its job -- none of those are FORTH-79/83 standard
words, so the walk was denying its own load-bearing infrastructure
partway through and then faulting the next time it tried to call it
("VM fault -- emergency console disabled; halting", reproduced twice
live). Fixed by explicitly protecting all four in the allowlist
(block 4047) -- they must stay allowed for the walk to finish, not
because they belong on a "standard words" list.

Verified live end-to-end: minted a throwaway test identity with the
restrict? flag, confirmed her WIREBIND birth completes cleanly (no
faults, no shadow conflicts) on a single real attach, then USE'd into
her VM and confirmed standard arithmetic and user-defined words work
(1 2 + . -> 3; : X 5 5 * . ; X -> 25) while KILL is entirely unknown to
her dictionary and VM-EXEC is denied. One real, non-fatal side effect
found and left as-is (not asked to fix): the fleet's inter-VM messaging
pump (MSG-ARENA) is also denied by the lockdown, logging a harmless
per-idle-tick warning -- a fully locked-down VM doesn't participate in
message routing.

Not yet applied to the real identity 00 -- this commit is the
mechanism, verified against a disposable test identity only.

Three-arch clean qemu acceptance (single Zuse device, standard
regression case) passed on amd64, aarch64, and riscv64.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ec88YKxxhZGG1RNnune78
This commit is contained in:
Robert Allan James
2026-09-07 15:41:56 -04:00
co-authored by Claude Sonnet 5
parent 8471d529bc
commit f4ded3e1a8
10 changed files with 27224 additions and 9 deletions
+28 -2
View File
@@ -1,5 +1,5 @@
# Capsule Block Manifest — Auto-generated
<!-- Generated by mkcapsule --manifest 2026-09-07T16:39:49Z -->
<!-- Generated by mkcapsule --manifest 2026-09-07T19:31:34Z -->
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
<!-- Hand-written justifications and immutability notes live -->
<!-- in MANIFEST.md alongside this auto-generated index. -->
@@ -9,6 +9,7 @@
| Capsule | Blocks claimed | xxHash64 | Signed |
|---------|----------------|----------|--------|
| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4015 | `0xd781d22148ff171d` | yes |
| `acl-std79.4th` | 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047 | `0x5a622e41d1fd0bb9` | yes |
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853, 4854 | `0x1bb1886fc961c152` | yes |
| `block-acl.4th` | 4019, 4020 | `0xf6cc2a59e3a6734e` | yes |
| `common:messaging.4th` | 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5020, 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034, 5035, 5036, 5037, 5038, 5039, 5040 | `0x9cb26fa2d67465db` | yes |
@@ -113,6 +114,31 @@
| 4020 | `block-acl.4th` | `0xf6cc2a59e3a6734e` | ok |
| 4021 | `zuse-eligibility.4th` | `0x8b49c1bc1e01dc58` | ok |
| 4022 | `zuse-eligibility.4th` | `0x8b49c1bc1e01dc58` | ok |
| 4023 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4024 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4025 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4026 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4027 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4028 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4029 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4030 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4031 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4032 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4033 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4034 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4035 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4036 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4037 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4038 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4039 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4040 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4041 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4042 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4043 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4044 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4045 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4046 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4047 | `acl-std79.4th` | `0x5a622e41d1fd0bb9` | ok |
| 4050 | `lib.4th` | `0x4b216635c359ef73` | ok |
| 4055 | `common:msg.4th` | `0x850a0382344ea6c4` | ok |
| 4060 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
@@ -361,4 +387,4 @@
None.
---
*34 capsule(s) scanned. Re-run `mkcapsule --manifest <dir>` to refresh.*
*35 capsule(s) scanned. Re-run `mkcapsule --manifest <dir>` to refresh.*