amd64/aarch64/riscv64 all boot clean to [zuse@Hera] ok>, zero UNKNOWN
WORD, and dict_hash identical across all three: Hera (PARITY:M7.1a)
0x6824fe5993239838, Hermes 0x062252c4da6858da, Artemis
0xed80117724c26f36. This is the gate task 0.0 exists for -- every later
task's acceptance in this document assumes this baseline is known-good.
Found and worked around a real confound along the way: disk/artemis.img
is deliberately shared across all three ISAs' qemu targets (FABRIC-3.md
SXXXV.2), so a same-order rerun has run 2 and 3 silently resume run 1's
already-formatted disk instead of formatting their own. The first
attempt (logs/20260919-124835 amd64, logs/20260919-124952 aarch64,
both kept for the record) shows exactly this: Artemis's dict_hash
diverges between the two runs even though Hera's and Hermes's do not,
because only Artemis's birth path branches on disk state. Restored
disk/artemis.img and disk/thumbdrives/zuse-thumb-ident.img to their
committed blank state before each of the three reruns that produced
the clean, matching baseline above, and recorded the finding in
FABRIC-3.6.md so a later task doesn't mistake the same confound for a
real architecture divergence.
capsules/BLOCK_MAP.md's timestamp header is regenerated by the build,
per .claude/CLAUDE.md's documented behavior for that generated file.
Authorized by Captain Bob ("begin", "clean new disk",
"document, commit, and push").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
18 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.
- 0.2 — Strip
capsules/common/msg.4th. Check: 3-arch boot; lint clean. - 0.3 — Strip
capsules/process.4th(takesEVENT-EMIT/-WAIT/-DRAINwith it, §XXXIII.3). Check: 3-arch boot; lint clean. - 0.4 — Strip
SPAWN-EVENT. Check: 3-arch boot; lint clean. - 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).