Files
LithosAnanake/docs/working/architecture/ARTEMIS-BAM-ACCEPTANCE-20260703.md
T

9.3 KiB
Raw Blame History

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 sets BLK-HEAT[n] = Q.1 on allocation
  • BLK-FREE — now sets BLK-HEAT[n] = 0 on release
  • BLK-FETCH — now refreshes BLK-HEAT[n] = Q.1 for data block accesses
  • ART-INIT — now zeroes the entire BLK-HEAT arena before boot detection
  • ART-STATUS — now prints K-total= via ART-K-TOTAL Q.PRINT
  • ART-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):

  1. MMIO access width. VirtioCommonCfg was 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-bit queue_size register (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 removing packed keeps the layout byte-identical while restoring exact-width access. amd64/aarch64 never saw this because GCC emits normal-width accesses there.

  2. 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)