docs: reorganise -- current reference gathered, finished work archived, superseded and dead ideas marked as such

docs/CLAUDE.md Phase 2, 2026-10-14.  All moves by git mv; every archived
file carries a header saying what it is, why, and where to look instead.

- docs/reference/ (new): roadmap and versioning policy, M7.1, word-ACL
  design, kernel args, hosted acceptance test, dictionary, primitives,
  ontology, L8 table -- previously spread over docs/, docs/lithosananke/
  and docs/03-architecture/.
- docs/working/archive/historical/: finished work (session plan, test-gap
  audit, birthing plan, fix write-ups, the January architecture draft).
- docs/working/archive/superseded/: the Hermes-VM Tripod docs and July
  Hermes designs (-> FABRIC-3.5/3.6), the StarForth roadmap, every working
  doc already flagged superseded or obsolete.
- docs/working/archive/dead/: the hal_* target contract (never adopted),
  L4Re, metrics-and-knobs.
- Papers and proposals into docs/working/papers/.
- References rewritten across the repo (not logs/, not docs/patent/);
  CLAUDE.md's documentation section rewritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-14 16:03:56 -04:00
co-authored by Claude Opus 5.5
parent 1a4b163861
commit 7aed588f78
116 changed files with 305 additions and 175 deletions
+4 -4
View File
@@ -148,7 +148,7 @@ This directory contains experimental designs, execution guides, and results for
- Results for publication: `06-research/results-for-publication.md`
```
#### `docs/03-architecture/README.md`
#### `docs/working/archive/superseded/2026-08-tripod/03-architecture-README.md`
```markdown
# Architecture
@@ -427,7 +427,7 @@ This document provides **kernel-specific implementation details**...
#### Incomplete Documents
**`docs/ONTOLOGY.md`:**
**`docs/reference/ONTOLOGY.md`:**
- Appears to be high-level conceptual framework
- Could benefit from linking to specific implementation docs
- Should reference HAL as part of platform layer
@@ -510,7 +510,7 @@ The `archive/` directory preserves historical context without cluttering active
- Mention StarKernel/StarshipOS vision
- **Effort:** 15 minutes
4. **Create `docs/03-architecture/README.md`**
4. **Create `docs/working/archive/superseded/2026-08-tripod/03-architecture-README.md`**
- Big picture of how subsystems fit together
- Roadmap (StarForth → StarKernel → StarshipOS)
- **Effort:** 1 hour
@@ -581,7 +581,7 @@ The `archive/` directory preserves historical context without cluttering active
1. Create 6 missing README files for numbered directories
2. Update `docs/CLAUDE.md` with HAL section
3. Update `docs/README.md` with current work
4. Create `docs/03-architecture/README.md`
4. Create `docs/working/archive/superseded/2026-08-tripod/03-architecture-README.md`
### Short-term Actions (1-2 weeks)
@@ -0,0 +1,246 @@
> **DEAD (docs triage 2026-10-14).** The proposed `hal_*` interface contract and its migration plan were never adopted; the kernel grew its own HAL (kernel/src/hal/, kernel/include/starkernel/hal/).
> Instead: kernel/src/hal/README.md. Moved here from `docs/working/architecture/03-architecture/hal/README.md`.
<!-- Moved from docs/03-architecture/hal/README.md to docs/working/archive/dead/hal-target-contract/README.md on 2026-06-16 (docs reorg Phase 2) -->
> **⚠ TARGET HAL — NOT THE BUILT INTERFACE (flagged 2026-10-09).** This document family
> describes a proposed `hal_*`-named interface and a `src/platform/<platform>/` layout that
> was never adopted as written. The implemented kernel HAL lives in `src/starkernel/hal/`
> with different (time-backend-style) naming. Treat all five documents here as design intent,
> not the current API. For current architecture see `.claude/CLAUDE.md`.
# Hardware Abstraction Layer (HAL) Documentation
This directory contains comprehensive documentation for StarForth's Hardware Abstraction Layer (HAL), which enables the evolution from hosted VM to StarKernel to StarshipOS.
> **HISTORICAL — L4Re/Fiasco.OC**: L4Re references throughout this directory's docs describe a target that was a supported platform through mid-2026. L4Re support has since been removed as an active target — `src/platform/l4re/time.c` and related `#ifdef __l4__` code are retained for reference but no longer wired into any build.
---
## Document Organization
Read in this order for full understanding:
### 1. **[overview.md](overview.md)** - Start Here
**What:** High-level HAL architecture, design principles, and rationale
**Who:** Everyone (developers, architects, contributors)
**Why read:** Understand the problem HAL solves and how it fits into StarForth → StarKernel → StarshipOS
**Key sections:**
- The Problem (why HAL is necessary)
- Architecture Overview (3-layer model)
- Design Principles (VM purity, contract-first, testability)
- HAL Subsystems (time, interrupts, memory, console, CPU)
- HAL and Physics Subsystems
- Success Criteria
---
### 2. **[interfaces.md](interfaces.md)** - The Contract
**What:** Detailed HAL interface specifications (function signatures, semantics, guarantees)
**Who:** VM developers, platform implementers
**Why read:** Understand exactly what each HAL function does and requires
**Key sections:**
- Time & Timers interface (`hal_time.h`)
- Interrupts interface (`hal_interrupt.h`)
- Memory interface (`hal_memory.h`)
- Console interface (`hal_console.h`)
- CPU interface (`hal_cpu.h`)
- Panic/Error interface (`hal_panic.h`)
- Interface safety summary (ISR-safe, thread-safe)
**Critical details:**
- Function semantics (what it does, guaranteed behavior)
- Error handling (when it can fail, how to handle)
- Performance expectations (latency, overhead)
- Concurrency model (thread-safe? ISR-safe?)
---
### 3. **[platform-implementations.md](platform-implementations.md)** - How to Implement
**What:** Platform-specific implementation examples and guidance
**Who:** Platform developers adding HAL support for new targets
**Why read:** Learn how to implement HAL for a specific platform
**Key sections:**
- Platform directory structure
- Linux HAL implementation (reference platform)
- Kernel HAL implementation (StarKernel)
- Platform testing strategy
- Common implementation pitfalls
**Includes complete code examples for:**
- Linux (POSIX, hosted)
- Kernel (freestanding, bare metal)
---
### 4. **[migration-plan.md](migration-plan.md)** - Refactoring Guide
**What:** Step-by-step plan for refactoring existing StarForth to use HAL
**Who:** Core developers doing the migration work
**Why read:** Execute the HAL migration safely with zero regressions
**Key sections:**
- 7-phase migration strategy
- Incremental refactoring approach
- Test validation after each phase
- Rollback strategy
- Timeline estimates (2-4 weeks)
**Phases:**
1. Define HAL interfaces (headers only)
2. Implement HAL for Linux
3. Migrate VM core to use HAL
4. Migrate physics subsystems to use HAL
5. Migrate REPL and word implementations
6. Implement HAL for L4Re (optional validation)
7. Validate deterministic behavior
---
### 5. **[starkernel-integration.md](starkernel-integration.md)** - Kernel Details
**What:** StarKernel-specific HAL implementation and boot sequence
**Who:** Kernel developers building StarKernel
**Why read:** Understand UEFI boot, freestanding C, hardware initialization
**Key sections:**
- StarKernel architecture (boot sequence)
- Directory structure (`src/platform/kernel/`)
- Boot sequence detail (UEFI → StarKernel → VM)
- HAL implementation details (time, interrupts, memory, console, CPU)
- Build system (freestanding toolchain, linker script)
- Testing on QEMU/OVMF
- Debugging techniques
- Roadmap to `ok` prompt
**Includes:**
- Complete UEFI loader implementation
- Kernel entry point
- Hardware initialization sequence
- QEMU testing guide
- Debugging strategies
---
## Quick Reference
### For Different Roles
**I'm a VM developer:**
- Read: `overview.md`, `interfaces.md`
- Use HAL functions in VM code
- Never call platform-specific APIs directly
**I'm adding a new platform:**
- Read: `overview.md`, `interfaces.md`, `platform-implementations.md`
- Implement all HAL interfaces for your platform
- Test against VM test suite (936+ tests must pass)
**I'm migrating existing code to HAL:**
- Read: `migration-plan.md`
- Follow 7-phase incremental approach
- Test after each phase
**I'm building StarKernel:**
- Read: All documents, especially `starkernel-integration.md`
- Start with UEFI boot + serial output
- Build incrementally to `ok` prompt
---
## Key Concepts
### HAL Principles
1. **VM Purity:** VM code is platform-agnostic, never knows which platform it's on
2. **Contract-First:** HAL interfaces are contracts with precise semantics
3. **Testability:** Develop/test on Linux, deploy on kernel
4. **Zero Overhead:** HAL inlines to direct hardware access when optimized
5. **Fail-Fast:** Validate platform assumptions at init, not during execution
### Success Criteria
The HAL is successful if:
- ✅ VM core has zero platform-specific code
- ✅ All 936+ tests pass on all platforms
- ✅ 0% algorithmic variance maintained
- ✅ No measurable performance regression
- ✅ StarKernel boots to `ok` prompt
- ✅ Physics subsystems work identically on all platforms
---
## Document Status
| Document | Status | Last Updated |
|----------|--------|--------------|
| overview.md | ✅ Complete | 2025-12-14 |
| interfaces.md | ✅ Complete | 2025-12-14 |
| platform-implementations.md | ✅ Complete | 2025-12-14 |
| migration-plan.md | ✅ Complete | 2025-12-14 |
| starkernel-integration.md | ✅ Complete | 2025-12-14 |
---
## Next Steps
### Immediate (HAL Migration)
1. Review and approve HAL interface specifications
2. Execute migration plan Phase 1 (define interfaces)
3. Execute migration plan Phase 2 (implement Linux HAL)
4. Continue through Phase 7 (validation)
### Near-Term (StarKernel)
1. Implement UEFI boot loader
2. Implement kernel HAL subsystems
3. Boot to `ok` prompt on QEMU
4. Validate physics subsystems on bare metal
### Long-Term (StarshipOS)
1. Add storage drivers (AHCI, NVMe)
2. Add networking stack (TCP/IP)
3. Implement process model (Forth tasks)
4. Build device model (block/net/char)
---
## References
### StarForth Documentation
- `docs/CLAUDE.md` - Project overview and build instructions
- `docs/03-architecture/heartbeat-system/` - Heartbeat subsystem details
- `docs/FEEDBACK_LOOPS.md` - Physics feedback loops
- `README.md` - Project quick start
### External Resources
- [UEFI Specification](https://uefi.org/specifications)
- [GNU-EFI](https://sourceforge.net/projects/gnu-efi/)
- [OSDev Wiki](https://wiki.osdev.org/)
- [Intel Software Developer Manual](https://www.intel.com/sdm)
- [ACPI Specification](https://uefi.org/acpi)
---
## Contributing
When updating HAL documentation:
1. **Keep documents synchronized** - Changes to interfaces require updates to implementation guides
2. **Maintain code examples** - Examples must compile and work
3. **Update this README** - Reflect new sections or document reorganization
4. **Version documentation** - Note "Last Updated" dates
5. **Test instructions** - Verify all commands and code snippets work
---
## Questions?
For questions about HAL architecture or StarKernel implementation, see:
- GitHub Issues: https://github.com/anthropics/starforth/issues (if public)
- Project maintainer: (contact info)
- Documentation feedback: (preferred method)
---
*The HAL is not just a kernel bootstrapping tool—it's the architectural foundation for StarForth → StarKernel → StarshipOS.*
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,203 @@
// DEAD (docs triage 2026-10-14). L4Re/Fiasco.OC was removed as a platform target in mid-2026. Instead: .claude/CLAUDE.md (Project Overview). Moved from docs/working/hardware/platform-integration/L4RE_DICTIONARY_ALLOCATION.adoc.
// Moved from docs/src/platform-integration/L4RE_DICTIONARY_ALLOCATION.adoc to docs/working/scratch/src/platform-integration/L4RE_DICTIONARY_ALLOCATION.adoc on 2026-06-16 (docs reorg Phase 2)
== Dictionary Allocation Strategy for L4Re
:toc: left
:toc-title: Contents
:toclevels: 3
xref:../README.adoc[← Back to Documentation Index]
=== Current Implementation
StarForth currently uses `+malloc()+` and `+free()+` from the host C
library for dictionary entry allocation:
* *Location*: `+src/dictionary_management.c:228+`
* *Function*: `+vm_create_word()+` uses `+malloc(total)+` to allocate
DictEntry structures
* *Cleanup*: `+FORGET+` uses `+free(e)+` to deallocate entries (line 554
in defining_words.c)
This works fine for hosted environments but creates a dependency on libc
heap allocator.
=== Why This Matters for L4Re/StarshipOS
==== Issues with Current Approach:
[arabic]
. *Heap Dependency*: Requires full malloc implementation in L4Re
environment
. *Non-Deterministic*: Heap fragmentation and unpredictable allocation
behavior
. *Separate Address Space*: Dictionary entries live outside VM memory
model
. *Hard to Introspect*: Can’t dump entire VM state as single memory
region
==== Benefits of VM-Based Allocation:
[arabic]
. *Zero External Dependencies*: No libc malloc needed
. *Deterministic*: Simple bump allocator, predictable behavior
. *Unified Address Space*: Everything in one 5MB VM memory region
. *Easy Snapshots*: Can serialize entire VM state
. *Better for Microkernel*: Aligns with L4Re dataspace model
=== Recommended Approach for L4Re
==== Strategy: Conditional Compilation
Add a compile-time flag to switch between malloc and VM-based
allocation:
[source,c]
----
// In dictionary_management.c
#ifdef STARFORTH_VM_DICT_ALLOC
/* VM-based allocation (for L4Re/embedded) */
DictEntry *entry = dict_alloc_from_vm(vm, total);
#else
/* Standard malloc (for hosted environments) */
DictEntry *entry = (DictEntry *) malloc(total);
#endif
----
==== Memory Layout (VM-Based Mode):
....
vm->memory[0...VM_MEMORY_SIZE] (5MB):
┌──────────────────────────────────────────┐
│ Dictionary Headers (256KB) │ ← dict_headers_used grows up
│ - DictEntry structures │
│ - Allocated via dict_alloc() │
├──────────────────────────────────────────┤
│ User Data & Code (variable) │ ← HERE grows up
│ - Compiled definitions │
│ - Variables, constants │
│ - String literals │
├──────────────────────────────────────────┤
│ Block Storage (remainder) │
│ - 1KB blocks for Forth block system │
└──────────────────────────────────────────┘
....
==== Implementation Steps:
[arabic]
. *Add Dictionary Allocator* (256KB bump allocator at `+memory[0]+`):
[source,c]
----
static DictEntry *dict_alloc_from_vm(VM *vm, size_t total_bytes) {
/* Align to cell_t boundary */
size_t align = sizeof(cell_t);
total_bytes = (total_bytes + align - 1) & ~(align - 1);
/* Check space */
if (vm->dict_headers_used + total_bytes > DICT_HEADERS_MAX) {
vm->error = 1;
return NULL;
}
/* Allocate from VM memory */
DictEntry *entry = (DictEntry *)(vm->memory + vm->dict_headers_used);
vm->dict_headers_used += total_bytes;
return entry;
}
----
[arabic, start=2]
. *Update FORGET* (no individual frees, just rewind):
[source,c]
----
/* Instead of free(e) loop, rewind allocator */
size_t target_offset = (uint8_t*)target - vm->memory;
vm->dict_headers_used = target_offset;
----
[arabic, start=3]
. *Adjust VM Initialization*:
[source,c]
----
vm->dict_headers_used = 0; /* Headers start at memory[0] */
vm->here = DICT_HEADERS_MAX; /* User data starts at 256KB */
----
[arabic, start=4]
. *No Changes to Fast-Lookup Cache*: Cache buckets still use malloc for
the pointer arrays, but entries themselves are in VM memory.
==== Testing Strategy:
[source,bash]
----
# Test with standard malloc (current):
make clean && make test
# Test with VM-based allocation:
make clean
CFLAGS="-DSTARFORTH_VM_DICT_ALLOC" make test
# Test L4Re minimal build:
make clean
CFLAGS="-DSTARFORTH_MINIMAL -DSTARFORTH_VM_DICT_ALLOC" make rpi4-cross
----
=== Current Status
*Decision*: Keep using `+malloc()+` for now, document the abstraction
point clearly.
*Rationale*:
* Current implementation is stable and well-tested
* L4Re port can implement the switch when needed
* Abstraction layer is simple and well-defined
* No performance difference between approaches
*Action Items for L4Re Port*:
[arabic]
. Define `+STARFORTH_VM_DICT_ALLOC+` in L4Re build
. Implement `+dict_alloc_from_vm()+` function
. Update `+FORGET+` to use rewind instead of free loop
. Test with full test suite
. Verify no memory leaks in microkernel environment
=== Minimal Code Changes Needed
The switch to VM-based allocation requires changes to only 3 functions:
[arabic]
. *`+vm_create_word()+`* - Use `+dict_alloc_from_vm()+` instead of
`+malloc()+`
. *`+dictionary_word_forget()+`* - Rewind `+dict_headers_used+` instead
of `+free()+` loop
. *`+vm_init()+`* - Initialize `+dict_headers_used+` and offset `+HERE+`
Add to `+VM+` struct in `+include/vm.h+`:
[source,c]
----
size_t dict_headers_used; /* Bytes used for dictionary headers (VM mode only) */
----
*Estimated effort*: 4 hours to implement + 2 hours testing = *6 hours
total*
=== References
* Current malloc usage: `+src/dictionary_management.c:228+`
* Current free usage: `+src/word_source/defining_words.c:554+`
* Fast-lookup cache: `+src/dictionary_management.c:43-67+` (unchanged)
* L4Re dataspace docs: `+docs/L4RE_INTEGRATION.md+`
'''''
*Author*: R. A. James *Date*: 2025-10-01 *Status*: Documented,
implementation deferred to L4Re port
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,193 @@
// DEAD (docs triage 2026-10-14). L4Re/Fiasco.OC was removed as a platform target in mid-2026. Instead: .claude/CLAUDE.md (Project Overview). Moved from docs/working/hardware/platform-integration/l_4_re_blkio_endpoints.adoc.
// Moved from docs/src/platform-integration/l_4_re_blkio_endpoints.adoc to docs/working/scratch/src/platform-integration/l_4_re_blkio_endpoints.adoc on 2026-06-16 (docs reorg Phase 2)
== StarForth Block I/O — L4Re Porting Endpoints
:toc: left
:toc-title: Contents
:toclevels: 3
xref:../README.adoc[← Back to Documentation Index]
This document explains how the existing `+blkio+` API maps cleanly onto
L4Re, what you need to implement, and where your VM and Forth block
words connect. The idea is: the *northbound API never changes*; you only
swap in different backends (dataspace or IPC service) when porting to
L4Re.
'''''
=== 1. Northbound API (unchanged)
Your VM and block words always call:
[source,c]
----
int blkio_open (blkio_dev_t *dev, const blkio_vtable_t *vt, const blkio_params_t *p);
int blkio_close(blkio_dev_t *dev);
int blkio_read (blkio_dev_t *dev, uint32_t fblock, void *dst);
int blkio_write(blkio_dev_t *dev, uint32_t fblock, const void *src);
int blkio_flush(blkio_dev_t *dev);
int blkio_info (blkio_dev_t *dev, blkio_info_t *out);
----
No matter what backend you use, these remain stable. That’s your ABI.
'''''
=== 2. In-process L4Re Dataspace Backend
Use when your VM can directly attach a dataspace. This gives you the
fastest path: no IPC.
*Symbols you implement:*
[source,c]
----
size_t blkio_l4ds_state_size(void);
int blkio_l4ds_init_state(void *state_mem, size_t state_len,
l4_cap_idx_t ds_cap,
l4_addr_t attach_addr,
l4_size_t attach_size,
uint32_t total_blocks,
uint32_t fbs,
uint8_t read_only,
void **out_opaque);
const blkio_vtable_t *blkio_l4ds_vtable(void);
----
*State struct:*
[source,c]
----
typedef struct {
l4_cap_idx_t ds; /* dataspace cap */
void *base; /* attached VA */
l4_size_t size; /* mapped length */
uint32_t fbs; /* block size */
uint32_t blocks; /* #blocks */
uint8_t ro;
} blkio_l4ds_state_t;
----
*Ops:*
* `+open+`: `+l4re_rm_attach()+` dataspace, derive block count.
* `+read/write+`: `+memcpy+` from attached region.
* `+flush+`: NOP (or `+l4re_ds_op+` if needed).
* `+close+`: `+l4re_rm_detach()+`.
'''''
=== 3. Out-of-process Block Server (IPC Backend)
Use when storage is owned by a different task (e.g., AHCI, NVMe, eMMC
server).
*Client-side symbols:*
[source,c]
----
size_t blkio_l4svc_state_size(void);
int blkio_l4svc_init_state(void *state_mem, size_t state_len,
l4_cap_idx_t server_cap,
l4_cap_idx_t bounce_ds,
uint32_t fbs,
uint8_t read_only,
void **out_opaque);
const blkio_vtable_t *blkio_l4svc_vtable(void);
----
*IPC protocol (example):*
[source,c]
----
enum bsvc_op {
BSVC_INFO = 1,
BSVC_READ = 2,
BSVC_WRITE = 3,
BSVC_FLUSH = 4,
BSVC_PING = 5
};
----
Transport choices:
* Shared dataspace (preferred): server + client map the same page(s).
* Inline IPC (simpler, less efficient): block payload in IPC message.
*Ops mapping:*
* `+read+`: send op + fblock, server fills shared buffer.
* `+write+`: copy into shared buffer, send op + fblock.
* `+info+`: query block size, count, flags.
'''''
=== 4. Factory Helpers on L4Re
You can add overloads to `+blkio_factory+` for clarity:
[source,c]
----
int blkio_factory_open_l4ds (blkio_dev_t *dev, l4_cap_idx_t ds_cap, uint32_t fbs, uint8_t ro);
int blkio_factory_open_file (blkio_dev_t *dev, const char *path, uint32_t fbs, uint8_t ro);
int blkio_factory_open_l4svc(blkio_dev_t *dev, l4_cap_idx_t server_cap, l4_cap_idx_t bounce_ds, uint32_t fbs, uint8_t ro);
----
This way `+main.c+` can pick a backend cleanly depending on CLI args and
environment.
'''''
=== 5. CLI Semantics on L4Re
* `+--disk-img=<path>+` → Either:
** VFS+file server that returns a dataspace → *l4ds backend*
** Or connect to a block server → *l4svc backend*
* `+--ram-disk=<MB>+` → Allocate RAM dataspace, use *l4ds backend*.
Fallback: if no `+--disk-img+`, create RAM disk from allocator.
'''''
=== 6. Composite Backends (RAM + Disk, 4 KiB packing)
Your design needs:
* Blocks 0–1023 → RAM backend.
* Blocks ≥1024 → Disk backend.
* All wrapped in a composite vtable that dispatches based on `+fblock+`.
Later: add an outer wrapper that packs 3×1 KiB + 1 KiB metadata into 4
KiB pages for device alignment. Still the same five ops.
'''''
== TL;DR — Endpoints to Implement for L4Re
*New backends:*
[source,c]
----
/* In-proc dataspace */
blkio_l4ds_state_size();
blkio_l4ds_init_state(...);
blkio_l4ds_vtable();
/* IPC client/server */
blkio_l4svc_state_size();
blkio_l4svc_init_state(...);
blkio_l4svc_vtable();
----
*Optional factory helpers:*
[source,c]
----
blkio_factory_open_l4ds(...);
blkio_factory_open_l4svc(...);
----
*Everything else stays the same*: VM calls only `+blkio_read+`,
`+blkio_write+`, etc. You swap backends, not call sites.
@@ -0,0 +1,148 @@
> **DEAD (docs triage 2026-10-14).** Already marked dead in its own header.
> Instead: its own header. Moved here from `docs/working/architecture/03-architecture/physics-engine/metrics-and-knobs.md`.
<!-- Moved from docs/03-architecture/physics-engine/metrics-and-knobs.md to docs/working/archive/dead/metrics-and-knobs.md on 2026-06-16 (docs reorg Phase 2) -->
# StarForth Metrics & Knobs: GAPS ONLY
## What's NOT Wired (Things to Add)
### DEAD CODE / NEVER CALLED
| What | Location | Status | Comment |
|------|----------|--------|---------|
| Bucket reordering | `physics_hotwords_cache.c:201-215` | Defined but NEVER CALLED | Bubble sort exists but no automatic trigger. Is this dead code or forgotten? |
---
### STACK METRICS (ZERO COLLECTION)
| Metric | File | Missing Since | Impact | Knob Needed |
|--------|------|---|---|---|
| Data stack peak depth | `stack_management.c` | Day 1 | Can't tell if workload needs larger stack | STACK_SIZE tuning blind |
| Return stack peak depth | `stack_management.c` | Day 1 | Can't measure colon definition nesting | Tail-call optimization impossible |
| Underflow attempts | `arithmetic_words.c:59-62` | Day 1 | Can't detect fragile code paths | Could optimize checks if zero underflows observed |
| Overflow attempts | `arithmetic_words.c` | Day 1 | Can't detect stack exhaustion | Early warning system missing |
---
### DICTIONARY METRICS (ZERO VISIBILITY)
| Metric | File | Missing Since | Impact | Why Matters |
|--------|------|---|---|---|
| Bucket load histogram | `vm.c: dict lookup` | Day 1 | First-char bucketing (26 buckets) may be unbalanced | Affects lookup latency, collision clustering |
| Dictionary growth rate | `memory_management.c` | Day 1 | No visibility into `here` pointer velocity | Can't predict "dictionary full" events |
| FORGET usage frequency | `dictionary_words.c` | Day 1 | No trace of word deletion patterns | Fragmentation unknown |
| Lookup failure rate | `vm.c` | Day 1 | How often is a word not found? | Error path frequency unknown |
| Word name length distribution | `vm.c` | Day 1 | Average name length unknown | Affects memory efficiency |
---
### BLOCK I/O METRICS (COMPLETELY DARK)
| Metric | File | Missing Since | Impact | Phase |
|--------|------|---|---|---|
| Block read frequency | `block_subsystem.c` | Day 1 | How often is BLOCK called? | DoE phase 1 |
| Block write frequency | `block_subsystem.c` | Day 1 | How often is UPDATE/FLUSH called? | DoE phase 1 |
| Writeback frequency | `block_subsystem.c:198-200` | Day 1 | When are dirty blocks flushed? | DoE phase 1 |
| Cache hit rate (disk) | `block_subsystem.c` | Day 1 | Blocks served from RAM cache % | DoE phase 1 |
| Dirty block ratio | `block_subsystem.c` | Day 1 | Blocks pending flush at time T | DoE phase 1 |
| I/O latency | `block_subsystem.c` | Day 1 | Time per read/write operation | DoE phase 2 |
| Fragmentation ratio | `block_subsystem.c` | Day 1 | Gaps in allocated blocks | DoE phase 2 |
---
### PER-WORD EXECUTION METRICS
| Metric | File | Missing Since | Impact | Use Case |
|--------|------|---|---|---|
| Per-word execution frequency | `vm.c: inner loop` | Day 1 | Which words are actually hot? | Profiling, hotspot detection |
| Per-word latency distribution | `vm.c` | Day 1 | Median/P99 time per word | Performance regression detection |
| Word category breakdown | `word_source/*.c` | Day 1 | Arithmetic vs. Stack vs. Control dominance | Workload characterization |
| Colon vs. native ratio | `vm.c` | Day 1 | User-defined word execution frequency | Code complexity analysis |
---
### HEAT DYNAMICS (PHASE 2 NOT ACTIVE)
| Metric | File | Status | Comment |
|--------|------|--------|---------|
| Heat decay trace | `physics_metadata.c: TODO` | Phase 2 placeholder | Need to measure if decay causes pattern loss |
| Heat percentile distribution | `physics_metadata.c` | Not updating dynamic | Stored but never dynamically recalculated |
| Heat concentration ratio | `physics_metadata.c` | Not tracked | (Top 10 words heat) / (total heat) |
| Heat velocity | `physics_metadata.c` | Not tracked | Rate of heat change per unit time |
| Heat plateau detection | `physics_metadata.c` | Not tracked | When does word heat level off? |
---
### PIPELINING METRICS (PHASE 1 INSTRUMENTATION, NOT USED)
| Metric | File | Status | Phase 2 Use |
|--------|------|--------|---|
| Prediction accuracy by depth | `physics_pipelining_metrics.c` | Not measured | Binary chop TRANSITION_WINDOW_SIZE |
| Context transition frequency | `physics_pipelining_metrics.c` | Counted but not reported | Validate context patterns |
| Speculation ROI histogram | `physics_pipelining_metrics.c` | Not aggregated | Tune SPECULATION_THRESHOLD |
| Misprediction cost (actual) | `physics_pipelining_metrics.c` | Measured but not validated | Calibrate cost model |
| Pipeline stall reduction | `physics_pipelining_metrics.c` | Not measured | Throughput impact unknown |
---
### CACHE POLLUTION & CYCLES
| Metric | File | Missing Since | Impact |
|--------|------|---|---|
| Cache eviction/re-promotion cycles | `physics_hotwords_cache.c` | Day 1 | Are we thrashing? |
| False negatives (words evicted before promotion) | `physics_hotwords_cache.c` | Day 1 | Should promotion threshold be lower? |
| Cache eviction candidate value | `physics_hotwords_cache.c` | Day 1 | Was LRU the right choice? |
| Bucket scan depth (position of hit) | `physics_hotwords_cache.c` | Day 1 | Is bucket order actually helping? |
| Promotion wait time | `physics_hotwords_cache.c` | Day 1 | How long does word stay in bucket before cache? |
---
## Priority for "Twisting the Dragon's Tail"
### 🔴 **CRITICAL (Do First)**
1. **Stack peak depth** - 5 minutes to add, massive insight
2. **Block I/O metrics** - Writeback behavior unknown (could be performance killer)
3. **Dictionary bucket load** - Unbalanced bucketing = latency tail
### 🟠 **HIGH (Phase 1 DoE)**
4. **Per-word execution frequency** - Validation for cache/window decisions
5. **Heat decay trace** - Validate Phase 2 feature before enabling
6. **Block I/O hit rate** - Complete the I/O picture
### 🟡 **MEDIUM (Phase 2 DoE)**
7. **Pipelining accuracy by depth** - Input to window size binary chop
8. **Colon definition nesting depth** - Tail-call optimization opportunities
9. **Dictionary growth velocity** - Predict "full" events
### 🟢 **NICE-TO-HAVE (Phase 3)**
10. Heat concentration ratio
11. Word category breakdown
12. Speculation ROI histogram
---
## Implementation Effort Estimate
| Category | Files | LOC | Time | Priority |
|----------|-------|-----|------|----------|
| Stack metrics | stack_management.c, vm.h | ~30 | 30 min | 🔴 |
| Dictionary metrics | vm.c, memory_management.c, vm.h | ~50 | 45 min | 🔴 |
| Block I/O metrics | block_subsystem.c, vm.h | ~80 | 1 hr | 🔴 |
| Per-word metrics | vm.c, physics_metadata.c, vm.h | ~100 | 1.5 hr | 🟠 |
| Heat dynamics | physics_metadata.c, vm.h | ~60 | 1 hr | 🟠 |
| Pipelining accuracy | physics_pipelining_metrics.c, vm.h | ~40 | 45 min | 🟡 |
---
## Bucket Reordering Mystery
**File**: `physics_hotwords_cache.c:201-215`
**Code**: `hotwords_bucket_reorder()` - bubble sort by execution_heat
**Status**: Function defined but **NEVER CALLED** from lookup path
**Question**: Is this dead code or forgot to hook it?
**If enabled, metrics needed:**
- Reorder frequency
- Cost (bubble sort latency)
- Benefit (does reordering actually improve hit latency?)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,228 @@
> **HISTORICAL (docs triage 2026-10-14).** A test-coverage audit of StarForth v3.0.3 / LithosAnanke v1.0.8, 2026-06-03; POST has grown since (1052 tests).
> Instead: v3/src/test_runner/ and the POST line of any current boot. Moved here from `docs/TEST_GAPS.md`.
# StarForth Dictionary Test Coverage — Gap Audit
**Branch:** `lithosananke` | **StarForth v3.0.3 / LithosAnanke v1.0.8**
**Audited:** 2026-06-03
---
## Summary
| Metric | Count |
|--------|-------|
| Total registered words | ~230 |
| Words with at least one test | ~115 |
| Words with **no** test | ~115 |
| Test files | 20 |
| Untested word categories | 5 (editor, inference, log, physics-diag, q48) |
Coverage is solid for the foundational FORTH-79 core but has critical holes
in control-flow completeness, format output, memory ops, and the S" word
just added in v3.0.3.
---
## Priority 1 — FORTH-79 Core: Missing Critical Words
These are standard FORTH-79 words used in virtually all real programs.
Missing tests here are compliance failures.
| Word(s) | Source file | Why critical |
|---------|-------------|--------------|
| `1+` `1-` `2+` `2-` `2*` `2/` | arithmetic_words.c | Shorthand increment/shift ops; used in almost every program. Arithmetic test only covers `/MOD` variants, not these. |
| `I` `J` | control_words.c | Loop index access. Every `DO...LOOP` that reads the index uses `I`; nested loops need `J`. No test at all. |
| `EXIT` | control_words.c | Return from word mid-execution. Essential for early-return patterns. No test. |
| `LEAVE` | control_words.c | Early exit from `DO...LOOP`. No test. |
| `UNLOOP` | control_words.c | Required to clean the return stack before `EXIT` inside a loop. Omitting it is a stack-corruption bug; no test exercises this. |
| `AGAIN` | control_words.c | `BEGIN...AGAIN` infinite loop. Common pattern, completely untested. |
| `CASE` `OF` `ENDOF` `ENDCASE` | control_words.c | Full `CASE` structure. Entire construct untested. |
| `+!` `-!` | memory_words.c | Modify-in-place. The single most common memory idiom in FORTH after `@` and `!`. No test. |
| `FILL` `MOVE` `ERASE` | memory_words.c | Bulk memory primitives. Used by string ops, block subsystem, array initialisation. No test. |
| `2!` | memory_words.c | Store double/address pair. `2@` is tested; its store partner is not. |
---
## Priority 2 — S" (New in v3.0.3) — Urgent
`S"` was added as a proper IMMEDIATE primitive in this release. It has zero
test coverage. Regression risk is high since the implementation is new.
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `S"` | string_words.c | No test for interpret-mode push (c-addr u), compile-mode inline (`(s")` runtime), or use inside a `:` definition. |
| `(s")` | string_words.c | Internal runtime for compiled `S"`. Exercised only by compiled `S"` — needs a compile-mode test. |
| `BL` | string_words.c | Space-character constant. Trivial but untested; often paired with `S"`. |
| `SOURCE` `>IN` | string_words.c | Input stream state. `SOURCE` returns ( c-addr u ); `>IN` is the offset. Both untested. |
---
## Priority 3 — Format / Output Words
`format_words.c` has 19 registered words. Only `.` and `BASE`/`DECIMAL` are
touched (from io_words_test.c). The pictured numeric output group is
completely dark.
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `HEX` `OCTAL` | format_words.c | Base switching. Used constantly in systems work. No test. |
| `.S` | format_words.c | Print entire stack without consuming it. Core debugging primitive. No test. |
| `?` | format_words.c | Print cell at address (` @ . `). Heavily used. No test. |
| `.R` `U.` `U.R` | format_words.c | Right-justified and unsigned output. No test. |
| `D.` `D.R` | format_words.c | Double-number output. No test. |
| `<#` `#` `#S` `#>` `HOLD` `SIGN` | format_words.c | Pictured numeric output group. Entire 6-word subsystem untested. |
| `DUMP` | format_words.c | Memory hex dump. No test. |
---
## Priority 4 — Logical / Comparison Gaps
logical_words_test.c covers the common cases but misses several FORTH-79 words.
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `0<>` | logical_words.c | Not-equal-to-zero. Symmetric counterpart to `0=`. No test. |
| `U<` `U>` | logical_words.c | Unsigned comparison. Critical for address arithmetic and char comparisons. No test. |
| `WITHIN` | logical_words.c | Range test. No test. |
| `TRUE` `FALSE` | logical_words.c | Boolean constants. Untested (though they're trivially `0` and `-1`). |
---
## Priority 5 — Stack Word Gaps
stack_words_test.c covers DUP DROP SWAP OVER ROT DEPTH PICK ROLL.
Two standard words missing:
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `?DUP` | stack_words.c | Conditional dup (dup only if non-zero). Common idiom. No test. |
| `-ROT` | stack_words.c | Reverse rotate. Tested implicitly via `ROT` but never directly. |
---
## Priority 6 — Double Number Gaps
double_words_test.c is thorough but misses:
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `S>D` | double_words.c | Convert single to double. The entry point for all `D`-word arithmetic. No test. |
| `D2*` `D2/` | double_words.c | Double arithmetic shifts. No test. |
| `2>R` `2R>` `2R@` | double_words.c | Double-number return stack. No test. |
---
## Priority 7 — Mixed Arithmetic Gap
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `M-` | mixed_arithmetic_words.c | `M+` and `M*` are tested; `M-` is not. |
---
## Priority 8 — Compilation / Meta Words
These are used to build user-defined IMMEDIATE words and to manipulate the
dictionary at compile time. None are tested.
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `COMPILE` `[COMPILE]` | defining_words.c | Used to force compilation of words inside IMMEDIATE definitions. No test. |
| `[']` | string_words.c | Compile-time version of `'` (tick). Returns XT of next word at compile time. No test. |
| `LIT` | defining_words.c | Internal compile-time literal push. No test. |
| `STATE` | defining_words.c / dictionary_manipulation_words.c | Dual-registered. Compile/interpret switch. No test. |
| `ALIGN` | dictionary_words.c | Align `HERE` to cell boundary. No test. |
| `'` (TICK) | dictionary_manipulation_words.c | Fetch execution token of named word. Core of `[']` and `EXECUTE`. No test. |
| `LITERAL` `[LITERAL]` | string_words.c | Compile a literal at runtime / inside definitions. Partially touched in io test but no dedicated test. |
---
## Priority 9 — Dictionary Traversal Words
These enable introspection of the dictionary structure. No tests at all.
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `>NAME` `NAME>` | dictionary_manipulation_words.c | Convert between CFA and NFA. No test. |
| `>LINK` `LINK>` | dictionary_manipulation_words.c | Navigate dictionary linked list. No test. |
| `CFA` `NFA` `LFA` `PFA` | dictionary_manipulation_words.c | Classic field-access words. No test. |
| `TRAVERSE` | dictionary_manipulation_words.c | Walk dictionary chain. No test. |
| `INTERPRET` | dictionary_manipulation_words.c | The outer interpreter. No test. |
---
## Priority 10 — System Words
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `ABORT"` `(ABORT")` | system_words.c | Conditional abort with message. Used in error handling. No test. |
| `WORDS` `VLIST` | system_words.c | Dictionary listing. No test. |
| `SEE` | system_words.c | Decompiler. No test. |
| `COLD` `WARM` | system_words.c | System restart/reinit. No test (understandably risky to test directly). |
| `QUIT` | system_words.c | Outer interpreter restart. No test. |
---
## Priority 11 — Block Word Gap
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `-->` | block_words.c | Chain-load next block. Used in multi-block definitions. No test. |
---
## Priority 12 — Lifecycle / Capsule Words
Capsule-BIRTH/KILL/PAUSE/RESUME/USE have partial coverage from mama_forth tests
but direct functional tests are missing.
| Word(s) | Source file | Gap |
|---------|-------------|-----|
| `KILL` `PAUSE` `RESUME` | lifecycle_words_hosted.c | Capsule lifecycle management. No direct test. |
| `USE` | lifecycle_words_hosted.c | Switch active VM. No test. |
---
## Priority 13 — Entire Untested Categories
These word groups have **zero test coverage**. Lower urgency than gaps above
because they are StarForth-specific extensions (not FORTH-79 compliance),
but they should be ticketed.
| Category | Source file | Word count | Notes |
|----------|-------------|------------|-------|
| Q48 fixed-point | q48_words.c | 21 | POST unit tests exist for the C layer but no FORTH-word tests |
| Inference | inference_words.c | 19 | Physics adaptive engine; complex to test deterministically |
| Log words | log_words.c | 7 | LOG-ERROR … LOG-LEVEL@; simple but untested |
| Physics diagnostics | physics_diagnostic_words.c | 4 | PHYSICS-WORD-METRICS etc. |
| Physics freeze | physics_freeze_words.c | 9 | FREEZE-WORD, HEAT@, etc. |
| Physics benchmark | physics_benchmark_words.c | 6 | BENCH-DICT-LOOKUP etc. |
| Physics pipelining diag | physics_pipelining_diagnostic_words.c | 6 | PIPELINING-SHOW-STATS etc. |
| Editor | editor_words.c | 4 | L, S, SHOW, EDIT — block editor; very low priority |
---
## Work Order (suggested sequence)
```
1. [ ] P1a arithmetic_words_test.c — add 1+ 1- 2+ 2- 2* 2/
2. [ ] P1b control_words_test.c — add I J EXIT LEAVE UNLOOP AGAIN
3. [ ] P1c control_words_test.c — add CASE OF ENDOF ENDCASE
4. [ ] P1d memory_words_test.c — add +! -! 2! FILL MOVE ERASE
5. [ ] P2 string_words_test.c — add S" (s") BL SOURCE >IN
6. [ ] P3a format_words_test.c — new file: HEX OCTAL .S ? .R U. U.R D. D.R
7. [ ] P3b format_words_test.c — add <# # #S #> HOLD SIGN DUMP
8. [ ] P4 logical_words_test.c — add 0<> U< U> WITHIN TRUE FALSE
9. [ ] P5 stack_words_test.c — add ?DUP -ROT
10.[ ] P6 double_words_test.c — add S>D D2* D2/ 2>R 2R> 2R@
11.[ ] P7 mixed_arithmetic_words_test.c — add M-
12.[ ] P8a defining_words_tests.c — add COMPILE [COMPILE] LIT STATE
13.[ ] P8b dictionary_manipulation_words_test.c — add ' ['] ALIGN LITERAL
14.[ ] P9 dictionary_manipulation_words_test.c — add >NAME NAME> CFA NFA LFA PFA TRAVERSE INTERPRET
15.[ ] P10 system_words_test.c — new file: ABORT" WORDS VLIST SEE
16.[ ] P11 block_words_test.c — add -->
17.[ ] P12 lifecycle capsule tests — add KILL PAUSE RESUME USE
18.[ ] P13a q48_words_test.c — new file: all 21 Q48 FORTH words
19.[ ] P13b log_words_test.c — new file: LOG-ERROR … LOG-LEVEL@
20.[ ] P13c physics words tests — new files as needed
```
@@ -0,0 +1,218 @@
> **HISTORICAL (docs triage 2026-10-14).** A session hand-off plan from 2026-06-10, on the pre-split `lithosananke` branch; every item in it is long done or overtaken.
> Instead: .claude/CLAUDE.md and docs/fabric/FABRIC-3.md for current status. Moved here from `docs/NEXT_SESSION.md`.
# Next Session Plan
Generated at end of session `cdcb1844` (2026-06-10).
Branch at close: `lithosananke` (merged and pushed; all three arches boot to `ok>`)
---
## What Was Accomplished This Session
- Fixed SysV ABI stack alignment bug in `kernel_entry.S` (`sub rax, 8`)
- Removed redundant kmalloc stack switch from `kernel_main.c`
- Fixed GOT/PE crash in `apply_sgr` — `FB_ANSI_PALETTE` got
`__attribute__((visibility("hidden")))` in both `framebuffer.h` and
`framebuffer.c`; EXEC-DOE now runs to full completion (160,673 rows)
- Added framebuffer host render test (`tools/fbtest.c`) and QEMU screendump
(`scripts/qemu_screenshot.sh`) to the amd64 `qemu` target
- CLAUDE.md: one-process-at-a-time build rule
- Design doc: `docs/reference/kernel-args/DESIGN.md` — UEFI
command-line argument system (KernelArgs)
---
## Task 0 — Fix doe.4th EXEC regression (do first)
All three architectures boot to `ok>` but `S" doe.4th" EXEC` fails at
runtime with "EXEC: failed: doe.4th" on every arch. Root cause: merge
conflict resolution took the remote's self-executing `doe.4th` (480 runs)
and `init.4th` (calls `S" doe.4th" EXEC`), but the capsule fails at runtime.
`EXEC-DOE` word is also absent (removed from `init.4th` by the remote).
Investigation starting point:
- Check `capsule_exec_init` return path — add diagnostic to distinguish
NOT_FOUND vs HASH_MISMATCH vs runtime error
- Verify new `doe.4th` block structure (correct block numbers, no undefined words)
- Consider restoring `EXEC-DOE` as an alias once doe.4th runs correctly
---
## Task 1 — Carry-over acceptance tests (do first, one at a time)
All three architectures now confirmed on `lithosananke`:
amd64 ✓ aarch64 ✓ riscv64 ✓
These were completed at end of session. No action needed unless a new
change is made — then re-run all three before merging.
```bash
make -f Makefile.starkernel ARCH=aarch64 clean qemu
make -f Makefile.starkernel ARCH=riscv64 clean qemu
```
Commit logs after each run. Do not proceed to any implementation task
until all three architectures have a clean `ok>` log committed.
---
## Task 2 — Memory size audit
Before tuning anything, measure the actual headroom:
- BSS stack (`g_kernel_stack`): currently 2 MB — log the deepest RSP
observed during EXEC-DOE and compare against the stack base
- VM data stack / return stack depths — check `vm.h` for current limits
- Rolling window buffer (`ROLLING_WINDOW_SIZE=4096`) — verify it isn't
being silently truncated under DoE load
- `KERNEL_HEAP_SIZE` (2 GB allocated, 1 GB physical in QEMU) — confirm
kmalloc never hits the limit during a full DoE run
There are no hard rules on these sizes; increase freely if headroom is
tight. Document findings in `docs/lithosananke/memory-audit.md`.
---
## Task 3 — Implement KernelArgs
Design doc: `docs/reference/kernel-args/DESIGN.md`
Implementation order (one commit per step):
1. `include/starkernel/kernel_args.h` — struct + default macros
2. `include/starkernel/boot_info_offsets.h` — assembly-visible offsets
with `_Static_assert` checks in C
3. `include/starkernel/uefi.h` — add `kernel_stack_base`,
`kernel_stack_size`, `KernelArgs args` to `BootInfo`
4. `include/starkernel/cmdline.h` + `src/starkernel/boot/cmdline.c` —
UCS-2→ASCII, tokeniser, parser
5. `src/starkernel/boot/uefi_loader.c` — call `cmdline_parse`, allocate
dynamic stack via `AllocatePages`
6. `src/starkernel/arch/amd64/kernel_entry.S` — dynamic stack switch,
fall back to BSS if `kernel_stack_base == 0`
7. `src/starkernel/kernel_main.c` — use `args.heap_size`, honour
`args.run_doe` and `args.log_level`
8. `Makefile.starkernel` — pass `--doe` via OVMF boot entry; remove socat
EXEC-DOE injection
Run all three arch acceptance tests after step 8.
---
## Task 4 — ISO real-hardware boot audit
The ISO built by xorriso works in QEMU but has a known gap for real
hardware (xorriso warns: "no directory /EFI/BOOT"). Real commodity UEFI
firmware expects `BOOTX64.EFI` present in the ISO *filesystem* at
`/EFI/BOOT/BOOTX64.EFI`, not just as an El Torito boot image.
Targets:
- **amd64** — commodity x86-64 machine: add `/EFI/BOOT/BOOTX64.EFI` to
the ISO filesystem tree in the Makefile xorriso invocation
- **aarch64 / RPi4** — needs `BOOTAA64.EFI`; RPi4 requires the
tianocore RPi4 UEFI firmware layer on the SD card/USB first; the ISO
sits on top
- **aarch64 / BeagleBone AI-64** (aspirational) — same EFI path as RPi4
Document the verified boot procedure for each target in
`docs/lithosananke/hardware-boot.md`.
---
## Task 5 — `REBOOT` word
A FORTH word that optionally accepts a next-boot argument string and
performs a cold reset via UEFI Runtime Services.
Key design decisions (agreed this session):
- **Not interpreter-only at the C level** — no `STATE` check, no special
flag
- **ACL-controlled** — the word-level ACL system (Task 6) governs access
- **On ACL denial**: emit warning, return to REPL; system keeps running
- **No abort** — consistent with how all sensitive words will work under ACL
Implementation sketch:
```forth
S" --doe --stack=8M" REBOOT \ reboot with next-boot args
REBOOT \ plain cold reboot
```
Under the hood:
1. If a string is on the stack: write it to a UEFI variable
(`StarForthNextArgs` under a custom GUID) via `RT->SetVariable`
2. Call `RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL)`
3. Loader reads the variable on next boot, merges with `LoadOptions`;
clears the variable after reading (one-shot)
`REBOOT` with no args is a plain cold reboot.
---
## Task 6 — `USE` word and resilient capsule loading
A general FORTH word (not capsule-specific) for loading external blobs.
```forth
S" hires-video.4th" USE
S" sound-card-1" USE \ fails → line gets commented out
S" sound-card-2" USE
```
On failure, `USE`:
1. Locates the calling line in the block buffer
2. Prepends `\ ` to comment it out (writes to RAM block)
3. Continues — one failure does not stop subsequent `USE` calls
4. Up to 16 lines per block may be commented out
**Self-healing property:** over multiple boots the system converges to a
stable configuration. Hardware that isn't present or drivers that don't
work are silently excluded. Hardware that works is locked in.
`REBOOT` integrates naturally:
```forth
S" hires-video.4th" USE
REBOOT \ apply hardware init needing a cold reset
hires-video-init? NOT IF
\ didn't take — USE mechanism will comment it out on next boot
THEN
```
---
## Task 7 — Forward word declarations
A FORTH analog of C prototypes: declare a word's name and stack effect
before its implementing capsule is loaded. Enables circular dependencies
between capsules without load-order brittleness.
```forth
FORWARD: init-network ( -- ) \ stub; filled when net capsule loads
FORWARD: video-mode? ( -- f ) \ stub; filled when video capsule loads
```
If a forward-declared word is called before its definition arrives, it
emits a warning and returns without crashing. When the implementing
capsule loads and defines the word, the stub is replaced.
This is a general VM feature — not kernel or capsule specific.
---
## Task 8 — Word-level ACL system (existing design, next to implement)
Design doc: `docs/reference/word-acl/DESIGN.md`
This is already designed. It is the policy engine that makes Tasks 5–7
safe. Implement before or alongside Task 5 (`REBOOT`) since `REBOOT`
depends on ACL for its safety guarantees.
---
## Pointer for Next Session
Start with Task 1 (aarch64 + riscv64 acceptance). Read this file and the
design docs listed above before touching any code. Present the task order
to Captain Bob for approval before each implementation step.
All development stays on the working branch; never merge to master.
@@ -0,0 +1,82 @@
> **HISTORICAL (docs triage 2026-10-14).** A generated diagnostic report from one test run, 2026-06-30.
> Instead: the boot POST in any current logs/ run. Moved here from `docs/BREAK_ME_REPORT.md`.
# 🔥 STARFORTH BREAK-ME DIAGNOSTIC REPORT 🔥
## Executive Summary
**Generated:** 2026-06-30 16:53:09
**Test Mode:** ULTRA-COMPREHENSIVE DIAGNOSTIC
**Purpose:** This report documents the results_run_01_2025_12_08 of the most exhaustive testing suite ever run on StarForth. Every word, every edge case, every pathological scenario has been tested to ensure rock-solid reliability and FORTH-79 standard compliance.
---
## 📊 Performance Metrics
| Metric | Value |
|--------|-------|
| Test Duration | 0.00 seconds |
| Total Tests | 1003 |
| Tests/Second | inf |
## 🖥️ System Information
| Component | Specification |
|-----------|---------------|
| VM Architecture | Direct-threaded |
| Standard | FORTH-79 + StarForth Extensions |
| Cell Size | 8 bytes |
| Stack Size | 1024 cells |
| Memory | 5242880 bytes |
---
## 🎉 EASTER EGG: THE STARFORTH CHALLENGE 🎉
```
⭐ C O N G R A T U L A T I O N S ⭐
You've discovered the hidden StarForth challenge!
Your system just survived 1003 exhaustive tests.
But can YOU survive the ULTIMATE FORTH CHALLENGE?
🏆 THE STARFORTH MASTER CHALLENGE 🏆
Write a Forth program that:
1. Prints the Fibonacci sequence up to 1000
2. Uses ONLY the following words:
: ; DUP OVER DROP SWAP . CR < IF THEN DO LOOP
3. Fits in exactly 79 characters (FORTH-79 tribute!)
Submit your solution to the StarForth community!
Hint: Think recursively, but remember FORTH-79
doesn't have RECURSE... 😉
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
BONUS SECRET: If you ran --break-me, you're already
in the top 1% of Forth enthusiasts. Welcome to the
elite club! Your system just proved it can handle
anything you throw at it.
May your stacks be balanced and your words defined,
-- The StarForth Development Team ⭐
```
### 🎮 More Easter Eggs to Find:
1. Try defining a word called `STARSHIP` and see what happens
2. Run `42 ENTROPY@ .` to see the universe's favorite number
3. Type `WORDS` and count how many contain 'STAR'
4. Check what happens when you `FORGET FORGET` (just kidding, don't!)
---
*Generated by StarForth --break-me mode*
*Copyright (c) 2025 Robert A. James - StarshipOS Forth Project*
@@ -0,0 +1,100 @@
> **HISTORICAL (docs triage 2026-10-14).** The write-up of one fix (APIC timer ISR, amd64), done.
> Instead: the code itself (kernel/src/arch/amd64/). Moved here from `docs/lithosananke/amd64-isr-fix/README.md`.
# APIC Timer ISR Fix — amd64
**Date**: 2026-06-03
**Branch**: `claude/starforth-architecture-review-oubN0`
**Commits**: `fb0c256`, `901f827`
---
## Problem
The LithosAnanke amd64 kernel was triple-faulting on the first APIC timer interrupt,
causing QEMU to exit immediately after printing `ok>`. The adaptive heartbeat never
fired and `Heartbeat: N ticks` never appeared in serial logs.
## Root Cause
The kernel is compiled with `-fPIC -fvisibility=hidden` (required for UEFI PE
relocation). Assembly symbols `isr_stub_table` and `isr_stub0` in `isr.S` were
declared `.global` with **default visibility**. The C compiler therefore accessed
them through GOT indirection. However, the linker — building a final non-shared
binary — collapsed the GOT references to point directly at the symbols themselves.
The net effect: "load from GOT[`isr_stub_table`]" loaded the 8-byte instruction
bytes of `isr_stub0` (`0x006a90eb006a006a`) rather than its address. Both
`link_time_addr` and `runtime_addr` in `arch_interrupts_init()` became the same
wrong value (instruction bytes), so `reloc_offset = 0` and all 256 IDT entries
received garbage handler addresses. IDT[32] was set to `0x6a006afffffe91e9`
(non-canonical), which triggered #GP → double fault → triple fault on the first
timer delivery.
The bug was confirmed by disassembling `arch_interrupts_init()` in the loader PE:
the compiler emitted a `mov` (load from memory) for `&isr_stub0` instead of a
`lea` (compute address), reading the function's instruction bytes.
## Fix
Two changes, one line each:
**`src/starkernel/arch/amd64/isr.S`** — Added `.hidden` directives for all symbols
referenced from C:
```asm
.hidden isr_stub_table
.hidden isr_stub0
.hidden isr_stub32
.hidden isr_stub_default
.hidden isr_common_entry
```
**`src/starkernel/arch/amd64/interrupts.c`** — Added visibility attributes to the
`extern` declarations:
```c
extern void *isr_stub_table[IDT_ENTRIES] __attribute__((visibility("hidden")));
extern void isr_stub0(void) __attribute__((visibility("hidden")));
```
With hidden visibility, the compiler uses direct RIP-relative `lea` instead of GOT
indirection, yielding correct runtime addresses for all 256 IDT entries.
## Result
| Criterion | Before | After |
|---|---|---|
| IDT[32] handler | `0x6a006afffffe91e9` (corrupt) | `0x3d90251c` (valid canonical address) |
| First timer interrupt | #GP → triple fault → QEMU exit | ISR fires cleanly, returns via `iretq` |
| `PARITY:OK` | ✅ (unaffected) | ✅ |
| `Init: init.4th OK` | ✅ (unaffected) | ✅ |
| `ok>` REPL | ✅ reached, then immediate crash | ✅ runs indefinitely |
| `Heartbeat: N ticks` | Never | Every second at 100 Hz, TIME-TRUST ≈ 0.999 |
## Secondary Fix
`repl_print_dec32`, `repl_lapic_ccr`, `repl_print_hex32`, and `idle_iters` in
`repl.c` are x86-64 specific (LAPIC MMIO, `pushfq`). They were unguarded, causing
`-Werror=unused-function` / `unused-variable` failures on aarch64 (clang) and
riscv64 (gcc). All moved inside `#ifdef ARCH_AMD64`.
## Acceptance Testing
All three architectures must boot to `ok>` with `PARITY:OK` and `Init: init.4th OK`.
amd64 additionally shows `Heartbeat: N ticks TIME-TRUST≈0.999` repeating at 1 Hz.
```bash
make -f Makefile.starkernel ARCH=amd64 clean qemu
make -f Makefile.starkernel ARCH=aarch64 clean qemu
make -f Makefile.starkernel ARCH=riscv64 clean qemu
```
Verify each log:
```bash
grep "PARITY:OK" logs/qemu-<arch>-*.log
grep "Init: init.4th OK" logs/qemu-<arch>-*.log
grep "ok>" logs/qemu-<arch>-*.log
grep "Heartbeat:" logs/qemu-amd64-*.log | head -5
```
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,25 @@
> **HISTORICAL (docs triage 2026-10-14).** The child-VM birthing plan and its acceptance record; built and live since (M7.1).
> Instead: docs/reference/M7.1.md and docs/fabric/. Moved here from `docs/birthing/README.md`.
# docs/working/archive/historical/2026-07-birthing/
Design and status for VM "birthing" — the mechanism by which Hera (the Tripod
governor) spawns Hermes and Artemis as child VMs at boot. See
`docs/working/archive/superseded/2026-08-tripod/TRIPOD.md` for the architectural contract this
work implements.
- **[PLAN.md](PLAN.md)** — Birthing plan for the initial three-VM constellation
(Hera/Hermes/Artemis). Marked DRAFT, requires Captain Bob approval before
implementation.
- **[STATUS.md](STATUS.md)** — Current work status: execution model (single
OS process, no threads/fork, VMs share one heap and address space, the C
call stack doubles as the execution stack), the birth-graph vs.
execution-stack distinction, and phase completion tracking.
- **[acceptance-logs/](acceptance-logs/)** — Three-architecture QEMU
acceptance test logs and summary for the lifecycle words (`BIRTH KILL
START STOP USE`).
## See also
- [`docs/working/archive/superseded/2026-08-tripod/README.md`](../03-architecture/tripod/README.md)
- [Project root](../../README.md)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,22 @@
> **HISTORICAL (docs triage 2026-10-14).** The child-VM birthing plan and its acceptance record; built and live since (M7.1).
> Instead: docs/reference/M7.1.md and docs/fabric/. Moved here from `docs/birthing/acceptance-logs/README.md`.
# docs/working/archive/historical/2026-07-birthing/acceptance-logs/
Kernel QEMU acceptance test results for the VM lifecycle words (`BIRTH KILL
START STOP USE`) and the `."` compile-mode fix, run across all three
supported architectures.
- **[SUMMARY.md](SUMMARY.md)** — Consolidated results table (800 tests run,
734 passed, 0 failed/errored on amd64/aarch64/riscv64), key serial-log
evidence, list of source files changed, and the remaining interactive
tests that require Captain Bob (`S" Hermes" USE`, KILL + re-BIRTH in the
same session).
- **[amd64.log](amd64.log)** — Raw QEMU serial log, amd64.
- **[arm64.log](arm64.log)** — Raw QEMU serial log, aarch64.
- **[riscv64.log](riscv64.log)** — Raw QEMU serial log, riscv64.
## See also
- [`docs/working/archive/historical/2026-07-birthing/README.md`](../README.md)
- [Project root](../../../README.md)
@@ -0,0 +1,66 @@
> **HISTORICAL (docs triage 2026-10-14).** The child-VM birthing plan and its acceptance record; built and live since (M7.1).
> Instead: docs/reference/M7.1.md and docs/fabric/. Moved here from `docs/birthing/acceptance-logs/SUMMARY.md`.
# Birthing — Kernel QEMU Acceptance Test Summary
**Date:** 2026-05-27
**Branch:** `birthing`
**Feature:** Lifecycle words (BIRTH KILL START STOP USE) + `."` compile-mode fix
## Scope
These logs cover the **kernel UEFI build** (`make -f Makefile.starkernel ARCH=<arch> clean qemu`).
All three architectures booted to `ok>`, ran POST, and executed `capsules/init.4th` successfully.
## Kernel QEMU Results
| Arch | Tests | Passed | Failed | Errors | BIRTH Hermes | BIRTH Artemis | `."` |
|------|-------|--------|--------|--------|-------------|---------------|------|
| amd64 | 800 | 734 | 0 | 0 | `[Hermes] Hermes Up` / live | `[Artemis] Artimis Up` / live | PASS |
| aarch64 | 800 | 734 | 0 | 0 | `[Hermes] Hermes Up` / live | `[Artemis] Artimis Up` / live | PASS |
| riscv64 | 800 | 734 | 0 | 0 | `[Hermes] Hermes Up` / live | `[Artemis] Artimis Up` / live | PASS |
## Key Evidence (all three architectures identical)
```
[Hera] POST: PASSED
[Hera] Init: loading init.4th...
[Hermes] Hermes UpBIRTH: Hermes live
[Artemis] Artimis UpBIRTH: Artemis live
[Hera] Init: init.4th OK
```
`."` in compile mode now uses the `(do-string)` inline runtime — string bytes live
inside the threaded code body, not at `body_addr`. The previous LIT-addr-LIT-len-TYPE
approach overwrote the start of the word body with string bytes, causing a triple fault
when `execute_colon_word` read them as DictEntry pointers.
## What Changed
- `src/word_source/io_words.c` — `."` compile mode replaced with `(do-string)` inline
approach; `(do-string)` runtime word reads inline string via return-stack IP, prints,
advances IP past padded block
- `src/starkernel/capsule/mama_forth_words.c` — BIRTH KILL START STOP USE kernel
implementations; fixed caddr+1 offset bug to align with FORTH-79 S"
- `src/word_source/string_words.c` — S" fixed to FORTH-79 standard ( -- c-addr u )
- `src/word_source/lifecycle_words_hosted.c` — hosted Linux stubs (guarded #ifndef __STARKERNEL__)
- `src/main.c` — register_lifecycle_words(&vm) wired in for hosted build
- `capsules/init.4th` — S" Hermes" BIRTH + S" Artemis" BIRTH
- `capsules/hermes/init.4th` — stub: `: UP ." Hermes Up" ; UP`
- `capsules/artemis/init.4th` — stub: `: UP ." Artimis Up" ; UP`
## Serial Logs
| Arch | Log file |
|------|----------|
| amd64 | `logs/qemu-amd64-20260526-234957.log` |
| aarch64 | `logs/qemu-aarch64-20260526-235056.log` |
| riscv64 | `logs/qemu-riscv64-20260527-000127.log` |
(`logs/` is gitignored — run locally to reproduce)
## Remaining Interactive Tests (require Captain Bob)
- `S" Hermes" USE` — switches system console to Hermes
- `S" Hera" USE` — switches back
- KILL + re-BIRTH a VM in the same session
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2dbe1a4abd9342a0ec96fbd4c4c15ab039385b2af9639c7489eda6fe9dfc6fa4
size 10216
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:25dc9dcce2403f30ef6b2c0d14e5462d7e17e42070c1afa443f92cf85985cd99
size 9889
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2af00462812d21a44807da17be38ad5fb5e97ca56b4c2b883cf192b7ef1778db
size 9885
@@ -0,0 +1,186 @@
> **HISTORICAL (docs triage 2026-10-14).** The write-up of one fix (kernel stack trampoline, riscv64), done.
> Instead: the code itself (kernel/src/arch/riscv64/). Moved here from `docs/lithosananke/riscv64-stack-fix/README.md`.
# Kernel Stack Trampoline Fix — riscv64
**Date**: 2026-08-02
**Branch**: `master`
**Commit**: `7366275`
---
## Problem
The riscv64 kernel crashed partway through VM bootstrap during the 2026-08-01
DoE campaign run, well after amd64 and aarch64 had both booted cleanly to
`ok>` in the same session. The crash was a wild jump: execution landed at an
address nowhere inside the kernel's own linked image, then almost immediately
faulted trying to load from a small, near-null address.
```
Registering FORTH-79 Standard word set...
Registering FORTH-79 arithmetic words...
FORTH-79 Standard word set registration complete
*** EXCEPTION (riscv64) ***
scause = 0x000000000000000d
sepc = 0x00000000be27c3c2
stval = 0x00000000000074d8
```
`scause = 0xd` is a supervisor-mode load page fault. `sepc` (~0xbe27c3c2) sat
near the top of QEMU's 1 GB RAM window — nowhere close to the kernel's own
`.text`/`.data`/`.bss` footprint (`0x400000`–`0xcdf9a0`, confirmed via `nm`/
`readelf` on the exact build that produced the log). `stval` (0x74d8, ~30 KB)
stayed fixed across rebuilds even as `sepc` drifted — the signature of a
corrupted return address rather than a fixed logic bug at one source line.
## Investigation
Two dead ends were ruled out before the real cause surfaced:
1. **ELF relocation / buffer overlap in the split-build loader.** The
codebase has a `!MONOLITHIC_BUILD` path (`elf_load_kernel()` in
`elf_loader.c`) that loads `kernel.elf` from the ESP into a UEFI
`AllocateAnyPages` buffer. This looked like a plausible overlap candidate
at first, but `Makefile.starkernel` defaults to `MONOLITHIC=1`, meaning
`kernel_main` is linked directly into the loader and that code path never
runs. Confirmed by checking the built binary for the investigation's own
diagnostic strings — absent, because the compilation unit was built with
`-DMONOLITHIC_BUILD` and the code was preprocessed out.
2. **`RAW_LOG()` silently no-ops on every non-amd64 arch.** All of
`load_kernel_from_esp()`'s narration (and an early ConOut-based
diagnostic) never reached the captured serial log, on riscv64, in any
build. `RAW_LOG` was defined only for `ARCH_AMD64`; everywhere else it
expanded to `((void)0)`. This made straightforward diagnosis impossible
until a real raw-UART writer was added for riscv64 (see Secondary Fix).
With real output available, `console_println()` checkpoints were bisected
through `vm_init_with_host()` and `sk_vm_bootstrap_parity()`. Every checkpoint
inside `vm_init_with_host()` printed successfully, including the very last
line of the function — but the checkpoint immediately after its *return*
never appeared. Re-running with a trivial, unrelated local-variable addition
shifted the crash earlier and changed the exception type entirely (from a
load fault to an instruction-fetch fault at `sepc == stval`, i.e. the CPU
tried to *execute* an unmapped address). A crash whose location and even
category shift under unrelated code changes is the standard signature of
stack corruption, not a fixed bug at a specific call site.
## Root Cause
`kernel_main.c` documented the gap directly, once read closely:
> On amd64, `kernel_entry.S` switches the stack from UEFI's default to a
> 2 MiB zero-initialised BSS stack and tail-calls this function as
> `kernel_main_impl`. On aarch64 and riscv64 the assembly trampoline is not
> yet implemented and the UEFI loader calls `kernel_main` directly.
amd64 has carried a dedicated stack-switch trampoline
(`src/starkernel/arch/amd64/kernel_entry.S`) since early on, with its own
comment explaining why: *"UEFI hands control to kernel_main() running on a
small UEFI-provided stack (typically 128 KB–256 KB). The FORTH interpreter +
DOE experiment loop can easily exceed that depth."* riscv64 never had the
equivalent. It ran the entire VM bootstrap — 27 chained word-registration
modules, physics/SSM init, Tripod capsule birth — directly on whatever small
stack EDK2's riscv64 firmware handed the loader, overflowing it and
corrupting a return address. aarch64 has the same theoretical exposure but
happens not to trip it, apparently because its firmware's default boot stack
is larger — incidental, not a guarantee.
## Fix
**`src/starkernel/arch/riscv64/kernel_entry.S`** (new) — RISC-V stack-switch
trampoline mirroring amd64's:
```asm
.section .bss
.align 4
.global g_kernel_stack
g_kernel_stack:
.space 0x200000
g_kernel_stack_top:
.global g_kernel_stack_top
.section .text
.extern kernel_main_impl
.global kernel_main
kernel_main:
ld t0, BOOT_INFO_KERNEL_STACK_BASE_OFFSET(a0)
bnez t0, .Ldynamic_stack
la t0, g_kernel_stack_top
j .Lstack_ready
.Ldynamic_stack:
ld t1, BOOT_INFO_KERNEL_STACK_SIZE_OFFSET(a0)
add t0, t0, t1
.Lstack_ready:
andi t0, t0, -16
mv sp, t0
mv s0, zero
tail kernel_main_impl
```
**`src/starkernel/kernel_main.c`** — riscv64 now builds `kernel_main_impl`
(invoked via the trampoline) instead of `kernel_main` directly, same pattern
as amd64:
```c
#if defined(__x86_64__) || defined(__riscv)
void kernel_main_impl(BootInfo *boot_info) {
#else
void kernel_main(BootInfo *boot_info) {
#endif
```
**`Makefile.starkernel`** — wires the new file into the riscv64 loader build:
```makefile
ifeq ($(ARCH),riscv64)
LOADER_ASM += $(KERNEL_SRC)/arch/$(ARCH)/kernel_entry.S
endif
```
## Secondary Fix
`RAW_LOG()` in `src/starkernel/boot/uefi_loader.c` was a no-op on every arch
except amd64, silencing all of the loader's own diagnostic messages on
riscv64 (and aarch64). Added a real raw-UART writer for riscv64, targeting
QEMU virt's 16550-compatible `uart8250` at MMIO `0x10000000` (matches
`Domain0 Region03` in the OpenSBI boot banner) — the same byte-polling
protocol as the existing amd64 port-I/O version, just MMIO instead of `outb`/
`inb`. Existing and future `RAW_LOG()` call sites in the loader now actually
produce output on riscv64.
## Result
| Criterion | Before | After |
|---|---|---|
| `sepc` after word registration | Wild address outside kernel image (`0xbe27c3c2`-ish, drifting per build) | N/A — no longer occurs |
| Exception | Load or instruction-fetch page fault, non-deterministic between builds | None |
| `[Hera] ok>` (riscv64) | Never reached | ✅ reached, Tripod fleet (Hera/Hermes/Artemis) runs to completion |
| `PASS: E2E msg flow` | Never logged | ✅ |
| `PARITY:MAMA_INIT` / `Init: Mama birth OK` | Never logged | ✅ |
| Loader `RAW_LOG()` output on riscv64 | Silent no-op | ✅ visible in serial log |
## Acceptance Testing
All three architectures must boot to `ok>`, run the Tripod fleet, and reach
`[Hera] ok>`. Per repo convention, run in this exact order, one QEMU instance
at a time, always `clean` before `qemu`:
```bash
make -f Makefile.starkernel ARCH=amd64 clean qemu
make -f Makefile.starkernel ARCH=aarch64 clean qemu
make -f Makefile.starkernel ARCH=riscv64 clean qemu
```
Verify each log:
```bash
grep "ok>" logs/<session>/<arch>/qemu-<arch>-*.log
grep "PASS: E2E msg flow" logs/<session>/<arch>/qemu-<arch>-*.log
grep "PARITY:MAMA_INIT" logs/<session>/<arch>/qemu-<arch>-*.log
grep "EXCEPTION" logs/<session>/<arch>/qemu-<arch>-*.log # must be empty
```
All three architectures confirmed clean on 2026-08-02 (see
`logs/20260802-064050/riscv64/`, `logs/20260802-064424/amd64/`,
`logs/20260802-064656/aarch64/`, committed alongside this fix).
@@ -0,0 +1,198 @@
> **HISTORICAL (docs triage 2026-10-14).** An orientation page for the old docs/lithosananke/ folder, flagged partly stale on 2026-10-09; the folder is gone (its parts are in docs/reference/ and this archive).
> Instead: docs/README.md. Moved here from `docs/lithosananke/README.md`.
# LithosAnanke — StarForth Kernel Branch
> **⚠ PARTIALLY STALE (flagged 2026-10-09).** This page predates the repo split and the
> Tripod/kernel reshuffle. There is no `lithosananke` branch in this repo — `master` is the
> sole production line — and the VM fleet is now **Hera / Artemis / Hestia** (the Hermes VM
> was removed; messaging moved into the kernel as kernel-Hermes). M7.1 is **live**, not
> merely designed. For authoritative status see `.claude/CLAUDE.md` and
> `docs/fabric/FABRIC-2.md` / `FABRIC-3.md` / `FABRIC-3.5.md` / `FABRIC-3.6.md`; for the
> milestone plan see `ROADMAP.md` (this file is an orientation page).
**Line:** `master` (sole production line post-split)
**Status:** M7 Complete (VM Parity) · M7.1 Live (capsules, Tripod, Stadium, word-level ACL Phases 1–7)
---
## What is LithosAnanke?
LithosAnanke is the kernel branch of StarForth — a UEFI-bootable microkernel with the StarForth VM as its native execution engine.
**Etymology:** *Lithos* (stone/foundation) + *Ananke* (necessity/inevitability)
The name reflects the project's nature: a necessary foundation for StarshipOS.
---
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ UEFI Firmware │
│ • ExitBootServices → handoff to kernel │
└─────────────────────┬───────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────┐
│ LithosAnanke Boot (M0) │
│ • UEFI loader collects BootInfo │
│ • Memory map, ACPI tables, framebuffer │
└─────────────────────┬───────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────┐
│ LithosAnanke HAL (M1-M6) │
│ • PMM: Physical Memory Manager (bitmap) │
│ • VMM: Virtual Memory Manager (4-level paging) │
│ • IDT: Interrupt Descriptor Table │
│ • APIC: Timer + IRQ routing │
│ • Heap: kmalloc/kfree │
│ • Console: Serial UART │
└─────────────────────┬───────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────┐
│ StarForth VM (M7+) │
│ • 295 FORTH-79 words │
│ • Parity validation (hash=0x684bbf2fa1d96d55) │
│ • Physics-driven adaptive runtime │
│ • Init capsule system (M7.1) │
└─────────────────────────────────────────────────────────────┘
```
---
## Current Milestones
| Milestone | Description | Status |
|-----------|-------------|--------|
| M0 | UEFI Boot + Serial Output | Complete |
| M1 | Physical Memory Manager | Complete |
| M2 | Virtual Memory Manager | Complete |
| M3 | IDT + Interrupts | Complete |
| M4 | APIC Timer | Complete |
| M5 | Timer Calibration | Complete |
| M6 | Kernel Heap | Complete |
| **M7** | **VM Parity Validation** | **Complete** |
| **M7.1** | **Capsules · Tripod · Stadium · ACL** | **Live** (see FABRIC docs) |
| M8 | REPL (keyboard input) | Superseded — see FABRIC-0 §25.5 item 4.4 |
| M9 | Block Storage / Block I/O | Live (virtio-blk + block subsystem) |
---
## Build & Run
```bash
# Build kernel with VM integration (loader + kernel)
make -f kernel/Makefile ARCH=amd64 STARFORTH_ENABLE_VM=1
# Run in QEMU
make -f kernel/Makefile ARCH=amd64 STARFORTH_ENABLE_VM=1 qemu
# Other architectures
make -f kernel/Makefile ARCH=aarch64 qemu
make -f kernel/Makefile ARCH=riscv64 qemu
```
**Output artifacts:**
- `build/amd64/kernel/starkernel_loader.efi` — UEFI loader
- `build/amd64/kernel/starkernel_kernel.elf` — Kernel binary
---
## Documentation
### Core Design
| Document | Description |
|----------|-------------|
| [M7.1.md](M7.1.md) | Init Capsule Architecture |
| [ROADMAP.md](ROADMAP.md) | Milestone roadmap |
| [amd64-isr-fix/README.md](amd64-isr-fix/README.md) | APIC timer ISR fix + kernel 3-arch acceptance test |
| [hosted-acceptance-test/README.md](hosted-acceptance-test/README.md) | Hosted VM 3-arch acceptance test (amd64 native, aarch64/riscv64 under QEMU user-mode) |
### HAL (Hardware Abstraction Layer)
| Document | Description |
|----------|-------------|
| [hal/overview.md](hal/overview.md) | HAL architecture and principles |
| [hal/interfaces.md](hal/interfaces.md) | HAL interface specifications |
| [hal/lithosananke-integration.md](hal/lithosananke-integration.md) | Kernel-specific HAL implementation |
| [hal/platform-implementations.md](hal/platform-implementations.md) | Platform implementation guide |
| [hal/migration-plan.md](hal/migration-plan.md) | Migration from hosted to kernel |
---
## Key Concepts
### One Truth Per VM
Every VM has exactly one birth capsule — its identity and provenance.
```
PARITY:BIRTH vm_id=42 capsule_id=0xA13F mode=p capsule_hash=0x... dict_hash=0x...
```
### DOMAIN vs PERSONALITY
**DOMAIN** is a construction concept that exists **only in Mama FORTH**. It's how Mama classifies, composes, and selects capsules. DOMAIN is never visible to baby VMs.
**PERSONALITY** is the result of executing a production `(p)` INIT capsule. It's what the baby VM *is* — its vocabulary, invariants, capabilities. PERSONALITY is immutable and defines the VM's entire worldview.
### Production (p) vs Experiment (e)
- **(p) capsules** are truth-bearing — they can birth VMs
- **(e) capsules** are Mama-only workloads — experiments that never touch babies
A baby VM never sees, executes, or knows about (e) capsules.
### Content-Addressed Capsules
Capsules are identified by content hash, not names. Names lie. Hashes don't.
### Mama FORTH
The root VM that holds all truths, manages child VMs, and enforces the birth protocol. Mama:
- Maintains the capsule directory
- Selects (p) capsules for birth
- Executes (e) capsules for experimentation
- Logs all births and runs for provenance
---
## Directory Structure
```
src/starkernel/
├── boot/ # UEFI loader, ELF loader
├── hal/ # Console, host services
├── memory/ # PMM, VMM, kmalloc
├── arch/amd64/ # x86_64 specific (APIC, IDT, timer)
├── vm/ # VM integration
│ ├── arena.c # VM memory arena
│ ├── parity.c # Parity validation
│ ├── bootstrap/ # sk_vm_bootstrap
│ └── host/ # Host services shim
└── kernel_main.c # Entry point
```
---
## Contributing
The contributing rules are:
1. Maintain parity validation (M7 baseline)
2. Pass the three-arch QEMU boot test (`ARCH={amd64,aarch64,riscv64}`)
3. Not break the hosted VM build (plain `make` at the repo root)
---
## References
- [StarForth README](../../README.md) — Main project
- [FORTH-79 Standard](http://www.forth.org/forth-79.html)
- [OSDev Wiki](https://wiki.osdev.org/)
- [UEFI Specification](https://uefi.org/specifications)
@@ -47,7 +47,7 @@ that actually matters).
## 2. Fix the broken riscv64 command in this branch's acceptance-test doc
`docs/lithosananke/hosted-acceptance-test/README.md` still documents the
`docs/reference/hosted-acceptance-test/README.md` still documents the
riscv64 leg using `riscv64-linux-gnu-gcc`, which cannot build this tree
(`nanosleep` visibility failure under `-std=c99`, unrelated to any project
change). This was already fixed in `master`'s `.claude/CLAUDE.md` (the
@@ -152,6 +152,6 @@ now — just flagging.
open item if anyone wants to chase it down.
- Today's aarch64/riscv64 `.hidden` ISR hardening (commit `5fe188bd`) only
has a CHANGELOG entry, not a dedicated writeup the way
`docs/lithosananke/amd64-isr-fix/README.md` documents the original amd64
`docs/working/archive/historical/2026-07-amd64-isr-fix/README.md` documents the original amd64
fix. Not urgent — the CHANGELOG entry covers it — but noting the
asymmetry in case someone later wants doc parity.
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More