9.3 KiB
Artemis BAM — Phase 1 Acceptance Report
Date: 2026-07-03
Branch: lithosananke
Commits: ed05db25 (implementation) · ff47e2ec (acceptance logs)
Author: Captain Bob / Claude Code
Overview
This report documents the Phase 1 implementation of the Artemis Block Allocation
Manager (BAM) and its three-arch QEMU acceptance. The work replaces the previous
integer ART-K counter with a proper Q48.16 block heat system, completing the
compudynamic block lifecycle in Artemis.
All implementation is in StarForth dialect. No C was touched.
What Was Built
Q48.16 Block Heat Arena
Replaced VARIABLE ART-K (integer counter, not thermodynamic) with a full
per-block Q48.16 heat array:
CREATE BLK-HEAT ART-DATA-BLKS CELLS ALLOT \ 22998 entries × CELL bytes
Each slot tracks the thermal mass of one data block (index n → LBN ART-DATA-LBN + n).
Block Lifecycle
| Event | Heat action |
|---|---|
BLK-ALLOC |
Set BLK-HEAT[n] = Q.1 (born hot) |
BLK-FETCH (data LBN) |
Refresh BLK-HEAT[n] = Q.1 (access reheats) |
ART-COOL |
Multiply all live slots by Q-DECAY (≈ 0.9950 per tick) |
ART-REAP |
Free any allocated block whose heat has decayed to zero |
BLK-FREE |
Set BLK-HEAT[n] = 0 immediately |
Q-DECAY = 65208 (Q48.16 ≈ 0.9950). A block untouched for ~200 ticks cools to zero
and is reaped automatically by ART-REAP.
New Words
| Word | Stack | Description |
|---|---|---|
BLK-HEAT@ |
( n -- q48 ) |
Read heat for data block index n |
BLK-HEAT! |
( q48 n -- ) |
Write heat for data block index n |
LBN>IDX |
( lbn -- n ) |
Convert data LBN to heat array index |
ART-K-TOTAL |
( -- q48 ) |
Sum all block heats (fleet K observability) |
ART-COOL |
( -- ) |
Apply Q-DECAY to all live block heat slots |
ART-REAP |
( -- ) |
Free allocated blocks with heat = 0 |
ART-TICK |
( -- ) |
ART-COOL ART-REAP — one lifecycle tick |
CD-INIT |
( -- ) |
Hera-callable init: zero BLK-HEAT, log ready |
Modified Words
BLK-ALLOC— now setsBLK-HEAT[n] = Q.1on allocationBLK-FREE— now setsBLK-HEAT[n] = 0on releaseBLK-FETCH— now refreshesBLK-HEAT[n] = Q.1for data block accessesART-INIT— now zeroes the entireBLK-HEATarena before boot detectionART-STATUS— now printsK-total=viaART-K-TOTAL Q.PRINTART-SELF-TEST— now prints K-total before and after alloc/free
init.4th (Block 2049)
Hera now calls CD-INIT on each baby VM immediately after BIRTH:
S" Artemis" BIRTH
S" CD-INIT" S" Artemis" VM-EXEC
S" Hermes" BIRTH
S" CD-INIT" S" Hermes" VM-EXEC
CD-INIT zeroes BLK-HEAT at ground-state join (heat does not persist across boots;
disk content does).
Block Inventory
All blocks are in capsules/artemis/init.4th. Block numbers are capsule-local
annotations; they do not map to shared ramdrive LBNs.
| Block | Status | Purpose |
|---|---|---|
| 4110 | Modified | Removed ART-K; added Q-DECAY = 65208 |
| 4111 | Unchanged | LE32!/LE32@ little-endian I/O |
| 4112 | Unchanged | SHL1N/SHR1N/BIT-TEST/BIT-SET/BIT-CLR |
| 4113 | Unchanged | Free-map (FM-ADDR-BIT/FM-TEST/FM-SET/FM-CLR) |
| 4122 | Modified | BLK-ALLOC/BLK-FREE with heat lifecycle |
| 4123 | Unchanged | ART-MAGIC!/ART-MAGIC? |
| 4124 | Modified | BLK-FETCH with heat bump; ART-BOOT-DETECT |
| 4125 | Unchanged | ART-HDR-WRITE |
| 4126 | Unchanged | ART-FORMAT/ART-RESUME/ART-HALT-UNRECOG |
| 4127 | Modified | ART-STATUS with Q.PRINT; WELCOME |
| 4128 | Unchanged | LE64!/LE64@ |
| 4130 | Unchanged | ART-BLANK? |
| 4131 | Modified | ART-INIT zeroes BLK-HEAT arena |
| 4132 | Modified | ART-SELF-TEST with K-total display |
| 4133 | Unchanged | Entry block (ART-INIT ART-BOOT-ENTRY WELCOME) |
| 4134 | Unchanged | ART-WRITE-TEST |
| 4135 | Unchanged | ART-READ-TEST |
| 4136 | Unchanged | ART-BOOT-ENTRY dispatch |
| 4137 | New | BLK-HEAT arena (CREATE BLK-HEAT) |
| 4138 | New | BLK-HEAT@/BLK-HEAT!/LBN>IDX |
| 4139 | New | ART-K-TOTAL/ART-COOL |
| 4140 | New | ART-REAP/ART-TICK |
| 4141 | New | CD-INIT (Hera-callable ground-state join) |
Design Decisions
ART-K-TOTAL is observability only
ART-K-TOTAL sums all block heats and is displayed in ART-STATUS. It is not
wired into K-FLEET in fleet-k.4th.
K-FLEET currently uses 2 K-LOCAL@ (rolling-window average) for Artemis. Replacing
this with ART-K-TOTAL would break K-CONSERVED? at boot: a fresh boot has zero
allocated blocks, so ART-K-TOTAL = 0, making fleet K ≈ 2/3 instead of 1.0.
The correct fix (Logical BAM) requires normalizing per-block heat so that the allocated
pool represents exactly Q.1 of Artemis's share. That is deferred.
ART-TICK is manual
ART-TICK is defined but not connected to any automatic heartbeat loop. Blocks cool
only when ART-TICK is called explicitly. Automatic integration with a compudynamic
tick loop is future work (same Logical BAM chapter).
No integer ART-K
The old VARIABLE ART-K (simple integer counter, not thermodynamic) is removed.
ART-K-TOTAL is Q48.16 and reflects actual thermal state.
Acceptance Results
Three-arch QEMU run, 2026-07-03. Logs in logs/20260703-15*/.
| ISA | Disk | Artemis boot test | Tripod (6/6) |
|---|---|---|---|
| amd64 | virtio-blk (resume) | PASS: persist-read | ✅ |
| aarch64 | virtio-blk (resume) | PASS: persist-read | ✅ |
| riscv64 | virtio-blk (resume, after fix d2bd448a) |
PASS: persist-read | ✅ |
Final accepted runs: amd64 20260703-183543, aarch64 20260703-183710,
riscv64 20260703-184730.
All six Tripod criteria on all three ISAs:
PASS: fleet K
PASS: Hermes liveness
PASS: Artemis ready
PASS: reap
K soak
PASS: E2E msg flow
=== TRIPOD DONE ===
Final prompt on all three: LithosAnanke v1.5.3
riscv64 dict hash divergence — investigated, root-caused, and FIXED
Capsule hash identical on all three ISAs: capsule_hash=0x79c2fefd5231fd24
In the original acceptance run, riscv64's Artemis dict hash diverged
(0x2404108ec607e88f vs 0xff81e587c380af4a shared by amd64/aarch64). The
divergence was traced to riscv64 taking the blank-disk boot path (ART-FORMAT +
ART-SELF-TEST + ART-WRITE-TEST) instead of resume (ART-RESUME +
ART-READ-TEST), because virtio-blk failed to attach — different words execute →
different execution_heat per DictEntry → different hash. The parity harness
fingerprinted the path difference correctly.
Why virtio-blk failed on riscv64 (commit d2bd448a fixes both):
-
MMIO access width.
VirtioCommonCfgwas declared__attribute__((packed)). riscv64 is a strict-alignment target, so GCC compiled packed-struct field access into byte-wise loads/stores. QEMU's virtio common-cfg MMIO handler dispatches on the base offset — a byte read of the 16-bitqueue_sizeregister (256 = 0x100) returned 0x100 & 0xFF = 0, and the driver bailed with "bad queue size". Every field in the struct is naturally aligned per virtio 1.0, so removingpackedkeeps the layout byte-identical while restoring exact-width access. amd64/aarch64 never saw this because GCC emits normal-width accesses there. -
Device selection. riscv64 boots from a GPT disk that is itself virtio-blk, so two virtio-blk devices sit on bus 0 and the driver takes the first slot — the boot disk, not artemis.img. Fixed deterministically with explicit PCI
addr=in the Makefile: artdisk at slot 1, boot disk at slot 2.
Result (run 20260703-184730): riscv64 attaches artemis.img, resumes the
LithosAnanke volume, passes persist-read, and its Artemis dict hash is
0xff81e587c380af4a — identical to amd64 and aarch64. Three-ISA parity closed.
Latent finding — heartbeat/compile race on riscv64 (REPORTED, NOT FIXED)
During the fix campaign, three riscv64 runs (182614, 183257, 183856) failed
TRIPOD-TEST with execute_colon_word: NULL cell in 'K-PUSH' after '(start)'
and TRIPOD-TEST landing in the capsule DEFER list at block 2052 load.
Bisection cleared the virtio change: run 182614 used pre-fix code with no disk
attached and still failed.
The discriminator is boot-time heartbeat tick alignment. DoE row 59 (sampled
mid capsule-load) reads ...,107,10,33,... in every passing run and
...,107,9,32,... in every failing run — one fewer physics count by tick 59.
The same binary produced both outcomes on consecutive runs (183856 fail,
184730 pass), so this is host-timing-sensitive, not code-dependent. When the
tick lands in the wrong window during Hera's dictionary compilation, compiled
words are corrupted (NULL cell in K-PUSH) or lost (TRIPOD-TEST undefined).
This is a pre-existing latent race between the heartbeat physics machinery and dictionary compilation, exposed on riscv64 where boot is slowest under TCG. Logs for all failing runs are committed as evidence. No fix attempted — awaiting Captain Bob's direction.
Deferred / Next
| Item | Notes |
|---|---|
| Logical BAM | Normalize per-block heat so Artemis participates in K-FLEET properly |
| ART-TICK heartbeat | Wire into compudynamic tick loop |
| Hermes G8 | K-FLEET integration with Hermes thermal mass |
| ACL Phase 8 | STOP before starting — PKI/Ed25519 thumbdrive (Captain Bob's standing instruction) |