Commit Graph
20 Commits
Author SHA1 Message Date
Robert Allan JamesandClaude Opus 5.5 7252e2ed72 FABRIC-3.10.8 K-11: check the lock order at run time
Every lock carries a rank (hermes < switch < registry < VM dict_lock <
VM tuning_lock < stadium < slot < doe < log < block < console < heap <
vmm < pmm); each core counts held locks per rank and an acquisition not
above the highest held rank counts an order violation, reported in full
at the idle point. Probe inversion reported exactly once; O-A, a 28-VM
churn and the standard sequence show 0 violations on all three ISAs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 11:37:23 -04:00
Robert Allan JamesandClaude Opus 5.5 a66c4f3d5e FABRIC-3.10.8 K-10: remove the stale Hermes-VM references
CONNECT-HERMES (birthed the removed hermes:init.4th; always failed) and
ARTEMIS-ANNOUNCE-READY (no callers) are gone; DoE CSV column 17 is now
hestia_heat_q48, same position. New baseline on all three ISAs:
word_count 544, M7.1a hash 0x927513aabd543433, Hera 0x4953a2e2d11fff34,
Artemis 0xc5a8cff4b805b6a0, Hestia unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:37:10 -04:00
Robert Allan JamesandClaude Opus 5.5 ff8e505308 FABRIC-3.10.8 K-9: remove a dead VM's physics node at KILL and reap
vm_physics_remove() retires the node (heat to the root) and frees it;
capsule_vm_kill() and capsule_vm_force_reap() call it, so WIREBIND/EJECT
kills and reaps now retire too (before, only the KILL word did). A dead
VM now leaves only its registry node (168 B). 3-ISA acceptance clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:03:26 -04:00
Robert Allan JamesandClaude Opus 5.5 1a3e21b51e FABRIC-3.10.8 §4.9: plan K-9 (physics node removal), K-10 (stale Hermes references), K-11 (lock rank check)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:26:38 -04:00
Robert Allan JamesandClaude Opus 5.5 f29658a65d FABRIC-3.10.8 K-8: free the vocabulary indexes and inference outputs at vm_cleanup
The ~3.4 KB/VM heap residual left after K-4 was each dead VM's CONTEXT
and FORTH first-character bucket arrays (84 blocks, 3,400 bytes per
worker), plus last_inference_outputs. New vocabulary_free_indexes();
both vm_cleanup()s call it and free the outputs. Per-VM residual is now
232 bytes: the registry node (kept by design) and the vm_physics node
(open finding). 3-ISA acceptance clean, hash 0x99b01134c3d3049c.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:21:16 -04:00
Robert Allan JamesandClaude Opus 5.5 acea36ea55 Stage K-6: riscv64 vblk_io timeouts root-caused and fixed -- time bound, exact used-ring accounting (FABRIC-3.10.8 §4.7)
- Investigation (riscv64): completions are slow, not lost -- up to 15 ms,
  while the ~1M-iteration bound was ~14 ms of guest time. Each timeout
  left the request in the device while the driver forgot it; the next
  request took its used entry as its own and returned before its own I/O
  finished, and so did every later one (394 in one boot), rewriting
  descriptors the device was still reading.
- Fix: VBLK_TIMEOUT_MS (2 s) on the raw hardware counter; each request
  waits for exactly one more used entry; a timed-out request stays
  outstanding and its completion is drained before anything is reused,
  or the next request is refused untouched. Counters for timeouts, late
  drains and busy refusals.
- After the fix, all three ISAs: 0 timeouts, 0 unaccounted completions
  over 1,912 I/Os; riscv64 slowest completion 7.7 ms (was 15.1).
- Standard sequence on amd64/aarch64/riscv64: hash, G, ledger unchanged;
  0 timeouts in the riscv64 log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 08:33:25 -04:00
Robert Allan JamesandClaude Opus 5.5 0c1fa2e510 Stage K-7: hosted Makefile stops copying the binary into lfs/ (FABRIC-3.10.8 §4.6)
- The all target copied the hosted binary to lfs/<arch>/starforth,
  rewriting a tracked file on every compile-sanity build (ruled: stop the
  copy). A forced relink now leaves lfs/ untouched. Hosted build only; no
  kernel change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 06:44:33 -04:00
Robert Allan JamesandClaude Opus 5.5 bfa876a0e2 Stage K-5: xHCI Input Context allocated full size once per slot (FABRIC-3.10.8 §4.5)
- New XHCI_INPUT_CTX_BYTES (control ctx + slot + 31 EP contexts).
  Address Device allocates the Input Context at that size once per slot;
  Configure Endpoint reuses it (bounds-checked). It allocated a fresh one
  on every attach and never freed the old.
