Commit Graph
1 Commits
Author SHA1 Message Date
Robert Allan JamesandClaude Sonnet 5 cd2fda4351 Add mkcapsule --resolve: build-time claim registry for capsule block collisions (FABRIC-3.md §XXIV)
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run
Traced what a "Block NNNN" collision actually means before designing
a fix for it: capsule_loader.c's block-write path routes through the
generic block-subsystem API, which kernel_main.c registers as two
devices in a fixed order -- the volatile ramdrive first (LBN
2048-3071), then Artemis's real virtio-blk device immediately after
(LBN 3072+, backed by disk/artemis.img). Every capsule this project
has lands in Artemis's persistent range, not the ramdrive, and
blk_update()'s dirty-marking + repl.c's idle-loop flush write that
content through to the real disk file on every boot. A block-number
collision is therefore a silent, persistent overwrite of real disk
content surviving reboots, not a transient RAM mixup.

The existing collision gate (check_block_conflicts(), already a hard
non-interactive build failure) already catches capsule-vs-capsule
collisions across the whole flat range. The real gap: zero visibility
into blocks something other than a capsule owns (Artemis's own
non-capsule persistent data), and no device-boundary/capacity
awareness at all.

Added, scoped step by step before writing any code:

- tools/capsule-claims.txt -- derived, auto-created/regenerated,
  git-ignored. Lets --resolve tell "this capsule's own content
  changed" apart from "genuinely new collision with something else."
- tools/capsule-reserved.txt -- human-authored, git-tracked, seeded
  with nothing yet rather than guessed at. Checked by both the plain
  build gate (new check_reserved_conflicts()) and --resolve.
- tools/patches/ -- git-tracked, one file per accepted interactive
  renumber; a structured old->new block list, not a generic diff,
  since that's the only thing a renumber ever changes.
- mkcapsule --resolve <dir> -- the only interactive mkcapsule mode,
  a deliberate separate invocation from the plain build path (which
  stays non-interactive so CI never blocks on a prompt). Suggests a
  renumbering that preserves a capsule's own existing block spacing,
  prompts y/N, rewrites the .4th source in place on acceptance.

Found and fixed a real bug during verification: the registry's
empty-block-list case (workload-5.4th, zero Block headers) serialized
with a stray trailing space that the reader parsed back as a phantom
block 0, causing spurious re-registration every run -- caught by
testing idempotency directly, not assuming a clean first run meant
it worked.

Verified: isolated collision tests confirm both accept and reject
paths, confirm a resolved collision doesn't re-prompt the other side,
confirm reserved-range collisions are caught by both --resolve and
the plain build gate. Full 3-architecture rebuild via the real
Makefile.starkernel succeeded clean; amd64 boots with an unchanged
dict_hash/capsule_hash from every prior boot this session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXieurDfDSsDFdnSyusuWo
2026-09-12 21:56:37 -04:00