feat(v4): a hook at call, for whoever runs the node

Plan 2026-10-20 (ENGINE step 4), Task A1, for #189 -- Captain Bob,
2026-11-12: the physics blocks alpha.5; order A, 1, 2, then 7.

- exec.h/exec.c: v4_call_hook, es->on_call/on_call_ctx; called at `call`
  once the return address is pushed, before P moves. NULL: as before.
- heat.h/heat.c: the per-call-target table (4096 slots, no capsule word
  counted), its freeze mask and v4_heat_call_* go (ENGINE.md step 3: "The
  per-call-target count goes"); the kernel will keep a word's accounts.
- tests: test_call_hook_sees_every_call, seen to fail first (no on_call);
  test_heat's per-call tests go with the table.
- the plan records today's rulings (order; HEAT-OP: both, a full array).

Suite (logs/20261112-225951/v4-tests): test, test-32, sanitize, 0
failures; hosted-check, the three alike. amd64 boot: POST 538/538,
dict_hash 0x8c92508f748f99cf, unchanged -- nothing sets the hook yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
This commit is contained in:
Claude
2026-11-12 23:01:52 +00:00
parent f38761ff66
commit 3c97534c8b
14 changed files with 110 additions and 169 deletions
@@ -55,6 +55,13 @@ minted, and the boot recognises it. Today it does not: the drive QEMU attaches b
`disk/thumbdrives/zuse-thumb-ident.img`, is all zeros (bleached, `e56974e0`), and the v4 boot reads
no thumbdrive and prints its prompt with no identity. See "The identity gate" below.
**RULED 2026-11-12 (Captain Bob), #189** -- v4 has no Compudynamics beyond its heat counters, and it
"blocks alpha.5": the physics comes first. **Order: Part A, Phase 1, Phase 2, then Phase 7**; Phases
3 to 5 follow after alpha.5. And **HEAT-OP**: "Add HEAT-OP. If it's a huge performance hit, we'll
revert it" -- both: `HEAT-OP[0..31]` and `ANTICLOCK` readable as registers now, a full 33-cell array
(`DECOMPOSITION.md` §7), and fed to the Stadium in Phase 1, measured, kept or reverted on the
numbers.
**Q1. What "Hera, Hermes, Artemis are kernel" means in v4.**
*Recommend:* each is a function of the kernel, not a VM or node with a capsule of its own:
- **Hera** — process management: the registry, births, `NODE-KILL`/`SLEEP`/`WAKE` and who may ask
@@ -160,11 +167,11 @@ acceptance. Only Part A is written in tasks below; it does not depend on Q1 to Q
**Interfaces:** Produces `typedef void (*v4_call_hook)(void *ctx, v4_node *n, v4_cell target);` and, in `v4_exec_state`, `v4_call_hook on_call; void *on_call_ctx;`. Called at `V4_OP_CALL` after the return address is pushed, before `n->p` moves. NULL = no hook.
- [ ] **Step 1: Failing test** `test_call_hook_sees_every_call`: a programme calling three routines, one twice; the hook records the four targets in order; with `on_call = NULL` the result is the same.
- [ ] **Step 2:** `make -C v4 test` — FAIL (no `on_call`).
- [ ] **Step 3:** Add the hook; remove `v4_heat_on_call`, `call[]`, the freeze mask and `v4_heat_call_*`, and their tests.
- [ ] **Step 4:** Suite passes at both widths and under sanitizers; `hosted-check` unchanged.
- [ ] **Step 5:** Commit `feat(v4): a hook at call, for whoever runs the node`. (No boot change: nothing sets the hook on bare metal yet. One amd64 boot to confirm POST 538/538 and the same `dict_hash`.)
- [x] **Step 1: Failing test** `test_call_hook_sees_every_call`: a programme calling three routines, one twice; the hook records the four targets in order; with `on_call = NULL` the result is the same.
- [x] **Step 2:** `make -C v4 test` — FAIL (no `on_call`).
- [x] **Step 3:** Add the hook; remove `v4_heat_on_call`, `call[]`, the freeze mask and `v4_heat_call_*`, and their tests.
- [x] **Step 4:** Suite passes at both widths and under sanitizers; `hosted-check` unchanged.
- [x] **Step 5:** Commit `feat(v4): a hook at call, for whoever runs the node`. (No boot change: nothing sets the hook on bare metal yet. One amd64 boot to confirm POST 538/538 and the same `dict_hash`.)
### Task A2: Words that are checked are called