Commit Graph
16 Commits
Author SHA1 Message Date
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