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>
This commit is contained in:
Robert Allan James
2026-09-26 03:13:21 -04:00
co-authored by Claude Opus 5.5
parent 27c430e0ca
commit c9c97cf769
11 changed files with 27609 additions and 14 deletions
+33
View File
@@ -479,3 +479,36 @@ In the same run, after the second churn, rajames's `1 2 + .` was **refused by ke
- The `dict_hash` set, the G string and the ledger line are unchanged.
- **K-1 closes §8 defects 5–9 and the `sf_realloc()`/call-state-stack bug.** Its churn-leak criterion carries into K-4.
### 4.2 K-2 — `COLD` and `PAD` (2026-09-26)
**Change.**
- **Defect 1 (`COLD`).** `reset_vm_state()`'s cold branch now calls a new `vm_dictionary_forget_to_fence()` (dictionary_management.c). It forgets every word defined since the fence exactly as FORGET does, and rewinds `HERE` to the fence:
- untrack (the id recycled, the Stadium cell reclaimed);
- free the transition metrics and their arrays;
- free the entry.
It used to rewind `HERE` alone, to 1024, leaving `latest` at live words that the next definitions compiled over.
- The fence is set after `vm_init()` allots the input buffers, so `HERE` can't land below them.
- What `COLD` forgets is therefore what FORGET could forget. For a worker that includes its workload capsule's words (the fence is set at `vm_init()`). Hera's SDK capsule raises FENCE, so her base and SDK words survive.
- FORGET itself is unchanged.
- **Defect 2 (`PAD`).** `PAD` is now `BLK_VM_WINDOW_BASE - 512`, the 512 bytes just below the block I/O window. It was `VM_MEMORY_SIZE - 512`, inside the window's top slot. The span between the 2 MB dictionary limit and the window is otherwise unused.
**Probe** (plain FORTH, `k2.sh`, run on the clean build after O-A; no temporary code):
- `7770 . PAD . PAD 511 + .` on Hera;
- a worker `kc` defines KA, KB and KC and prints whether KA and KC are findable, then HERE;
- then `COLD`, `FIND` for each of the three, HERE, and a new definition `: KD 4 ; KD .`.
The results are identical on all three ISAs:
| ISA | log | PAD … PAD+511 | window base / dictionary limit | before COLD: KA, KC found; HERE | after COLD: KA, KB, KC; HERE; KD |
|---|---|---|---|---|---|
| amd64 | `logs/20260926-023300` | 5,238,272 … 5,238,783 | 5,238,784 / 2,097,152 | yes, yes; 1856 | 0, 0, 0; 1424 (the fence); 4 |
| aarch64 | `logs/20260926-024629` | same | same | same | same |
| riscv64 | `logs/20260926-030013` | same | same | same | same |
**Standard sequence** (the same runs, after the probe).
- All three ISAs pass: hash `0x99b01134c3d3049c`, G byte-identical (A=40 B=40, run before the probe), MINT / WIREBIND / USE / `1 2 + .` → `3`, 0 B idle growth, 0 UNKNOWN and 0 faults.
- The ledger totals (pulled 262144 / returned 259359) are higher than the usual line only because the probe worker's messages are counted; held and consumed are unchanged, and `stadium_conserved(self)=true`.
- The hosted `make` builds.
- **K-2 closes §8 defects 1 and 2.**