431 lines
17 KiB
Markdown
431 lines
17 KiB
Markdown
<!-- Moved from docs/01-getting-started/DEVELOPER.md to docs/working/architecture/getting-started/DEVELOPER.md on 2026-06-16 (docs reorg Phase 2) -->
|
||
# StarForth Developer Guide
|
||
|
||
## Development Environment Setup
|
||
|
||
### Required Tools
|
||
|
||
#### Core Build Tools
|
||
|
||
```bash
|
||
sudo apt-get update
|
||
sudo apt-get install build-essential gcc make git
|
||
```
|
||
|
||
#### Optional Tools
|
||
|
||
- **Doxygen** - For API documentation generation
|
||
- **syft** - For SBOM generation
|
||
- **fpm** - For package building (DEB/RPM)
|
||
|
||
```bash
|
||
# Doxygen
|
||
sudo apt-get install doxygen
|
||
|
||
# syft
|
||
wget https://github.com/anchore/syft/releases/latest/download/syft_linux_amd64.tar.gz
|
||
tar -xzf syft_linux_amd64.tar.gz
|
||
sudo mv syft /usr/local/bin/
|
||
|
||
# fpm (for packaging)
|
||
sudo apt-get install ruby-dev build-essential
|
||
sudo gem install fpm
|
||
```
|
||
|
||
### Isabelle/HOL Installation
|
||
|
||
**Isabelle is required for formal verification documentation generation.**
|
||
|
||
#### Download & Install
|
||
|
||
1. **Download Isabelle2025** from https://isabelle.in.tum.de/
|
||
|
||
```bash
|
||
# Example installation to ~/bin/
|
||
cd ~/bin
|
||
wget https://isabelle.in.tum.de/dist/Isabelle2025_linux.tar.gz
|
||
tar -xzf Isabelle2025_linux.tar.gz
|
||
```
|
||
|
||
2. **Add Isabelle to your PATH** in `~/.bashrc`:
|
||
|
||
```bash
|
||
# Add Isabelle2025 binaries to PATH
|
||
export PATH="$PATH:$HOME/bin/Isabelle2025/bin"
|
||
```
|
||
|
||
3. **Reload your shell**:
|
||
|
||
```bash
|
||
source ~/.bashrc
|
||
```
|
||
|
||
4. **Verify installation**:
|
||
|
||
```bash
|
||
isabelle version
|
||
# Should output: Isabelle2025
|
||
```
|
||
|
||
#### Project Integration
|
||
|
||
The StarForth build system expects `isabelle` to be available on the `PATH`. The Makefile will automatically detect it:
|
||
|
||
```makefile
|
||
# From Makefile line 24:
|
||
ISABELLE ?= isabelle
|
||
```
|
||
|
||
**Do NOT commit Isabelle to the repository.** It's excluded via `.gitignore`:
|
||
|
||
```
|
||
/tools/Isabelle2025/
|
||
```
|
||
|
||
### Isabelle Make Targets
|
||
|
||
Once Isabelle is installed, you can use these targets:
|
||
|
||
```bash
|
||
# Verify all formal theories
|
||
make isabelle-build
|
||
|
||
# Quick syntax check (faster)
|
||
make isabelle-check
|
||
|
||
# Generate audit-ready documentation
|
||
make docs-isabelle
|
||
```
|
||
|
||
## Build Configuration (Kconfig)
|
||
|
||
StarForth has a Linux-kernel-style Kconfig system for its ~40 build-time
|
||
tuning knobs (physics/SSM engine, adaptive heartbeat, pipelining
|
||
speculation, architecture, build profile, platform mode, kernel-only
|
||
flags). **It is entirely optional.** Nothing changes about a plain `make`
|
||
or `make -f Makefile.starkernel` until you explicitly generate a
|
||
`.config` — until then, every knob uses the same bare defaults it always
|
||
has, and the two Makefiles behave exactly as if Kconfig didn't exist.
|
||
|
||
### Configuring
|
||
|
||
Config lives **per architecture**, under `build/$(ARCH)/.config` — not one
|
||
root `.config` — because building all three kernel architectures
|
||
back-to-back in one script is this project's normal QEMU acceptance
|
||
workflow, and a single shared config would desync from whichever arch is
|
||
actually being built.
|
||
|
||
```bash
|
||
# Interactive, curses-based menu (recommended)
|
||
make menuconfig # hosted build, current ARCH
|
||
make -f Makefile.starkernel ARCH=amd64 menuconfig
|
||
|
||
# Interactive, Qt-based GUI menu
|
||
make xconfig
|
||
|
||
# Line-by-line interactive prompts (every symbol, in order)
|
||
make config
|
||
|
||
# Re-prompt only for symbols that are new or changed since last time
|
||
make oldconfig
|
||
|
||
# Apply one of the example configs below non-interactively
|
||
make hosted_standard_defconfig
|
||
make -f Makefile.starkernel ARCH=amd64 kernel_amd64_defconfig
|
||
```
|
||
|
||
Four example configs ship in `configs/`: `hosted_standard_defconfig`,
|
||
`kernel_amd64_defconfig`, `kernel_aarch64_defconfig`,
|
||
`kernel_riscv64_defconfig`. Each just selects the architecture/variant
|
||
choice; every other symbol takes its Kconfig `default`.
|
||
|
||
Once a `.config` exists for an architecture, a plain `make` (or
|
||
`make -f Makefile.starkernel ARCH=...`) picks it up automatically — no
|
||
extra flag needed. Editing the `.config` by hand or re-running
|
||
`menuconfig` and rebuilding does **not** force recompilation of unrelated
|
||
object files (the same is true of today's bare `?=` knobs); run
|
||
`make clean` first if you want a config change to take full effect.
|
||
|
||
**Command-line always wins.** `make ROLLING_WINDOW_SIZE=8192` (or any
|
||
knob, or `MINIMAL=1` for platform mode) overrides whatever the
|
||
active `.config` says, whether or not Kconfig is in use at all. This is
|
||
true for every symbol below without exception.
|
||
|
||
### Symbol reference
|
||
|
||
#### Architecture & build variant (`Kconfig.arch`, `Kconfig.variant`)
|
||
|
||
| Symbol | Type | Default | Effect |
|
||
|---|---|---|---|
|
||
| `ARCH` (choice: AMD64/AARCH64/RISCV64) | choice | AMD64 | Selects the `ARCH=` value passed to whichever Makefile is driven from this config. |
|
||
| `STARFORTH_VARIANT` (choice: HOSTED/KERNEL) | choice | HOSTED | Which Makefile this config targets. Gates the choices below — a kernel-variant config never offers `TARGET`/`PLATFORM`, and `Kconfig.kernel`'s symbols only exist for a kernel-variant config. |
|
||
| `TARGET` (choice: standard/fast/fastest/turbo/pgo/asan) — hosted only | choice | standard | Hosted `TARGET=` build profile: optimization level, LTO, direct threading, ASan/UBSan instrumentation. `pgo` only selects which multi-stage `make` recipe runs, not a flag set. |
|
||
| `PLATFORM` (choice: default/minimal) — hosted only | choice | default | `minimal` swaps in freestanding platform sources (`-nostdlib -ffreestanding`, no libc dependency surface). HISTORICAL: a third mode, `l4re` (L4Re/Fiasco.OC, `-D__l4__=1`, forced `HEARTBEAT_THREAD_ENABLED` off), existed here through mid-2026; removed as an active target. |
|
||
|
||
#### Physics / SSM engine tuning (`Kconfig.physics`)
|
||
|
||
| Symbol | Type | Default | Effect |
|
||
|---|---|---|---|
|
||
| `STRICT_PTR` | bool | y | VM memory bounds checking on every pointer access. Disable only for raw benchmarking comparisons. |
|
||
| `ENABLE_HOTWORDS_CACHE` | bool | n | Physics-driven hot-words cache — 1.78× speedup on dictionary lookups when on. Also gates L8 Jacquard's `L1_heat_tracking` bit. |
|
||
| `ENABLE_PIPELINING` | bool | n | Speculative execution via word-transition prediction. Also gates L8 Jacquard's `L4_pipelining` bit, and gates every symbol below down to `MINIMUM_PREFETCH_ROI`. |
|
||
| `TRANSITION_WINDOW_SIZE` | int | 8 | Word-transition lookahead depth for pipelining prediction. Range 1–8. |
|
||
| `SPECULATION_THRESHOLD_Q48` | hex (Q48.16) | 0x8000 (0.50) | Minimum transition probability before pipelining will speculate on a word. Range 0.10 (aggressive) to 0.95 (conservative). |
|
||
| `SPECULATION_DEPTH` | int | 1 | How many words ahead to prefetch speculatively. Range 1–4. |
|
||
| `MIN_SAMPLES_FOR_SPECULATION` | int | 10 | Transitions observed before pipelining makes a speculation decision for a word. |
|
||
| `MISPREDICTION_COST_Q48` | hex (Q48.16) | 0x190000 (25 ns) | Estimated cost of recovering from a wrong speculation. |
|
||
| `MINIMUM_PREFETCH_ROI` | hex (Q48.16) | 0x1199A (1.10) | Minimum expected return-on-investment ratio for speculation to be worthwhile. (Corrected 2026-07-08 from a long-shipped `0x11999A`, which was ~17.6 in Q48.16 — an order of magnitude off from the documented 1.10 intent and effectively disabling speculation whenever pipelining was on.) |
|
||
| `ROLLING_WINDOW_SIZE` | int | 4096 | Initial execution-history capture size (rolling window of truth). Automatically shrinks at runtime if pattern diversity plateaus. |
|
||
| `ADAPTIVE_SHRINK_RATE` | int | 50 | Percentage of the rolling window retained when an adaptive shrink fires. Range 50–95; lower = more aggressive. |
|
||
| `ADAPTIVE_MIN_WINDOW_SIZE` | int | 256 | Floor — the rolling window never shrinks below this many word IDs. |
|
||
| `ADAPTIVE_CHECK_FREQUENCY` | int | 512 | How often (in executions) to measure pattern diversity for the shrink decision. |
|
||
| `ADAPTIVE_GROWTH_THRESHOLD` | int | 5 | Growth-rate percentage below which the window is considered saturated and a shrink is considered. |
|
||
| `INITIAL_DECAY_SLOPE_Q48` | int (Q48.16) | 21845 (≈0.333) | Cold-start seed for the adaptively-inferred heat-decay slope (Loop #6 retunes it at runtime; this only matters at boot). |
|
||
| `DECAY_MIN_INTERVAL` | int | 500 | Historical minimum-interval knob. No longer load-bearing since decay went tick-based (2026-07); kept only because `doe_metrics.c` still reports it. |
|
||
| `DECAY_RATE_PER_US_Q16` | int (Q16) | 1 | Heat decay rate. Half-life ≈6.5s at the default; 0 disables decay entirely. |
|
||
| `HEARTBEAT_INFERENCE_FREQUENCY` | int | 1000 | Heartbeat ticks between inference-engine runs (window-width + decay-slope re-inference). Set very high (e.g. 999999) to effectively disable inference for a static-configuration run. |
|
||
| `SSM_ENTROPY_HIGH_THRESHOLD` | string (float) | "0.75" | Rolling-window entropy above this votes to enable L8 Jacquard's Loop #2 (diversity). |
|
||
| `SSM_CV_HIGH_THRESHOLD` | string (float) | "0.15" | Short-term volatility above this votes to enable Loops #5/#6 (inference). |
|
||
| `SSM_TEMPORAL_DECAY_THRESHOLD` | string (float) | "0.5" | Temporal-locality strength above this votes to enable Loop #3 (decay). |
|
||
| `SSM_TEMPORAL_DECAY_LOW_THRESHOLD` | string (float) | "0.3" | Lower temporal-locality bound that, combined with a high-CV vote, also enables Loop #6. |
|
||
| `SSM_HYSTERESIS_TICKS` | int | 5 | Consecutive ticks required before an L8 mode change actually commits (prevents thrashing). |
|
||
|
||
#### Heartbeat / adaptive tick coordinator (`Kconfig.heartbeat`)
|
||
|
||
| Symbol | Type | Default | Effect |
|
||
|---|---|---|---|
|
||
| `HEARTBEAT_THREAD_ENABLED` — hosted only | bool | y | `vm_tick()` runs in a dedicated background thread (optimal) vs. inline from the interpreter loop (legacy). Invisible/off for a kernel-variant config — LithosAnanke has no pthreads — and the kernel Makefile keeps an unconditional `-D...=0` override regardless, as a second, independent guarantee of the same fact. |
|
||
| `HEARTBEAT_TICK_NS` | int | 10000 | Background heartbeat thread wake period, nanoseconds. Only meaningful when `HEARTBEAT_THREAD_ENABLED` is on. |
|
||
| `HEARTBEAT_CHECK_FREQUENCY` | int | 256 | Word executions between heartbeat checks — the counter that makes `vm->heartbeat.tick_count` a purely execution-driven virtual clock, which is also what Loop #3 heat decay reads (kept architecture-invariant on purpose). |
|
||
| `HEARTBEAT_WINDOW_TUNING_FREQUENCY` | int | 1000 | Heartbeat ticks between Loop #5 (window-width inference) runs. |
|
||
| `HEARTBEAT_SLOPE_VALIDATION_FREQUENCY` | int | 5000 | Heartbeat ticks between Loop #6 (decay-slope inference) revalidation runs. |
|
||
| `EMERGENCY_CONSOLE_ENABLED` | bool | y | REPL recovers from errors and continues (interactive fallthrough), vs. exiting to `vm_fault_handler()`. Set `n` for production/embedded/high-security builds with no interactive fallthrough surface. Applies to both builds; on the kernel side this only bypasses the bare `ok>` REPL — `zuse` sessions are always subject to ACL regardless. |
|
||
|
||
#### Kernel-only options (`Kconfig.kernel`) — kernel variant only
|
||
|
||
| Symbol | Type | Default | Effect |
|
||
|---|---|---|---|
|
||
| `STARFORTH_ENABLE_VM` | bool | y | Compiles the full StarForth VM source tree into the kernel image and enables capsule birth/execution (M7 milestone). Off builds a kernel that only reaches M0–M6 (console, PMM, VMM, interrupts, timers, kmalloc) — no interpreter, no capsules, no `ok>` REPL. |
|
||
| `PARITY_MODE` | bool | n | Enables the parity/determinism verification harness used to compare `dict_hash`/capsule state across independent runs. |
|
||
| `SK_PARITY_DEBUG` | bool | n | Extra diagnostic logging in the parity/vocabulary code paths. |
|
||
| `HEARTBEAT_DOE_LOG` | bool | y | Per-heartbeat-tick DoE observation logging. The bare-metal DoE tooling (`experiments/bare_metal/`) expects this on. |
|
||
|
||
**Out of scope for Kconfig, by design:** `compudynamics.h`'s `CDTuning`
|
||
values (C function return values, not macros); runtime-only parameters
|
||
like `PROFILE`, `DOE_INJECT`/`DOE_REPS`/`DOE_SEED`, `KERNEL_ARGS` (these
|
||
govern a specific run, not a compiled configuration).
|
||
|
||
## CI/CD Considerations
|
||
|
||
### GitHub Actions / GitLab CI
|
||
|
||
For CI/CD pipelines, you'll need to install Isabelle as part of the build process:
|
||
|
||
#### GitHub Actions Example
|
||
|
||
```yaml
|
||
name: Build & Verify
|
||
|
||
on: [push, pull_request]
|
||
|
||
jobs:
|
||
build:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v3
|
||
|
||
- name: Install build dependencies
|
||
run: |
|
||
sudo apt-get update
|
||
sudo apt-get install -y build-essential gcc make
|
||
|
||
- name: Install Isabelle
|
||
run: |
|
||
wget -q https://isabelle.in.tum.de/dist/Isabelle2025_linux.tar.gz
|
||
tar -xzf Isabelle2025_linux.tar.gz
|
||
echo "$GITHUB_WORKSPACE/Isabelle2025/bin" >> $GITHUB_PATH
|
||
|
||
- name: Verify Isabelle installation
|
||
run: isabelle version
|
||
|
||
- name: Build StarForth
|
||
run: make fastest
|
||
|
||
- name: Run tests
|
||
run: make test
|
||
|
||
- name: Build formal verification docs
|
||
run: make docs-isabelle
|
||
|
||
- name: Upload documentation artifacts
|
||
uses: actions/upload-artifact@v3
|
||
with:
|
||
name: isabelle-docs
|
||
path: docs/src/isabelle/
|
||
```
|
||
|
||
#### GitLab CI Example
|
||
|
||
```yaml
|
||
variables:
|
||
ISABELLE_VERSION: "2025"
|
||
ISABELLE_URL: "https://isabelle.in.tum.de/dist/Isabelle2025_linux.tar.gz"
|
||
|
||
before_script:
|
||
- apt-get update -qq
|
||
- apt-get install -y -qq build-essential gcc make wget
|
||
- wget -q $ISABELLE_URL
|
||
- tar -xzf Isabelle2025_linux.tar.gz
|
||
- export PATH="$PATH:$PWD/Isabelle2025/bin"
|
||
- isabelle version
|
||
|
||
build:
|
||
stage: build
|
||
script:
|
||
- make fastest
|
||
- make test
|
||
|
||
docs:
|
||
stage: deploy
|
||
script:
|
||
- make docs-isabelle
|
||
artifacts:
|
||
paths:
|
||
- docs/src/isabelle/
|
||
```
|
||
|
||
### Docker Considerations
|
||
|
||
If building in Docker, Isabelle requires **Java** (JDK 17+):
|
||
|
||
```dockerfile
|
||
FROM ubuntu:22.04
|
||
|
||
# Install build tools
|
||
RUN apt-get update && apt-get install -y \
|
||
build-essential \
|
||
gcc \
|
||
make \
|
||
wget \
|
||
openjdk-17-jdk \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
# Install Isabelle
|
||
RUN wget -q https://isabelle.in.tum.de/dist/Isabelle2025_linux.tar.gz && \
|
||
tar -xzf Isabelle2025_linux.tar.gz && \
|
||
rm Isabelle2025_linux.tar.gz
|
||
|
||
ENV PATH="/Isabelle2025/bin:${PATH}"
|
||
|
||
# Verify
|
||
RUN isabelle version
|
||
```
|
||
|
||
### CI/CD Performance Notes
|
||
|
||
- **Isabelle build takes 5-10 minutes** for all theory verification
|
||
- Consider **caching Isabelle installation** between builds
|
||
- Use `isabelle-check` for quick syntax checking in pre-commit hooks
|
||
- Only run full `isabelle-build` on main branch or release tags
|
||
|
||
#### GitHub Actions Caching Example
|
||
|
||
```yaml
|
||
- name: Cache Isabelle
|
||
uses: actions/cache@v3
|
||
with:
|
||
path: Isabelle2025
|
||
key: isabelle-2025-${{ runner.os }}
|
||
|
||
- name: Install Isabelle (if not cached)
|
||
if: steps.cache-isabelle.outputs.cache-hit != 'true'
|
||
run: |
|
||
wget -q https://isabelle.in.tum.de/dist/Isabelle2025_linux.tar.gz
|
||
tar -xzf Isabelle2025_linux.tar.gz
|
||
```
|
||
|
||
## Quick Start
|
||
|
||
```bash
|
||
# Clone the repository
|
||
git clone <repo-url>
|
||
cd StarForth
|
||
|
||
# Install dependencies (including Isabelle - see above)
|
||
# ...
|
||
|
||
# Build the fastest version
|
||
make fastest
|
||
|
||
# Run tests
|
||
make test
|
||
|
||
# Generate documentation (requires Isabelle)
|
||
make docs-isabelle
|
||
|
||
# View generated docs
|
||
ls -la docs/src/isabelle/
|
||
```
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
StarForth/
|
||
├── src/ # C source code
|
||
├── include/ # Header files
|
||
├── docs/
|
||
│ ├── src/
|
||
│ │ ├── internal/formal/ # Isabelle theory files
|
||
│ │ └── isabelle/ # Generated Isabelle docs (gitignored)
|
||
│ └── DEVELOPER.md # This file
|
||
├── scripts/
|
||
│ └── isabelle-to-adoc.sh # Isabelle doc generator
|
||
├── build/ # Build artifacts (gitignored)
|
||
├── tools/
|
||
│ └── Isabelle2025/ # Local Isabelle (gitignored)
|
||
└── Makefile # Build system
|
||
```
|
||
|
||
## Formal Verification
|
||
|
||
StarForth includes machine-checked correctness proofs using **Isabelle/HOL**:
|
||
|
||
- **Location**: `docs/src/internal/formal/*.thy`
|
||
- **Sessions**: `VM_Formal`, `Physics_Formal`
|
||
- **Generated docs**: `docs/src/isabelle/` (after `make docs-isabelle`)
|
||
|
||
### Theory Files
|
||
|
||
- `VM_Core.thy` - Core VM semantics
|
||
- `VM_Stacks.thy` - Stack operations
|
||
- `VM_StackRuntime.thy` - Runtime stack management
|
||
- `VM_Words.thy` - Word definitions
|
||
- `VM_DataStack_Words.thy` - Data stack operations
|
||
- `VM_ReturnStack_Words.thy` - Return stack operations
|
||
- `VM_Register.thy` - Register operations
|
||
- `Physics_StateMachine.thy` - Physics state machine
|
||
- `Physics_Observation.thy` - Observation model
|
||
|
||
All theories are **fully verified** with machine-checked proofs.
|
||
|
||
## Contributing
|
||
|
||
When contributing code that affects the VM semantics:
|
||
|
||
1. Update relevant Isabelle theories if needed
|
||
2. Run `make isabelle-build` to verify proofs
|
||
3. Run `make docs-isabelle` to regenerate documentation
|
||
4. Include Isabelle docs in your pull request
|
||
|
||
## Support
|
||
|
||
- **Issues**: GitHub Issues
|
||
- **Discussions**: GitHub Discussions
|
||
- **Isabelle Help**: https://isabelle.in.tum.de/
|
||
- **Formal Verification**: See `docs/src/isabelle/VERIFICATION_REPORT.adoc`
|
||
|
||
---
|
||
|
||
**Last Updated**: 2025-10-30
|
||
**Isabelle Version**: 2025
|
||
**Build System**: GNU Make |