Add diagnostic scan cross-check of the Hermes counters -- FABRIC-3.6.md task 2.8

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-09-21 08:46:07 -04:00
co-authored by Claude Sonnet 5
parent 2a2bf6eb35
commit feace42397
7 changed files with 27832 additions and 1 deletions
+28
View File
@@ -982,6 +982,34 @@ static void kernel_main_deep(BootInfo *boot_info) {
if (!stadium_conserved(alloc_test_id)) sb = 0; /* after release */
sk_hermes_ledger(&h, &p_, &r, &c);
if (h != held0 || !sk_hermes_audit_values(h, p_, r, c)) sb = 0;
/* Task 2.8: scan cross-check of the counters -- mid-hold
* and after decay it must equal `held` and be non-zero
* (vacuity guard); after release it must be zero. The
* mid-hold/decay points are re-established here on a
* short fresh hold. */
{
size_t live = 0, live2 = 0;
uint64_t s1, s2;
int sc = 1;
uint64_t k = 0;
if (!sk_hermes_scan_check() || sk_hermes_scan_held(&live) != 0 || live != 0) sc = 0;
while (k < 4 && sk_hermes_alloc(alloc_test_id, &msg) == 0) msgs[k++] = msg;
if (k != 4) sc = 0;
s1 = sk_hermes_scan_held(&live);
sk_hermes_ledger(&h, &p_, &r, &c);
if (s1 == 0 || live != 4 || s1 != h || !sk_hermes_scan_check()) sc = 0;
for (i = 0; i < k; i++) if (sk_hermes_decay(msgs[i]) != 0) sc = 0;
s2 = sk_hermes_scan_held(&live2);
sk_hermes_ledger(&h, &p_, &r, &c);
if (s2 >= s1 || s2 != h || live2 != 4 || !sk_hermes_scan_check()) sc = 0;
for (i = 0; i < k; i++) if (sk_hermes_release(msgs[i]) != 0) sc = 0;
if (sk_hermes_scan_held(&live) != 0 || live != 0 || !sk_hermes_scan_check()) sc = 0;
console_puts("Scan cross-check (counters vs arena): ");
console_println(sc ? "PASS" : "FAIL");
print_uint(" scan_held_before_decay=", s1);
print_uint(" scan_held_after_decay=", s2);
if (!sc) sb = 0;
}
console_puts("Stage B (ledger + stadium_conserved): ");
console_println(sb ? "PASS" : "FAIL");
print_uint(" vm_consumed=", stadium_consumed_peek(alloc_test_id));
+18
View File
@@ -88,6 +88,24 @@ uint64_t sk_hermes_audit_failure_count(void) {
return sk_hermes_audit_failures;
}
uint64_t sk_hermes_scan_held(size_t *live_count) {
uint64_t sum = 0;
size_t n = 0;
int i;
for (i = 0; i < SK_HERMES_MSG_MAX; i++) {
if (!sk_hermes_msgs[i].in_use || sk_hermes_msgs[i].stadium_cell < 0) continue;
sum += stadium_cells()[sk_hermes_msgs[i].stadium_cell].header.heat;
n++;
}
if (live_count) *live_count = n;
return sum;
}
int sk_hermes_scan_check(void) {
return sk_hermes_scan_held((size_t *)0) == sk_hermes_held;
}
static int sk_hermes_find_free_slot(void) {
int i;
for (i = 0; i < SK_HERMES_MSG_MAX; i++) {