Rewrote EXEC-STD79-DOE-CD's dispatch to coordinate via MSG-SEND/ MSG-TICK instead of blocking VM-EXEC, now that Hera can genuinely message (§XX). RUN-TEST/EXEC-STD79-DOE (the serialized baseline) are untouched, kept as a byte-for-byte-reproducible historical comparison point. A small 2-identity smoke test before any multi-architecture commitment caught two real defects the design alone didn't predict: 1. Absolute VM-HEAT can't produce fine-grained interleaving -- a fresh identity starts at heat=0 against Hera's ~62000+, a gap no 1..24 divisor closes, so priority locked onto whichever identity had executed least, for its entire campaign. Fixed with BASE-HEAT: each identity's heat is snapshotted once at campaign start, and priority is computed from heat gained *this campaign*, not lifetime heat. 2. Single-test-per-message granularity silently drops most of a campaign's data: MSG-SEND no-ops on MSG-ALLOC failure, and the turn bookkeeping advanced regardless, so rows looked complete while missing most of their tests. A live reservoir probe showed Hera's own STADIUM-RES@ draining ~725/cycle with no replenishment observed -- a 648-send full campaign would exhaust it almost immediately. Fixed by dispatching a whole rep (24 tests, one concatenated command, measured 442 bytes, well under VM-EXEC's 1025-byte cap) per message instead -- 27 sends for a full campaign, not 648. Re-verified after both fixes: 99/99 expected test outputs present, zero drops, zero faults, genuine rep-level interleaving instead of either the serialized baseline's fixed order or the first cut's 72-test lock-in. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXieurDfDSsDFdnSyusuWo
450 lines
19 KiB
Forth
450 lines
19 KiB
Forth
( std79-doe.4th - 3(arch, fixed per boot) x 9(identity) x 3(rep) )
|
|
( randomized full-factorial DoE. Same 24-case content as )
|
|
( std79-exerciser.fth, driven via VM-EXEC into each identity's own )
|
|
( live VM (all 9 pre-attached before this runs); "zuse" dispatches )
|
|
( into "Hera" herself since her power is a session flag on Hera, )
|
|
( not a separate registered VM. Fisher-Yates shuffle matches )
|
|
( doe.4th's own algorithm/style; seed fixed for cross-architecture )
|
|
( reproducibility (same permutation applied on every arch). )
|
|
|
|
9 CONSTANT N-ID
|
|
3 CONSTANT N-REPS
|
|
27 CONSTANT N-RUNS
|
|
24 CONSTANT N-TESTS
|
|
|
|
: ID-NAME ( idx -- c-addr u )
|
|
CASE
|
|
0 OF S" Hera" ENDOF
|
|
1 OF S" rajames" ENDOF
|
|
2 OF S" 00" ENDOF
|
|
3 OF S" 01" ENDOF
|
|
4 OF S" 02" ENDOF
|
|
5 OF S" 03" ENDOF
|
|
6 OF S" 04" ENDOF
|
|
7 OF S" 05" ENDOF
|
|
8 OF S" 06" ENDOF
|
|
ENDCASE ;
|
|
|
|
: ID-LABEL ( idx -- c-addr u )
|
|
CASE
|
|
0 OF S" zuse" ENDOF
|
|
1 OF S" rajames" ENDOF
|
|
2 OF S" 00" ENDOF
|
|
3 OF S" 01" ENDOF
|
|
4 OF S" 02" ENDOF
|
|
5 OF S" 03" ENDOF
|
|
6 OF S" 04" ENDOF
|
|
7 OF S" 05" ENDOF
|
|
8 OF S" 06" ENDOF
|
|
ENDCASE ;
|
|
|
|
( idx 0 (zuse) runs natively on Hera -- never via VM-EXEC targeting )
|
|
( "Hera" herself: VM-EXEC's own vm_state_push/pop only saves )
|
|
( rsp/exit_colon/ecw_nesting, not input_buffer/input_pos, so a )
|
|
( self-targeting call while THIS capsule's own vm_interpret call is )
|
|
( still mid-line would risk clobbering the outer parse -- the exact )
|
|
( class of bug the idle-tick reentrancy guards (repl.c) exist for, )
|
|
( just not covered by VM-EXEC's own narrower state stack. Sidestepped )
|
|
( entirely by never dispatching a string back into the caller's own )
|
|
( VM; the same 24 cases are just directly-compiled code below. )
|
|
: RUN-TEST-NATIVE ( n -- )
|
|
CASE
|
|
0 OF 7 3 /MOD SWAP . . ENDOF
|
|
1 OF -7 3 /MOD SWAP . . ENDOF
|
|
2 OF 7 -3 /MOD SWAP . . ENDOF
|
|
3 OF -7 -3 /MOD SWAP . . ENDOF
|
|
4 OF 2147483647 1 + . ENDOF
|
|
5 OF -2147483648 NEGATE . ENDOF
|
|
6 OF -2147483648 ABS . ENDOF
|
|
7 OF -1 1 RSHIFT . ENDOF
|
|
8 OF -8 2 RSHIFT . ENDOF
|
|
9 OF 1 31 LSHIFT . ENDOF
|
|
10 OF -1 0 < . ENDOF
|
|
11 OF -1 0 U< . ENDOF
|
|
12 OF 123 456 M* SWAP D. ENDOF
|
|
13 OF -123 456 M* SWAP D. ENDOF
|
|
14 OF 100000 S>D SWAP 7 M/MOD . . ENDOF
|
|
15 OF 7 11 3 */ . ENDOF
|
|
16 OF 7 11 3 */MOD SWAP . . ENDOF
|
|
17 OF -5 S>D SWAP D. ENDOF
|
|
18 OF -5 S>D 3 S>D D+ SWAP D. ENDOF
|
|
19 OF -5 S>D DNEGATE SWAP D. ENDOF
|
|
20 OF -5 3 MIN . -5 3 MAX . ENDOF
|
|
21 OF 5 0 10 WITHIN . ENDOF
|
|
22 OF -1 0 AND . -1 0 OR . 5 3 XOR . ENDOF
|
|
23 OF -2147483648 2/ . ENDOF
|
|
ENDCASE ;
|
|
|
|
: TEST-CMD ( n -- c-addr u )
|
|
CASE
|
|
0 OF S" 7 3 /MOD SWAP . ." ENDOF
|
|
1 OF S" -7 3 /MOD SWAP . ." ENDOF
|
|
2 OF S" 7 -3 /MOD SWAP . ." ENDOF
|
|
3 OF S" -7 -3 /MOD SWAP . ." ENDOF
|
|
4 OF S" 2147483647 1 + ." ENDOF
|
|
5 OF S" -2147483648 NEGATE ." ENDOF
|
|
6 OF S" -2147483648 ABS ." ENDOF
|
|
7 OF S" -1 1 RSHIFT ." ENDOF
|
|
8 OF S" -8 2 RSHIFT ." ENDOF
|
|
9 OF S" 1 31 LSHIFT ." ENDOF
|
|
10 OF S" -1 0 < ." ENDOF
|
|
11 OF S" -1 0 U< ." ENDOF
|
|
12 OF S" 123 456 M* SWAP D." ENDOF
|
|
13 OF S" -123 456 M* SWAP D." ENDOF
|
|
14 OF S" 100000 S>D SWAP 7 M/MOD . ." ENDOF
|
|
15 OF S" 7 11 3 */ ." ENDOF
|
|
16 OF S" 7 11 3 */MOD SWAP . ." ENDOF
|
|
17 OF S" -5 S>D SWAP D." ENDOF
|
|
18 OF S" -5 S>D 3 S>D D+ SWAP D." ENDOF
|
|
19 OF S" -5 S>D DNEGATE SWAP D." ENDOF
|
|
20 OF S" -5 3 MIN . -5 3 MAX ." ENDOF
|
|
21 OF S" 5 0 10 WITHIN ." ENDOF
|
|
22 OF S" -1 0 AND . -1 0 OR . 5 3 XOR ." ENDOF
|
|
23 OF S" -2147483648 2/ ." ENDOF
|
|
ENDCASE ;
|
|
|
|
CREATE RUN-MATRIX N-RUNS CELLS ALLOT
|
|
: MATRIX! ( val idx -- ) CELLS RUN-MATRIX + ! ;
|
|
: MATRIX@ ( idx -- val ) CELLS RUN-MATRIX + @ ;
|
|
VARIABLE SW-I VARIABLE SW-J VARIABLE SW-VI VARIABLE SW-VJ
|
|
: SWAP-MTX ( i j -- )
|
|
SW-J ! SW-I !
|
|
SW-I @ MATRIX@ SW-VI !
|
|
SW-J @ MATRIX@ SW-VJ !
|
|
SW-VJ @ SW-I @ MATRIX!
|
|
SW-VI @ SW-J @ MATRIX! ;
|
|
: INIT-MATRIX ( -- ) N-RUNS 0 DO I I MATRIX! LOOP ;
|
|
: SHUFFLE-MATRIX ( -- )
|
|
N-RUNS 1 - 0 DO
|
|
I N-RUNS 1 - RANDOM
|
|
I SWAP-MTX
|
|
LOOP ;
|
|
|
|
VARIABLE CURR-ID
|
|
VARIABLE CURR-REP
|
|
|
|
( Boot-batching support, added 2026-09-11 (FABRIC-3.md SXV). Originally a )
|
|
( workaround for a real aarch64 Stadium/COOL scaling bug -- root-caused and )
|
|
( fixed 2026-09-11/12 (FABRIC-3.md SXVI, src/starkernel/vm/stadium.c): )
|
|
( stadium_grant_quota() halves the granting VM's own free list on every )
|
|
( birth with no floor, and stadium_admit()'s eviction fallback used to scan )
|
|
( the ENTIRE global cell array (stadium_ncells, in the hundreds of )
|
|
( thousands on aarch64's larger RAM-scaled Stadium) filtered by owner, )
|
|
( instead of walking just the calling VM's own resident cells as its own )
|
|
( doc comment already claimed -- fixed by threading a real per-VM resident )
|
|
( list. A single boot with all 9 identities simultaneously live now works )
|
|
( cleanly on all three architectures (see results-20260911-stadium-fix/), )
|
|
( so ACTIVE-LO/ACTIVE-HI is no longer load-bearing -- kept only as general )
|
|
( flexibility: every boot shares the SAME seed so INIT-MATRIX/SHUFFLE-MATRIX )
|
|
( produce the identical master 27-slot permutation regardless of how many )
|
|
( boots this runs across; only the ACTIVE-LO/ACTIVE-HI filter differs if )
|
|
( split. The recorded run_id is always I itself (the slot's true position )
|
|
( in the master shuffle), never a separately-incremented counter, so row )
|
|
( order stays meaningful and comparable across any number of boots. )
|
|
VARIABLE ACTIVE-LO
|
|
VARIABLE ACTIVE-HI
|
|
: ACTIVE? ( idx -- flag )
|
|
DUP ACTIVE-LO @ >=
|
|
SWAP ACTIVE-HI @ <=
|
|
AND ;
|
|
|
|
: RUN-TEST ( n -- )
|
|
CURR-ID @ 0= IF
|
|
RUN-TEST-NATIVE
|
|
ELSE
|
|
TEST-CMD CURR-ID @ ID-NAME VM-EXEC
|
|
THEN ;
|
|
|
|
VARIABLE CURR-RUN-ID
|
|
: RUN-TRIAL ( id-idx rep run-id -- )
|
|
CURR-RUN-ID !
|
|
CURR-REP ! CURR-ID !
|
|
." DOE-RUN," CURR-RUN-ID @ . ." ," CURR-ID @ . ." ,"
|
|
CURR-ID @ ID-LABEL TYPE ." ," CURR-REP @ . CR
|
|
N-TESTS 0 DO I RUN-TEST LOOP ;
|
|
|
|
( HB-ON/HB-OFF (doe_log.c) bracket the trial loop below so the per-tick )
|
|
( DoE-tagged physics/heartbeat CSV -- 20 columns: tick_number, elapsed_ns, )
|
|
( hot_word_count, avg_word_heat_q48, window_width, apic_ticks, )
|
|
( hera/hermes/artemis heat_q48, fleet_k_q48, fleet_conserved, etc. -- )
|
|
( covers exactly this run's window, not the whole boot. )
|
|
( g_doe_log_enabled defaults OFF (doe_log.c), so )
|
|
( every prior campaign run's extracted CSV (scripts/extract_doe.sh, run )
|
|
( automatically at the end of every `make qemu`) was silently empty; )
|
|
( without this bracket there is no per-tick data to analyze the 3x9x3 )
|
|
( factorial's physics behavior by, only the DOE-RUN/DOE-HEADER correctness )
|
|
( lines already printed below. NOTE: this comment deliberately never )
|
|
( spells out the literal tag string doe_log.c prefixes each row with -- )
|
|
( writing it here once already corrupted a real extracted CSV live )
|
|
( 2026-09-12, since scripts/extract_doe.sh greps the log for exactly that )
|
|
( substring and can't tell a real telemetry row from this comment's own )
|
|
( compile-time echo saying the same characters. )
|
|
: EXEC-STD79-DOE ( seed lo hi -- )
|
|
ACTIVE-HI ! ACTIVE-LO !
|
|
SEED
|
|
INIT-MATRIX SHUFFLE-MATRIX
|
|
." DOE-HEADER,run_id,id_idx,id_label,rep" CR
|
|
HB-ON
|
|
N-RUNS 0 DO
|
|
I MATRIX@
|
|
DUP N-REPS /
|
|
DUP ACTIVE? IF
|
|
SWAP N-REPS MOD I RUN-TRIAL
|
|
ELSE
|
|
DROP DROP
|
|
THEN
|
|
LOOP
|
|
HB-OFF
|
|
." STD79-DOE: complete" CR ;
|
|
|
|
( ============================================================ )
|
|
( Compudynamic turn-attractor (FABRIC-3.md SXIX, 2026-09-12). )
|
|
( EXEC-STD79-DOE above is strictly serialized: each of the 27 )
|
|
( shuffled (identity,rep) cells runs its full 24-test block to )
|
|
( completion before the next starts -- confirmed live that this is )
|
|
( the real null hypothesis behind SXVIII's K result, not "real )
|
|
( concurrent multi-VM load": VM-EXEC's vm_interpret() call blocks )
|
|
( the caller until the target returns (mama_forth_words.c), and )
|
|
( vm_tick() -- hence vm_physics_heartbeat_tick() -- is driven by )
|
|
( each VM's OWN word dispatch (vm_runtime.c), so an idle identity )
|
|
( accrues zero ticks between its own turns, not just "not currently )
|
|
( executing a word." )
|
|
( )
|
|
( EXEC-STD79-DOE-CD replaces the fixed shuffle-order sequencing )
|
|
( with a turn-attractor: at every step, whichever LIVE identity )
|
|
( has the lowest VM-HEAT / tests-remaining-in-its-current-rep gets )
|
|
( the next single test dispatched -- the same least-dense-candidate )
|
|
( judgment stadium_admit() already trusts for eviction (heat/mass), )
|
|
( applied to "whose turn is next" instead of "who gets evicted," )
|
|
( with tests-remaining standing in for mass (Stadium's own mass )
|
|
( field is hardcoded to 1 for every patron -- see FABRIC-3.md SXIX -- )
|
|
( so this computes its own local ratio rather than hijacking that )
|
|
( field). Equal-priority candidates are broken by TIE-BREAK, a )
|
|
( seeded coin toss (swappable for inference later, not built yet). )
|
|
( No fixed round-robin, no priority levels, no preemption -- )
|
|
( deliberately not a scheduler. )
|
|
( )
|
|
( FABRIC-3.md SXX/SXXI (2026-09-12): rebuilt on real messaging. This )
|
|
( draft's first pass (still visible in RUN-TEST/EXEC-STD79-DOE's own )
|
|
( turn dispatch above, untouched, kept as the historical serialized )
|
|
( baseline) and this word's own first cut both dispatched turns via )
|
|
( blocking VM-EXEC -- no different from the null hypothesis this )
|
|
( whole mechanism exists to move past. Hera can now genuinely message )
|
|
( every identity (SXX closed the "Hera can't message" gap), so )
|
|
( RUN-REP-CD below queues each turn's whole rep as a real message )
|
|
( (MSG-SEND, one per rep -- SXXII cut this from one-message-per-test )
|
|
( after a live reservoir probe showed that granularity silently )
|
|
( dropped work, see RUN-REP-CD's own comment) and pumps it (MSG-TICK) )
|
|
( instead of calling VM-EXEC directly. MSG-DELIVER still calls VM-EXEC under the hood )
|
|
( (messaging.4th), so actual instruction execution stays serialized )
|
|
( at delivery time -- that's a real constraint of a single-threaded )
|
|
( VM, not something this mechanism claims to remove. What changes is )
|
|
( who pays and how turns are queued: MSG-ALLOC's STADIUM-RES-PULL )
|
|
( pulls Q.SLOT admission heat from the CALLING VM's own reservoir )
|
|
( (mama_forth_words.c -- confirmed, not assumed), so queuing a turn )
|
|
( costs Hera, the orchestrator, not the identity receiving the turn -- )
|
|
( "sender pays," not "winner pays." zuse's (idx 0) tests still run )
|
|
( natively on Hera, message-free, for the same reason as before: )
|
|
( MSG-DELIVER's own VM-EXEC would be self-targeting into Hera's own )
|
|
( input buffer mid-parse, the same reentrancy class the idle-loop )
|
|
( pump guards against. The 27-slot run_id/(id_idx,rep) LABEL mapping )
|
|
( from SHUFFLE-MATRIX is preserved exactly (REV-MATRIX inverts it) )
|
|
( so run_id means the same thing as every prior campaign, even though )
|
|
( real execution order is now priority-driven, not shuffle-position- )
|
|
( driven. )
|
|
|
|
CREATE REV-MATRIX N-RUNS CELLS ALLOT
|
|
: REV! ( val idx -- ) CELLS REV-MATRIX + ! ;
|
|
: REV@ ( idx -- val ) CELLS REV-MATRIX + @ ;
|
|
: BUILD-REV-MATRIX ( -- ) N-RUNS 0 DO I I MATRIX@ REV! LOOP ;
|
|
|
|
CREATE REP-IDX N-ID CELLS ALLOT ( each identity's current/next rep, 0..2; N-REPS = done )
|
|
: REP-IDX! ( val idx -- ) CELLS REP-IDX + ! ;
|
|
: REP-IDX@ ( idx -- val ) CELLS REP-IDX + @ ;
|
|
|
|
: TURN-HEAT ( idx -- heat )
|
|
DUP 0= IF DROP S" Hera" VM-HEAT
|
|
ELSE ID-NAME VM-HEAT THEN ;
|
|
|
|
( BASE-HEAT: each identity's TURN-HEAT captured once, at campaign )
|
|
( start (CAPTURE-BASE-HEAT, called from EXEC-STD79-DOE-CD before the )
|
|
( turn loop begins). Live-probed before trusting this design (2026- )
|
|
( 09-12, amd64): right after attach, before a single test has run, )
|
|
( S" Hera" VM-HEAT . -> 62672, S" rajames" VM-HEAT . -> 0 -- a ~63000x )
|
|
( gap. Absolute VM-HEAT mostly encodes how long a VM has existed and )
|
|
( how much boot/capsule-load work it already did, not how recently )
|
|
( it took a DoE turn: Hera's dictionary alone (fabric.4th, ACL.4th, )
|
|
( messaging.4th, etc.) generates heat no identity VM ever will. )
|
|
( Dividing that gap by a 1..24 tests-remaining divisor cannot close )
|
|
( 4-5 orders of magnitude -- confirmed live: an early two-identity )
|
|
( smoke test with the undivided-baseline formula produced zuse )
|
|
( running one rep, then rajames sweeping all 3 of its reps back to )
|
|
( back before zuse got another turn, not fine-grained alternation. )
|
|
( Subtracting each identity's own BASE-HEAT zeroes out the pre- )
|
|
( existing disparity: every identity's priority starts at 0 for its )
|
|
( very first candidate turn (a genuine N-way tie -- see TIE-BREAK )
|
|
( below), and diverges afterward strictly from heat gained during )
|
|
( THIS campaign, which is the comparison that was actually intended. )
|
|
CREATE BASE-HEAT N-ID CELLS ALLOT
|
|
: BASE-HEAT! ( val idx -- ) CELLS BASE-HEAT + ! ;
|
|
: BASE-HEAT@ ( idx -- val ) CELLS BASE-HEAT + @ ;
|
|
: CAPTURE-BASE-HEAT ( -- )
|
|
N-ID 0 DO I REP-IDX@ N-REPS < IF I DUP TURN-HEAT SWAP BASE-HEAT! THEN LOOP ;
|
|
|
|
( reps left for idx, ranges 1..N-REPS whenever this is called -- )
|
|
( PICK-NEXT-TURN only ever evaluates idx's still REP-IDX@ < N-REPS. )
|
|
( SXXII (2026-09-12): reps, not tests, are this campaign's real turn )
|
|
( granularity -- see the RUN-REP-CD comment below for why a whole )
|
|
( rep is dispatched as one message instead of 24 single-test )
|
|
( messages, confirmed live via a direct reservoir probe. )
|
|
: REPS-REMAINING@ ( idx -- n ) REP-IDX@ N-REPS SWAP - ;
|
|
|
|
( priority = (heat - base-heat) / reps-remaining -- heat gained )
|
|
( THIS campaign so far, per rep still owed -- same "coolest wins" )
|
|
( direction as stadium_admit()'s heat/mass density, with reps- )
|
|
( remaining standing in for mass (Stadium's own mass field is )
|
|
( hardcoded to 1 for every patron -- see FABRIC-3.md SXIX -- so this )
|
|
( computes its own local ratio rather than hijacking that field). )
|
|
( Plain integer "/" is correct even though heat is Q48.16 fixed- )
|
|
( point: dividing a Q48.16 value by a plain integer divisor )
|
|
( preserves the Q48.16 scale, no Q./ needed. )
|
|
: TURN-PRIORITY ( idx -- priority )
|
|
DUP TURN-HEAT OVER BASE-HEAT@ - SWAP REPS-REMAINING@ / ;
|
|
|
|
( seeded coin toss (RANDOM draws off the same SEED'd stream )
|
|
( EXEC-STD79-DOE-CD's SHUFFLE-MATRIX already consumes, so the whole )
|
|
( run stays reproducible run-to-run) -- swappable later for a )
|
|
( rolling-window-of-truth inference, per Bob: "start with a coin )
|
|
( toss or go straight to inference?" -- coin toss first. )
|
|
: TIE-BREAK ( idx1 idx2 -- idx )
|
|
0 1 RANDOM IF SWAP THEN DROP ;
|
|
|
|
VARIABLE BEST-IDX VARIABLE BEST-PRI
|
|
: PICK-NEXT-TURN ( -- idx )
|
|
-1 BEST-IDX !
|
|
N-ID 0 DO
|
|
I REP-IDX@ N-REPS < IF
|
|
I TURN-PRIORITY
|
|
BEST-IDX @ -1 = IF
|
|
BEST-PRI ! I BEST-IDX !
|
|
ELSE
|
|
DUP BEST-PRI @ = IF
|
|
DROP BEST-IDX @ I TIE-BREAK BEST-IDX !
|
|
ELSE
|
|
DUP BEST-PRI @ < IF BEST-PRI ! I BEST-IDX ! ELSE DROP THEN
|
|
THEN
|
|
THEN
|
|
THEN
|
|
LOOP
|
|
BEST-IDX @ ;
|
|
|
|
VARIABLE SR-IDX VARIABLE SR-REP VARIABLE SR-RUNID
|
|
: START-REP ( idx -- )
|
|
SR-IDX !
|
|
SR-IDX @ REP-IDX@ SR-REP !
|
|
SR-IDX @ 3 * SR-REP @ + REV@ SR-RUNID !
|
|
." DOE-RUN," SR-RUNID @ . ." ," SR-IDX @ . ." ,"
|
|
SR-IDX @ ID-LABEL TYPE ." ," SR-REP @ . CR ;
|
|
|
|
( message-type tag for a queued turn's rep command. Past the )
|
|
( highest constant messaging.4th itself defines (BLK-ATTACH-EVENT=9); )
|
|
( kept local to this file rather than added to the shared common )
|
|
( capsule, since it's specific to this campaign's own dispatch, not )
|
|
( general messaging infrastructure. )
|
|
10 CONSTANT DOE-TEST-EVENT
|
|
|
|
( REP-CMD-BUF: scratch buffer holding one whole rep's 24 test )
|
|
( commands concatenated with spaces (BUILD-REP-CMD). 442 bytes for )
|
|
( the real 24-test set, measured; 1024 leaves ample headroom and )
|
|
( stays well under mama_word_vm_exec's own INPUT_BUFFER_SIZE (1025) )
|
|
( refusal threshold (checked in the C source, not assumed -- it )
|
|
( prints "VM-EXEC: command too long" and returns cleanly rather than )
|
|
( truncating, so an oversized rep would fail loudly, not silently). )
|
|
CREATE REP-CMD-BUF 1024 ALLOT
|
|
VARIABLE REP-CMD-LEN
|
|
: REP-CMD-RESET ( -- ) 0 REP-CMD-LEN ! ;
|
|
: REP-CMD-APPEND ( addr u -- )
|
|
>R
|
|
REP-CMD-BUF REP-CMD-LEN @ + R@ CMOVE
|
|
REP-CMD-LEN @ R> + REP-CMD-LEN !
|
|
REP-CMD-BUF REP-CMD-LEN @ + 32 SWAP C!
|
|
1 REP-CMD-LEN +! ;
|
|
: BUILD-REP-CMD ( -- )
|
|
REP-CMD-RESET
|
|
N-TESTS 0 DO I TEST-CMD REP-CMD-APPEND LOOP ;
|
|
|
|
( RUN-REP-CD ( idx -- ): the messaging-based, whole-rep sibling of )
|
|
( RUN-TRIAL -- RUN-TEST/RUN-TRIAL/EXEC-STD79-DOE (the serialized )
|
|
( baseline above) are deliberately left untouched, so that campaign )
|
|
( stays a byte-for-byte-reproducible historical baseline, not )
|
|
( silently migrated onto messaging along with this one. )
|
|
( )
|
|
( SXXII (2026-09-12): this dispatches a WHOLE REP (all 24 tests, one )
|
|
( concatenated command string) per message, not one message per )
|
|
( single test as the first cut of this word did. Confirmed live, )
|
|
( directly, why that had to change: a probe of STADIUM-RES@ (Hera's )
|
|
( own reservoir, the thing MSG-ALLOC's STADIUM-RES-PULL draws every )
|
|
( MSG-SEND from) showed it draining by roughly Q.SLOT-scale per )
|
|
( send/tick cycle with no observed replenishment during the run -- )
|
|
( 21760 -> 13811 over just 11 send+tick cycles in one live probe. A )
|
|
( full 9-identity x 3-rep x 24-test campaign at single-test )
|
|
( granularity is 648 sends, which exhausts that budget almost )
|
|
( immediately: an actual two-identity smoke run at that granularity )
|
|
( silently dropped roughly half of every rep's tests (MSG-SEND no- )
|
|
( ops on MSG-ALLOC failure, and STEP-TURN's old per-test bookkeeping )
|
|
( advanced regardless, so the row looked complete when it wasn't). )
|
|
( Batching to one message per rep cuts a full campaign to 27 sends )
|
|
( total -- comfortably inside the reservoir budget the probe )
|
|
( measured -- while still keeping genuine attractor behavior: )
|
|
( PICK-NEXT-TURN still re-evaluates priority between every rep, so )
|
|
( which identity goes next is still heat-driven, not shuffle-order- )
|
|
( driven, just at rep granularity instead of single-test granularity. )
|
|
( zuse (CURR-ID = 0) still runs natively, unchanged, same )
|
|
( reentrancy reasoning as RUN-TEST's. )
|
|
: RUN-REP-NATIVE ( -- ) N-TESTS 0 DO I RUN-TEST-NATIVE LOOP ;
|
|
: RUN-REP-CD ( idx -- )
|
|
DUP CURR-ID !
|
|
0= IF
|
|
RUN-REP-NATIVE
|
|
ELSE
|
|
BUILD-REP-CMD
|
|
DOE-TEST-EVENT 0 CURR-ID @ DOE-IDX>MSG-IDX
|
|
REP-CMD-BUF REP-CMD-LEN @
|
|
0
|
|
MSG-SEND
|
|
MSG-TICK
|
|
THEN ;
|
|
|
|
: STEP-TURN ( idx -- )
|
|
DUP RUN-REP-CD
|
|
DUP REP-IDX@ 1+ OVER REP-IDX!
|
|
DUP REP-IDX@ N-REPS < IF DUP START-REP THEN
|
|
DROP ;
|
|
|
|
: INIT-TURN-STATE ( -- )
|
|
N-ID 0 DO
|
|
I ACTIVE? IF 0 I REP-IDX! ELSE N-REPS I REP-IDX! THEN
|
|
LOOP ;
|
|
|
|
: PRINT-INITIAL-HEADERS ( -- )
|
|
N-ID 0 DO I REP-IDX@ N-REPS < IF I START-REP THEN LOOP ;
|
|
|
|
: EXEC-STD79-DOE-CD ( seed lo hi -- )
|
|
ACTIVE-HI ! ACTIVE-LO !
|
|
SEED
|
|
INIT-MATRIX SHUFFLE-MATRIX
|
|
BUILD-REV-MATRIX
|
|
INIT-TURN-STATE
|
|
CAPTURE-BASE-HEAT
|
|
." DOE-HEADER,run_id,id_idx,id_label,rep" CR
|
|
HB-ON
|
|
PRINT-INITIAL-HEADERS
|
|
BEGIN
|
|
PICK-NEXT-TURN DUP -1 <>
|
|
WHILE
|
|
STEP-TURN
|
|
REPEAT
|
|
DROP
|
|
HB-OFF
|
|
." STD79-DOE: complete" CR ;
|