capsules/lib.4th:13-14 defined ": USE ( addr u -- ) EXEC ;" and the same for RUN, shadowing the C-registered mama_word_use()/RUN primitives (CLAUDE.md names both, with BIRTH, as untouchable C primitives) with an unrelated "load/exec a capsule" meaning. This broke the interactive USE-based VM-redirect (S" Artemis" USE printed "EXEC: failed: Artemis" instead of redirecting), discovered while chasing FABRIC-3.md's live-MIGRATE verification. Traced every real caller before touching anything: RUN's alias was dead code, never called anywhere as bare RUN. USE's alias had exactly one real caller -- capsules/hermes/init.4th:397, intentionally exploiting the shadow to load common:msg.4th right after lib.4th itself loaded. Both aliases were pure EXEC wrappers with zero added behavior, so this deletes both definitions outright and switches the one real call site (plus its matching doc comment in capsules/common/msg.4th) to call EXEC directly. No new names invented, the C primitives untouched. Verified live: Hermes still births and her COMMON-CH-eviction self-test (depends on common:msg.4th having loaded) still passes; interactively, S" Artemis" USE now correctly redirects the REPL and prints "USE: now using Artemis". mkcapsule --lint clean (31/31). Clean compile and clean boot with Stadium conservation intact (resident_sum + reservoir == Q48_ONE) on all three architectures. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXjAPTEKrgY2Mrk25KoLDn
433 lines
28 KiB
Markdown
433 lines
28 KiB
Markdown
# FABRIC-3.md — the Stadium, continued again
|
||
|
||
**Status:** Living working document, opened 2026-08-25 as the successor to `FABRIC-2.md`
|
||
(now closed/archival — see its own header). This document does not repeat `FABRIC-2.md`'s
|
||
design argument or history; it restates only outcomes, with pointers back to the section
|
||
that derived them. Read `FABRIC.md` for the original "why," `FABRIC-2.md` for everything
|
||
derived through 2026-08-25, this document for what's left as of that date onward.
|
||
|
||
**Provenance.** Everything in Section A below is a full, non-sampled carry-forward of every
|
||
open (`- [ ]`) item in `FABRIC-2.md` as of 2026-08-25 — 51 items, confirmed by
|
||
`grep -c '^- \[ \]' FABRIC-2.md`, none dropped (Section A itself holds 49: the other 2,
|
||
`FABRIC-2.md` §F.3's own two checkbox lines, were pure summaries cross-referencing items
|
||
already listed individually elsewhere — 4.4s/1.11/4.3/§17.4 and 5.1/ACL-RWT re-measurement,
|
||
both of which are carried forward as their own individual items above — not distinct content,
|
||
confirmed by diffing item text programmatically before writing this document, not assumed).
|
||
Extracted mechanically (a script pulling each checkbox item's own text, stopping at the first
|
||
blank line rather than the next checkbox, to avoid pulling in unrelated already-resolved
|
||
narrative that happened to sit between two open items in the source document) and spot-checked
|
||
against the original. Item numbers/labels are
|
||
carried forward unchanged, for traceability — this is not a renumbering or a re-prioritization.
|
||
Section groupings match `FABRIC-2.md`'s own (documentation debt, xHCI WRITE(10), Milestone
|
||
3–9 punch lists, etc.) — items are relocated, not reorganized.
|
||
|
||
**How to use this document going forward.** New findings, new punch-list items, and new
|
||
decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABRIC-2.md`
|
||
§(intro) established for how work gets picked up, closed, and recorded.
|
||
|
||
---
|
||
|
||
## A. Carried forward from FABRIC-2.md (51 items, all still open as of 2026-08-25)
|
||
|
||
### From FABRIC-2.md §A — Blocked or scoped, not started
|
||
|
||
- [ ] **1.11 — Dirty-event granularity.** Leaning region-based. Blocked on item 4.3 — settled
|
||
as part of the console migration, not speculatively before it. *Refs (FABRIC.md):* §17.5,
|
||
§23.2, §23.4 #1.
|
||
|
||
- [ ] **4.3 — Console.** Umbrella item; settles 1.11 as part of the work. Nearly everything
|
||
under it (4.3.1–4.3.7f, 4.4–4.4ac) is done — the parent stays open only because 4.4s below
|
||
is still blocked and nothing has formally closed the umbrella. *Refs (FABRIC.md):* §17.5,
|
||
§27.
|
||
|
||
- [ ] **4.4s — `(user)` prompt segment.** Scoped, blocked, not started. Extends 4.4's prompt
|
||
format. *Refs (FABRIC.md):* §27.8, 4.4.
|
||
|
||
- [ ] **5.1 — Re-run the DoE on the new substrate.** A green POST suite is not evidence that
|
||
determinism holds under the Stadium migration — needs its own campaign. Not started.
|
||
|
||
### From FABRIC-2.md §D — Design questions still genuinely open
|
||
|
||
- [ ] **§17.4 — the framebuffer utility's internal heat/decay dynamics are undesigned.**
|
||
Explicitly "Open, deferred": not a Stadium patron, but what physics (if any) governs it
|
||
internally was never designed. Not blocking anything. Blocked on item 1.11 specifically
|
||
(dirty-event granularity), not "the framebuffer work" in general — see `FABRIC-2.md` §D's
|
||
own 2026-08-13 refinement of this item before assuming it's ripe.
|
||
|
||
### From FABRIC-2.md §E — Documentation debt
|
||
|
||
- [ ] **ACL-RWT DoE overhead re-measurement.** The measured overhead numbers in
|
||
`.claude/CLAUDE.md` ("+0.0054%–+0.0088%") were all captured at `-O0`, before item 4.5
|
||
enabled real compiler optimization. Nobody has re-measured, or even confirmed the old and
|
||
new numbers are comparable at all. Flagged in passing during item 4.5f, never formally
|
||
scoped. **Ruled 2026-08-19 (`FABRIC-2.md` §F.3): wait for Artemis to land before
|
||
re-running** — Artemis has since landed; this is now unblocked but still not started.
|
||
|
||
### From FABRIC-2.md §J — Maintainability sweep (2026-08-18)
|
||
|
||
- [ ] `docs/lithosananke/ROADMAP.md` and `M7.1.md` — stale `Branch: lithosananke` (no such
|
||
branch exists post-split), `M7.1.md`'s "Status: Design Complete" (shipped and live, not
|
||
just designed), `ROADMAP.md`'s self-contradiction (M8 marked OBSOLETE in one place, still
|
||
a live success criterion in another), and its stale "AHCI driver" claim for M9 (real
|
||
implementation is `virtio_blk.c`) — not fixed, flagged.
|
||
|
||
- [ ] Top-level `ROADMAP.md` (StarForth-era, "Phase 0 Complete... Phase 1 Starting," dated
|
||
2025-12-14) — badly stale, no historical/superseded banner to warn a reader. Not fixed.
|
||
|
||
- [ ] `docs/03-architecture/word-acl/DESIGN.md` says ACL Phase 7 (LithosAnanke kernel parity)
|
||
is still "remaining" — direct contradiction with `.claude/CLAUDE.md`, which states Phase 7
|
||
is independently verified complete. Not fixed.
|
||
|
||
- [ ] `VM-FLEET-ATTRACTOR-DESIGN-20260705.md` claims `doe-campaign.4th` is "broken and being
|
||
superseded" — unverified against repeated successful `L8-DOE` runs (a different FORTH entry
|
||
point; not confirmed either way).
|
||
|
||
- [ ] Isabelle/HOL: the pipeline-metrics model/C-struct mismatch this sweep surfaced —
|
||
flagged in the `.thy` file itself, not independently tracked elsewhere, not fixed.
|
||
|
||
### From FABRIC-2.md §X, Milestone 2 — USB hardware stack
|
||
|
||
- [ ] Decide and implement where the hotplug event surfaces to the rest of the kernel —
|
||
likely a callback registered by whatever owns the home-blocks logic, not xHCI code calling
|
||
into `block_subsystem.c` directly (matching the existing "kernel/Artemis decoupling
|
||
boundary" pattern already documented in `block_subsystem.c`). **Partially addressed by
|
||
Milestone 2h's `blkio_usb.c`/connect-time attach wiring (`FABRIC-2.md`, 2026-08-25) — worth
|
||
re-checking whether that closes this item outright before treating it as still fully open.**
|
||
|
||
- [ ] Implement CBW/data/CSW for SCSI WRITE(10) — this is where the earlier "read/write,
|
||
unquestionable" requirement actually gets satisfied. Still the single biggest functional
|
||
gap in the xHCI driver — blocks writing to a real USB thumb drive at all (`blkio_usb.c` is
|
||
read-only today specifically because of this).
|
||
|
||
- [ ] Implement basic error/stall recovery (CSW failure status, endpoint stall clear) — at
|
||
minimum enough to not wedge the controller on a single bad transfer.
|
||
|
||
### From FABRIC-2.md §X, Milestone 3 — Block subsystem extensions
|
||
|
||
- [ ] Implement the CA-signed-cert verification path (Milestone 6 dependency — the cert chain
|
||
validator doesn't exist yet either).
|
||
|
||
- [ ] Implement the first-touch allocation function: given a verified identity pubkey and a
|
||
requested block count, either read an existing range from the drive's map or claim a new
|
||
one at `g.total_user_lbn` and write it back. *(Single-block relocation itself — the
|
||
mechanism this would allocate ranges for — is done: `blk_subsys_relocate_block()`/
|
||
`RELOCATE-BLOCK`, `FABRIC-2.md`, commit `36d832f`. This item is about the identity→range
|
||
allocation that decides what to relocate blocks* into*, still unbuilt.)*
|
||
|
||
- [ ] Design the on-drive block-map format (Section U item 4) — what it records (block ranges
|
||
claimed? individual block liveness? something else), how it's serialized.
|
||
|
||
- [ ] Implement writing the block-map to a drive.
|
||
|
||
- [ ] Implement reading/validating the block-map from a drive on insertion.
|
||
|
||
- [ ] Design the migration state machine (Section U item 5) — states, transition triggers.
|
||
Session direction, 2026-08-25: **ACL manages *when* to relocate** (capacity pressure, or a
|
||
compudynamics heat/cold signal); migration itself is expected to be rare, not routine. The
|
||
`physics_hotwords_cache.c`-reuse question is settled differently than originally framed —
|
||
see this document's new §B below (Stadium unification), which reframes block/word placement
|
||
as a `compudynamics.c`-driven decision generically, not a `physics_hotwords_cache.c`
|
||
(`DictEntry*`-hardcoded) reuse question specifically.
|
||
|
||
- [ ] Decide and implement unclean-removal handling (Section U's explicitly flagged open
|
||
question — never answered) — at minimum, detect a mid-flush disconnect via Milestone 2e's
|
||
disconnect signal and decide what state that leaves affected blocks in.
|
||
|
||
### From FABRIC-2.md §X, Milestone 4 — Drive/credential security
|
||
|
||
- [ ] Design the home-blocks drive signature format (Section U item 7) — reusing
|
||
`CAPSULE_MAGIC_PACK`'s pattern (magic + version in a fixed header field) as the confirmed
|
||
precedent, applied to a drive's reserved header block instead of a capsule.
|
||
|
||
- [ ] Implement the signature check, called before any write path touches a newly-inserted
|
||
drive.
|
||
|
||
- [ ] Implement the warn-and-refuse behavior for blank/foreign/unrecognized media.
|
||
|
||
- [ ] Extend `acl_pinned`'s one-way-ratchet mechanism (already exists, already proven, just
|
||
needs applying) to gate zuse credential minting specifically — confirm whether this
|
||
literally reuses the existing `acl_pinned` bit on some relevant `DictEntry`, or needs its
|
||
own analogous one-way flag on the credential data itself (the credential isn't a dictionary
|
||
word, so the existing bit may not directly apply — open question, not yet resolved).
|
||
|
||
### From FABRIC-2.md §X, Milestone 5 — Console/VM key-match binding
|
||
|
||
- [ ] Settle the still-open question: reuse `ACL-PIN`/`acl_allow` directly, or build a
|
||
separate key-matching primitive — `ACL-PIN` gates word execution specifically and nothing
|
||
today gates console-session-to-VM ownership, so this decision needs to happen before any
|
||
code gets written here.
|
||
|
||
- [ ] Design the key/lock data shape (what the console presents, what the VM carries, how
|
||
they're compared).
|
||
|
||
- [ ] Wire drive insertion (Milestone 2e's hotplug signal, post-identity-authentication) to a
|
||
call into `capsule_birth_baby()` (confirmed a real, callable, on-demand birth path already)
|
||
to spin up or re-attach that identity's VM.
|
||
|
||
- [ ] Implement the actual attach/bind step — extending `sk_repl_set_active_vm()` (confirmed
|
||
to exist, currently an unguarded raw pointer-set) with the key-match check from above, so a
|
||
console can only bind to the one VM whose lock matches its key.
|
||
|
||
- [ ] Implement detach behavior on console disconnect or VM teardown.
|
||
|
||
### From FABRIC-2.md §X, Milestone 6 — Kernel/capsule PKI signing chain
|
||
|
||
- [ ] Generate (offline, outside the kernel/repo entirely) the real root CA keypair — "stays
|
||
unrevocable," never embedded, never loaded by any kernel code.
|
||
|
||
- [ ] Generate the "snakeoil" intermediate certificate, signed by that real root CA (this is
|
||
a real CA-signed intermediate, not a self-signed/untrusted cert despite the name —
|
||
"snakeoil" names its informal/private-project status).
|
||
|
||
- [ ] Embed the already-CA-signed snakeoil intermediate as a capsule blob at build time
|
||
(mechanically proven already via the font-capsule precedent — no new embedding
|
||
infrastructure needed, just a new payload). **Bootstrapping resolved: no kernel-boot-time
|
||
verification of a hardcoded CA public key is needed at all** — trust is established once,
|
||
at build time, by whoever holds the real root CA and produces the build.
|
||
|
||
- [ ] Add a signing step to the `mkcapsule` build tool (or a separate signing tool) that
|
||
produces a signature alongside each capsule's existing xxHash64.
|
||
|
||
- [ ] Extend `MANIFEST_AUTO.md`'s generation to add a signature-status column, matching the
|
||
existing xxHash64 column's generation pattern.
|
||
|
||
- [ ] Implement magic-number-based content-type detection (Section U item 14) — a shared
|
||
primitive, also usable for Milestone 4's foreign-drive check.
|
||
|
||
### From FABRIC-2.md §X, Milestone 7 — Contributor capsules / trust tiers
|
||
|
||
- [ ] Create the `capsules/contrib/` directory (mechanically trivial, matches existing
|
||
subdirectory convention — the directory itself is not the work).
|
||
|
||
- [ ] Add a `FLAG_CONTRIB` bit to `mkcapsule.c`'s flag system, assigned by path match
|
||
(`contrib/` prefix), same pattern as how `init.4th` already gets `FLAG_MAMA_INIT`.
|
||
|
||
- [ ] Decide and implement one of the four spitballed trust-tier directions (signature-
|
||
authority tiers / block-namespace sandboxing / QEMU-vs-real-hardware conditional
|
||
enforcement) — none chosen yet, this is a real decision point, not just an implementation
|
||
task.
|
||
|
||
- [ ] If block-namespace sandboxing is chosen: extend `mkcapsule`'s existing conflict-
|
||
detection logic to also reject a `contrib/`-path capsule claiming blocks outside its
|
||
reserved range.
|
||
|
||
### From FABRIC-2.md §X, Milestone 8 — Bare-metal boot from physical USB
|
||
|
||
- [ ] Build a fresh `starkernel.iso` via `make -f Makefile.starkernel ARCH=amd64 clean` + the
|
||
ISO-build step.
|
||
- [ ] Identify the exact block device path for the target USB drive on the host doing the
|
||
flashing (`lsblk`/`dmesg` after insertion — care needed, wrong device = data loss).
|
||
- [ ] `dd if=build/amd64/kernel/starkernel.iso of=/dev/sdX bs=4M status=progress` (or
|
||
equivalent) — confirm `dd` is the right tool for an El Torito ISO vs. needing `isohybrid`
|
||
first (open question, not yet verified).
|
||
- [ ] Physically boot the real machine from the flashed drive (BIOS/UEFI boot-order menu,
|
||
Secure Boot may need disabling — unknown until tried).
|
||
- [ ] Capture what happens with no serial-socket log available (real hardware has no
|
||
`qemu-serial-*.sock` to `socat` into) — decide the observation method.
|
||
- [ ] Confirm POST reaches the same 1012/0/0 result on real hardware as every QEMU acceptance
|
||
run.
|
||
- [ ] Confirm `ok>` prompt is reachable and a basic command (e.g. `HEARTBEAT-TICKS@ .`) works
|
||
identically to QEMU.
|
||
- [ ] Document the result (pass/fail, and if fail, what diverged from QEMU) — first real
|
||
external validation this project has ever had outside QEMU TCG emulation.
|
||
|
||
### From FABRIC-2.md §X, Milestone 9 — Networking / capsule distribution server
|
||
|
||
- [ ] (Deferred) Revisit and punch-list this milestone once Milestone 7 closes, not before.
|
||
|
||
---
|
||
|
||
## B. Stadium unification — words/VMs/blocks/messages on the same engine
|
||
|
||
Raised 2026-08-25: "words are stadium patrons, VMs are patrons, blocks are patrons, messages
|
||
are stadium patrons, all should be operated on by THE SAME ENGINE." Investigated before
|
||
designing anything — the real state is more nuanced than "everything's a stub," verified via
|
||
direct reads and `git log`, not assumed:
|
||
|
||
**`FABRIC.md` §18.3 already decided the mapping** (not invented here): blocks → `MIGRATE`,
|
||
messages → `DELIVER`, ACLs → `EXPIRE`, words and VMs both → `COOL`. `stadium_evict()`
|
||
(`src/starkernel/vm/stadium.c`) — real, tested infrastructure: bitmap tracking, pin/`contains`
|
||
refusal, the Hera-patron-zero panic guard, heat-conservation back to the owner's reservoir on
|
||
every reap — calls `stadium_dispatch()` for the actual payload action when a patron departs.
|
||
|
||
**Per-behaviour status, as of 2026-08-25:**
|
||
|
||
- **`MIGRATE` (blocks)** — zero consumer, genuinely stub (`stadium_dispatch()`'s case prints
|
||
`"MIGRATE (stub)"` and returns). This session already built the real mechanical primitive
|
||
it needs: `blk_subsys_relocate_block()`/`RELOCATE-BLOCK` (`FABRIC-2.md`, commit `36d832f`),
|
||
live-verified (redirect + content survive an abrupt kill and reboot) but never wired to
|
||
`stadium_dispatch()` — it's a separate, parallel, already-working mechanism today, not
|
||
routed through Stadium at all.
|
||
- **`COOL` (words *and* VMs, same tag)** — half real. **Words are fully live**, but via a
|
||
*separate, bespoke* mechanism, `stadium_word_dispatch()` (`stadium_words.c`, item 4.1),
|
||
wired directly into the real VM word-execution hot path (`vm_core.c:690,885,896`) — it does
|
||
**not** go through the generic `stadium_dispatch()` switch at all. `ONTOLOGY.md` §IX
|
||
claiming words are "not yet migrated" is itself stale documentation drift (same class of
|
||
bug as the "glibc" misattribution corrected earlier this session — flagged as a small,
|
||
separate fix below, not blocking). **VM cooling has no evidence of ever being wired
|
||
anywhere** — still genuinely stub.
|
||
- **`DELIVER` (Hermes messages)** — `FABRIC.md` (~line 3452) records this explicitly as
|
||
"Open, surfaced not resolved": Hermes's message/channel heat already integrates with
|
||
Stadium's reservoir accounting (`STADIUM-HEAT@`, `STADIUM-RES-PULL/PUSH`), but which Hermes
|
||
lifecycle event maps to `DELIVER` vs. `EXPIRE` was never decided, let alone wired. Real,
|
||
substantial, Hermes-specific integration work.
|
||
- **`EXPIRE` (ACL TTL expiry)** — no evidence of any wiring anywhere; `ACL.4th`/
|
||
`acl_recheck()` has zero Stadium involvement today. Also substantial, separate work.
|
||
|
||
**Why `DELIVER`/`EXPIRE` aren't being resolved in the same pass as `MIGRATE`:** each is a
|
||
full subsystem integration (Hermes lifecycle mapping; ACL-to-Stadium wiring where none has
|
||
ever existed) in its own right — attempting all four stubs at once risks exactly the rushed,
|
||
shipped-but-incomplete outcome the no-stubs rule (below) exists to prevent. `MIGRATE` gets
|
||
resolved for real because this session already has a tested primitive underneath it; the
|
||
other three become honest, explicit punch-list items instead of being touched speculatively.
|
||
|
||
**Punch list:**
|
||
|
||
- [x] **Investigated (2026-08-25): block-patron admission does not exist yet, but is
|
||
architecturally straightforward, not blocked.** Confirmed via `stadium_admit()`'s own doc
|
||
(`stadium.h`) that it REFUSES any candidate with `mass != 1`, and that a `mass > 1`
|
||
multi-cell patron would need a continuation chain nothing has ever designed — this looked
|
||
at first like a hard blocker for a 1024-byte block. It isn't: confirmed via
|
||
`stadium_word_dispatch()`'s real candidate construction (`stadium_words.c:245-252`) that
|
||
Stadium cells carry pure identity/heat/bookkeeping only — `candidate.identity = word_id`,
|
||
`payload[32]` unused — the actual word content stays in the dictionary; Stadium never holds
|
||
it. By the same pattern, a block patron's cell would carry `identity = LBN`, `mass = 1`,
|
||
`payload` unused — the actual 1024 bytes of block content stays exactly where it already
|
||
lives (block cache / disk via `block_subsystem.c`), unmoved. So `mass != 1` is a non-issue;
|
||
the real gap is just that nothing has ever built the LBN→cell_index residency map (the
|
||
block-patron analogue of `stadium_word_dispatch()`'s `resolve_resident_cell()`) or the
|
||
touch-on-access hook (the analogue of `vm_core.c`'s three `stadium_word_dispatch()` call
|
||
sites). Not yet built — this is real, scoped, buildable work, not a stub-around candidate.
|
||
**Still open**, plan to be presented before implementation per the no-stubs/no-early-coding
|
||
conventions.
|
||
- [x] **Resolved (2026-08-25): real block-patron admission + real `MIGRATE` dispatch, both
|
||
live.** New `stadium_blocks.h`/`stadium_blocks.c` mirror `stadium_words.c`'s shape (Option B
|
||
starter-grant admission, redirected Loop #3 cooling, self-healing stale-entry detection) but
|
||
key residency by `(quota_slot, lbn)` in a fixed-capacity open-addressing hash table sized off
|
||
`stadium_cell_count()` (tombstone-based deletion, since LBN space isn't densely bounded like
|
||
`word_id`), not a dense array. Wired into `block_word_block()`/`block_word_buffer()`/
|
||
`block_word_update()` (`block_words.c`), `#ifdef __STARKERNEL__`-guarded. `stadium_dispatch()`'s
|
||
`MIGRATE` case now calls `blk_flush(lbn)` for real (confirmed `blk_flush()`, not
|
||
`blk_subsys_relocate_block()`, is the right primitive — the latter is for compudynamics-driven
|
||
relocation to a *different* LBN mid-residency, not ordinary reap write-back). Three new Kconfig
|
||
tuning constants (`STADIUM_BLOCK_HEAT_QUANTUM`/`STADIUM_BLOCK_COOL_RATE_Q48`/
|
||
`STADIUM_BLOCK_TRACK_CAP_MULT`) mirror the word-patron ones exactly, same three-layer wiring.
|
||
**Verified:** clean compile, zero warnings, on all three architectures; clean boot to
|
||
`zuse)ok>`/`ok>` REPL on all three, conservation (`resident_sum + reservoir == Q48_ONE`) intact
|
||
identically across all three; `BLOCK`/`BUFFER` touches exercised live from the REPL on amd64 and
|
||
riscv64 with no crash; a 22,000-distinct-block flood loop (amd64, artificially shrunk to a
|
||
20,971-cell Stadium via a one-off smaller `-m` to make quota pressure reachable) ran clean under
|
||
heavy admission-path load with no corruption. **Live `MIGRATE` fire confirmed (2026-08-26):**
|
||
interactive flooding alone never triggered it — Hera's reservoir was already sitting exactly at
|
||
the `Q48_ONE / 3` floor from the boot-time self-tests, so every block-touch candidate pulled 0
|
||
heat, and a 0-heat candidate can never be *strictly denser* than an existing resident, so
|
||
`stadium_admit()`'s eviction fallback correctly refuses rather than evicts once the free list is
|
||
exhausted (a pre-existing reservoir-floor/density-eviction interaction, applies equally to word
|
||
patrons, not introduced by this pass). Closed deterministically instead with a temporary boot
|
||
probe (`kernel_main.c`, inserted into the existing Artemis 4.6 self-test block, reverted
|
||
immediately after capture — no code left behind): `100 65536 0 STADIUM-ADMIT ... STADIUM-EVICT`
|
||
against the live Artemis VM. Captured live: `Stadium: dispatch cell=63257 behaviour=MIGRATE
|
||
lbn=100`, followed by `DBG err after MIGRATE probe=0` — `blk_flush(100)` fired for real, with
|
||
the correct LBN threaded through from the departing patron's `identity` field exactly as
|
||
designed. (Artemis's own reservoir went briefly out of Q48_ONE-balance during the probe — raw
|
||
`STADIUM-ADMIT` doesn't debit the reservoir on its own, by its own doc, so a heat value handed
|
||
to it directly is invented, not pulled; harmless here since Artemis is killed and her whole
|
||
economy discarded immediately after, and Hera's own conservation was independently confirmed
|
||
back at the normal 43691/21845/65536 baseline afterward.)
|
||
- [x] **Bug found, reported, then fixed on request (2026-08-25/26): `capsules/lib.4th:13-14`
|
||
shadowed the C primitives `USE`/`RUN`.** While chasing the live-MIGRATE test above,
|
||
`S" Artemis" USE` (meant to redirect the REPL into Artemis's own vocabulary,
|
||
`mama_word_use()`) instead printed `EXEC: failed: Artemis`. Root cause: `capsules/lib.4th:13`
|
||
defined `: USE ( addr u -- ) EXEC ;` — a FORTH word with the same name but a completely
|
||
different meaning ("load/exec a capsule"), which shadowed the C-registered `USE` in
|
||
dictionary search order since `lib.4th` loads after primitive registration. `lib.4th:14` did
|
||
the identical thing to `RUN`, which CLAUDE.md also names as an untouchable C primitive
|
||
("BIRTH, RUN, USE are primitives — registered in C exactly like DUP, BYE, EXEC"). Same bug
|
||
class as the K-PUSH dictionary-shadowing issue
|
||
(`docs/working/architecture/K-PUSH-DICTIONARY-SHADOWING-BUG-20260704.md`). Reported first
|
||
per CLAUDE.md's rule against unrequested fixes; Captain Bob then explicitly asked for the fix.
|
||
**Fix:** traced every real caller before touching anything — `RUN`'s alias was dead (never
|
||
called anywhere as bare `RUN`); `USE`'s alias had exactly one real caller,
|
||
`capsules/hermes/init.4th:397` (`S" common:msg.4th" USE`, intentionally exploiting the shadow
|
||
to load that capsule right after `lib.4th` itself loaded). Both aliases were pure
|
||
`EXEC` wrappers with zero added behavior, so the fix deleted both definitions from `lib.4th`
|
||
outright and changed the one real call site plus its matching doc comment
|
||
(`capsules/common/msg.4th:4`) to call `EXEC` directly — no new names invented, the C
|
||
primitives untouched, `mkcapsule --lint` clean (31/31 pass). **Verified live:** rebuilt and
|
||
booted amd64 — Hermes still births and her `COMMON-CH`-eviction self-test (which depends on
|
||
`common:msg.4th` having loaded) still passes exactly as before; interactively, `S" Artemis"
|
||
USE` now correctly prints `USE: now using Artemis` and switches the REPL's console-name
|
||
coloring, confirming the C primitive runs unshadowed. Clean compile and clean boot with
|
||
conservation intact on all three architectures (amd64/aarch64/riscv64).
|
||
- [ ] Scope VM-`COOL`: confirm whether `capsule_vm_kill()`/Tripod's existing VM lifecycle has
|
||
any real hook point equivalent to `stadium_evict()`, or needs the same kind of admission
|
||
work `MIGRATE` needs. **Deferred (2026-08-25)** per the user's own "we're going to have to
|
||
iterate" framing of the final Tripod/Zuse/messaging shape (see §D below) — building VM
|
||
eviction/cooling machinery ahead of that design risks throwaway or conflicting work. Resolve
|
||
only after that shape is nailed down, or if it turns out trivially small on its own.
|
||
- [ ] `DELIVER` (Hermes) — scope as its own future item once `MIGRATE`/VM-`COOL` land; do not
|
||
re-decide the `DELIVER`-vs-`EXPIRE` message/channel mapping here, `FABRIC.md`'s own note
|
||
already flags it as genuinely open, not casually assumable.
|
||
- [ ] `EXPIRE` (ACL) — scope as its own future item; ACL has never touched Stadium, this is
|
||
new integration work, not a wire-up of something partially built.
|
||
- [ ] Fix `ONTOLOGY.md` §IX's "words (dictionary, warehouse-resident today, not yet migrated)"
|
||
line — stale, words are fully migrated and live via `stadium_word_dispatch()`. Small,
|
||
independent doc fix, not blocking any of the above.
|
||
|
||
---
|
||
|
||
## C. Standing rule: no stubs or TODOs, ever
|
||
|
||
Stated directly, 2026-08-25, after the `stadium_dispatch()` stub investigation above:
|
||
**"I've never allowed stubs before."** Saved as a persistent memory
|
||
(`feedback_no_stubs_or_todos.md`) so this applies across sessions, not just this one. Full
|
||
statement: no stub function that prints a placeholder and returns, no `TODO`-and-move-on
|
||
comment in place of real logic, in any language, ever committed as if it were finished work.
|
||
Small, honest increments are still fine and encouraged — each increment just has to be a
|
||
complete, real implementation of whatever slice it covers, never a placeholder for a later
|
||
slice. A pre-existing stub found while working nearby (as here) gets flagged and resolved,
|
||
not built on top of or left in place.
|
||
|
||
---
|
||
|
||
## D. Tripod final shape — minting, one-time Zuse fuse, messaging-only (vision, not yet scoped)
|
||
|
||
Stated directly by Captain Bob, 2026-08-25: "we're going to have to iterate because I know
|
||
what the final shape of the tripod will be." Recorded here as a forward-looking vision, not
|
||
yet broken into implementable items — captured so near-term Stadium/VM work (§B above) is
|
||
made against the right end-state rather than in ignorance of it. Full detail also saved as
|
||
memory `project_tripod_final_shape_vision.md`.
|
||
|
||
- **Thumbdrive presentation → legality check → mint.** A newly presented thumbdrive is
|
||
checked for legality (against the CA-root-derived identity/certificate scheme already
|
||
decided earlier this session, `FABRIC-2.md`). If not legal, it is "minted" — formatted for
|
||
system use — which (1) spins a new user VM and (2) attaches the console VM to it.
|
||
- **One-time Zuse mint + fuse-blow on first install.** A brand-new system instance
|
||
("Install"/"Try It") mints exactly one Zuse superuser, then irreversibly "blows a fuse":
|
||
direct quote, "we mint one and only one Zuse user and blow a fuse. The only way around is a
|
||
new system." Post-fuse, no further Zuse can ever be minted on that instance — but the
|
||
system is NOT bricked: the existing Zuse superuser keeps working, and ordinary users can
|
||
still "thumb in" via regular thumbdrives.
|
||
- **Messaging-only once Tripod is fully live.** All inter-VM interaction becomes Hermes
|
||
messaging, not direct calls/shared state — a stated end-state, not the current
|
||
implementation.
|
||
- **Polymorphic block-boundary behavior for user VMs.** Stated in one sentence, not yet
|
||
elaborated: a user VM needs to behave polymorphically when crossing block boundaries.
|
||
Needs a dedicated follow-up conversation before this is actionable.
|
||
- **`ClaudeEXPORT/`** (repo root, new as of 2026-08-25) — a prior Claude data export the user
|
||
pointed at for "concepts and thoughts as guidelines" on this vision, explicitly flagged as
|
||
possibly containing superseded/conflicting ideas, not authoritative. `conversations.json` is
|
||
~66MB; mine selectively (grep or a subagent) rather than reading wholesale. See memory
|
||
`project_claude_export_archive.md`.
|
||
|
||
**Why this affects §B:** VM-`COOL` (and any inter-VM Stadium wiring) sits close to this
|
||
still-iterating design. Building it now risks conflicting with or being thrown away by the
|
||
Zuse/messaging shape once that gets its own pass — hence §B's punch list defers VM-`COOL`
|
||
explicitly rather than resolving it in this pass. Block-patron `MIGRATE` work does not
|
||
obviously depend on this vision and is not deferred for this reason.
|
||
|
||
**Next step:** no implementation here yet. When this gets its own design pass, start by
|
||
clarifying "polymorphic block-boundary behavior" and the exact legality-check mechanism
|
||
(presumably the CA-root certificate scheme), then scope minting as its own capsule-birth-style
|
||
protocol (mirroring the existing capsule birth writeup's rigor) before writing any code.
|