FABRIC-2.md Section Q: heartbeat-tick ACL-TTL remeasurement finds the
instrument blind to the effect, not a corrected number Per Captain Bob's correction (heartbeat tick counter is the sole canonical clock, not wall-clock), added HEARTBEAT-TICKS@ and re-ran the ACL-TTL overhead measurement using tick deltas. Diagnostics confirmed the counter is a FORTH-level colon-word-dispatch counter (frozen at idle, jumps with real work) -- not a wall-clock proxy. A pilot pair (amd64, seed 12345, 30 reps, ACL disabled vs enabled) produced byte-identical deltas (261064 ticks both runs): acl_recheck() runs at the C dispatch level and doesn't change which/how many colon words execute, so it's invisible to a counter gated on colon-word-entry count. Root-caused, not proceeding to the full 18-cell campaign -- every cell would read +0.00% by construction. Section P's wall-clock numbers stand as the best estimate on record pending a instrument that can see per-dispatch cost rather than control-flow shape. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
a7a837e136
commit
3998ce6aaf
+80
@@ -2187,3 +2187,83 @@ effect size. A tighter measurement would need either (a) many more replications
|
|||||||
shrink the standard error, or (b) reading a VM-internal tick/cycle counter directly (matching
|
shrink the standard error, or (b) reading a VM-internal tick/cycle counter directly (matching
|
||||||
the original campaign's own method) rather than host-side wall-clock bracketing. Neither
|
the original campaign's own method) rather than host-side wall-clock bracketing. Neither
|
||||||
attempted here; scoped as a natural next step, not undertaken in this pass.
|
attempted here; scoped as a natural next step, not undertaken in this pass.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Q. ACL-TTL overhead via heartbeat ticks — instrument found blind to the effect, 2026-08-20/21
|
||||||
|
|
||||||
|
Section P's wall-clock methodology was flagged by Captain Bob as a direct violation of
|
||||||
|
established project law: **the adaptive heartbeat tick counter is the one and only clock**,
|
||||||
|
not host wall-clock. Correcting for this required a new read-only accessor and a re-run —
|
||||||
|
the re-run surfaced a real, substantive negative result rather than a corrected number.
|
||||||
|
|
||||||
|
**`HEARTBEAT-TICKS@` ( -- n ).** Added to `src/word_source/starforth_words.c`, pushes
|
||||||
|
`vm->heartbeat.tick_count`. Read-only by design — no corresponding store word. Three-arch
|
||||||
|
QEMU acceptance (amd64/aarch64/riscv64): POST 1012/0/0 on each, word live-tested returning a
|
||||||
|
real, non-zero count on all three. Committed `0b11f92` (word) + `a7a837e` (acceptance logs).
|
||||||
|
|
||||||
|
**Diagnostic checks, before trusting the instrument for a campaign** (amd64 only, per
|
||||||
|
advisor guidance — cheaper than discovering the same problem 18 cells in):
|
||||||
|
|
||||||
|
1. **Idle behavior.** Read at `ok>`, wait 30s of real wall-clock time doing nothing, read
|
||||||
|
again: **frozen** (`77` both times). Traced to `sk_repl_idle()` in
|
||||||
|
`src/starkernel/repl.c` — a documented placeholder no-op. The idle poll loop services a
|
||||||
|
*separate* low-level ISR tick counter (`heartbeat_ticks()`/`heartbeat_service()`) but never
|
||||||
|
calls `vm_tick()` on the Hera VM itself, so `vm->heartbeat.tick_count` does not advance
|
||||||
|
from real time passing while idle.
|
||||||
|
2. **Work sensitivity.** Loaded `doe.4th`, ran a trivial 2-rep `EXEC-DOE`: ticks jumped
|
||||||
|
`77 → 17600`. Confirmed the counter *does* respond to VM activity — just not to elapsed
|
||||||
|
time.
|
||||||
|
3. **Mechanism.** `src/starkernel/vm/vm_core.c:813-818`: inside `execute_colon_word` (the
|
||||||
|
inner FORTH interpreter loop), `vm->heartbeat.check_counter` increments once per colon-word
|
||||||
|
entered; every `HEARTBEAT_CHECK_FREQUENCY` such entries, `vm_heartbeat_run_cycle()` fires
|
||||||
|
and increments `tick_count`. **This is a FORTH-level colon-word-dispatch counter, gated at
|
||||||
|
a fixed cadence — not a wall-clock proxy, and not sensitive to per-dispatch CPU cost.**
|
||||||
|
Reconciled against the boot-time `Heartbeat: 3007 ticks` line: that's a *different* counter
|
||||||
|
(`fleet_heartbeat_tick_count` in `capsule_vm_physics.c`, incremented once per live VM's own
|
||||||
|
`vm_tick()` — advances faster in wall-clock terms with more live VMs, not the same
|
||||||
|
quantity). `HEARTBEAT-TICKS@` correctly reads Hera's own counter, the right target for
|
||||||
|
measuring Hera's own `EXEC-DOE` work.
|
||||||
|
4. **HB-OFF/HB-ON interaction.** Confirmed `HB-OFF` only gates `g_doe_log_enabled` (CSV row
|
||||||
|
emission, `src/starkernel/doe_log.c`) — it does not touch `heartbeat_enabled` or `vm_tick()`
|
||||||
|
at `vm_runtime.c:501`. Safe to bracket `EXEC-DOE` with `HB-OFF`/`HB-ON` as before.
|
||||||
|
|
||||||
|
**Pilot pair (not a full campaign): amd64, seed 12345, 30 reps (480/480 rows, 0 errors),
|
||||||
|
ACL disabled vs. enabled**, `EXEC-DOE` bracketed by `HEARTBEAT-TICKS@` reads:
|
||||||
|
|
||||||
|
| ACL state | before | after | delta |
|
||||||
|
|-----------|--------|-------|-------|
|
||||||
|
| disabled | 17600 | 278664 | **261064** |
|
||||||
|
| enabled | 79 | 261143 | **261064** |
|
||||||
|
|
||||||
|
**The deltas are identical to the tick, both runs.** ACL-enabled cell independently confirmed
|
||||||
|
live (`' EXEC ACL-MODE@ .` → `1`, STRICT) before the run, so this isn't a case of ACL silently
|
||||||
|
not being active — enforcement was genuinely on, and it left no trace in this counter.
|
||||||
|
|
||||||
|
**Root cause, not just an observation.** `acl_recheck()` executes inside the C-level word
|
||||||
|
lookup/dispatch machinery per word execution — it does not add, remove, or otherwise change
|
||||||
|
which or how many *colon words* get entered at the FORTH level. `check_counter` only counts
|
||||||
|
colon-word entries (item 3 above). Since `EXEC-DOE`'s control flow is deterministic and
|
||||||
|
identical regardless of ACL state, the exact same number of colon-word-entry events occurs,
|
||||||
|
so the exact same number of `vm_heartbeat_run_cycle()` firings occurs, so `tick_count` advances
|
||||||
|
by the exact same amount — independent of how much *extra C-level work* each dispatch actually
|
||||||
|
cost. This is consistent with, and likely a direct consequence of, this project's deliberate
|
||||||
|
determinism goal (0.000% CV across runs, `.claude/CLAUDE.md`): the heartbeat tick counter is
|
||||||
|
*designed* to be a function of program control flow, immune to real execution-time noise. That
|
||||||
|
is exactly why it is unsuitable for measuring a cost — like ACL's per-dispatch recheck — that
|
||||||
|
changes execution time without changing control flow.
|
||||||
|
|
||||||
|
**Conclusion: the heartbeat tick counter, though correctly identified as this project's one
|
||||||
|
canonical clock, is the wrong instrument for this specific measurement.** It is real, it is
|
||||||
|
read correctly, it responds to VM work — but it is blind by construction to any overhead that
|
||||||
|
doesn't alter which FORTH words get dispatched. ACL-TTL overhead is exactly that kind of cost.
|
||||||
|
**Not proceeding to an 18-cell campaign** — every cell would read +0.00% by construction,
|
||||||
|
which would look like a clean result and would not be one. `HEARTBEAT-TICKS@` remains
|
||||||
|
committed as a real, useful accessor for future work that *does* want a control-flow-invariant
|
||||||
|
clock; it is simply not the right tool for ACL overhead specifically. Section P's wall-clock
|
||||||
|
numbers stand as the best empirical estimate on record (methodologically noisy, not
|
||||||
|
methodologically blind) unless a cycle-accurate or dispatch-level-cost instrument is added.
|
||||||
|
Candidates for a follow-up, not undertaken here: (a) a separate counter incremented inside
|
||||||
|
`acl_recheck()` itself (would directly count ACL work, trivially showing 0 when disabled), or
|
||||||
|
(b) instrumenting at the CPU-cycle level (`rdtsc`/equivalent) around the word-dispatch
|
||||||
|
primitive rather than at the colon-word-entry granularity.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Capsule Block Manifest — Auto-generated
|
# Capsule Block Manifest — Auto-generated
|
||||||
<!-- Generated by mkcapsule --manifest 2026-08-21T03:09:23Z -->
|
<!-- Generated by mkcapsule --manifest 2026-08-21T03:22:02Z -->
|
||||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||||
<!-- Hand-written justifications and immutability notes live -->
|
<!-- Hand-written justifications and immutability notes live -->
|
||||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user