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

65 KiB
Raw Blame History

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. 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 USEd 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.