Files
LithosAnanke/.claude/memory/docs-notes.md
T
Claude ce04420f6b Add Claude's working notes: rules, document notes, code review, discrepancies
Session notes from reading the repo and reviewing the v4 engine and kernel v4 path.
Findings are reported, not fixed (Captain Bob's Law).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
2026-11-11 16:18:35 +00:00

736 lines
65 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Document notes, in the order read
Dates are the documents' own. "Bob" = Captain Bob (R. A. James). Rulings are quoted where short.
## Top level and `.claude/`
- `.claude/CLAUDE.md` — authoritative. Summarised in [rules.md](rules.md). Status it states: M7.1; v4 default
build since 2026-10-14; v3 "being retired", not part of acceptance; kernel `4.0.0-alpha.4`, engine `3.2.0`;
v4 parity `word_count=318 hash 0x8c92508f748f99cf` (2026-11-10, on the working branch only, PR 164).
- `.claude/README.md` — STALE: still calls TRIPOD/HERMES/ARTEMIS "binding constraints"; CLAUDE.md says they are
frozen history (superseded 2026-08-15, archived as-is 2026-09-22).
- `README.md` — v4.0.0-alpha.4. Three products: Hosted StarForth F18, FPGA StarForth F18, StarshipOS.
Says v4 POST 538 tests, `word_count=317 dict_hash=0xfec8c47cfc6f437f`; v3 1052 tests, 526 words.
(CLAUDE.md on the branch says 318 / `0x8c92...` — see discrepancies.)
- `CONTRIBUTING.md` — STALE, StarForth-era: `make test`, "780+ tests", feature branches, `hal_*` interfaces,
`docs/02-experiments/`. Contradicts CLAUDE.md on every one of these.
- `docs/README.md` — the map and the authority order. `docs/CLAUDE.md` — docs triage rules (two tiers:
`formal/` press-ready LaTeX, `working/` living; INDEX.md hand-maintained; never delete without Bob).
- `docs/DEAD-AND-REVISED.md` — register of dead ideas (L4Re, `hal_*` contract, ACL-RECHECK-RW, the Hermes VM,
elevation words, PIN/passphrase, cloned-drive defence, 2^6 factorial DoE) and revised claims
(ACL overhead is +0.0603%; block rule is ≥2048 and 64×16; v4 boots by default).
## `docs/v4.0.0/` — StarForth v4 (the F18-derived engine)
Authority inside the set, newest wins: MACHINE.md (2026-10-15, amended 10-20) > ENGINE.md (10-05, §2 withdrawn
10-20) > NUCLEUS.md (10-05; §6 POST stands) > DECOMPOSITION.md (the word-by-word spec). DATASHEET-F18.md is the
machine as built. STICK.md is the PC stick. V3-PARITY.md is the gap record.
### JUSTIFICATION.md
- Why: v3 has 300+ C primitives, 64-bit cells, 5 MB per VM, software Hermes; fine for an OS, wrong for silicon.
- v4 = 32-opcode core ISA from Moore's F18 (5-bit opcodes, six slots in a 32-bit instruction word); everything
else is capsule code; a mesh of small nodes with blocking ports; Hermes becomes the network;
compudynamics as a side effect of instruction retirement; RWT governor controls timing only.
- Cell width is a build parameter (32/64). Heat and K arithmetic stay 64-bit.
- Physics split: virtual heat (deterministic) decides WHAT runs; physical power (XADC) decides WHEN.
- Path: hosted golden model → hosted mesh → Verilator co-sim → FPGA (2×2 on PZ7020) → ASIC (Tiny Tapeout, IHP SG13G2).
- §14 definition of done; §15 three products (ruled 2026-10-03); §16 acceptance: v4 equivalent to v3 at any
point; every ISA hosted and bare metal reaches `ok`. `make -C v4 test` is a development check only.
### ENGINE.md
- Rule (2026-10-05): v4 is exactly like v3 functionally up to the first prompt. "Nothing is stubbed,
simulated or stood in for."
- §2 AMENDED 2026-10-20: "MACHINE.md stands; v3 goes after parity; Hera, Hermes, Artemis are now all kernel."
Hera = process management (`v4/src/manage.c`), Hermes = wires (`v4/src/wire.c`, `message.c`),
Artemis = block serving (`v4/system/blocks.c`), Hestia = the kernel's console. No capsule for any of them.
The first node keeps the name Hera. No identity drive = headless; console only once a drive is in.
2026-10-26: "Gate first" (identity gate before the rest of step 4).
- Interface a node must answer (§3): interpret a line; char out; ask the kernel (blocking port write,
`KERNEL-WORD`); stacks/dictionary from the kernel side; the hook at `call`; error; tick; dict hash.
- §3b ruling "A": word code lives on the node, its accounts live in a kernel record, joined by word ID.
- §3a: multiuser, multitasking, hybrid preemptive/cooperative. A node can stop between any two instruction
words (`v4_exec_step_word`). Hera decides which nodes exist and are awake, not whose turn it is.
- §3d: nodes born empty, first thing received is a capsule of F18 code. First geometry "2x2 + 1 central",
centre = Hera; ports are a parameter (6 discussed, default 8 in code); geometry is data; units join
centre-to-centre.
- Steps: 1 done, 2 carrier done, 3 hook at call, 4 node as kernel interpreter, 6 Hera, 7 fleet, 8 identity.
Open: who runs next (step 7), `PAD 42 OVER !` byte address to `!` (issue #12).
### NUCLEUS.md
- Nucleus = what must stay in assembler (opcodes/registers, what reads a capsule, code generator words).
- §5.2 block rule: ≥2048, no ceiling. §5.3 loading: find, hash, signature (invalid stops, missing warns),
feed lines; a failed line stops the boot (no v3-style retry).
- §6 POST (stands): cases in `v4/system/post_cases.c`, generated by `v4/tools/mkpost.py` from v3's test
modules with expected values from hosted v3; runner `v4/system/post.c`; every case compares stack and
output; seal before, `COLD` after, nothing left. Exceptions in `v4/tools/post79_rules.py` → `POST79.md`.
- §7 parity lines: `PARITY:V4_NUCLEUS`, `V4_CAPSULE`, `V4_POST tests= pass= fail=`, `V4_SYSTEM word_count= dict_hash=`,
`PARITY:OK`, `POST: PASSED`. v4 dict hash = FNV-1a over node memory code..HERE plus LATEST.
- Lesson recorded in §6.3: a ruling was once made on a false reading of v3 (`run_single_test` vs
`run_test_suite`). Read the whole of the thing before telling Bob what v3 does.
### MACHINE.md (governs)
- Capsule = semi-truck: engine (32 opcodes), ROM = "the VM" (prebuilt F18 binary that assembles `.f18`),
trailer = source blobs (`.f18` assembler, `.4th` FORTH).
- ROM: host ROM 2372 words (entries 0–18), mesh ROM 277 words (entries 0–5: UM*, UM/MOD, D+, DNEGATE, Q.*, Q./).
Entry table at ROM base; read-only (store = address fault). Built by `v4/tools/mkrom.c`; `mkmap.c` gives constants.
- Boot: engine reset → ROM assembles system `.f18` (`capsules/v4/sys`) → `forth79.4th`, `starforth.4th`,
other system capsules → POST → `init.4th` → `ok>`.
- §5.1 v3 leaves every build once v4 is at parity (ruled 10-15, confirmed 10-20). Issue #156 tracks it.
- §6 order: 1 ROM (done), 2 trailer (done), 3 `init.4th` after POST, 4 Hera streams the ROM,
5 FORTH-79 out of `.f18` into `forth79.4th`, 6 v3 out. Steps 3–6 not built (issue #83).
- §7 rulings: VM is a machine; `.f18` plain text; v3 deleted only after parity; all system capsules load
before POST; `forth79.4th` names all 130 Required words; `init.4th` is the system's init.
### DATASHEET-F18.md (machine as built, 2026-10-15)
- Registers P A B T S R (+I hidden). Stacks counted and guarded (D-16): mesh 10/9 deep, host 32/32.
- Word-addressed (D-1). RAM `V4_NODE_WORDS` (1024 mesh, 16384 host). `V4_PORTS` default 8.
- Instruction word 32 bits at every cell width (D-9). Branch reach by slot: 27/22/17/12 bits; slots 4,5 outside spec.
- 32 opcodes 00–1F: `; ex jump call unext next if -if @p @+ @b @ !p !+ !b ! +* 2* 2/ inv + and xor drop dup pop over a nop push b! a!`.
- Faults: address 0, data over/under 1/2, return over/under 3/4, raised 5 (store to NODE-ERROR).
- MMIO: CONSOLE-TX/RX/STATUS, DSTACK/RSTACK-DEPTH, ports (k, any, which, writers, readers, Wire, A, B, Do, How, Have).
- §13 "not yet as intended": per-call-target heat is a 4096-entry stand-in; device addresses not fixed (D-4,
issue #9); stale comment in `stack.h`; branches in slots 4/5 not trapped.
### STICK.md (the x86_64 StarshipOS stick; 2026-10-26, amended 10-29)
- Goal: one USB stick is the whole OS, plug and play: boot → `[zuse@Hera] ok>`, nothing to set up. v4 only.
- GPT, three partitions: ESP (FAT32, BOOTX64.EFI, starforth.cfg), StarshipOS identity (500 MiB),
StarshipOS Artemis (grows to fill the stick at first boot, cap 256 GiB, metadata-only writes).
Image as built 2 GiB; minimum stick 8 GB.
- First boot mints the stick's **proxy Zuse** (full Zuse until a real one is minted). `MINT-ZUSE` puts the real
Zuse on a second stick; after that the proxy only shows a fixed screen offering R = mint a replacement
(the old stick "dies for good"). Genesis marker version 2 holds both keys.
- `system=v3` is refused on a stick. Standing rule: "QEMU and bare metal ALWAYS hold parity."
- Every `clean qemu` boot attaches a fresh GPT data stick over xHCI, so every acceptance run is a first boot.
- §11 increments: 1–5a done (5a done 2026-11-10, #92); 6 pull/replug + flush (#93), 7 splash + progress bar (#94),
8 acceptance moves to the stick boot (#95) — open.
- Known and accepted: the system stick stays a master key (fallback can mint a new Zuse).
### V3-PARITY.md (gap record, started 2026-10-05)
- Two rulings: v4 = v3 up to the first prompt; "I would never stub, simulate or develop outside of functional,
as-intended code. Piecemeal is how errors and intent get hidden."
- §1a correction by Bob: "You haven't looked at the codebase ... Don't look at pieces until you see how they
fit." The v3 boot order in `kernel_main_deep`: fleet tables → `sk_vm_bootstrap_parity()` → devices →
`capsule_birth_mama()` runs init.4th → timer → self-tests, Hestia/Artemis born, Zuse, banner, REPL.
- Stadium frame (§1c, §1g): everything is a patron (word, VM, block, message), 64-byte cell of nine wires;
each patron kind has its own accounting layer (`stadium_words.c`, `stadium_blocks.c`, `capsule_vm_physics.c`,
`kernel_hermes.c`). K = conservation of heat (shares of 1.0).
- ACL word card stays per word, checked at run time at the `call` hook; TTL adaptive = heat/4 + 256, capped.
In-line words `>R R> R@ I J LEAVE` cannot be called: checked at compile time.
- Opcode heat: counted, left unwired for now (§1h). Word accounts: ruling "A" (kernel record per word ID).
- §3 lists self-declared stand-ins in v4 (per-call heat, `ACL-HEAT@` = 0, console, memory map, CA key placeholders).
### DECOMPOSITION.md (the specification: every v3 C primitive's fate)
- Fates: OP (opcode), IN (in-line macro), CAP (core capsule colon def), CC (compiler capsule, host node only),
DEV (device service), HERA (Hera service), MM (memory-mapped register), RET (retired).
- Decisions D-1..D-19 (ruled 2026-10-01 to 10-05). The ones that bite:
- D-1 word addressing; byte address = 4×word + 0..3; `CELLS` is a no-op; `C@`/`C!` are CAP.
- D-3 plain F18 `+*` (carry out of T not kept); `UM*` written for it, exact, proven on the golden model.
- D-4 memory map DEFERRED; D-6 heat structures DEFERRED (answered per-opcode in V3-PARITY §2.7).
- D-7 `PICK`/`ROLL` count from one (FORTH-79); v3 counts from zero.
- D-8 Q48.16 signed; D-10 a Q value is two cells at every width; D-11 `Q./` saturates and flags, by zero sets NODE-ERROR.
- D-9 instruction word 32 bits at every cell width.
- D-14 address fault; D-15 division by zero guarded; D-16 stacks counted and guarded (revises D-2);
D-17 host node 32/32 deep, mesh node 10/9; D-18 "guard all errors": error codes 1–16 (+17 Storage refused,
18 No one on that port, 19 Message refused, 20 Node gone, 21 Interrupted added by MESH).
- D-19 block registers REPLACED 2026-10-07 by kernel requests on port 0.
- Standing ruling: where v3 departs from FORTH-79, FORTH-79 wins and the departure is reported
(`LEAVE`, `MOVE`, `.R`, `'`, `WORD`, `NUMBER`, `LATEST`, `COMPILE`, `ABORT"`, `FORGET`, vocabularies).
Several v3 bugs are "reported, not fixed" here (v3 `LATEST` pushes HERE; v3 `COMPILE` broken; v3 `ABORT"`
segfaults in a compiled word; v3 `FORGET DUP` succeeds).
- Entry layout: xt-3 flags (1 immediate, 2 hidden, 4 data; ACL: bit5 denied, bit6 pinned, bits 8–15 mode,
16–31 TTL), xt-2 name address, xt-1 link, xt code. Names ≤31 chars.
- §5.20: v4's word ACL is weaker than v3's: checked when interpreted and when compiled, not at each run of a
compiled call. Closing it needs the check at `call` (issue #6).
- §6 ports: originally four (UP/DOWN/LEFT/RIGHT), withdrawn; `V4_PORTS` is a parameter, wiring is a table.
- File paths in this document are the OLD ones (`v4/capsule/*.v4`); since MACHINE.md they are `.f18` blobs
under `capsules/v4/sys/`.
### MESH.md ("Talking nodes", 2026-10-06 onward; long, with its own history)
- Rulings: ports are the transport, the Hermes message is what travels; geometry is data; first geometry
2×2 + centre, units join centre to centre; scales at run time; Hera decides which nodes exist/are awake;
a node is born empty; built hosted first, then bare metal.
- §4 engine ports: `base+k` port k; then any, which, writers, readers, Wire, A, B, Do, How, Have.
- §5 a capsule of F18 code is just the words a neighbour writes to the port (`@p a! @p push` / `@p !+ unext`).
- §6 message: 7 words (to, from, type+channel, heat+TTL, ACL tag, sequence, length) + text, 4 chars/word.
Types: 1 text, 2 output, 3 done, 4 NACK, 5 GONE. At most 16 hops.
- History worth remembering:
- §7a (looking before writing, lower-number rule, 400-cell ring) — a RECORD since step 6e.
- §7c "the wait" (step 6d) — built 2026-10-08, two reviews found it unsound, BACKED OUT the same day.
Root causes (§7c.7): `EMIT` ran past the output buffer; a message's first word moved before room for the
rest was known. Stack size was never the cause.
- §7d "messages on the wire" (step 6e, built/reviewed/mended 2026-10-13): the fabric moves WHOLE messages;
each wire has a queue each way of `V4_WIRE_CELLS` = 1024; put/take are all-or-nothing; ten operations
(look, take, move, drop, put, first, next, sleep, sleep-for-room, room). Only printing waits for room.
The kernel's port has no queue.
- §8 storage (ruled 2026-10-07, "v3's way in full"): every node asks the kernel for a block by number on
port 0 (requests -1..-5: BLOCK BUFFER UPDATE SAVE-BUFFERS EMPTY-BUFFERS); the kernel keeps the node's window
of four 256-cell slots (`v4/system/blocks.c` over `v3/src/block_subsystem.c`). §8.6/8.7 list what was
WITHDRAWN (disk as a port device, nodes without storage, per-node drives, device identity in header).
Not yet: who may have which block (needs identity).
- §9/§9a births follow v3 (2026-10-16): any node may birth, parent = the asker; KILL/PAUSE/RESUME are Hera's
alone, by number; the kernel keeps the registry (`v4/src/manage.c`), requests -6..-18
(NODE-ME, NODE-BORN, NODE-WIRE, NODE-UNWIRE, NODE-SLEEP, NODE-WAKE, NODE-KILL, NODE-PARITY, CAPSULE-OPEN,
CAPSULE-CELL, CAPSULE-LINE, NODE-CHILD, NODE-PLACE). The KERNEL tells a node's going (GONE), no node hands
it on (amended 2026-10-20). Capsules `capsules/v4/centre.4th` (blocks 8100+) and `hera.4th` (8000+).
- §10 steps: 1–7 done (7 in the fabric under test only). **Steps 8 and 9 NOT done: the hosted product and
bare metal are still ONE node each** (issue #85). Step 3 leftover: KEY/EXPECT/QUERY still read console
registers, not messages (issue #84).
- Recurring method in this file: design → plan → build test-first → independent review "told to break it" →
Bob rules "fix them all, test first" → verify on six systems with log dirs cited. "No bad code is ever released."
- dict_hash history (word_count 317/318): 0x220ab283a504a3b3 (10-07, 314 words) → ... → 0xe5a57f3eb72ff94a (10-13)
→ 0x248b4edc47f4357e (10-16, 318) → 0xfec8c47cfc6f437f (10-20, 317).
### `docs/v4.0.0/plans/` — step plans (all executed; format: Goal, Rulings, Global Constraints, Review Focus, Tasks with failing test first)
- Every plan repeats the working contract: branch `StarForth-v4.0.0`; strict C99 `-Werror`; v3 behaviour
unchanged; QEMU/bare-metal parity; "no fix outside the plan; report it"; each task = failing test written
and SEEN to fail → implement → pass → regressions → full acceptance → commit with the logs.
No kernel unit tests: kernel tests are QEMU sessions driven by `scripts/qemu_session.py` over serial + QMP.
Every new console/log message ≤ 63 chars (`LOG_LINE_MAX` 64 truncates; known defect, awaiting ruling).
- Plans say: commit with the LFS filter OFF
(`git -c filter.lfs.process= -c filter.lfs.clean=cat -c filter.lfs.smudge=cat -c filter.lfs.required=false`)
and push with GitKraken's git-lfs on PATH. That is how logs end up committed as plain text against
`.gitattributes` — see discrepancies.md.
- 2026-10-20 engine-step4 (node in the VM's place), revised under MACHINE.md: Q1–Q5 ruled as recommended.
Phases: Gate (done) → A (hook at `call`; every word but `>R R> R@ I J LEAVE` called) → 1 v4 in the kernel's
boot → 2 word accounts at call → 3 init.4th/starforth.4th → 4 ACL → 5 Artemis writes → 6 identity/prompt →
7 physics on word records (v3's whole POST passes = parity) → 8 v3 leaves the build.
Only Part A is written out; later phases get their own plan when the previous is accepted.
v3 has 526 words before its prompt, a node has 317/318: the gap is the parity work (#4).
- 2026-10-26 identity gate (done): D1 split `capsule_zuse_boot_check` out (no VM); D2 recognise only (genesis
later — later lifted by stick-5); D3 prompt `[zuse@Hera] ok>`; D4 minted pair the QEMU default (later
replaced by the fresh data stick). New files `kernel/src/v4/sk_v4_identity.c/.h`.
- 2026-10-27 stick-4 (one disk): loader passes `BootDisk {gpt, is_stick, disk_guid}` in `BootInfo`;
partition type GUIDs: identity `23BEBFE1-4817-4CF3-A537-9069BF159788`, Artemis
`BCD7B586-1C8E-4EEF-86A3-273A8D8EE624`; chain on v4 = fast RAM, ramdrive, stick's Artemis, its identity;
detach tail-first; amd64 QEMU gets RDRAND; `screen=boot` keeps the console on screen until login (for the
SER5, which has no serial port).
- 2026-10-29 stick-5 (proxy Zuse, growth, real Zuse; Tasks 1–5 all accepted, #92 done 2026-11-10):
marker v2 `{magic, version, proxy_pubkey[32], real_pubkey[32], has_real, crc}`; `sk_v4_marker.c`,
`sk_v4_grow.c`, `sk_v4_mint.c`, `gpt.c` writer (`gpt_grow_last`, `gpt_write_one`); R1 cap 256 GiB because
the block map costs 2 bytes of kernel heap per 1 KiB block and the heap is 2 GiB; `MINT-ZUSE` is kernel
word request 2 in `sk_v4_words[]` (`BYE` is 1) → word_count 318, dict_hash `0x8c92508f748f99cf`.
Bob, 2026-11-08: "work in small increments and memorize frequently" — hence the Progress section kept at
the foot of the plan, one line per increment.
- 2026-11-10 alpha4-documents: #138 Book of Fabric (`docs/book/fabric.tex`, `make fabric`, 722 pages),
#157 dictionary (`docs/reference/v4-dictionary.tsv`, `v4/tools/mkdictionary.py check`, `make dictionary`),
#126 Downloads/Documents pages (`site/com/build.py --release TAG --sums SHA256SUMS`, `install.sh` is Bob's).
- NOT YET READ in full: 2026-10-06 step6-storage, 10-07 step6b/6c/6d, 10-08 step6e, 10-15 machine-step1-rom,
10-15 mesh-rom, 10-16 mesh-step7, 10-26 stick-1, stick-2, 10-27 stick-3 (all executed; MESH.md and STICK.md
already carry their outcomes).
## `docs/fabric/FABRIC-3.md` — the LIVING record ("bare metal boot", opened 2026-09-04; 6,515 lines)
House style of every FABRIC entry: write the decision and reasoning BEFORE building; "investigated, not
assumed"; findings are report-only unless Bob names them; close each item with a dated note citing real
evidence (log dirs, commit ids); never silently drop a stale claim — correct it in place with the date.
Paths in early sections are pre-reorganisation (`src/starkernel/…`, `Makefile.starkernel`); today they are
`kernel/src/…`, `kernel/Makefile`.
- §I.1–I.2 (09-04): `v2.0.1` fast-forwarded into `master`; version rolled back to 2.0.0 (2.0.1 names the SER5
hardware line and claimed unverified progress); tag `v2.0.0` moved; branch `v2.0.1` deleted. Versioning is
SEMANTIC, not sequential (roadmap table in `kernel/Makefile`).
- §II three hardware scopes: amd64 = ANY x86_64 UEFI PC (Beelink SER5 is only the reference; anything
SER5-specific is a bug); aarch64 = Raspberry Pi 5 only; riscv64 = Milk-V Mars only.
- §III amd64 audit (report-only, still open unless later closed): HPET base hardcoded `0xFED00000` (no ACPI
"HPET" lookup); LAPIC base hardcoded `0xFEE00000` (MADT type 5 not parsed); i8042 and 8259 PIC poked with no
FADT presence check; `arch_cold_reset()` uses the i8042 pulse instead of the ACPI Reset Register (live via `BYE`).
Clean: COM1 probed before use; ACPI 2.0 then 1.0; GetMemoryMap/ExitBootServices golden path; APIC timer
calibrated at run time; IOAPIC from MADT; PM timer port from FADT.
- §IV Pi 5: NATIVE boot (not UEFI — `rpi5-uefi` is archived). `config.txt`: `kernel=kernel_2712.img`,
`os_check=0`, `device_tree=bcm2712-rpi-5-b.dtb`, `enable_uart=1`. Entry x0 = 32-bit DTB pointer. New files
(aarch64): `native_rpi5_entry.S`, `rpi5_native_boot.c` (DTB → existing `BootInfo`, then the unmodified
`kernel_main()`), `rpi5_mailbox.c` (VideoCore mailbox framebuffer), `rpi5_dtb.c` (UART/mailbox bases, soc
`ranges` offset 0x10_0000_0000), `hal/fdt.c` extensions. GIC bases and PSCI conduit now come from the DTB
with QEMU constants as fallback. RP1 sits behind Broadcom's INDIRECT PCIe config window
(`brcm,bcm2712-pcie`), a third config mechanism — not implemented (no QEMU model; needs hardware).
Pi 5 RNG: no known register; not a boot blocker. No non-amd64 ISA turns its MMU on (VA == PA).
- §V Mars: U-Boot + OpenSBI + DTB, entry a0 = hart id, a1 = DTB. PLIC base from DTB (`sifive,plic-1.0.0`)
with QEMU fallback; `satp` cleared only if not already Bare. JH7110 display and PCIe unresearched.
riscv64's SBI timer and SBI SRST reset are the most portable of the three.
- §VI hardware reference (SER5 = some Ryzen 7; Pi 5 = BCM2712 4×A76; Mars = JH7110 4×U74; Zynq PZ7020 for the
FPGA milestone; BeagleBone Black noted only).
- §VII xHCI/BOT went multi-device (closed 09-05): per-slot `xhci_msc_slot_t` registry sized off
`dev->max_slots`; pending connect/disconnect queue; boot scan no longer stops at the first port.
Bob's rule quoted: "we REALLY need to not paint ourselves into ANY scale issues by taking an easier way out."
A worse bug found only by live two-device testing: `transfer_purpose`/`next_action` were shared scalars.
- §VIII (09-05) headless-until-login: `EMERGENCY_CONSOLE_ENABLED` default n — no banner, no prompt until an
identity drive logs in; a runtime VM error halts (no recovery REPL) in production builds. "There should be
nothing special about zuse as a user except zuse has no acl's." KILL now detaches the console if it kills
the `USE`d VM.
- §IX (09-06) four bugs found by actually minting the 8 identity thumbdrives; IX.1: detach of an unrelated
drive ended Zuse's/WIREBIND's session — both now compare the departing device.
- §IX.2–IX.5 (09-06): `vm_cleanup()` never freed `DictEntry` allocations (leak → PANIC after 8–9 birth/kill
cycles); `sf_free()` was a deliberate no-op bump allocator → real free list; headless gate re-engages after a
mid-boot logout ("we should never see an unauthorized, no session forth prompt"), via live
`sk_console_identity_present()`; `MINT` verifies its own write (`MINT_ERR_VERIFY_FAILED`).
- §X (09-06/07): "4th device fails" was QEMU's xHCI having only 4 real ports (auto-inserted hub) → `XHCI_PORTS`
Make variable (default 16), explicit `port=`; real driver bug: Configure Endpoint submitted unconditionally
with several outstanding → single-in-flight. Heap: identity = 2 VM births = exactly 457,392 bytes; the 4 MiB
`alloc_kernel.c` arena was the wall → `sf_malloc/sf_free` now delegate to `kmalloc_aligned/kfree`
(the kernel's real heap: 2 GiB default floor, `--heap=`, splits and coalesces). Orphaned console VM on a
failed WIREBIND birth now killed. Open lever: per-VM dictionary size.
Flagged not fixed: `printf '$(KERNEL_ARGS)\n'` breaks when args start with `--`.
- §XI (09-07/09): `MINT` restricted personality (`capsules/acl-std79.4th`, `ACL-LOCKDOWN-STD79`, allowlist of
~200 FORTH-79/83 words; `-1 MINT`); storage attach goes Hera → Artemis by message
(`HERA-BLK-ATTACH-REQ` / `BLK-ATTACH-ACK`); "identity attach never completes without Zuse" was TWO bugs:
(1) `blk_migration_idle_check()` scanning ~16,000 devblocks every idle tick (fixed: `has_ever_claimed`,
resume cursor, budget 256) — found by a fresh reader of the code after hours of live forensics;
(2) cert verification gated on Zuse's live session instead of her persisted PUBLIC key
(`zuse_genesis_marker_t` → `zuse_root_pubkey`). Bob: "zuse is zuse, [each identity] is [itself]".
A guest's ACL denial used to halt the whole machine → only Hera's own session fails closed; a guest session
prints "VM fault -- session recovered, resuming". xHCI now drives Port Reset on port reuse; WIREBIND teardown
kills the console VM too. All 9 thumbdrives minted; 8 non-Zuse ones carry the restricted personality.
Lesson recorded: check for a leaked `qemu-system-*` process before believing a slow/odd result.
- §XII.1 (09-10): `EXEC` no longer clears the capsule's blocks afterwards, so a locked-down identity can
`LOAD` them (standard word) — `capsule_exec_init()` in `capsule_loader.c`.
- §XII.3 (09-10): use-after-free — `sk_repl_run()` captured `active` before a blocking read; a detach of A
then attach of B never showed in the generic "anyone attached" boolean. Fix: re-read `g_repl_active_vm`
after the read. Rule recorded: compare IDENTITY, not a boolean guard. The `.elf` is not the running binary
for the monolithic build — use console probes compiled into the image, not GDB symbols.
- §XII.4 (09-11) 27-leg campaign (9 identities × 3 ISAs), cross-identity parity perfect. Bugs fixed on
request: `M*` treated a double as 32-bit halves → `__int128` multiply; `M/MOD` same class → hand-rolled
128÷64 restoring division (no `__udivti3` in a freestanding build); `D+`, `D-`, `DNEGATE`, `d_compare` used
bare `unsigned long`, which is 32-BIT ON THE aarch64 CROSS TARGET (64 on amd64/riscv64) → `ucell_t`.
Lesson: `cell_t` width ≠ C `long` width; never use `long` for cell arithmetic.
- §XIII (09-10) heap corruption on the 3rd WIREBIND cycle = same stale-pointer class: `sk_console_readline()`
kept calling `sk_repl_idle(active_vm)` on a freed VM, and `blk_vm_flush_all()` wrote into kmalloc's free
list. Fix: re-resolve the live VM on every idle tick. `kmalloc_debug_census()` kept as permanent tooling;
all other probes reverted ("write, run once, capture, revert").
- §XIV concurrent attach gap (only some of 8 simultaneous drives detected) — never fixed directly; no longer
reproduces 2026-10-14 on all three ISAs (5/5), probably the xHCI pending-events queue. Note in that entry:
every image under `disk/thumbdrives/` and `disk/artemis.img` is ALL ZEROS since `e56974e0` (bleached).
- §XV (09-11) std79 DoE: 3 arch × 9 identity × 3 rep, randomized (Fisher-Yates, seed 12345), all in FORTH
(`experiments/std79-doe/std79-doe.fth`), driven by `VM-EXEC`. 81/81 correct. Rule: "any defect repair
requires rerunning the DoE from the top."
- §XVI: aarch64 stall = `stadium_admit()` eviction fallback scanned all `stadium_ncells` (335,544 on a 4 GiB
guest vs 83,886 on 1 GiB) instead of the VM's own residents → per-quota resident list. Stadium sizing:
1% of heap for cells, 50% of the rest for VM slots. §XVII: grant from `stadium_best_donor()` (most free
cells), not always Hera; `free_count` O(1).
- §XVIII (09-12): per-tick CSV gained `fleet_k_q48`, `fleet_conserved`; K = 1.0 (Q48.16 65536) on all 775
ticks, sd 0. Report: `experiments/std79-doe/report-20260912/report/std79_doe_report.pdf`.
- §XIX: honest caveat — execution was strictly SERIAL (`VM-EXEC` is a synchronous C call; idle VMs accrue
zero ticks), so K's result checks sequential accounting, not concurrency. Direction agreed: no scheduler;
a compudynamic turn-attractor (coolest live VM goes next) in `capsule_vm_physics.c`. `VM-HEAT` word added.
- §XX (09-12): Hera could not message because 8 `STADIUM-*` primitives were registered for child VMs but not
for her; an undefined word during compilation SILENTLY DROPS the definition. Fixed "by symmetry, not
special-cased". Bob: "I don't want us to begin thinking of Hera as being different than any other VM...
the only real difference in Hera should be access to the kernel capsule repository."
(All of §XX–§XXIII describes v3's FORTH messaging; the Hermes VM and `messaging.4th` were removed 09-22.)
- §XXI turn-attractor on messaging: priority = (heat gained this campaign) / reps remaining; sender pays;
one message per rep (27 sends, not 648) because `MSG-SEND` silently no-ops when the reservoir is dry.
- §XXII riscv64 "stall" at 9 VMs = the idle pump dispatched `MSG-TICK` into EVERY live VM every beat (O(N));
fixed with round-robin batching (`SK_MSG_PUMP_BATCH` 4). Bob: "we really will be giving birth to potentially
hundreds of VMs." Method lesson: three premature kills on "no output" — sample the qemu process's
`/proc/<pid>/stat` utime to tell slow from stuck; `run_doe_batch.sh` now writes `host-sample-*.csv`.
- §XXIII: `N-REPS` > 3 loses data (reservoir refills ~6.8 units/s); left at 3 (this is issue #51, blocked).
`capsules/init-0..9.4th` renamed `workload-0..9.4th`.
- §XXIV: a `Block N` collision is a silent PERSISTENT disk overwrite (capsule blocks land in Artemis's range,
LBN 3072+). `mkcapsule --resolve` (interactive renumber), `tools/capsule-claims.txt` (derived, ignored),
`tools/capsule-reserved.txt` (human, tracked), `tools/patches/`. "mkcapsule is our secret sauce linker."
mkcapsule.c (1600+ lines) is due an ETL-shaped decomposition (not done).
- §XXV: governing principle in Bob's words: "the trick is to make system calls, schedulers and filesystems
more or less go away and at the same time introduce more automanagement and make that shit obsolete."
Workloads run as ephemeral child VMs, born per trial and reaped. `BIRTH`/`CAPSULE-BIRTH` registered for
every VM and carved into `ACL-STD79-LIST` (block 4048) as the one deliberate non-standard exception.
- §XXVI (09-13) CORRECTION: the "lockdown never engages" finding of §XXV was wrong — the wrong VM was tested.
WIREBIND births TWO VMs per identity: console proxy `<user>` (not locked) and `<user>~user` (locked).
Lesson: confirm which VM a name resolves to before concluding anything. Console prefix unified to
`[user@VMName]`. Flagged: the messaging DoE had been driving the console proxies, not the `~user` VMs.
- §XXVII: disk-backed log ring on Artemis (`kernel/src/log_region.c`, devblocks 65–96 from top; eligibility
list 1–63 (now reserved/unused), `artemis_sig_t` 64); `LOG-APPEND` attributes the source VM itself (no
caller-supplied source) and is pinned. Banner: "StarForth CLI", no em dash (font cannot draw it).
- §XXVIII (09-13/14) preemptive switching between v3 VMs, staged with go/no-go gates, one commit + full
3-arch acceptance per stage. Discovery: every VM ran as recursive C on ONE shared kernel stack.
Stage 0 full trap frames (amd64 gained FXSAVE/FXRSTOR — a real pre-existing FP gap; aarch64 +v8–v15;
riscv64 +s0–s11, fs0–fs11). Stage 1 a guarded 2 MiB native stack per VM (`sk_vm_native_stack_alloc`).
Stage 2 `sk_vm_switch_to/prime` in per-arch `switch.S`, `vm/switch.c`, `VM_STATE_SWITCHED_OUT`; KILL refuses
a switched-out VM. Stage 3 timer sets a flag only; the switch happens at a per-word checkpoint on the
mainline (word granularity ruled "fine grained enough"); readiness signal in `capsule_vm_switch_signal.c`.
XXVIII.1: "Stage 3 CLOSED" had overclaimed — a quiet log looks the same for a healthy idle REPL and a
livelock. Real defect: checkpoint fired inside nested `VM-EXEC` on a borrowed stack → only at the OUTERMOST
`vm_interpret()` (`g_vm_interpret_depth`). XXVIII.2: `has_work` eligibility (`SWITCH-MARK-WORK`);
"who is current" tracked in `switch.c`, not by log attribution. XXVIII.3: off-by-one `dsp < 2` (dsp is an
INDEX, -1 = empty) set `vm->error` on every `MSG-SEND`.
Verification rule: prove liveness by typing over QMP `send-key` and seeing a computed answer, not by log growth.
- §XXIX/§XXX Stage 4: WIREBIND user VMs are switch participants; per-device live table (13 slots);
tombstone `pending_reap` + `capsule_vm_force_reap()` at the switcher's safe point. Found, pre-existing:
interactive `USE <identity>` on a fresh WIREBIND identity halted the kernel.
- §XXXI DoE rerun after Stage 4: 81/81; harness bug (waited for ANY attach line, not the named one) had
reproduced §XIV — check `VM-EXEC: VM not found` count is zero before trusting a run.
- §XXXII (09-15) new initiative scoped: human vs unattended identity, the `USE` halt root cause, a primitive
error-handling audit, logging cleanup. All FABRIC files were read before planning it.
- §XXXII.1: any unknown word typed at Zuse's console used to HALT the kernel (Zuse's session runs on Hera's own
VM; Hera's session failed closed). Now both `sk_repl_step()` and `sk_repl_run()` recover unconditionally
("VM fault -- session recovered, resuming"); `sk_fault_handler()` removed. Verify at ZUSE'S console.
- §XXXII.2 (ratified 09-16): unattended identities = cert + personality, NEVER a seed; minted at run time
against a RAM scratch device (`MINT-SCRATCH`, `MINT-SCRATCH-EMIT`), hand-transcribed into a `.4th` capsule,
born with `UNATTENDED-BIRTH`; `CONSOLE-ATTACH` pairs a console later. Invariant: an unattended birth must
never touch the console-pairing global (would open a prompt with no human present). No C capability bit —
ACL policy belongs in `ACL.4th`.
- §XXXII.3–.6 error-handling audit of the kernel-only words (v3): 105 `vm->error = 1` sites triaged, 75 silent
ones given diagnostics in 7 batches. Rules that came out of it: an interactive command's direct reply goes to
the console; everything else goes through `log_message()`; in a function, match the convention its other
guards already use; `defer_words.c` is the model (report, then fault). `SWITCH-MARK-WORK` and `VM-HEAT` must
never error (hot path). Found two real NULL-deref guards in `vm_compile_call`/`vm_exit_compile_mode`.
The vendored `word_source/` files (e.g. `memory_words.c` pre-checks in `@`/`!`) were left for FABRIC-4.
- §XXXII.4 log ring eviction is level-aware (ERROR/WARN protected); `log_region_append()` returns 0 / 1
(dropped by design) / -1. `LOG-FLUSH` built later (10-14, §XXXVIII).
- §XXXIII (09-16) multiuser/multitasking DoE design (issue #58, deferred past bare metal): factors
concurrency 2/4/8 × workload uniform/heterogeneous; "rule of 3's" in every DoE. New words `WORKER-BIRTH`
(no identity), `VM-ERROR?`; every birth caller must itself call `capsule_vm_registry_set_name()` and
`vm_physics_init()` — `capsule_birth_baby()` does neither. Heat only moves from a VM's SECOND touch.
Per-tick CSV = `doe_log.c` (`HB-ON`/`HB-OFF`, off by default), columns `vm_name`, `vm_id_hex` first.
Capsule format rule found: a `: … ;` definition and any control structure in it must fit inside ONE
16-line block (the loader keeps no control-flow state across `Block` headers).
`workload-5` = ~2.4 trillion word executions per call, `workload-1` ~875M at birth → `-lite` variants.
One physical terminal = one foreground session by construction (multi-seat is a deferred idea).
- §XXXIV: `THRU`/`LOAD` swallowed the rest of their line (fixed 10-14: `vm_interpret()` saves/restores the
outer text). A second Claude session killed a live campaign by assuming a running QEMU was an orphan —
NEVER assume a live qemu is an orphan; check its command line and log first. 30 reps/cell would have been
~10.3 days → ratified: per-ISA, one seed per ISA, 6 cells × 3 reps = 18 trials/ISA, ~24.8 h/ISA.
Stop a campaign with SIGTERM to the qemu process (not the wrapper) so the Makefile's cleanup and
`scripts/extract_doe.sh` still run.
- §XXXV.1–2 (09-17): block-backed DoE persistence design (issue #60): bare metal has no host to scrape
serial; `disk/artemis.img` was 30 MiB, raw per-tick data ~64 MB/trial; the metadata fence is addressed
BACKWARD from the end of the device, so a naive resize moves every fence consumer.
- §XXXV (09-17, design only): persist ONE binary record per trial in a new fence region (97+ from top),
host reads it back after; prefer N=2 reps/cell; §XXXV.6 ratified a fresh 1 GiB `disk/artemis.img` and a full
re-mint (never done for the committed images; they were bleached — see §XIV note).
- §XXXVI (10-14) one delivery path: a VM takes its own kernel-Hermes messages on its own turn, on its own
native stack; Hera's idle beat runs only her own. Found: amd64 first-entry frame left rsp misaligned (#GP on
an aligned SSE store) → 64-byte frame.
- §XXXVII (10-14) security: `KH-ELEVATE-SEND` and `KH-BLK-ATTACH-SEND` let ANY identity run text as Zuse on
Hera — elevation removed entirely (ruled not needed: "privilege comes from the drive"); `KH-BLK-ATTACH-SEND`
only from Artemis, `BLK-ATTACH-ACK` only by Hera; a message could run twice (drain now pops before running).
v3 baseline became 523 words / `0xb73b58052d591638`, then (§XXXVIII, `LOG-FLUSH`/`LOG-SHOW`)
526 / `0x82f4ae7cb2e2d424`. The freestanding `snprintf` has no `%lld`, no `%016llx`, no `%f`.
- §XXXVIII `LOG-FLUSH` (every VM) / `LOG-SHOW` (Hera only): per-VM 900-byte buffer; flush = one kernel-Hermes
message type 10 to Artemis; flushed on demand, when full, and at once on ERROR; ring-growth bug fixed.
- §XXXIX Pi 5 native path: MMU + caches on in the entry stub (identity map), bounded mailbox waits,
framebuffer address via `dma-ranges`. Rehearsal target: `make -f kernel/Makefile ARCH=aarch64
RPI5_NATIVE_BASE=0x40080000 rpi5-rehearsal` (QEMU virt at EL2). It found: PL011 register shift, GIC address
through `ranges` (`fdt_reg_address()`), no IRQ at EL2 without `HCR_EL2.IMO/FMO/AMO`.
- §XL xHCI found by PCI class 0C/03/30 from any vendor, real BAR size, BIOS handoff, 64-byte contexts
(handoff and 64-byte contexts unproven until the SER5). §XLII every controller (up to 8), per-controller slots.
- §XLI USB HID boot keyboard (`kernel/src/usb/usb_kbd.c`), Caps/Num Lock, keypad; serviced every timer tick
while waiting for a key. S3: a PC with no PS/2 controller hung in `i8042_init()` (0x64 reads 0xFF) — fixed.
"Keyboard VMs" noted as a concept only.
- §XLIII `system=v3|v4` boot argument; then (same day) v4 the default everywhere; acceptance = three ISAs as
built (v4) + `make -C v4 test-32`; "i don't care about v3".
- §XLIV (10-29) first SER5 boot faulted in the loader: ~9,000 32-bit absolute relocations break when firmware
loads the image above 2 GiB (QEMU q35 always loads low). Ruled: `-fpie` + everything hidden
(`kernel/include/starkernel/pie_hidden.h`, `#pragma GCC visibility push(hidden)`), link refuses
`R_X86_64_32/32S`/GOT relocations (`AMD64_RELOC_FORBIDDEN`), and `qemu-stick-high` (pc machine, 3 GiB)
joined acceptance. The SER5 itself: new stick not yet booted at that entry.
- §XLV.1–2 (11-06) "the Captain Bob method" ruled; static review of v4 (11-02) fixed three bugs in `fd208825`
(hosted over-long line, bare-metal line cut at 255, a refused store still moved A/P); logs + DoE CSVs
renormalised into LFS (`027b144e`, 1,003 files); `make ARCH=… init` installs the toolchain;
`scripts/nightly.sh` stages: `accept <isa|stick-high>`, `test-32`, `proofs`, `images`, `publish`, `docs`,
`publish-docs`.
- §XLV.4–8 (11-06): workflows `nightly.yml` 03:00 UTC, `nightly-docs.yml` 04:00 UTC, `release.yml` on tag
`v<LITHOS_VERSION>` (a tag naming another version is refused), `acceptance.yml` on every PR into master,
`build.yml` on every push. Nexus coordinates `org.starship:kernelImage` (classifiers `pc`, `pc-stick`,
`raspi5`, `milkv`, `logs`) and `org.starship:documentation` (`book`, `vol1..3`, `api`, `fabric`,
`dictionary`); classifier = the BOARD, not the ISA. Runner container pinned
(`gitea/runner-images:ubuntu-24.04-v26.11.03`, later the project's own `lithosananke-runner`).
Branch protection on `master`: no push by anyone, merge needs `Acceptance / Acceptance (pull_request)`,
PR must be up to date, admin override blocked. StarForth repo archived as tag
`archive/starforth-2026-09-17` and deleted. Repo renamed LithosAnanake → LithosAnanke (redirect kept).
Gitea: wiki off; labels `kind/` `priority/` (exclusive), `area/`, `board/`, `status/`; the project board
has no API. The `.org` XWiki is the project's entry point, the `.com` its public face.
- §XLVI (11-07) StarshipOS CA: Root CA (Ed25519, 20 y, key only on the CI box in `/var/lib/starshipos-ca`) and
"StarshipOS Capsule Signing" intermediate (10 y) in the tree as `capsules/pki/starshipos-intermediate.der`;
`ci/pki/make-ca.sh`; signing key = repo secret `CAPSULE_SIGN_KEY`; `SIGN_KEY` has no default, so local
builds are UNSIGNED and log `signature: missing (unsigned)` — a warning by design. `mkcapsule` refuses a key
that does not match the certificate. NOT done: the kernel does not check the intermediate against a root,
and an unsigned capsule only warns (issue #139).
- §XLVII alpha releases: kernel `LITHOS_VERSION` 2.1.0 → 4.0.0-alpha.1; engine `VERSION` stays 3.2.0. 4.x is a
working line (even major); LTS takes the next odd major. alpha.1 and alpha.2 were tagged but never
published (the server has 3.8 GiB RAM: HOL-Library is prebuilt as a registry package, Isabelle capped to
one thread / Java 512 MiB / Poly/ML 900 MiB); alpha.3 was the first published; "the tag stays where it is"
— a failed release gets a new number, tags are never moved.
- §XLVIII (11-07 → 11-10): the ranked issue list after alpha.3 (milestone alpha.4, index #147);
developer protocol #135 (`scripts/nightly.sh protocol` → `PROTOCOL.md`, checked by CI — not built);
alpha.5 = the SDK (capsule repository in blocks #149, K under network latency #150); demo
(try.starshipos-f18.com: ttyd behind Apache, guests 384 MiB, `DEMO_MAX_GUESTS` 2, "busy" message);
#151 idle loop now `arch_halt()` (hlt/wfi) — QEMU 100% → 1% of a core; #131 was QEMU's serial capture
doubling a byte under load, not the kernel; #155 BAM flush touches only the pages in use (1.1 s vs 5–6 s);
licence headers: "Starship License, Version 1.0 (SL-1.0)" / `SPDX-License-Identifier: LicenseRef-Starship-1.0`
(patent/formal docs keep the old wording by ruling; capsules and proofs await a ruling);
#156 retire v3 = its own milestone (what v4 takes from v3: the block layer, blkio, log, platform time,
the `VM *` type in two headers; `proof/`'s 52 theories are all of the v3 VM);
#158 a DoE per release; #92 done 2026-11-10 (Tasks 1–5).
"Fabric is all about steady state" — the Book of Fabric is published.
### What FABRIC-3 teaches about method (the nearest thing in the tree to a "Bulldozer" description)
1. Decide on paper first; Bob rules, usually from a short written trade-off with a recommendation.
2. Test first and SEE it fail; say so in the record ("Tested first, seen to fail"). Say when it was not.
3. Small increments, each with full three-ISA acceptance and its logs committed; no bundling.
4. Any defect repair invalidates earlier results: rerun from the top.
5. Root-cause, never patch a symptom; "no bad code is ever released"; "fix them all, test first".
6. Never trade scale for convenience; fix by symmetry, not by special case.
7. Record slips and corrections in place, dated; never quietly edit history.
8. Report what was NOT verified, and what was found but not fixed, every time.
9. Probes: write, run once, capture, revert. Check for leaked QEMU processes. One QEMU at a time.
10. An independent reviewer "told to break it" reads each finished step.
## `boards/BRINGUP.md` (written 2026-10-13, amended through 11-10) — NOTHING here has run on hardware except the
SER5's first failed stick boot (10-29)
- Boards: `PC` (amd64, any UEFI PC; bench unit Beelink SER5), `RASPI` (Pi 5), `MILKV` (Mars), `ZYNQ7020` (no ARMv7 port).
- Blocker table (IDs used across the repo and issues):
A1 xHCI by class — fixed; A2 headless without login (bring-up builds set `EMERGENCY_CONSOLE_ENABLED=1`);
A3 USB keyboard — fixed; A4 only disk driver is virtio (v3) — n/a on v4 (Artemis from the stick over USB);
A5 entropy: RDRAND on amd64 only, virtio-rng elsewhere → Pi 5/Mars cannot mint; A6 both systems per image — fixed.
PC: S1 HPET address fixed, S2 LAPIC address fixed, S3 i8042 half fixed (PIC unchecked), S4 `BYE` via i8042,
S5 serial header unknown. Pi 5: R1 UART from DT — fixed, R2 MMU/caches — fixed, R3 mailbox partly fixed,
R4 RP1 PCIe driver not written (no USB on the Pi 5), R5 no entropy. Mars: M1 UART layout — fixed,
M2 framebuffer depends on U-Boot, M3 PCIe unknown, M4 image is the UEFI loader run by `bootefi`, M5 Zkr unknown.
- Order on the bench: SER5, Mars, Pi 5. Secure Boot stays OFF (unsigned loader, no shim; ruled 10-28).
- §4.2 the SER5 bench script for plug and play: first boot, second boot, `MINT-ZUSE`, system stick alone
(fixed screen), both sticks at power-on — each rehearsed in QEMU by a named `qemu_session.py` mode.
- §5 pass levels 1–6 (level 4 = same parity as QEMU; 6 = hardware entropy + mint + re-attach).
- "Do not change two things between attempts." Logs/photos/firmware versions are kept and committed.
- STALE inside it: §5 still compares `PARITY:M7.1a` (v3) and says "once A6 is built"; §8 lists pre-alpha
admin items (release number, CHANGELOG gap, SBOM, the old merge) that have since moved.
## `v4/README.md`
- Five parts: engine `v4/src`; ROM `capsules/v4/rom/*.f18` (built by `v4/tools/mkrom.c`); system source
`capsules/v4/sys/*.f18`; capsules `capsules/v4/*.4th`; boot `v4/system/boot.c`.
- Products: hosted (`make -C v4 hosted` → `v4/build/starforth4-{amd64,aarch64,riscv64}`, static, 64-bit cells)
and bare metal (`kernel/src/v4/sk_v4.c`).
- Targets: `make -C v4 test` (both widths), `sanitize` (ASan+UBSan), `hosted-check` (three ISAs, identical
output, also a deliberately failing POST), `post`, `post79` (regenerate cases; needs hosted v3), `test-32`.
- POST: 538 cases, 126 of the 130 Required words; 431 are v3's cases. Not tested: KEY EXPECT QUERY QUIT.
- Open: `PAD 42 OVER !` (#12). "The Required Word Set list in `tools/mkpost.py` was written from memory of the
standard and has not been checked against the document."
- STALE (issue #24): the opening still says "There is no POST and no K measurement yet", "circular stacks",
"per-call-target heat", shows `PARITY:V4_NUCLEUS` lines, says `forth79.4th` holds two definitions and
that the node starts "before the fleet tables"; "BYE is the one kernel word so far" (now also `MINT-ZUSE`).
## `docs/reference/ROADMAP.md` ("roadmap and the ratified versioning policy")
- Versioning policy (ratified 2026-09-19, FABRIC-3.5 §XXX): ODD major = LTS (fixes only), EVEN major =
working line (breaking changes); minor = release in the line; patch = working builds. Kernel
`LITHOS_VERSION` and engine `VERSION` are independent. Engine bumps: major = FORTH-79-visible semantics
change, minor = words added/removed, patch = build only.
- Five LTS criteria: real-hardware boot on the amd64 reference board with logs; no known reproducible
silent-failure defect; ACL Phase 8 closed; `proof/` boundary restated and not contracted; a soak of one
release cycle.
- Three-product split (2026-08-29) and IP framing: Patent 1 + mark StarForth; Patent 2 + marks StarshipOS,
LithosAnanke; Patent 3 + mark Compudynamics. The Dec-2025 provisional's conversion window is ~Dec 2026
("#1 is on a hard clock"); "full StarshipOS is the December deliverable". Open points are for counsel.
- STALE throughout below the policy: "Current: M7.1", the ladder stops at v2.x/"v3.0.0 first LTS" (the kernel
is 4.0.0-alpha.4; FABRIC-3 §XLVII says v3.0.0 is no longer the next LTS number), board gates v2.2/2.4/2.5,
"POST 1012/0/0", M8 "OBSOLETE"/M9 "PLANNED" bars (README says both done in QEMU), validation commands use
`clean-kernel`, examples show 295 words and `LithosAnanke v0.3.0`.
## `docs/reference/` (continued)
- `word-acl/DESIGN.md` (v3 word ACL): four `DictEntry` fields (acl_ttl, acl_allow, acl_mode, acl_pinned);
hot path = one decrement + branch, cold path calls FORTH `ACL-RECHECK`; `ACL-PIN` one-way; birth copies
mode, clears pin, resets TTL/decision; policy all in `ACL.4th`; Phases 1–7 done; 5 `ACL_*.thy` proofs.
STALE: says `EMERGENCY_CONSOLE_ENABLED` default 1 (now n), "Phase 8 FUTURE/current open item" (closed
10-14), "ACL.4th opt-in commented out", CA key placeholder in Block 2066, `src/...` paths, "800/800" POST,
"challenge-response" (ruled out). v3-only; goes with v3 (#156).
- `kernel-args/DESIGN.md`: says "Branch: lithosananke / Design complete — awaiting implementation" but it IS
implemented (`kernel/src/boot/cmdline.c`, `--heap=`, `--log-level=`, `--doe`, plus later `system=`,
`screen=boot`). `REBOOT` word design (NVRAM one-shot, max 3 tries) — implementation status unverified.
- `hosted-acceptance-test/README.md`: hosted v3 three-ISA test via qemu-user (`make rpi4-cross`,
`make riscv64-clang` — riscv64 must use clang). Paths are pre-reorg (`src/`). v3-only.
## `experiments/bare_metal/README.md` (MANDATORY before touching any `.4th`) + its `CLAUDE.md`
- Capsule format rules: first line of each block `Block NNNN`; numbers unique, ≥ 2048, no upper bound;
≤ 16 content lines × ≤ 64 chars per block; `( ... )` comments; `: NAME ... ;`; check with
`mkcapsule --lint capsules/`. Shared namespace: 2048–2099 init.4th, 2100–2199 doe.4th, 3000–3999 workloads,
4000+ user capsules. (Plus FABRIC-3 §XXXIII.6: a definition and its control structures must fit in one block.)
- Only the exact filename `init.4th` is the `MAMA_INIT` capsule; `workload-N.4th` are alternate personalities.
- STALE: "the DoE runs automatically because init.4th calls it" (it does not; no DoE since 2026-09-16),
`Makefile.starkernel`, `logs2/`, 15-column CSV (now 28+ with vm_name/vm_id_hex/K/switch columns).
- `experiments/bare_metal/CLAUDE.md`: the ACL-RWT campaign (+0.0054–0.0088%) is superseded; use
+0.0603% ACL-TTL overhead, CV 0.000% (FABRIC-1 §T).
## `disk/README.md`
- Committed QEMU fixtures; convention: every test disk image lives in `disk/` and is committed.
- `disk/zuse-scratch/{artemis.img, zuse-thumb-ident.img}` = the minted Zuse pair (2026-10-26): a PAIR (marker on
the Artemis fence names the drive's key). Boot COPIES; put back with `git checkout -- disk/zuse-scratch`.
Since 2026-11-08 used only by tests that ask for it and by `system=v3`.
- `disk/artemis.img` rebuilt blank at 1 GiB 2026-09-17, never re-minted; `artemis-30mb-pre-1gib-backup.img`
kept; `artemis-unrecognized-test.img` must stay byte-identical across a boot (regression fixture);
`artemis-debug-roundtrip.img` must stay passing. `artemis.img` gains a `mounted_time` on every boot:
revert it before committing.
- The stick and data stick are BUILD OUTPUT, not here (`build/boards/pc/lithos-pc.img`,
`build/<arch>/kernel/datastick.img`), checked by `scripts/check_images.sh`.
- STALE: `Makefile.starkernel`, `src/` paths, `zuse.img` (deleted per FABRIC-3 §X.1).
## `proof/COVERAGE.md` (Isabelle/HOL, 52 theories, `isabelle build -D proof/`)
- Goal (Bob): not a green build but "identify precisely what cannot be proven and why". Companion
`proof/FINDINGS.md` (file-scope statics standing in for per-VM state, missing overflow guards, duplicate
registration, an unchecked pointer cast in `EXECUTE`).
- Covers v3's `word_source/*.c` word by word, the 7 physics loops, 5 ACL theories, Q48.16. Structurally not
provable without big modelling: block-window cache, parts of TIB input, stdio, raw-pointer dictionary
navigation, vocabulary statics, hot-words cache.
- ALL of it is about v3 (#156 proposes archiving under a tag). There are NO v4 proofs (issue #11).
- STALE: reproduce path is Bob's home directory; "generated 2026-08-14".
## `docs/fabric/FABRIC-4.md` (ideas caught early, not scoped)
1. A Stadium-level "wheel": a second clock (Q48.16 phase accumulator, `rate` fixed first, adaptive only after a
measured baseline) fed by fleet-wide rolling-window/inference output; a gate for a future "sieve stack".
Purpose deliberately not stated yet ("we'll talk about why later").
2. A pinned GPIO VM per board (Pi 5 yes; Mars undecided). (Pre-dates "Hera/Hermes/Artemis are kernel".)
3. "Information state over information moment" (10-16): Bob's theory of information; H0/H1 written:
delivering facts as persistent state vs as instantaneous events (signals/interrupts); measures loss,
corruption under pressure, variance, cost. Bob's question to answer, not scoped.
- Note: FABRIC-3 §XXXII.3 says the vendored word_source sweep was "spun off as its own future FABRIC-4.md";
that content is NOT in FABRIC-4.md.
## `CHANGELOG.md` — milestone-level entries; alpha.1–alpha.4 (11-07 → 11-10), 11-06 gate, then a gap back to
10-09 and 08-18. Its footer flags `master`'s `INPUT_BUFFER_SIZE` 256 — that was the old StarForth repo's master,
no longer relevant here (check v3/include/vm.h in the code review).
## Board READMEs, `capsules/README.md`, `kernel/src/hal/README.md`
- `boards/README.md`: TARGET → dir/ISA/boot path/image; `board.mk` vars `BOARD_DESC/ARCH/BOOT/IMAGE`;
`scripts/mkdiskimage.sh` (no root, no loop devices); default image 128 MiB (the PC stick is 2 GiB).
- STALE: `boards/pc/README.md` says one FAT32 partition (it is the three-partition stick since 10-27);
`boards/raspi/README.md` says the EL2/MMU-off difference "has not been exercised" (FABRIC-3 §XXXIX rehearsed
it); `capsules/README.md` lists `hermes/init.4th` (gone), says "1024 bytes, verify with wc -c" (wrong rule),
`EXEC-DOE`; `kernel/src/hal/README.md` header path `src/starkernel/hal/`, no mention of fdt*, rpi5_*.
- Zynq: board is a Puzhi PZ-StarLite (Zynq-7020): FT232HL JTAG (no AMD tools — ruled; `openFPGALoader`/
OpenOCD), CH340E serial; trial Cortex-A9 compile built 147/151 sources (fails: fe25519.c, scalar25519.c,
hal.c, mixed_arithmetic_words.c — `__int128`). Vendor files are on Bob's machine, not in the repo.
## `docs/v4.0.0/POST79.md` (generated by `v4/tools/mkpost.py` from `post79_rules.py` — do not edit by hand)
- 538 cases = 431 v3 cases (v3 binary's results as expected) + 59 rewritten for FORTH-79 + 20 address-dependent
(count of values checked, not values) + 28 hand-written (words v3 has no case for), with 39 v3 cases left out.
- Rewrites encode the standing ruling "FORTH-79 wins": PICK/ROLL from 1, `>R R> R@` only inside a definition,
`<# # #S #>` on doubles, `MOVE` moves cells, `LEAVE` ends at the next LOOP, `FIND` leaves 0, vocabularies
separate, `>IN` is an offset.
- OPEN: 12 `C!`/`C@`/`FILL`/`COUNT`/`CMOVE`/`TYPE` cases out because HERE is a cell address and those take
byte addresses (they wrote into the nucleus's code), and `PAD.usable` (#12).
- Not tested: KEY EXPECT QUERY QUIT. 6 cases where v3 contradicted its own table.
## `proof/FINDINGS.md` (v3 sweep, 2026-08-14)
- File-scope statics standing in for per-VM state: #1 control-flow compile state and #5 vocabulary subsystem
FIXED 09-05 (`vm->cf`, `vm->vocab`); still open: `WORD` scratch, `system_running`/`79-STANDARD` flags,
`g_prng_state` (shared RNG across VMs), TTF ready flag, INTERPRET's dead `state_variable`.
- `VM_PUSH` is unchecked only under `STARFORTH_PERFORMANCE`, which no build defines. `DECAY-RATE@` fixed.
- Dead duplicate registrations removed (`[ ] STATE`, `DEFER IS DEFER@`); `starforth_words.c` double
registration untouched.
- One-offs: `EXECUTE` pointer cast, `?`/`DUMP`, `TYPE` overflow, `DECIMAL/HEX/OCTAL` fixed 09-05; still open:
`LATEST` == `HERE` in v3; `INFER-*` errors AND pushes; three different L8 selector representations.
## `docs/fabric/FABRIC-3.7.md` — CLOSED 10-14 (elevation not needed, removed; see FABRIC-3 §XXXVII)
- Its own correction: §2's "raw cross-VM address" claim was wrong (the caller copied text); recorded struck,
not deleted. Lessons kept: read how the caller builds a message before diagnosing the callee.
- Ruled 09-23: no knowledge factor, ever — "There's only the drive." A byte-for-byte drive clone made OUTSIDE
StarshipOS is accepted by design; cloning from WITHIN (MOVE/CMOVE/CMOVE>/RELOCATE-BLOCK across devices)
is refused (Phase 8 v3). Plans referenced in Bob's `~/.claude/plans/` (not in the repo).
## `docs/reference/M7.1.md` (capsule architecture, v3; "shipped and live")
- The Immutable Law: exactly ONE production `(p)` INIT defines a baby VM; no shared/base INIT. DOMAIN is
Mama-only (construction/selection), PERSONALITY is the baby's only truth. "Names lie. Hashes don't."
- CapsuleDesc 64 bytes (magic 'CAPS'|ver|hashAlg, capsule_id == content_hash xxHash64, offset, length, flags,
owner_vm, birth_count, created_ns); flags ACTIVE/REVOKED/DEPRECATED/PINNED, mode PRODUCTION xor EXPERIMENT;
REVOKED overrides ACTIVE; (e) capsules never touch babies. Parity lines `PARITY:BIRTH`, `PARITY:RUN`,
`PARITY:BIRTH_FAILED`; VM states EMBRYO/LIVE/DEAD/STILLBORN.
- STALE: implementation checklist all unticked though built; `src/starkernel/` paths. Superseded for v4 by
MACHINE.md (capsule = ROM + `.f18`/`.4th` trailer).
## `docs/INDEX.md` — 547-row catalogue of every document with a status (CURRENT/WORKING/HISTORICAL/SUPERSEDED/
DEAD/RECORD/FORMAL/LEGAL HOLD); last edited 2026-10-14, so it lags (README listed as "v2.1.0", CONTRIBUTING as
CURRENT). Hand-maintained (docs/CLAUDE.md). Skimmed, not read row by row.
## `docs/fabric/FABRIC-3.5.md` (design of the Tripod/kernel reshuffle; CLOSED at v2.1.0, 2026-09-22) — structure
read fully, key sections read in full (§XV, §XXII, §XXXV); the rest by heading
- Outcome: Hermes VM → kernel-Hermes (C); Tripod = Hera/Artemis/Hestia; BIRTH general; one failure ladder;
`SOS` message type 10; Hestia = the console's VM face (HAL must never know a VM exists); versioning policy
(§XXX); kernel-Hermes sinks when its own heat ledger stops adding up, epsilon zero (§XXXVI–XL).
- §XV the authority rulings — the philosophy in Bob's words:
"Any VM can birth another VM that is almost a clone of itself with its own ACL DNA";
"Nobody declares a VM dead, it died a compudynamic death"; "Nobody owns the turn order. The turn order is
compudynamic"; and what survives a death: "nothing survives except K". Three of four questions answered by
rejecting the premise: no owner, no supervisor, no scheduler — authority flows only down the birth graph,
everything else is physics. Flag: `SK_SWITCH_READINESS_THRESHOLD = 50u` is a hardcoded seam.
- §XXII execution method (Bob): strip the anticipated-dead code FIRST, then code; more dead code "falls out"
as code/test iterate. Category A (dead today) stripped first in its own commit + boot; Category B (dead on
arrival of the replacement) only once the replacement runs. Reachability is NEVER established by grep alone
(capsules are born by runtime-built names; DoE capsules are invisible to a boot). Treat experiment/DoE
capsules as live by default.
- §XXXV pre-mortem (Bob asked for it before the build): "Things here fail without saying anything" — silent
failure is this codebase's dominant failure mode; name in advance, per stage, the observation that proves
it worked ("not 'it booted'"); `SK_SWITCH_MAX_SLOTS` 16 was a future wall; the most repeated failure is
"declared done, and it wasn't".
- §XXXI gap sweep: FABRIC-2's close overclaimed; FABRIC-0 had seven open items.
## `docs/fabric/FABRIC-3.6.md` (execution log of the reshuffle; CLOSED at v2.1.0) — handoff, standing rules and
findings log read in full; phase task lists by heading
- Its "five traps" for a fresh session (still true in spirit):
1. silent failure dominates — a green boot is weak evidence; name the proving observation BEFORE running;
2. grep cannot establish capsule reachability; 3. `fleet_conserved` cannot see Stadium heat (two
decoupled accountings); 4. dict_hash CHANGING is expected, DIVERGING across ISAs is the stop condition —
never "fix" a changed hash; 5. docs drift — trust the code, and record the drift.
- Standing rules: one task one commit; three-ISA boot is acceptance; lint clean; no task without
authorization; report, don't fix in passing. Checkbox convention restored (`[x]` only when the check ran;
`[~]` started) so "is anything open" stays answerable by grep.
- Task 0.0: capture a three-ISA BASELINE before changing anything, so the first red boot is interpretable.
Shared `disk/artemis.img` confounded dict_hash across ISAs — reset disks before each ISA.
- Findings: a FORTH address popped in a C word must go through `vm_ptr()`/`VM_ADDR()` (raw cast silently read
zeros); kernel-Hermes messages now COPY their payload (`payload_buf`) — pointer aliasing lost a second
identity's attach; an unexplained 40-minute freeze (logs/20260922-092154) never reproduced, kept open;
`sk_console_readline()` submitted CRLF as two lines (doubled ` ok`) — fixed by peeking for the pair;
noise: `Stadium: dispatch` lines were ungated `console_puts` → `log_message(LOG_DEBUG)`.
- Prompt rule: `[zuse@Hera]` at top level; `[rajames@rajames]` once USE'd into an identity's console VM
("R.A. James is also a VM"). An over-ambitious first design was reverted, not patched forward.
- Out of scope carried: should a Stadium reservoir replenish (item 43); FABRIC-2 §17.4 re-home; `.c.bak`.
## `docs/fabric/FABRIC-0.md` "the Stadium" (CLOSED 2026-08-12, 7,622 lines) — §1–15 design argument read in full,
§16–27 by heading
- The claim: four subsystems (Artemis blocks, Hermes messages, Console, ACLs) implement one physics; lift the
dictionary one level and each becomes an instance. Five patron kinds: block, message, VM, word, ACL
(the console's patron is the dirty EVENT, not the cell).
- The Stadium: one bounded region outside any VM holding what is LIVE (not everything that exists); allocated
at boot before any VM. One entry shape (64-byte cell): identity, heat, TTL, pin, link (index, not pointer),
code field (closed enumeration of behaviours, fixed at build time — "the code field is the entire type
system"; a type field means the design has gone wrong), mass, payload, contains. A cell is a header or a
continuation cell (side bitmap).
- Heat is conferred by traffic; conserved share of 1.0 (K); density = heat ÷ mass; "ranking is read, not
decided — there is no scheduler because there is no policy". Departure: TTL, cooling, or never (pin).
- Storage is BENEATH (warehouse: Artemis, dictionary), devices BESIDE (utility: framebuffer), patrons ON the floor.
- Boot order: kernel opens the hall, Hera walks in first "and cannot be asked to leave".
- Admission test before any code: what does heat mean for this thing, and what is its reap event?
- Debt rules: never two live mechanisms at once (dual paths); no speculative generality; decide the exception
early. Formal payoff: one datatype, no pointers, finite state, one conservation theorem.
- §14: K is 1.0 by construction (a correctness check, not a diagnostic); ENTROPY of the heat distribution is
the real instrument; the system is a driven dissipative system ("Prigogine, not Carnot").
- "Phenomenon first, then mathematics."
- §16–27 (history): substrate findings, patrons, L0 engine, mass/density/K, VMs as patrons, nesting, elastic
quota over one pool, 25.x punch list (phases 0–5), §26 the hardware heartbeat must itself be adaptive (RULED
08-03), §27 console as drawing fabric.
## `docs/fabric/FABRIC-1.md` (CLOSED 08-25) and `FABRIC-2.md` (CLOSED 09-04) — read by structure and headers
- FABRIC-1: open items A–E carried from FABRIC-0; Stadium VM bound made RAM-derived (§G); quota-grant ordering
bug (§H); aarch64 BYE SMC→HVC (§I); SDK v1.9.0 scoping (§K); Fisher-Yates `SWAP-MTX` never shuffled (§N);
ACL-TTL overhead campaign → final +0.0603% (§P–T); Artemis thumbdrive / home-blocks / PKI design (§U–X).
- FABRIC-2: §B Stadium unification; **§C standing rule: "I've never allowed stubs before." — no stub, no
TODO-and-move-on, ever; small honest increments are fine, each a complete real slice; a stub found nearby
gets flagged and resolved, not built on**; §D Tripod final shape; §E the pile as a graph; §F scoped plans;
§G release plan; §H session = VM, identity/ACL "card" model; §I consolidated punch list.
- Carry-forward discipline: when a FABRIC doc closes, every `- [ ]` is extracted mechanically into the
successor, none dropped (FABRIC-3 broke the checkbox habit; FABRIC-3.6 restored it).
## Archive trees — SURVEYED, not read file by file (be honest about this if asked)
- `docs/working/` (253 docs; 128 under `archive/`): architecture notes, DoE designs/data, papers (claim tables,
ANTI_CLAIMS, null hypothesis, SSRN companion), scratch (incl. old `docs/src/` dev reference), legal (HOLD).
Its README is the 2026-06-16 reorg note.
- `docs/formal/` (255 docs; 210 `scraps/`): press-ready LaTeX — vol1 VM physics, vol2 kernel, vol3 research,
dev/user guides, cookbook, standalone experiments/proofs/ssrn/patent. Rules in `docs/formal/CLAUDE.md`
(draft 06-16): scraps mirror `docs/working/` paths with a `%% SCRAP/SOURCE/STATUS/FITS/EDITORIAL` header,
every claim checked against `ANTI_CLAIMS.md`, `%% TODO(bob):` for dictation, `%% PATENT:` flags.
Note the tension with "no TODOs ever" — `%% TODO(bob)` is the sanctioned doc-tier marker.
- `docs/patent/` (43 docs): provisional patent (SSM), claim map, USPTO cover letter. LEGAL HOLD — read-only,
ask Bob before touching anything there or in `formal/patent/`, `formal/scraps/legal/`, `working/legal/`.
- `experiments/` (49 docs): bare_metal analysis/reports (L8 DoE, ACL-TTL), std79-doe and its reports,
std79-exerciser, artemis_stress.
- `.claude/TRIPOD.md`, `HERMES.md`, `ARTEMIS.md`, `CONSOLE.md`: each still opens "This document constrains
Claude Code behavior. Read it completely before touching ..." — but line 7 (21 in CONSOLE) says SUPERSEDED
2026-08-15. Frozen; do not use for design authority. Not read in full.
- `capsules/MANIFEST.md` (551 lines, block ownership justifications; FABRIC-3.6 trap 5 says it is stale
about blocks 4055 and 2049), `BLOCK_MAP.md` / `MANIFEST_AUTO.md` (generated) — not read in full.