- Probe (removed), identical on all three ISAs: after the standard
  sequence's attach/detach/re-attach, input-context allocations=2 (one
  per xHCI slot) against configure-endpoint=3.
- Standard sequence on amd64/aarch64/riscv64: hash, G, ledger unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 06:43:59 -04:00
Robert Allan JamesandClaude Opus 5.5 1166713cc9 Stage K-4: quota slots released to the best donor; message cells out of the admission fallback (FABRIC-3.10.8 §4.4)
- stadium_release_quota(): evict every patron but pending messages, mark
  the slot retiring; stadium_retire_sweep() releases a retiring slot once
  nothing is resident -- free cells to the best donor (ruled), word row
  and block-table entries cleared, slot free for reuse. Swept at release
  and after evictions while any slot is retiring.
- Called on KILL and reap, and for the nine synthetic self-test ids after
  the boot self-tests. Hera's slot never released.
- Admission fallback skips DELIVER (message) cells.
- Probe (removed): slots in use == live VMs after boot and after 56-64
  churned VMs on all three ISAs; forced fallback kept the message cell
  resident and intact; conserved everywhere; K-1's post-churn Hermes
  refusal gone (1 2 + . -> 3 on the churned system). Heap growth per
  28-VM churn halved (~3.4 KB/VM still retained -- open as K-8).
- Standard sequence on amd64/aarch64/riscv64: hash, G, ledger unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 05:44:33 -04:00
Robert Allan JamesandClaude Opus 5.5 9e41fb03ab Stage K-3: drain and channel-open policy self-tests retargeted to Hestia (FABRIC-3.10.8 §4.3)
- Both looked up the retired Hermes VM and printed SKIPPED on every boot.
  Drain test: target Hestia, nested VM-EXEC of "1 DROP". Policy test:
  Hestia is the no-policy VM (never loads ACL.4th). A missing target now
  prints FAIL, not SKIPPED.
