5.1: Isabelle/HOL pass (52 theories, clean) -- restated the boundary rather than just citing the green build: proof/ scope was already entirely outside this reshuffle's footprint (src/starkernel/, capsules/*.4th), so the boundary is unchanged, not moved. 5.2: Documentation sweep. CLAUDE.md's stale WIP banner and Tripod fleet description updated now that Phases 0-4 have actually landed (Hera/ Artemis/Hestia, no Hermes). MANIFEST.md rides the strip -- hermes/init.4th's block table replaced with a deletion note, init.4th/doe-campaign.4th/ hestia/init.4th entries corrected to match the post-strip live files. Confirmed the TRIPOD.md/0.1 contradiction was already resolved (2026-08-13). Settled the superseded-docs call explicitly: archive as-is, do not rewrite. Fixed experiments/bare_metal/README.md's block-size framing (still said 1024-byte budget; real rule is 64 chars x 16 lines). K-qualification checked clean against the two living documents; full retroactive sweep of the closed archival FABRIC corpus explicitly declined as disproportionate. 5.3: make sbom. Installed syft (user-local, approved). Found and fixed a real Makefile bug while at it -- the sbom target hardcoded --source-name StarForth, so DocumentName was wrong even after regenerating. 5.4: LITHOS_VERSION 2.0.0 -> 2.1.0, engine VERSION 3.1.0 -> 3.2.0 (minor, per the dictionary-visible-only rule). Replaced the stale version-comment block in Makefile.starkernel (had the odd/even LTS rule backwards) and docs/lithosananke/ROADMAP.md's retired versioning-policy section with the ratified ladder. Verified on all three architectures; riscv64's first pass hit a transient virtio_blk timeout during boot-time Zuse genesis mint, reported and confirmed non-reproducing on an immediate clean retry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
592 lines
25 KiB
Markdown
592 lines
25 KiB
Markdown
# LithosAnanke Roadmap
|
||
|
||
**Branch:** `master` (post-split: this repo's `master` is the sole LithosAnanke production
|
||
line; the old `lithosananke` branch belonged to the pre-split combined monorepo and no
|
||
longer exists here — see `.claude/CLAUDE.md`'s "On the branch topology" note)
|
||
**Current:** M7.1 in progress — see `FABRIC-0.md`/`FABRIC-1.md`/`FABRIC-2.md` for real status
|
||
|
||
---
|
||
|
||
## Release Versioning Policy (ratified 2026-09-19, FABRIC-3.5.md §XXX — supersedes the
|
||
2026-08-28 policy below)
|
||
|
||
This is the standing release-versioning policy for LithosAnanke. It is authoritative; the
|
||
FABRIC documents track implementation against it, and any permanent change to the policy
|
||
belongs here.
|
||
|
||
**Superseded 2026-09-19.** The original 2026-08-28 policy (`X.0.0` = QEMU release, `X.5.0` =
|
||
hardware bare-metal release, **even** major = LTS) used the minor field to carry a milestone
|
||
meaning and had the LTS parity backwards relative to the ratified policy below. It is kept
|
||
struck through immediately after this note for historical traceability, not as current rule.
|
||
|
||
- **Major: ODD = LTS line** (non-breaking fixes only — backports, never redesigns). **EVEN =
|
||
working line** (breaking changes land here). The line you are on tells you whether breakage
|
||
is possible at all — not the major number's parity signaling "supported vs. not" the way the
|
||
retired policy read it.
|
||
- **Minor** — release within that line. No longer carries a milestone meaning (`X.5.0` no
|
||
longer means anything special) — milestones are roadmap entries now, not arithmetic.
|
||
- **Patch** — working builds within a release.
|
||
- **`LITHOS_VERSION` (kernel) and `VERSION` (embedded StarForth engine) are independent and do
|
||
not auto-sync** — do not infer a relationship if they ever coincide.
|
||
- **Engine `VERSION` bumps at tag time by what actually changed:** major = any
|
||
FORTH-79-visible word semantics change; minor = words added/removed/relocated; patch =
|
||
build-only, no dictionary-visible change.
|
||
|
||
```
|
||
v1.0.x — serial-only production (released, historical encoding)
|
||
v1.5.x — framebuffer VT100 console milestone (released, historical encoding)
|
||
v2.0.0 — QEMU release: three-arch QEMU story complete (released)
|
||
v2.0.1 — SER5 hardware-track line (historical; superseded by this policy)
|
||
v2.1.0 — Tripod/kernel reshuffle: Hermes into the kernel, Tripod = Hera/Artemis/Hestia
|
||
v2.2.0 — amd64 bare-metal bring-up (Beelink SER5)
|
||
v2.x — further working releases; riscv64 / aarch64 board bring-up
|
||
v3.0.0 — FIRST LTS, when and only when all 5 criteria below are met
|
||
```
|
||
|
||
**LTS criteria (a tag may take an odd major only when all five hold):** real-hardware boot
|
||
demonstrated on at least the amd64 reference board, logs committed as audit artifacts; no
|
||
known-reproducible silent-failure defect open; ACL Phase 8 closed (or explicitly scoped out in
|
||
writing); the `proof/` boundary restated and not contracted relative to the prior LTS; a soak —
|
||
architecture unchanged for at least one full release cycle. The first tag meeting all five
|
||
takes the odd major — no judgement call.
|
||
|
||
See `FABRIC-3.5.md` §XXX for the full ratified policy text and reasoning, and `FABRIC-2.md` §G
|
||
for the release-gate punch lists this ladder replaced the arithmetic reading of.
|
||
|
||
<details>
|
||
<summary>Historical: the retired 2026-08-28 policy (kept for traceability only)</summary>
|
||
|
||
- ~~`X.0.0` — QEMU release. A whole-number minor in the `X.0` position is the QEMU-only
|
||
release: the point where the three-architecture (amd64/aarch64/riscv64) story under QEMU
|
||
is complete and defensible on its own terms.~~
|
||
- ~~`X.5.0` — Hardware bare-metal release. Real-hardware-only work gates `X.5.0`, not
|
||
`X.0.0`.~~
|
||
- ~~Even major numbers are LTS.~~ **Wrong — the ratified policy is odd = LTS.**
|
||
|
||
</details>
|
||
|
||
**Board-by-board hardware rollout, decided 2026-08-29 (extends the above as boards come
|
||
online; corrected 2026-09-22 for the ratified §XXX policy — these are working-line minor
|
||
releases, not LTS cuts, since v2.x is the even/working line).** Real silicon is arriving
|
||
incrementally (Beelink SER5 in hand now; RasPi 5 + Milk-V orderable around Mon 2026-08-31), so
|
||
the hardware release is split per real board in hand, each its own minor cut on the v2.x
|
||
working line (v2.1.0, the Tripod/kernel reshuffle, landed first — see the ladder above):
|
||
|
||
- **v2.2.0 — amd64 bare metal.** Beelink SER5 (in hand). Gate: the generic GPT/FAT32
|
||
thumbdrive image (`make -f Makefile.starkernel ARCH=amd64 thumbdrive`) flashes to and boots
|
||
on the real SER5 via its real UEFI; POST + `ok>`; the amd64 **RDRAND** backend
|
||
(`rng: backend = rdrand`) serves live entropy; and a real Zuse identity is minted on a
|
||
second thumbdrive in real hardware and re-attaches. Two 16 GB sticks available: one to boot
|
||
the image, one to mint the Zuse user.
|
||
- **v2.4.0 — aarch64 bare metal.** Raspberry Pi 5 (orderable ~Mon 2026-08-31). Gate: boots
|
||
on the real board, aarch64 peripheral-RNG backend live, Zuse mint/attach on real media.
|
||
- **v2.5.0 — all three bare metal.** Adds Milk-V (riscv64) to the above; the Zkr (RNDR)
|
||
backend live. This is the full "same story on all three arches on real silicon" cut.
|
||
|
||
**Beyond v2.5.0 — Zynq FPGA is the next big milestone, after a hardening phase.** Once the
|
||
three general-purpose boards close, the next major transfer is to a **Zynq (AMD Xilinx)
|
||
FPGA** SoC — the step where the battle-tested amd64/aarch64/riscv64 story rides on
|
||
configurable silicon. That is a genuinely bigger milestone than any single prior board: an
|
||
FPGA demands its platform be carried forward rather than ported with trivial
|
||
architecture-delta work, and it reshapes the hardware story (soft/hard CPU cores, PL fabric,
|
||
non-standard memory map, custom peripherals). Expect a new even-major line for it once the
|
||
coloring-in period below lands.
|
||
|
||
**The FPGA creates a three-product split, decided 2026-08-29.** The Zynq is not just a fourth
|
||
platform to port to — it is the pivot that forces the project to separate into three
|
||
distinct products, each with its own host, delivery, and proof character. This is the neat
|
||
partition the FPGA's configurable-silicon nature makes possible and demands:
|
||
|
||
1. **Hosted StarForth** — the hosted/interpreted StarForth product that already exists
|
||
(3-arch acceptance-tested; runs StarForth hosted on an OS). Its delivery is the Forth
|
||
+ VM + capsule semantics as a portable, embeddable interpreted runtime.
|
||
2. **A full StarshipOS** — the standalone operating system built on LithosAnanke
|
||
(LithosAnanke → StarshipOS). Its delivery is a self-booting OS on general-purpose
|
||
silicon (the SER5/RasPi/Milk-V line already covers this).
|
||
3. **Hardware steady-state machinery with sealed executions, HOL-proven** — the
|
||
FPGA-native product: hardware-enforced sealed executions and steady-state machinery
|
||
whose guarantees are machine-checked in a proof assistant (HOL). This is the product only
|
||
configurable silicon can honor — secret/hardware-boundary enforcement and formally
|
||
verified behavior carried in silicon rather than software. Its delivery is the bitstream +
|
||
the HOL proof artifacts (not just a port of the OS).
|
||
|
||
The coupling is the point: the FPGA is where product 3 is born, and product 3's existence is
|
||
what cleanly separates 1 from 2 from 3. Product 1 ships hosted on an OS; product 2 ships as
|
||
an OS on general silicon; product 3 ships as proven hardware. Anything that straddles those
|
||
boundaries after this decision is a conscious product-line choice, not an accident of history.
|
||
Scoping of each product's concrete gates, and the new even-major line that carries products 1
|
||
through 3 as separate tracks, is defined at v2.5.0 close / during the coloring-in phase.
|
||
(This complements, and does not retract, the existing "hardware bare-metal release" policy
|
||
above.)
|
||
|
||
**IP framing of the three products — 3 patent applications + 3 marks, decided 2026-08-29.**
|
||
The three products are treated as **three patent applications**, each matched to a trademark,
|
||
with one caveat about the pre-existing provisional:
|
||
|
||
- **Patent 1 + mark StarForth.** The hosted/interpreted StarForth runtime product.
|
||
- **Patent 2 + marks StarshipOS + LithosAnanke.** The full standalone OS
|
||
(LithosAnanke → StarshipOS). (Noted as "StarshopOS" in the 2026-08-29 decision words;
|
||
canonical repo spelling and mark is **StarshipOS** — confirmed as the literal mark
|
||
to register.)
|
||
- **Patent 3 + mark Compudynamics.** The Zynq hardware steady-state machinery with sealed
|
||
executions, HOL-proven — anchored by the physics-adaptive runtime.
|
||
|
||
**Driving deadlines (why "no hurry" is wrong for #1 and #2), clarified 2026-08-29.** Two
|
||
clocks bind the near term, independent of product #3 and the FPGA:
|
||
|
||
- **#1 — the provisional will expire before conversion.** Its priority claim is time-boxed:
|
||
if the non-provisional isn't filed claiming benefit before the provisional's window lapses
|
||
(provisional filed ~Dec 2025 → window ~Dec 2026), the provisional's priority is lost and
|
||
the same subject matter cannot be re-staked by refiling thereafter. So #1 is on a hard
|
||
clock regardless of the December scope.
|
||
- **#2 — full StarshipOS is the December deliverable.** This is what "keeps the flagship
|
||
covered": the standalone-OS product (and, pending confirmation below, possibly the vehicle
|
||
that converts #1's provisional) must deliver by December.
|
||
|
||
- **Open point to resolve with counsel:** is **#2's** application (or the December delivery)
|
||
the **conversion vehicle** for #1's provisional — i.e., does it claim benefit from the
|
||
#1 provisional and thereby secure what would otherwise lapse — or is #1 converted by a
|
||
filing separate from #2? Captured as a decision record; no filing made.
|
||
|
||
**Relationship to the existing provisional (must be reconciled, not assumed).** The repo
|
||
already carries a **"Patent pending"** USPTO **provisional filed December 2025** for the
|
||
physics-grounded self-adaptive runtime (the Compudynamics adaptive runtime), sourced in
|
||
`docs/patent/` and referenced in `README.md`. Compudynamics is therefore already staked as
|
||
the brand of that foundation. Open points to resolve with counsel before any filing, so
|
||
nothing is invented or double-filed: is patent 3 the continuation/refinement of that
|
||
provisional (its HOL hardware realization) or a fresh application? Are the three product
|
||
applications additive to, or folding in, the Dec-2025 provisional? This record states intent;
|
||
it does not file, claim, or draft legal text.
|
||
|
||
**Before the FPGA — "coloring in", decided 2026-08-29.** The period between the all-three
|
||
bare-metal cut (v2.5.0) and starting the Zynq is finishing/hardening work that thickens the
|
||
shape of what already exists rather than adding new silicon. This is not idle time; it is
|
||
the point where v2.5.0's real-hardware story is made production-honest before the FPGA asks
|
||
to carry it further. Concrete items to define during it (draft scope, to be firmed at v2.5.0
|
||
close): Zynq-preflight robustness of the USB BOT/xHCI and block paths; live-entropy and
|
||
Zuse-cert hardening on the three real boards; SMP/multi-core bring-up and IRQ routing on real
|
||
ASICs (parked in the HAL notes); driver set expansion beyond the three boards before
|
||
committing an FPGA port; and whatever v2.5.0's real-board validation surfaces. As boards
|
||
land and the v2.5.0 gates close, this list is edited down to the concrete coloring-in punch
|
||
list, and the Zynq becomes the even-major target after it.
|
||
|
||
QEMU remains the zero-degradation reference on every line; each `X.Y.0` must reproduce the
|
||
QEMU acceptance story (`POST 1012/0/0` + `ok>`, block-fence Zuse true, backend entropy
|
||
non-deterministic) on its board before it closes.
|
||
|
||
---
|
||
|
||
## Milestone Overview
|
||
|
||
```
|
||
M0 UEFI Boot ████████████████████ COMPLETE
|
||
M1 PMM ████████████████████ COMPLETE
|
||
M2 VMM ████████████████████ COMPLETE
|
||
M3 IDT ████████████████████ COMPLETE
|
||
M4 APIC ████████████████████ COMPLETE
|
||
M5 Timer ████████████████████ COMPLETE
|
||
M6 Heap ████████████████████ COMPLETE
|
||
M7 VM Parity ████████████████████ COMPLETE
|
||
M7.1 Capsules ████████████████░░░░ LIVE — see FABRIC-0.md/FABRIC-1.md/FABRIC-2.md
|
||
M8 REPL ░░░░░░░░░░░░░░░░░░░░ OBSOLETE — see FABRIC-0.md §25.5 item 4.4
|
||
M9 Block I/O ░░░░░░░░░░░░░░░░░░░░ PLANNED
|
||
M10 Networking ░░░░░░░░░░░░░░░░░░░░ FUTURE
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 1: Boot Foundation (M0-M6)
|
||
|
||
### M0: UEFI Boot + Serial Output
|
||
|
||
**Goal:** Kernel prints "LithosAnanke booting..." to serial
|
||
|
||
**Deliverables:**
|
||
- [x] UEFI loader (`uefi_loader.c`)
|
||
- [x] BootInfo handoff (memory map, ACPI, framebuffer)
|
||
- [x] ExitBootServices
|
||
- [x] Serial console output
|
||
|
||
**Validation:**
|
||
```
|
||
StarKernel UEFI Loader
|
||
Loading...
|
||
RAW SERIAL UP
|
||
```
|
||
|
||
---
|
||
|
||
### M1: Physical Memory Manager
|
||
|
||
**Goal:** Track and allocate physical page frames
|
||
|
||
**Deliverables:**
|
||
- [x] Bitmap allocator
|
||
- [x] Parse UEFI memory map
|
||
- [x] `pmm_alloc_pages()` / `pmm_free_pages()`
|
||
- [x] Statistics reporting
|
||
|
||
**Validation:**
|
||
```
|
||
PMM initialized.
|
||
PMM statistics:
|
||
Total pages: 249450
|
||
Free pages : 247921
|
||
```
|
||
|
||
---
|
||
|
||
### M2: Virtual Memory Manager
|
||
|
||
**Goal:** 4-level paging, identity + higher-half mapping
|
||
|
||
**Deliverables:**
|
||
- [x] PML4 → PDPT → PD → PT setup
|
||
- [x] CR3 switch
|
||
- [x] `vmm_map()` / `vmm_unmap()`
|
||
- [x] Self-test
|
||
|
||
**Validation:**
|
||
```
|
||
VMM initialized (mapped RAM, CR3 switched)
|
||
VMM self-test: mapped OK at 0xffff800000000000
|
||
```
|
||
|
||
---
|
||
|
||
### M3: Interrupt Descriptor Table
|
||
|
||
**Goal:** CPU exceptions and IRQ handling
|
||
|
||
**Deliverables:**
|
||
- [x] 256-entry IDT
|
||
- [x] ISR stubs (asm)
|
||
- [x] Exception handlers (div-by-zero, page fault, etc.)
|
||
- [x] IRQ routing framework
|
||
|
||
**Validation:**
|
||
```
|
||
IDT installed.
|
||
```
|
||
|
||
---
|
||
|
||
### M4: APIC Timer
|
||
|
||
**Goal:** Local APIC initialization and timer IRQs
|
||
|
||
**Deliverables:**
|
||
- [x] Local APIC enable
|
||
- [x] APIC timer configuration
|
||
- [x] Spurious interrupt vector
|
||
|
||
**Validation:**
|
||
```
|
||
APIC: init...
|
||
APIC enabled (SIVR=0xFF).
|
||
APIC: init done
|
||
```
|
||
|
||
---
|
||
|
||
### M5: Timer Calibration
|
||
|
||
**Goal:** Accurate time measurement
|
||
|
||
**Deliverables:**
|
||
- [x] TSC frequency detection
|
||
- [x] HPET calibration (when available)
|
||
- [x] PM Timer fallback
|
||
- [x] Relative vs. absolute trust levels
|
||
|
||
**Validation:**
|
||
```
|
||
Timer: init...
|
||
Timer: trust=1 (0=NONE,1=REL,2=ABS), TSC=0 Hz
|
||
Timer: init done
|
||
```
|
||
|
||
---
|
||
|
||
### M6: Kernel Heap
|
||
|
||
**Goal:** `kmalloc()` / `kfree()` working
|
||
|
||
**Deliverables:**
|
||
- [x] Heap initialization
|
||
- [x] Allocation tracking
|
||
- [x] Statistics
|
||
|
||
**Validation:**
|
||
```
|
||
Kernel heap initialized.
|
||
Heap statistics:
|
||
Total bytes: 16777176
|
||
Free bytes: 16777176
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 2: VM Integration (M7)
|
||
|
||
### M7: VM Parity Validation
|
||
|
||
**Goal:** StarForth VM boots with reproducible dictionary hash
|
||
|
||
**Deliverables:**
|
||
- [x] VMHostServices abstraction
|
||
- [x] VM arena allocation (5 MB)
|
||
- [x] FORTH-79 word registration (295 words)
|
||
- [x] Parity checkpoint logging
|
||
- [x] Heartbeat thread start
|
||
|
||
**Validation:**
|
||
```
|
||
VM: bootstrap parity...
|
||
[HAL][host] VMHostServices table registered
|
||
VM arena allocated: 0xffff900000000000 (5 MB)
|
||
Registering FORTH-79 Standard word set...
|
||
PARITY:M7.1a word_count=295 here=0x30 latest_id=294 hash=0x684bbf2fa1d96d55
|
||
PARITY:OK
|
||
VM: parity bootstrap complete
|
||
Starting heartbeat...
|
||
APIC Timer: started
|
||
```
|
||
|
||
**Commit:** `6f350bc` — M7: StarForth VM integration with parity validation
|
||
|
||
---
|
||
|
||
## Phase 3: Capsule Architecture (M7.1)
|
||
|
||
### M7.1: Init Capsule System
|
||
|
||
**Goal:** Content-addressed, immutable init capsules for VM birth
|
||
|
||
**Status:** Design Complete (see [M7.1.md](M7.1.md)) — this section predates the actual
|
||
capsule/Tripod/Stadium work and is not current. **See `FABRIC-0.md`/`FABRIC-1.md` for real
|
||
status** (per `.claude/CLAUDE.md`'s standing redirect) — Tripod (Hera/Hermes/Artemis),
|
||
word-level ACL Phases 1–7, and the Stadium physics-economy migration are all live, not just
|
||
designed. Most recently: item 4.6 (Artemis's block-heat arena migrated to Stadium
|
||
admission-on-allocate) verified passing its 30-rep stress campaign on all three
|
||
architectures 2026-08-18, after fixing a quota-grant ordering bug (`capsule_birth.c`) that
|
||
had made every admission fail; see `FABRIC-1.md` Section H. The same pass also fixed a
|
||
long-standing aarch64-only crash on `BYE` (wrong PSCI conduit — SMC has nothing to answer it
|
||
under AAVMF/no-EL3 boot; switched to HVC), see `FABRIC-1.md` Section I.
|
||
|
||
**Core Concepts:**
|
||
|
||
| Concept | Description |
|
||
|---------|-------------|
|
||
| **DOMAIN** | Mama-only construction space — never visible to babies |
|
||
| **PERSONALITY** | Baby-only identity — result of executing (p) INIT |
|
||
| **(p) Production** | Truth-bearing capsules that birth VMs |
|
||
| **(e) Experiment** | Mama-only workloads for DoE |
|
||
|
||
**Birth Protocol:**
|
||
1. Mama selects one production `(p)` capsule by content hash
|
||
2. Mama validates eligibility (ACTIVE, PRODUCTION, not REVOKED)
|
||
3. Mama allocates new VM
|
||
4. INIT blocks copied to execution window (RAM blocks 0–2047)
|
||
5. INIT blocks executed sequentially
|
||
6. Execution window cleared
|
||
7. VM begins life with PERSONALITY imprinted
|
||
8. Mama logs `PARITY:BIRTH vm_id=N capsule_id=X mode=p ...`
|
||
9. Mama increments `capsule.birth_count`
|
||
|
||
**Deliverables:**
|
||
- [ ] `CapsuleDesc` struct (64 bytes, cache-aligned)
|
||
- [ ] `CapsuleDirHeader` struct
|
||
- [ ] xxHash64 implementation (freestanding)
|
||
- [ ] `capsule_validate()` function
|
||
- [ ] Birth protocol (`PARITY:BIRTH` logging)
|
||
- [ ] DoE run logging (`CapsuleRunRecord`)
|
||
- [ ] `mkcapsule` build tool
|
||
|
||
**Key Design Decisions:**
|
||
- Content-addressed: `capsule_id == content_hash`
|
||
- (p) Production vs (e) Experiment modes
|
||
- One truth per VM — no shared/implicit base INITs
|
||
- Mama holds all truths — (e) capsules never touch babies
|
||
- Twins/variants are just VMs with same/similar capsules
|
||
|
||
---
|
||
|
||
## Phase 4: Interactive Forth (M8)
|
||
|
||
> **⚠ OBSOLETE (2026-08-11).** This entire M8 section is superseded by
|
||
> `FABRIC-0.md` §25.5 item 4.4 (REPL). The console/REPL design has moved past
|
||
> what's scoped here — do not use this section as a source for REPL or
|
||
> CANVAS design decisions. Kept in place for history only.
|
||
|
||
### M8: REPL + Interactive Forth
|
||
|
||
**Status:** Scoped 2026-08-11 (this section). Substrate (interrupt-driven keyboard
|
||
input, glyph rendering) already complete via Stadium's Console fabric work
|
||
(FABRIC-0.md §25.5 items 4.3.5–4.3.7f) — see "What's already done" below. This
|
||
scoping pass covers what's left: wiring the existing keyboard-event stream into
|
||
the REPL's character input path.
|
||
|
||
**Goal:** Type Forth at the kernel *keyboard* (not just serial), get `ok` prompt.
|
||
The REPL already works interactively over serial today (`sk_repl_run()`,
|
||
`src/starkernel/repl.c`) — that is not what this milestone adds. What's missing
|
||
is a second input source feeding the same loop.
|
||
|
||
**What's already done, read from the code before scoping this, not assumed:**
|
||
- Interrupt-driven keyboard input on all three architectures (amd64 i8042,
|
||
aarch64/riscv64 virtio-keyboard-pci + GIC/PLIC), converged behind one shared
|
||
interface: `KEY-EVENT ( -- keycode pressed -1 | 0 )` in
|
||
`src/word_source/keyboard_words.c`, `keycode` in the Linux input keycode
|
||
namespace. FABRIC-0.md items 4.3.5–4.3.5f, verified live on all three
|
||
architectures with real keypresses.
|
||
- Glyph rendering, both paths: the stroke-drawn font (`TEXT`, capsule-based,
|
||
113-glyph v1 repertoire, FABRIC-0.md 4.3.6–4.3.6g) and TrueType (`TTF-TEXT`,
|
||
proportional spacing via real `hmtx` advance widths, FABRIC-0.md 4.3.7–4.3.7f).
|
||
Neither is required for the REPL text itself, though — see the VT100 finding
|
||
below.
|
||
- **The REPL's on-screen text already renders independently of both of the
|
||
above.** `console_fb_init()` (`src/starkernel/hal/console.c`) calls
|
||
`vt100_init()`, which mirrors every `console_putc()`/`console_puts()` call to
|
||
the framebuffer via the baked-in `font_8x16.c` raster font. This is *already
|
||
live* — the REPL prompt and its output appear on screen today, serial-driven,
|
||
no CANVAS/glyph-capsule dependency. This confirms §27.6's mockup: a fixed
|
||
VT100 REPL strip (already working) plus a separate large CANVAS region above
|
||
it (still unsized — see the last deliverable below).
|
||
|
||
**What's actually missing, confirmed by reading the code, not assumed:**
|
||
`src/starkernel/repl.c`'s `sk_readline()` reads characters via
|
||
`console_getc()` (`src/starkernel/hal/console.c`), which is serial-UART-only —
|
||
it never looks at `KEY-EVENT`. Separately, the FORTH-79 words `KEY`/`?TERMINAL`
|
||
(`src/word_source/io_words.c:84-108`, shared/vendored source) are dead in the
|
||
kernel build: `KEY` calls libc `getchar()`, which the kernel shim
|
||
(`src/starkernel/vm/host/shim.c:1206`) hardcodes to return `-1` (EOF);
|
||
`?TERMINAL` is a literal stub that always returns false. Neither path has ever
|
||
been wired to a real keyboard.
|
||
|
||
**Deliverables:**
|
||
- [ ] Minimal scancode→ASCII layout: a small lookup table (US QWERTY,
|
||
unshifted/shifted rows only — no dead keys, no locale switching) driven
|
||
by `KEY-EVENT`'s Linux-namespace keycodes, plus shift-state tracking
|
||
(`KEY_LEFTSHIFT`/`KEY_RIGHTSHIFT` press/release) since `KEY-EVENT` itself
|
||
carries no modifier state today (confirmed by reading
|
||
`keyboard_words.c` — deferred at 4.3.5f, not implemented anywhere).
|
||
- [ ] Merge keyboard into `console_getc()`'s poll: extend it (or add a second
|
||
function `sk_readline()` polls alongside it) to also drain `KEY-EVENT`
|
||
and translate presses to ASCII via the layout table above. **Serial stays
|
||
a co-equal input source, not replaced** — the entire acceptance/DoE
|
||
harness injects FORTH commands over the serial socket
|
||
(`socat ... UNIX-CONNECT:$SERIAL_SOCK`) and greps the serial log for
|
||
`ok>`; breaking that path breaks `make qemu`, `DOE_INJECT`, and every
|
||
screendump verification technique used throughout 4.3.x. Both sources
|
||
feed the same byte stream into the existing `sk_readline()` — no new
|
||
line-editing code needed, backspace/echo already work
|
||
(`sk_readline()`, `repl.c:83-141`).
|
||
- [ ] Wire `KEY`/`?TERMINAL` (`io_words.c`) to the same merged source under
|
||
`#ifdef __STARKERNEL__`, for FORTH-79 compliance — any capsule calling
|
||
these directly (not just the REPL) should get real input too, not a
|
||
permanently-EOF stub. Small addition once the merge above exists.
|
||
- [ ] CANVAS viewport sizing (§27.6's explicit deferral to this milestone): the
|
||
large graphics region above the VT100 REPL strip needs an actual
|
||
scrollable framebuffer viewport size decided (e.g. 640×480, per the
|
||
original mockup) — layout/presentation, not input plumbing; do this
|
||
last, after keyboard input works, since it doesn't block interactivity.
|
||
|
||
**Explicitly out of scope for this milestone (minimal bar, matches "Line
|
||
editing (backspace, minimal)"):** extended (`0xE0`-prefixed) i8042 scancodes,
|
||
virtio-input autorepeat (`value=2`) as actual character repeat, arrow-key
|
||
cursor movement/history, non-US keyboard layouts. Deferred to a later item if
|
||
ever needed — not blocking "type Forth at the kernel, get `ok`."
|
||
|
||
**Validation:**
|
||
```
|
||
LithosAnanke v0.3.0
|
||
ok 1 2 + .
|
||
3 ok
|
||
```
|
||
(via a real keypress on all three architectures, same live-keypress
|
||
verification standard FABRIC-0.md 4.3.5f already established — not a
|
||
serial-injected synthetic test, though serial injection must still work
|
||
identically afterward.)
|
||
|
||
---
|
||
|
||
## Phase 5: Persistence (M9)
|
||
|
||
### M9: Block Storage
|
||
|
||
**Goal:** Read/write blocks to disk
|
||
|
||
**Deliverables:**
|
||
- [x] Block device driver — implemented via `virtio_blk.c` (virtio block device), not the
|
||
AHCI/SATA driver originally scoped here; see `.claude/CLAUDE.md`'s M9 note.
|
||
- [x] Block device abstraction — `block_subsystem.c`'s unified LBN address space, backend-agnostic
|
||
across RAM/RAMDRIVE/DISK/USB via the `blkio_dev` vtable.
|
||
- [x] `BLOCK` / `BUFFER` / `UPDATE` / `FLUSH` words — live, `src/word_source/block_words.c`.
|
||
- [ ] Persistent dictionary — no evidence found of word definitions surviving reboot; not
|
||
independently verified as done, left unchecked rather than assumed from the rest of this
|
||
list being live.
|
||
|
||
---
|
||
|
||
## Future Milestones
|
||
|
||
### M10: Networking
|
||
- VirtIO-net driver
|
||
- TCP/IP stack (minimal)
|
||
- DHCP client
|
||
|
||
### M11: Process Model
|
||
- Forth tasks
|
||
- Scheduling
|
||
- IPC
|
||
|
||
### M12: Self-Hosting
|
||
- Compile Forth on LithosAnanke
|
||
- Edit/assemble/link cycle
|
||
|
||
---
|
||
|
||
## Validation Commands
|
||
|
||
```bash
|
||
# Build
|
||
make -f Makefile.starkernel ARCH=amd64 STARFORTH_ENABLE_VM=1
|
||
|
||
# Run QEMU
|
||
make -f Makefile.starkernel ARCH=amd64 STARFORTH_ENABLE_VM=1 qemu
|
||
|
||
# Clean
|
||
make -f Makefile.starkernel ARCH=amd64 clean-kernel
|
||
```
|
||
|
||
---
|
||
|
||
## Branch Relationship
|
||
|
||
```
|
||
master (hosted StarForth)
|
||
│
|
||
├── lithosananke (kernel branch)
|
||
│ │
|
||
│ └── M7 complete, M7.1 design complete
|
||
│
|
||
└── starkernel-junkyard (legacy, can delete)
|
||
```
|
||
|
||
---
|
||
|
||
## Success Criteria
|
||
|
||
LithosAnanke is successful when:
|
||
|
||
1. **M7 Parity** — VM dictionary hash reproducible across boots
|
||
2. **M7.1 Capsules** — Birth protocol enforced, provenance logged
|
||
3. ~~**M8 REPL** — Interactive Forth at bare metal~~ — superseded, this criterion is now met
|
||
via Stadium's Console fabric work (`FABRIC-0.md` §25.5 item 4.4), not a standalone M8; see
|
||
the OBSOLETE banner above Phase 4
|
||
4. **M9 Persistence** — State survives reboot
|
||
|
||
---
|
||
|
||
*The foundation is laid. The necessity is clear.*
|