Dead per task 0.1's reachability check (156d1642): zero references by
name anywhere in the tree outside its own definition -- process.4th's
own SPAWN/PAUSE/RESUME/KILL-VM calls passed bare numeric literals
(1/2/3/4), never this constant's name. Removed the single line only;
PAUSE-EVENT/RESUME-EVENT/KILL-EVENT are left in place, matching the
punchlist's stated scope -- they are equally dead-by-name but that
widening was flagged in 0.1's findings, not folded into this task.
mkcapsule --lint capsules/ clean, 37 files / 0 violations, unchanged
(one-line edit, no file added or removed). Three-arch boot clean:
amd64/aarch64/riscv64 all reach [zuse@Hera] ok>, zero UNKNOWN WORD.
dict_hash moved for Hermes/Artemis (both load messaging.4th) and is
identical across all three architectures; Hera's PARITY:M7.1a snapshot
unchanged as in the prior two strips.
Phase 0's three strips (0.2-0.4) are now all done. capsule-reserved.txt
and MANIFEST.md's stale block-4055/2049 entries remain for 0.5/0.6.
Authorized by Captain Bob ("Yes, please continue.").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
24 KiB
FABRIC-3.6.md — the Tripod/kernel reshuffle: execution log
START HERE — session handoff
If you have just been told "go build it", read this section, then
FABRIC-3.5.md's §XLI, then start at task 0.0 below. Do not re-derive the design — it is settled.Where the code is. This repo is LithosAnanke, on the Gitea instance at
gitea.strshipos.com, repoadmin/LithosAnanake— Captain Bob has the credentials. Confirm you are in the right repo before anything else.git remote -vmust showgitea.strshipos.com/admin/LithosAnanake. Nothing outside Gitea is this project. (The handoff was authored in a container whose default working directory was a different, empty repo on an unrelated remote — if you ever see that, you are in the wrong place.)masteris the sole production line. Work on branchclaude/starshipos-tripod-kernel-reshuffle-itbjns(a clean fast-forward ofmasterate56974e; documentation only — no reshuffle code has been written. The branch head is the source of truth; do not trust a commit id quoted here).The two documents.
FABRIC-3.5.mdis the design record and is authoritative — every ruling, with its reasoning and evidence, §I–§XLIII. This document is the execution log. Rulings are cited here, never restated. If a task proves a ruling wrong, record the finding here and amendFABRIC-3.5.md— never silently diverge.First action: task 0.0, the three-ISA baseline. It is a gate, not a formality — see its own rationale below. Nothing else starts until it is recorded.
Five traps this project's own history proves are real. A fresh session will walk into these:
- Silent failure is the dominant mode here.
FABRIC-3.5.md§XXXV.0 lists four independent instances. Most relevantly: "a switch storm and a healthy idle REPL produce an identical serial log." A green boot is weak evidence. Name the specific observation that proves a task worked, before running it.grepcannot establish capsule reachability. Capsules are birthed by name from runtime strings. A reference count overcapsules/andsrc/put the six liveinit-l8-*capsules at zero references; includingexperiments/found 18–19 each. §XXII.2. Use the three routes, never grep alone.fleet_conservedcannot see Stadium heat. The two heat accountings are entirely decoupled (§XXXIX). A leaking message allocator leavesfleet_conservedreporting a serene1. Stage B's evidence is the ledger plusstadium_conserved(), neverfleet_conserved.dict_hashchanging is expected;dict_hashdiverging across architectures is the stop condition. §XXXIV.6. Do not "fix" a changed hash.- Documentation in this repo drifts from the code — trust the code.
.claude/CLAUDE.mdcarried four stale claims; all four were corrected 2026-09-19 (§XLIV) and it is now reliable. Others are not:capsules/MANIFEST.mdstill describes block 4055 as a live "immutable ABI" thatFABRIC-2.md:2773declared stale, and still misdescribes block 2049.FABRIC-0.md§25.7 lists resolved defects as open. Where a document and the code disagree, the code wins — and record the drift rather than working around it.Blocked, and not to be worked around: Phase 3 needs three decisions from Captain Bob — B1 channels (one membership or negotiation), B2 the
SK_SWITCH_MAX_SLOTSceiling of 16, B4 the payload bound againstINPUT_BUFFER_SIZE1025. All design is complete; these are rulings, not investigations.Do not: create branches, stash, fix defects found in passing, bundle tasks into one commit, or start any task without explicit authorization. Captain Bob's Law,
.claude/CLAUDE.md.
Status: LIVING WORKING DOCUMENT, opened 2026-09-19. This is the execution record for
the reshuffle designed in FABRIC-3.5.md. Work is tracked, annotated and closed here.
Why this is a separate document, per the series' own rule. FABRIC-1.md closed at 4,420
lines for a stated reason: "continuing to append here made the still-open work hard to find."
FABRIC-3.5.md stands at 4,452 lines with 40+ open punch items scattered among hundreds of
settled rulings — it has crossed the same threshold, for the same reason. Annotating a task
list inside it, commit by commit, would bury the design record it exists to be.
The split of responsibility is strict, and stated because FABRIC-3.5.md §XXXI found that
documents in this series lose track of each other:
FABRIC-3.5.md |
FABRIC-3.6.md (this) |
|
|---|---|---|
| Holds | The design record — every ruling, its reasoning, its evidence | The work — tasks, results, dates, commits |
| State | Design phase closed; archival close at v2.1.0 (§XXVI.5) |
Living until the work is done |
| On a conflict | Authoritative | Defers, and records the discrepancy |
Design rulings are never restated here, only cited (§XXXIV.2, §XL.4, …). If a task needs
a rule explained, read FABRIC-3.5.md. If executing a task proves a ruling wrong, that is a
finding: record it here and amend FABRIC-3.5.md there — never silently diverge.
The checkbox convention is deliberate. FABRIC-3.5.md §XXXI.2 found the series'
carry-forward discipline was mechanically auditable (grep -c '\- \[ \]') up to FABRIC-2.md,
and broke at FABRIC-3.md, which uses no checkboxes at all — after which "is anything still
open?" stopped being a grep and became a reading exercise. This document restores the
convention, so that question stays answerable by machine.
Standing rules
Apply to every task, from .claude/CLAUDE.md and FABRIC-3.5.md §XXXIV:
- One task, one commit. No bundling.
- Acceptance is the three-architecture QEMU boot —
clean qemu, amd64/aarch64/riscv64, one at a time, in the foreground. Logs committed. There is no other acceptance test. dict_hashchanging is expected.dict_hashdiverging between architectures is a stop condition (§XXXIV.6).mkcapsule --lint capsules/clean after any capsule change.- No task starts without explicit authorization. Captain Bob's Law.
- Report, don't fix. A defect found while doing a task is recorded here, not repaired in passing.
Annotation convention
- [x] 0.2 — Strip common/msg.4th
2026-09-DD · commit abc1234 · 3-arch boot clean, lint 0 violations
note: <anything surprising; a finding gets its own entry below>
Mark [~] for started-not-finished, with what is outstanding. Never mark [x] on a task
whose check did not actually run — FABRIC-3.5.md §XXXV.6 records that declaring done too
early is this project's most repeated failure.
Pre-flight — establish the baseline before anything changes
Branch state at open (2026-09-19): claude/starshipos-tripod-kernel-reshuffle-itbjns, head
3a4e5cf, working tree clean, pushed, 33 commits ahead of master — all documentation, no
code. master is unmoved at e56974e, so the branch remains a clean fast-forward. Execution
starts from this commit.
- 0.0 — Three-ISA baseline smoke test on the unmodified branch.
make -f Makefile.starkernel ARCH=<arch> clean qemufor amd64, aarch64, riscv64 — one at a time, in the foreground, per.claude/CLAUDE.md. Check: all three reachzuse)ok>; zeroUNKNOWN WORD; logs committed underlogs/<timestamp>/<arch>/; record eachdict_hashand confirm the three are identical. 2026-09-19 ·logs/20260919-130023/amd64/,logs/20260919-130137/aarch64/,logs/20260919-130319/riscv64/— all three reach[zuse@Hera] ok>, zeroUNKNOWN WORD.dict_hashidentical across all three: Hera (PARITY:M7.1a)0x6824fe5993239838, Hermes0x062252c4da6858da, Artemis0xed80117724c26f36. note: first attempt confounded, see findings log —logs/20260919-124835/amd64/andlogs/20260919-124952/aarch64/(kept, not deleted) show Artemis'sdict_hashdiverging (0xed80117724c26f36vs0x93d6e815354b61c0) purely becausedisk/artemis.imgis shared across all three ISAs'qemutargets (FABRIC-3.md§XXXV.2) and the second run resumed the first run's already-formatted disk instead of formatting its own. Restoreddisk/artemis.imganddisk/thumbdrives/zuse-thumb-ident.imgto their committed blank state (git checkout --) before each of the three reruns above to remove the confound.
Why this is a gate and not a formality. Every task in this document takes the
three-architecture boot as its acceptance (§XXXIV). Without a known-good baseline captured
first, the first red boot is ambiguous — pre-existing fault or something task 0.2 just did?
This project has been bitten by exactly that ambiguity before (FABRIC-3.md §XXVI: "the
lockdown was never broken — wrong VM tested"). The baseline is what makes every later
acceptance run interpretable, and the recorded dict_hash triple is the reference every
subsequent §XXXIV.6 divergence check compares against.
Run it yourself — you are expected to. Captain Bob confirmed (2026-09-19) that execution
happens on his PC with the full toolchain installed, so the session reading this can and
should run task 0.0 directly, once authorized. Verify first that qemu-system-x86_64,
qemu-system-aarch64, qemu-system-riscv64, the aarch64/riscv64 cross-compilers and
OVMF/AAVMF are all present; if any are missing you are not on the intended machine — stop and
say so rather than improvising a partial test.
(Historical note: this document was authored in a container with none of that toolchain, which is why task 0.0 was written but never run. Do not take its unchecked state as a prior failure — it has simply not been attempted.)
Phase 0 — Preparation (no behaviour change)
Gate: all three architectures boot to zuse)ok>, stadium_conserved() true, no
UNKNOWN WORD.
-
0.1 — Establish Category A reachability by §XXII.2's three routes (boot path, tooling, baked capsule directory). Never by grep alone. Check: a written list naming the route that proves each entry dead. 2026-09-19 · investigation only, no code changed. Checked by all three routes — a boot-path trace of
init.4th/hera/hermes/init.4th/artemis/init.4thfor anyEXEC/S" name"load, an experiments/tools/docs invocation search, and confirming presence in the baked capsule directory doesn't by itself make a name reachable if nothing constructs it at runtime:| Candidate | Boot path | Tooling/experiments/docs | Verdict | |---|---|---|---| | `capsules/common/msg.4th` | zero `EXEC`/load sites in any boot-loaded capsule | zero invocations; its only two words `HERMES-ACK`/`HERMES-NACK` have zero callers anywhere; `messaging.4th` block 5033's own comment: "common:msg.4th's HERMES-ACK/NACK indirection is retired" | **DEAD** | | `capsules/process.4th` | zero `EXEC` sites anywhere | zero invocations; its four words `SPAWN`/`PAUSE`/`RESUME`/`KILL-VM` have zero callers outside the file itself | **DEAD** | | `SPAWN-EVENT` (constant, `messaging.4th`) | N/A — a constant, only ever defined, never read by name | zero invocations by name anywhere | **DEAD** | Both files are present in the baked capsule directory (`mkcapsule` build log: `[p] common:msg.4th`, `[p] process.4th`) — noted per §XXII.2 that presence alone proves nothing; it only means nothing constructs either name at runtime to reach them, which the other two routes confirm. finding: `EVENT-EMIT`/`EVENT-WAIT`/`EVENT-DRAIN` (`messaging.4th`, Category B, staying) have one caller beyond `process.4th` that §XXXIII.3 missed — `tools/hermes_smoke.sh` calls all three directly. This does not make them live: the script is already broken on its own terms, referencing `capsules/core/init.4th` and `build/amd64/standard/starforth`, neither of which exists in this repo, and calling the pre-rename `CD-INIT` word (`messaging.4th` block 5033 renamed it to `MSG-CD-INIT`) — it cannot currently execute. Task 0.3's plan stands unchanged; recorded because §XXXIII.3's "only other reference is `MANIFEST.md`" was itself an undercount of exactly the kind §XXII.2 warns about, even though the conclusion survives. finding: `PAUSE-EVENT`/`RESUME-EVENT`/`KILL-EVENT` (`messaging.4th`) are exactly as dead-by-name as `SPAWN-EVENT` — zero references anywhere outside their own definition; `process.4th`'s calls pass bare numeric literals (`1`/`2`/`3`/`4`), never the constant names. Task 0.4 only names `SPAWN-EVENT`; not expanding its scope here, but flagging that the other three meet the identical bar for whoever picks up Category A stripping next. -
0.2 — Strip
capsules/common/msg.4th. Check: 3-arch boot; lint clean. 2026-09-19 ·logs/20260919-131945/amd64/,logs/20260919-132054/aarch64/,logs/20260919-132226/riscv64/— all three reach[zuse@Hera] ok>, zeroUNKNOWN WORD.mkcapsule --lint capsules/clean, 38 files, 0 violations (was 39 before the strip).dict_hashunchanged from the task 0.0 baseline on all three (Hera0x6824fe5993239838, Hermes0x062252c4da6858da, Artemis0xed80117724c26f36) — expected, not a defect: task 0.1 confirmedmsg.4thwas neverEXEC'd into any VM's dictionary, so removing the dead file from the baked capsule directory doesn't move anything actually loaded.capsule-reserved.txtnot yet touched — block 4055's range is returned in task 0.6 per the punchlist's own ordering.MANIFEST.md's stale block-4055 entry not yet corrected — bundled into task 0.5 alongside block 2049's correction, per the punchlist. -
0.3 — Strip
capsules/process.4th(takesEVENT-EMIT/-WAIT/-DRAINwith it, §XXXIII.3). Check: 3-arch boot; lint clean. 2026-09-19 ·logs/20260919-132914/amd64/,logs/20260919-133024/aarch64/,logs/20260919-133156/riscv64/— all three reach[zuse@Hera] ok>, zeroUNKNOWN WORD.mkcapsule --lint capsules/clean, 37 files, 0 violations (was 38). Deletedcapsules/process.4thoutright andmessaging.4th's Block 5030 in full (EVENT-EMIT/EVENT-WAIT/EVENT-DRAIN— a self-contained block, nothing else in it).dict_hash: Hera'sPARITY:M7.1asnapshot unchanged (0x6824fe5993239838— it fires before any capsule loads, so capsule edits never move it); Hermes and Artemis both moved (0xa0f5c639a1228596,0x1650cb7153056160) since both loadmessaging.4th— identical across all three architectures, which is the actual property that matters (§XXII.4: every strip changesdict_hash, cross-arch identity is the invariant).capsule-reserved.txtstill untouched (task 0.6);MANIFEST.md's stale block-4055/2049 entries still untouched (task 0.5, now unblocked since both 0.2 and 0.3 are done). -
0.4 — Strip
SPAWN-EVENT. Check: 3-arch boot; lint clean. 2026-09-19 ·logs/20260919-133452/amd64/,logs/20260919-133559/aarch64/,logs/20260919-133731/riscv64/— all three reach[zuse@Hera] ok>, zeroUNKNOWN WORD.mkcapsule --lint capsules/clean, 37 files, 0 violations (unchanged — a one-line edit withinmessaging.4th, no file added or removed). Removed the single1 CONSTANT SPAWN-EVENTline only, per task 0.1's finding —PAUSE-EVENT/RESUME-EVENT/KILL-EVENTleft in place, matching the punchlist's stated scope.dict_hashmoved for Hermes/Artemis (0x52801b746e063ae9,0x6ad92fa3935918d4), identical across all three architectures; Hera'sPARITY:M7.1asnapshot unchanged as before.capsule-reserved.txtandMANIFEST.md's stale entries still untouched — Phase 0's strips (0.2–0.4) are now all done; 0.5 and 0.6 are next. -
0.5 — Correct
capsules/MANIFEST.mdblocks 4055 and 2049 as their files are stripped (§XXII.5). Check: manifest describes no file that no longer exists. -
0.6 — Return freed block ranges to
capsule-reserved.txt. Check: lint clean. -
0.7 — Add
stadium_conserved():Σ patron + reservoir + consumed == Q48_ONE, epsilon zero (§XL.4, item 41). Check: true on a clean boot, all three arches. -
0.8 — Audit that
PLOT/FB-WIDTH/FB-HEIGHTare registered nowhere but the table Hestia will own (item 33). Check: read-only; a second site is a defect to report.
Phase 1 — Hestia (messaging untouched)
Gate: Tripod is Hera/Artemis/Hestia plus Hermes; drawing works from Hestia and only Hestia; headless policy intact.
- 1.1 — Allocate Hestia's block range vs.
capsule-reserved.txt, avoiding 4997. Check: lint clean. - 1.2 — Create
capsules/hestia/init.4th: messaging load,MSG-CD-INIT, banner. No fabric yet. Check: boots; Hestia not yet birthed. - 1.3 — Add Hestia to
is_fleet_foundation(capsule_birth.c:793-796) — four names, Hermes retained (§XXXIV.4). Check: 3-arch boot; Hermes still live. - 1.4 — Birth Hestia in
kernel_main.c, alongside Hermes's existing birth. Check: registry shows both;dict_hashidentical across arches. - 1.5 — Register Hestia for switch signals (the
:1007pattern). Check: boot clean; no switch storm (§XXVIII.2's shape — and note it is invisible by default, §XXXV.0). - 1.6 — Move
fabric.4thfrominit.4thtohestia/init.4th. Check: Hera's dict shrinks, Hestia's grows; cross-arch identity holds. - 1.7 — Move
font.4thlikewise. Check: same. - 1.8 — Move
PLOT/FB-WIDTH/FB-HEIGHTregistration to Hestia's table only. Check: positively verify a non-Hestia VM callingPLOTgetsUNKNOWN WORD. - 1.9 — Assert §XVIII.6's headless invariant: Hestia's birth sets no
g_wirebind_attached_usernameand mints no proxy. Check: boot headless, no thumbdrive, no prompt appears.
Phase 2 — Allocator and audit (inert) — the real go/no-go
Gate: task 2.7. If it fails, stop and re-plan. Do not proceed to Phase 3.
- 2.1 — Kernel-Hermes message/membership structures, wired to nothing, drawing no
heat. Check: boot byte-identical;
dict_hashunmoved. - 2.2 — Allocate: pull
Q.SLOTfrom the caller's reservoir; roll back on refusal. Check: N allocs against a known reservoir; refusal at the right count. - 2.3 — Release: return remaining heat via the eviction path. Check: reservoir restored exactly for an undecayed message.
- 2.4 — The four counters:
held,pulled,returned,consumed(§XL.4). Check: each increments at exactly one site. - 2.5 — Decay: apply, and record the delta into
consumed(§XXXVII.3). Check:consumedgrows by exactlyheat_before − heat_after. - 2.6 — Self-audit:
held == pulled − returned − consumed, epsilon zero. Check: holds across the cycle; deliberately corrupt a counter → audit fires on the first unit. - 2.7 — Stage B proof (§XXXIV.3 as corrected by §XXXIX.4): alloc/free cycle
verifying (a) the ledger and (b)
stadium_conserved()before and after. Check: both true, all three arches.fleet_conservedis not evidence here — it cannot see Stadium heat (§XXXIX.1). - 2.8 — Scan-based cross-check of the counters, diagnostics only, off the hot path (§XXXVII.4). Check: scan agrees with counters.
Phase 3 — Cutover — BLOCKED
Not buildable until all three clear. Shape once unblocked (§XXXIV.3): cut over
BLK-ATTACH-EVENT alone, then remaining types one at a time, under §XXXIV.2's partition rule —
one message type owned by exactly one layer, no message shared.
- B1 — Item 27: channels — negotiation, or one broadcast membership? (§XXXIII.5 recommends the latter; unruled.)
- B2 — Item 32:
SK_SWITCH_MAX_SLOTSis 16 and §XXXII made the switcher the sole mover of control. Constant bump or table redesign? - B3 — CLEARED 2026-09-19 by
FABRIC-3.5.md§XLIII: the target drains its own queue at its own outermost interpret checkpoint; kernel-Hermes publishes and never dispatches. Reusessk_vm_at_outermost_interpret()and the Stage 3 checkpoint. - B4 — Item 44: payload bound or chunking against
INPUT_BUFFER_SIZE1025 (§XLIII.6.1). Decide before Phase 3.
Phase 4 — Category B strip
Only after every live type is cut over. Hermes leaves is_fleet_foundation and
kernel_main.c here, not earlier (§XXXIV.4).
- 4.1 — Strip
capsules/hermes/init.4th. - 4.2 — Strip the FORTH routing table and slot-3 pairing convention.
- 4.3 — Strip
capsules/common/messaging.4th. - 4.4 — Remove Hermes from
is_fleet_foundationand its birth fromkernel_main.c.
Phase 5 — Close-out
- 5.1 — Isabelle/HOL pass. Deliverable is the restated boundary, explicitly including §XXV.4's coverage loss — not a green build (§XXV.3).
- [~] 5.2 — Documentation sweep, grepping by exclusion (§XXVIII.3).
CLAUDE.md's four errors: DONE 2026-09-19 (§XLIV), pointer to this document added.
Outstanding:
MANIFEST.md(rides the strip, §XXII.5), theTRIPOD.md/0.1 contradiction, item 42's K-qualification, the superseded subsystem docs' update-or-archive call, and item 45 (experiments/bare_metal/README.mdblock framing). - 5.3 —
make sbom; checkCreated:andDocumentName(§XXVI.2). - 5.4 —
LITHOS_VERSION = 2.1.0; engineVERSIONper §XXX.6's rule; roadmap table gains its2.1.0line in two live places (§XXVIII.2). - 5.5 — Resolve the stray
refs/heads/v2.0.1and PR #1 (§XXVI.4). Investigate, do not delete. - 5.6 — Merge to
master; tagv2.1.0. - 5.7 — Archival close of
FABRIC-3.5.md(§XXVI.5) and of this document.
Findings log
Defects and surprises found while executing. Reported, not fixed (unless the task was to fix
them). A finding that contradicts a FABRIC-3.5.md ruling must also be amended there.
2026-09-19, task 0.0 — shared disk/artemis.img confounds cross-ISA dict_hash comparison
unless reset between runs. Not a code defect and does not contradict any FABRIC-3.5.md
ruling — FABRIC-3.md §XXXV.2 already documents that the disk is deliberately shared across all
three ISAs' qemu targets. But it means a same-order rerun of the three architectures will have
run 2 and 3 silently take Artemis's resuming branch instead of its blank disk -- formatting
branch, producing a different dict_hash for Artemis alone (Hera and Hermes are unaffected —
neither touches the artdisk at birth). Worth carrying forward: any task in this document that
checks dict_hash identity across architectures and involves Artemis should restore
disk/artemis.img and disk/thumbdrives/zuse-thumb-ident.img to their committed blank state
(git checkout --) before each architecture's run, or the check will fail on a confound rather
than a real divergence.
Out of scope, carried for visibility
Recorded in FABRIC-3.5.md, deliberately not part of this reshuffle. Listed so they are not
absorbed by accident:
- Item 43 — should a Stadium reservoir ever replenish? (§XL.6) A VM's send capacity declines monotonically today.
- Items 23–26 — the
FABRIC-3.5.md§XXXI gap-analysis follow-ups: re-homeFABRIC-2§17.4, consolidate the three reported-not-scheduled registries, decideFABRIC-2's five orphaned design items, reconcileFABRIC-0's seven opens. src/*.c.bak— tracked-but-stale, reported in three places and actioned in none (§XXII.5).