Files
LithosAnanake/FABRIC-3.6.md
T
Robert Allan JamesandClaude Sonnet 5 4544877a36 FABRIC-3.6.md task 0.0: three-ISA baseline smoke test, PASS
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>
2026-09-19 13:08:32 -04:00

18 KiB
Raw Blame History

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, repo admin/LithosAnanake — Captain Bob has the credentials. Confirm you are in the right repo before anything else. git remote -v must show gitea.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.) master is the sole production line. Work on branch claude/starshipos-tripod-kernel-reshuffle-itbjns (a clean fast-forward of master at e56974e; 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.md is 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 amend FABRIC-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:

  1. 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.
  2. grep cannot establish capsule reachability. Capsules are birthed by name from runtime strings. A reference count over capsules/ and src/ put the six live init-l8-* capsules at zero references; including experiments/ found 18–19 each. §XXII.2. Use the three routes, never grep alone.
  3. fleet_conserved cannot see Stadium heat. The two heat accountings are entirely decoupled (§XXXIX). A leaking message allocator leaves fleet_conserved reporting a serene 1. Stage B's evidence is the ledger plus stadium_conserved(), never fleet_conserved.
  4. dict_hash changing is expected; dict_hash diverging across architectures is the stop condition. §XXXIV.6. Do not "fix" a changed hash.
  5. Documentation in this repo drifts from the code — trust the code. .claude/CLAUDE.md carried four stale claims; all four were corrected 2026-09-19 (§XLIV) and it is now reliable. Others are not: capsules/MANIFEST.md still describes block 4055 as a live "immutable ABI" that FABRIC-2.md:2773 declared 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_SLOTS ceiling of 16, B4 the payload bound against INPUT_BUFFER_SIZE 1025. 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_hash changing is expected. dict_hash diverging 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 qemu for amd64, aarch64, riscv64 — one at a time, in the foreground, per .claude/CLAUDE.md. Check: all three reach zuse)ok>; zero UNKNOWN WORD; logs committed under logs/<timestamp>/<arch>/; record each dict_hash and 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>, zero UNKNOWN WORD. dict_hash identical across all three: Hera (PARITY:M7.1a) 0x6824fe5993239838, Hermes 0x062252c4da6858da, Artemis 0xed80117724c26f36. note: first attempt confounded, see findings log — logs/20260919-124835/amd64/ and logs/20260919-124952/aarch64/ (kept, not deleted) show Artemis's dict_hash diverging (0xed80117724c26f36 vs 0x93d6e815354b61c0) purely because disk/artemis.img is shared across all three ISAs' qemu targets (FABRIC-3.md §XXXV.2) and the second run resumed the first run's already-formatted disk instead of formatting its own. Restored disk/artemis.img and disk/thumbdrives/zuse-thumb-ident.img to 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 (takes EVENT-EMIT/-WAIT/-DRAIN with 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.md blocks 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-HEIGHT are 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_hash identical across arches.
  • 1.5 — Register Hestia for switch signals (the :1007 pattern). Check: boot clean; no switch storm (§XXVIII.2's shape — and note it is invisible by default, §XXXV.0).
  • 1.6 — Move fabric.4th from init.4th to hestia/init.4th. Check: Hera's dict shrinks, Hestia's grows; cross-arch identity holds.
  • 1.7 — Move font.4th likewise. Check: same.
  • 1.8 — Move PLOT/FB-WIDTH/FB-HEIGHT registration to Hestia's table only. Check: positively verify a non-Hestia VM calling PLOT gets UNKNOWN WORD.
  • 1.9 — Assert §XVIII.6's headless invariant: Hestia's birth sets no g_wirebind_attached_username and 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_hash unmoved.
  • 2.2 — Allocate: pull Q.SLOT from 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: consumed grows by exactly heat_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_conserved is 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_SLOTS is 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. Reuses sk_vm_at_outermost_interpret() and the Stage 3 checkpoint.
  • B4 — Item 44: payload bound or chunking against INPUT_BUFFER_SIZE 1025 (§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_foundation and its birth from kernel_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), the TRIPOD.md/0.1 contradiction, item 42's K-qualification, the superseded subsystem docs' update-or-archive call, and item 45 (experiments/bare_metal/README.md block framing).
  • 5.3 — make sbom; check Created: and DocumentName (§XXVI.2).
  • 5.4 — LITHOS_VERSION = 2.1.0; engine VERSION per §XXX.6's rule; roadmap table gains its 2.1.0 line in two live places (§XXVIII.2).
  • 5.5 — Resolve the stray refs/heads/v2.0.1 and PR #1 (§XXVI.4). Investigate, do not delete.
  • 5.6 — Merge to master; tag v2.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-home FABRIC-2 §17.4, consolidate the three reported-not-scheduled registries, decide FABRIC-2's five orphaned design items, reconcile FABRIC-0's seven opens.
  • src/*.c.bak — tracked-but-stale, reported in three places and actioned in none (§XXII.5).