- Both PASS on amd64/aarch64/riscv64; standard sequence passes (hash, G,
  MINT/WIREBIND/USE, conserved, 0 idle growth). Ledger baseline now
  pulled 262144 / returned 259359 (the drain test's real message).
- Found, not fixed: ARTEMIS-ANNOUNCE-READY, doe_log's "Hermes" heat
  column and CONNECT-HERMES still reference the retired Hermes VM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 03:52:55 -04:00
Robert Allan JamesandClaude Opus 5.5 c9c97cf769 Stage K-2: COLD forgets to the fence; PAD moved below the block window (FABRIC-3.10.8 §4.2)
- Defect 1: COLD now forgets every word since the fence exactly as FORGET
  does (new vm_dictionary_forget_to_fence(): untrack, metrics, entry) and
  rewinds HERE to the fence. It rewound HERE alone to 1024, leaving live
  words to be compiled over.
- Defect 2: PAD = BLK_VM_WINDOW_BASE - 512 (was inside the window's top
  slot, shared with BLOCK/BUFFER).
- Probe (plain FORTH, all three ISAs identical): PAD..PAD+511 =
  5238272..5238783 below the window (5238784); on a worker KA/KC found,
  COLD, then KA/KB/KC not found, HERE at the fence (1424), new word works.
- Standard sequence on amd64/aarch64/riscv64: hash and G unchanged,
  MINT/WIREBIND/USE ok, conserved, 0 idle growth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 03:13:21 -04:00
Robert Allan JamesandClaude Opus 5.5 27c430e0ca Stage K-1: real kernel realloc; word-metrics defects closed (FABRIC-3.10.8 §4.1)
- Kernel sf_realloc() is a real realloc (copy min(old,new) via new
  kmalloc_usable_size(), free old, NULL-on-0 frees). It allocated fresh
  and nothing else: every growth leaked, and vm_state_push()'s call-state
  stack lost every saved state past depth 8 (found here).
- Shim realloc() copies min(old,new) (over-read when growing).
- Defect 9: FC bucket growth no longer leaks or patches a copy; no
  sf_xrealloc() (freed a block the index still held on failure).
- Defect 5: heat snapshot heap-sized (was heats[1024], truncating).
- Defect 6: word refused whole when its metrics can't be allocated.
- Defect 7: vm_cleanup() (both) frees metrics' inner arrays.
- Defect 8: most-likely-next kept incrementally; no full id scan.
- Probe (removed): realloc keeps contents, heap returns exactly; call
  stack depth 20 intact; all three ISAs. Churn criterion NOT met: ~7 KB
  retained per churned VM (quota slots/word rows -- K-4 re-measures); a
  post-churn CONSOLE-CMD refusal attributed to the quota leak, K-4 retests.
- Standard sequence on amd64/aarch64/riscv64: hashes, G, ledger unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 02:30:43 -04:00
Robert Allan JamesandClaude Opus 5.5 ef849906d9 FABRIC-3.10.8 §4: plan for closing the known issues (K-1..K-7), rulings recorded
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 01:13:18 -04:00
Robert Allan JamesandClaude Opus 5.5 02c4c7e620 Stage MC-0d: Stadium partitioned by quota slot, one lock per slot (FABRIC-3.10.8 §3.5)
- Ruling (Captain Bob): per-slot locks, not "own path needs no lock" --
  a lock only on the cross-slot side can't exclude an unlocked owner
  (Hermes release evicting a sender's cell while the sender admits).
  FABRIC-3.10.0 §3.6 amended.
- StadiumVMQuota.lock covers the slot's lists, reservoir, consumed, word
  row and its cells. Word dispatch holds only its own slot lock for the
  whole dispatch (*_in_slot forms); peek-then-pull is one step.
- g_lock_stadium: grant slot allocation (new slot published with release
  in_use) and the shared block table (ruled: the one shared-lock Stadium
  path). Taken before a slot lock.
- Bitmap bytes set/cleared atomically (8 cells, possibly 8 slots).
- Cross-slot writers moved under the owner's lock: Hermes decay
  (stadium_cell_decay), Hermes release ledger (stadium_evict_credit),
  session pin (stadium_cell_set_pin). stadium_conserved() one hold.
- Word and block cell lookups check the cell is still this slot's.
- Probe (removed), identical on all three ISAs: 10,746,599 of 10,746,616
  word dispatches took exactly one lock (own slot), the 17 others all row
  growths; every live VM conserved; Hermes audit failures 0.
- Findings reported: births/USE run a VM's words while another VM is the
  core's current VM (MC-3 claim must cover it); quota slots never
  released; owner admission can evict a live message cell (latent, 0).
- Standard sequence on amd64/aarch64/riscv64: dict_hash set and G
  byte-identical, MINT/WIREBIND/USE ok, conservation true, 0 idle growth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 22:40:33 -04:00
Robert Allan JamesandClaude Opus 5.5 355909d46f Stage MC-0c: shared VM code made per-VM or atomic (FABRIC-3.10.8 §3.4)
- Dictionary lookup index is per VM (vm->fc_index, struct SfFcIndex):
  was one global index rebuilt whenever a different VM was searched, and
  heat reorganization could reorder another VM's buckets. Allocated on
  first lookup, freed by vm_cleanup(); allocation failure counted/logged,
  lookup falls back to a newest-first dictionary walk.
- PRNG: still one stream, stepped by compare-and-swap; SEED one store.
- state_variable removed (write-only; STATE is vm->mode).
- Sweep additions (Captain Bob's ruling): heartbeat_export.c delta
  last-values moved into each VM's HeartbeatState (were statics shared by
  every VM -- wrong across VMs today); TOP-WORDS list heap-sized per call
  (was static [1000]); inference_outputs_to_string() takes a caller
  buffer; three failure counters atomic; crc64 table published with
  release/acquire.
- Confirmed, unchanged: g_runtime compiled out of the kernel,
  g_hotwords_cache unreferenced, ttf cache core-0-only.
- Probe (removed): every VM has its own index; two VMs searched
  alternately 2x5000 lookups: 0 rebuilds, 0 wrong-VM results, all three
  ISAs.
- Standard sequence on amd64/aarch64/riscv64: dict_hash set unchanged,
  G byte-identical, MINT/WIREBIND/USE ok, conservation true, 0 idle growth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:05:20 -04:00
Robert Allan JamesandClaude Opus 5.5 33f4090d6d Stage MC-0b2: block subsystem behind g_lock_block (FABRIC-3.10.8 §3.3)
- block_subsystem.c (vendored): every public function's body becomes a
  static *_locked function; bodies call each other only through the
  _locked forms, breaking the internal cycles (relocate, meta relocate,
  migration scan, firsttouch, the meta accessors). Thin public wrappers
  take g_lock_block under __STARKERNEL__; hosted build has no lock and
  still builds clean.
- Lock order: hermes, switch, registry, doe, log, block, console, heap,
  vmm, pmm (Stadium, MC-0d, above block).
- Documented, not coverable by this lock: blk_get_buffer() pointers are
  used after release -- block-buffer ownership across cores is open for
  MC-3.
- Probe (removed): block lock balances on all three ISAs (2,057-2,379
  acquisitions), 0 recursions, 0 held at switch; vblk_io timeouts
  (0/0/4 probe, 0/0/2 acceptance) within the pre-lock riscv64 baseline
  of 0-6.
- Standard sequence on amd64/aarch64/riscv64: hashes and G byte-identical
  to MC-0b, MINT/WIREBIND/USE ok, conservation true, 0 idle growth.
- FABRIC-3.10.8 §3.2 wording fix; lock order noted as checked by
  inspection only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 18:57:38 -04:00
Robert Allan JamesandClaude Opus 5.5 5bc7b4dee7 Stage MC-0b: real kernel spinlocks; sf_mutex no longer a no-op (FABRIC-3.10.8 §3.2)
- New spinlock primitive (spinlock.h/.c): CAS on an owner word (core+1),
  interrupts masked while any lock is held (state kept in the per-core
  block, so release order doesn't matter). Recursion, release-not-held,
  held-at-switch and destroyed-while-held are counted and logged, never
  silent. Locks are no-ops until the boot core's block is installed
  (riscv64's monolithic early boot prints before sk_percpu_boot_init()).
- Kernel locks in a documented order: hermes, switch, registry, doe, log,
  console, heap, vmm, pmm. sf_mutex (dict_lock/tuning_lock) uses the same
  lock word.
- Hermes: public functions over *_locked internals; never held across the
  drain's vm_interpret_kind(); switch notifications after dropping the
  lock; event payload moved off static storage. Switch table and registry
  never call out while held (slot/entry copied under the lock).
- No lock crosses a switch: checked at context switch (leave, resume) and
  the idle point.
- Probe (removed): every lock balances on all three ISAs; 0 held at
  switch over 7.5M-51M checks; 0 recursions, 0 bad releases.
- Standard sequence on amd64/aarch64/riscv64: hashes and G byte-identical
  to MC-0a, MINT/WIREBIND/USE ok, conservation true, 0 idle growth.
- Block subsystem split out as MC-0b2 (Captain Bob's ruling).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 16:43:19 -04:00
Robert Allan JamesandClaude Opus 5.5 8409e376cf Stage MC-0a: per-core block on one core -- current VM moves behind the per-CPU register (FABRIC-3.10.8 §3.1)
- New sk_percpu_t { self, core_id, current_vm }, reached via GS base
  (amd64, %gs:0), TPIDR_EL1 (aarch64), tp (riscv64). Boot core's block is
  one static object installed right after arch_early_init(); secondary
  cores' blocks come with MC-1.
- switch.c's global g_switch_current_vm is gone; current VM is
  sk_percpu()->current_vm, re-read after resume in the context switch.
- Probe (removed): normal path and every heartbeat ISR found core 0's
  block on all three ISAs (ISR ok 889/1877/1625, bad 0).
- Standard sequence on amd64/aarch64/riscv64: hashes unchanged from O-C,
  G A=40 B=40, MINT/WIREBIND/USE ok, conservation true, 0 idle growth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 13:56:48 -04:00
Robert Allan JamesandClaude Opus 5.5 8d33f7a959 Record the stopped O-D amd64 run and the ruling: no DoE execution until everything is closed
- logs/20260925-112529/amd64/: O-D amd64 launch (12345 3 S" amd64" DOE,
  rows on), stopped via QMP after 81 min / 131,537 rows with no trial
  complete, so the row path could be fixed (row path A ruled).
- FABRIC-3.10.8: Captain Bob, 2026-09-25: "until we close everything, do
  not do ant DoE eecution." MC-4's campaigns wait; stage evidence is the
  standard sequence plus probes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 12:58:42 -04:00
Robert Allan JamesandClaude Opus 5.5 4419ea953f FABRIC-3.10.0 ruled (multi-core now, ahead of O-D; row path A for O-D) and FABRIC-3.10.8 execution plan
- Captain Bob, 2026-09-25: "pin observr and dynmically utilize worker VM's";
  MC-R1..R5 as proposed; MC-R6 changed to start now; O-D relaunches with
  row path A (serial-only DoE rows). The amd64 O-D launch was stopped after
  81 min / 131,537 rows for this.
- FABRIC-3.10.8: the traced inventory of shared state (kernel subsystems
  and the shared VM code -- notably one global dictionary lookup index for
  all VMs), and stages MC-0a..MC-4 with evidence named in advance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 12:58:19 -04:00