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:
co-authored by
Claude Sonnet 5
parent
8471d529bc
commit
f4ded3e1a8
@@ -0,0 +1,179 @@
|
||||
Block 4023
|
||||
( acl-std79.4th - FORTH-79/83 standard-word-only lockdown )
|
||||
( Denies+pins every dict word not on ACL-STD79-LIST below. )
|
||||
( Excludes: BYE, COLD/WARM/REBOOT/SAVE-SYSTEM, the block )
|
||||
( editor (L S SHOW EDIT UPDATE SAVE-BUFFERS), BLK-ACL-*, )
|
||||
( FORGET/FENCE. Kept: (BRANCH) etc -- IF/DO/LOOP compile )
|
||||
( calls to these; denying them breaks control flow. )
|
||||
( Full rationale: FABRIC-3.md, 2026-09-07. )
|
||||
CREATE ACL-STD79-LIST
|
||||
|
||||
Block 4024
|
||||
( Stack + return stack )
|
||||
' DROP , ' DUP , ' ?DUP , ' SWAP , ' OVER ,
|
||||
' ROT , ' -ROT , ' DEPTH , ' PICK , ' ROLL ,
|
||||
' >R , ' R> , ' R@ ,
|
||||
|
||||
Block 4025
|
||||
( Memory )
|
||||
' @ , ' ! , ' C@ , ' C! , ' +! , ' -! ,
|
||||
' 2@ , ' 2! , ' FILL , ' MOVE , ' ERASE ,
|
||||
' CELLS ,
|
||||
|
||||
Block 4026
|
||||
( Arithmetic )
|
||||
' + , ' - , ' * , ' / , ' MOD , ' /MOD ,
|
||||
' */ , ' */MOD , ' 1+ , ' 1- , ' 2+ , ' 2- ,
|
||||
' 2* , ' 2/ , ' ABS , ' NEGATE , ' MIN , ' MAX ,
|
||||
|
||||
Block 4027
|
||||
( Logical / comparison, part 1 )
|
||||
' AND , ' OR , ' XOR , ' NOT , ' INVERT ,
|
||||
' LSHIFT , ' RSHIFT , ' 0= , ' 0< , ' 0> ,
|
||||
' 0<> , ' = , ' <> ,
|
||||
|
||||
Block 4028
|
||||
( Logical / comparison, part 2 )
|
||||
' < , ' > , ' >= , ' <= , ' U< , ' U> ,
|
||||
' WITHIN , ' TRUE , ' FALSE ,
|
||||
|
||||
Block 4029
|
||||
( Mixed / double arithmetic, part 1 )
|
||||
' M+ , ' M- , ' M* , ' M/MOD ,
|
||||
' S>D , ' D+ , ' D- , ' DNEGATE , ' DABS ,
|
||||
' DMAX , ' DMIN , ' D< , ' D= ,
|
||||
|
||||
Block 4030
|
||||
( Mixed / double arithmetic, part 2 )
|
||||
' 2DROP , ' 2DUP , ' 2SWAP , ' 2OVER ,
|
||||
' 2ROT , ' 2>R , ' 2R> , ' 2R@ ,
|
||||
' D0= , ' D0< , ' D2* , ' D2/ ,
|
||||
|
||||
Block 4031
|
||||
( Formatted output )
|
||||
' . , ' .R , ' U. , ' U.R , ' D. , ' D.R ,
|
||||
' .S , ' ? , ' DUMP , ' <# , ' # , ' #S ,
|
||||
' #> , ' HOLD , ' SIGN , ' BASE ,
|
||||
' DECIMAL , ' HEX , ' OCTAL ,
|
||||
|
||||
Block 4032
|
||||
( Strings, part 1 )
|
||||
' COUNT , ' EXPECT , ' SPAN , ' QUERY ,
|
||||
' TIB , ' WORD , ' (s") , ' S" , ' >IN ,
|
||||
' SOURCE , ' BL , ' ['] ,
|
||||
|
||||
Block 4033
|
||||
( Strings, part 2 )
|
||||
' LITERAL , ' [LITERAL] , ' CONVERT ,
|
||||
' NUMBER , ' ENCLOSE , ' -TRAILING ,
|
||||
' CMOVE , ' CMOVE> , ' COMPARE ,
|
||||
' SEARCH , ' SCAN , ' SKIP , ' BLANK ,
|
||||
|
||||
Block 4034
|
||||
( I/O )
|
||||
' EMIT , ' CR , ' KEY , ' ?TERMINAL ,
|
||||
' TYPE , ' SPACE , ' SPACES ,
|
||||
' (do-string) , ' ." ,
|
||||
|
||||
Block 4035
|
||||
( Block -- read-only subset, no editor/writer )
|
||||
' BLOCK , ' BUFFER , ' FLUSH , ' LOAD ,
|
||||
' LIST , ' THRU , ' SCR , ' --> ,
|
||||
|
||||
Block 4036
|
||||
( Dictionary space )
|
||||
' HERE , ' ALIGN , ' ALLOT , ' , , ' C, ,
|
||||
' 2, , ' PAD , ' SP! , ' SP@ , ' LATEST ,
|
||||
|
||||
Block 4037
|
||||
( Dictionary internals -- introspection only; )
|
||||
( execution stays gated per-target-word. )
|
||||
' SMUDGE , ' HIDDEN , ' >BODY , ' >NAME ,
|
||||
' NAME> , ' >LINK , ' LINK> , ' CFA ,
|
||||
' LFA , ' NFA , ' PFA , ' TRAVERSE ,
|
||||
' INTERPRET , ' FIND ,
|
||||
|
||||
Block 4038
|
||||
( Vocabulary / search order )
|
||||
' VOCABULARY , ' DEFINITIONS , ' CONTEXT ,
|
||||
' CURRENT , ' FORTH , ' ORDER , ' (FIND) ,
|
||||
|
||||
Block 4039
|
||||
( System -- lifecycle words excluded )
|
||||
' WORDS , ' VLIST , ' SEE , ' PAGE ,
|
||||
' EXECUTE , ' NOP , ' QUIT , ' ABORT ,
|
||||
' (ABORT") , ' ABORT" , ' ( , ' \ ,
|
||||
|
||||
Block 4040
|
||||
( Defining words -- FORGET/FENCE excluded )
|
||||
' : , ' ; , ' CREATE , ' VARIABLE ,
|
||||
' CONSTANT , ' IMMEDIATE , ' STATE ,
|
||||
' [ , ' ] , ' COMPILE , ' [COMPILE] ,
|
||||
' LIT , ' DOES> ,
|
||||
|
||||
Block 4041
|
||||
( Control flow runtime primitives -- kept, )
|
||||
( IF/DO/LOOP compile calls to these. )
|
||||
' (BRANCH) , ' (0BRANCH) , ' (?DO) ,
|
||||
' (DO) , ' (LOOP) , ' (+LOOP) , ' (LEAVE) ,
|
||||
|
||||
Block 4042
|
||||
( Control flow, part 1 )
|
||||
' IF , ' ELSE , ' THEN , ' BEGIN ,
|
||||
' WHILE , ' REPEAT , ' AGAIN , ' UNTIL ,
|
||||
|
||||
Block 4043
|
||||
( Control flow, part 2 )
|
||||
' ?DO , ' DO , ' LOOP , ' +LOOP ,
|
||||
' LEAVE , ' I , ' J , ' UNLOOP ,
|
||||
' EXIT , ' CASE , ' OF , ' ENDOF ,
|
||||
' ENDCASE ,
|
||||
|
||||
Block 4044
|
||||
( ACL-STD79-ALLOWED? ( xt -- flag ) )
|
||||
: ACL-STD79-ALLOWED? ( xt -- flag )
|
||||
>R
|
||||
ACL-STD79-LIST
|
||||
BEGIN
|
||||
DUP @
|
||||
WHILE
|
||||
DUP @ R@ = IF R> DROP DROP TRUE EXIT THEN
|
||||
1 CELLS +
|
||||
REPEAT
|
||||
DROP R> DROP FALSE ;
|
||||
|
||||
Block 4047
|
||||
( ACL-LOCKDOWN-STD79's own walk loop calls all )
|
||||
( four of these on every iteration -- if the )
|
||||
( walk denied any one, it would deny its own )
|
||||
( ability to keep running: a real self- )
|
||||
( referential fault caught live 2026-09-07 (VM )
|
||||
( fault, emergency console disabled), twice, one )
|
||||
( word at a time. Must all stay allowed. Sentinel )
|
||||
( last. )
|
||||
' ACL-STD79-LIST , ' ACL-STD79-ALLOWED? ,
|
||||
' ACL-ALLOW! , ' ACL-PIN ,
|
||||
0 , ( sentinel )
|
||||
|
||||
Block 4045
|
||||
( ACL-WALK-MARK's own xt = correct walk- )
|
||||
( start (the true dictionary head at the )
|
||||
( moment the walk runs). Same >LINK/LINK> )
|
||||
( traversal ACL-INIT-PRIMITIVES/WORDS use. )
|
||||
: ACL-WALK-MARK ( -- ) ;
|
||||
|
||||
Block 4046
|
||||
: ACL-LOCKDOWN-STD79 ( -- )
|
||||
['] ACL-WALK-MARK
|
||||
BEGIN
|
||||
DUP
|
||||
WHILE
|
||||
DUP ACL-STD79-ALLOWED?
|
||||
IF 1 OVER ACL-ALLOW!
|
||||
ELSE 0 OVER ACL-ALLOW!
|
||||
THEN
|
||||
DUP ACL-PIN
|
||||
DUP >LINK LINK>
|
||||
SWAP DROP
|
||||
REPEAT
|
||||
DROP ;
|
||||
Reference in New Issue
Block a user