Stage D batch 1: fix silent error sites in repl.c and inference_words.c (FABRIC-3.md §XXXII.6)
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

repl.c's sk_word_blk_attach_ack() and inference_words.c's array_ptr()
helper + infer_word_run()'s allocation guard now log a diagnostic via
log_message(LOG_ERROR, ...) before setting vm->error, matching
defer_words.c's own gold-standard pattern (§XXXII.3) -- these are
internal/background conditions (a malformed message-callback, a bad
array reference or allocation failure), not interactive usage mistakes,
so the fix keeps the fault and reports it rather than dropping it like
USE's own fix did.

Batched together (4 sites total, smaller combined than the next file)
rather than two separate acceptance cycles for negligible size.

Three-arch clean qemu acceptance passed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
Robert Allan James
2026-09-15 16:23:14 -04:00
co-authored by Claude Sonnet 5
parent 09959c6ca2
commit 5417ffb2bf
11 changed files with 27189 additions and 3 deletions
+29
View File
@@ -4515,3 +4515,32 @@ Matching §XXVIII's own gated-stage shape (each stage its own commit, its own fu
**Nothing in this section has been implemented.** This write-up is the deliverable for this **Nothing in this section has been implemented.** This write-up is the deliverable for this
pass -- Stage A begins only once reviewed. pass -- Stage A begins only once reviewed.
### XXXII.6 -- Stage D: fixes, smallest file first
Per direct instruction, batches ordered by file size (silent-site count), not by finding
severity -- §XXXII.3's own "two findings above the rest" get fixed as part of whichever file's
batch they fall in, not pulled forward.
**Batch 1 -- DONE, 2026-09-15: `repl.c` (1 site) + `inference_words.c` (3 sites), combined into
one commit.** Deliberately batched together rather than run two separate 3-arch acceptance
cycles for 4 total sites -- their combined size is still smaller than the next file
(`log_words.c`, 10 sites), so splitting them would add cost without adding review granularity.
- `repl.c:231` (`sk_word_blk_attach_ack`, the `BLK-ATTACH-ACK` message-callback dispatched via
`VM-EXEC` from Artemis's own `MSG-TICK`, not a directly human-typed command): diagnostic added
via `log_message(LOG_ERROR, ...)`, matching `defer_words.c`'s gold-standard shape (report,
then still fault) since this condition -- the ack message arriving malformed -- indicates a
real protocol violation somewhere upstream, not an ordinary usage mistake to just recover from.
- `inference_words.c`'s `array_ptr()` helper (lines 76-84, feeding `Q.VARIANCE`/
`INFER-DECAY-SLOPE`/`INFER-WINDOW-WIDTH`) and `infer_word_run()`'s allocation guard (line 142):
same shape -- `log_message(LOG_ERROR, ...)` added before each existing `vm->error = 1`, no
behavior change beyond the new diagnostic. Required adding `#include "log.h"` to this file (not
previously included). All three callers of `array_ptr()` already handle its `NULL` return by
pushing a safe default and continuing, so only the diagnostic was missing, not error recovery.
**Verified:** three-architecture `clean qemu` acceptance (amd64/aarch64/riscv64) passed, standard
regression unaffected. Not separately live-fired against either failure condition (both need a
genuinely malformed message or an out-of-bounds array reference to trigger) -- the fix is
mechanical (add a `log_message()` call, no logic change) and low-risk, matching this project's
own precedent for this class of change.
+1 -1
View File
@@ -1,5 +1,5 @@
# Capsule Block Manifest — Auto-generated # Capsule Block Manifest — Auto-generated
<!-- Generated by mkcapsule --manifest 2026-09-15T17:51:41Z --> <!-- Generated by mkcapsule --manifest 2026-09-15T20:13:26Z -->
<!-- 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. -->
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -228,7 +228,11 @@ static sk_blk_attach_pending_t *g_blk_attach_pending = (void *)0;
* failed blk_subsys_attach_device() call, and simply never births * failed blk_subsys_attach_device() call, and simply never births
* anything for this attach. */ * anything for this attach. */
static void sk_word_blk_attach_ack(VM *vm) { static void sk_word_blk_attach_ack(VM *vm) {
if (vm->dsp < 1) { vm->error = 1; return; } if (vm->dsp < 1) {
log_message(LOG_ERROR, "BLK-ATTACH-ACK: stack underflow");
vm->error = 1;
return;
}
cell_t ok_flag = vm_pop(vm); cell_t ok_flag = vm_pop(vm);
cell_t dev_addr = vm_pop(vm); cell_t dev_addr = vm_pop(vm);
blkio_dev_t *dev = (blkio_dev_t *)(uintptr_t)dev_addr; blkio_dev_t *dev = (blkio_dev_t *)(uintptr_t)dev_addr;
+10 -1
View File
@@ -49,6 +49,7 @@
#include "vm.h" #include "vm.h"
#include "word_registry.h" #include "word_registry.h"
#include "log.h"
#include "q48_16.h" #include "q48_16.h"
#include "inference_engine.h" #include "inference_engine.h"
#include "ssm_jacquard.h" #include "ssm_jacquard.h"
@@ -74,11 +75,15 @@ static inline double q48_to_dbl(q48_16_t q) { return (double)q / 65536.0; }
static const uint64_t *array_ptr(VM *vm, vaddr_t addr, cell_t u) static const uint64_t *array_ptr(VM *vm, vaddr_t addr, cell_t u)
{ {
if (u <= 0 || addr >= (vaddr_t)VM_MEMORY_SIZE) { if (u <= 0 || addr >= (vaddr_t)VM_MEMORY_SIZE) {
log_message(LOG_ERROR, "inference: bad array reference (addr=%lu u=%ld)",
(unsigned long)addr, (long)u);
vm->error = 1; vm->error = 1;
return NULL; return NULL;
} }
size_t bytes = (size_t)u * sizeof(cell_t); size_t bytes = (size_t)u * sizeof(cell_t);
if ((size_t)addr + bytes > VM_MEMORY_SIZE) { if ((size_t)addr + bytes > VM_MEMORY_SIZE) {
log_message(LOG_ERROR, "inference: array reference out of bounds (addr=%lu u=%ld)",
(unsigned long)addr, (long)u);
vm->error = 1; vm->error = 1;
return NULL; return NULL;
} }
@@ -139,7 +144,11 @@ static void infer_word_run(VM *vm)
/* Allocate outputs struct if not yet done */ /* Allocate outputs struct if not yet done */
if (!vm->last_inference_outputs) { if (!vm->last_inference_outputs) {
vm->last_inference_outputs = (InferenceOutputs *)sf_malloc(sizeof(InferenceOutputs)); vm->last_inference_outputs = (InferenceOutputs *)sf_malloc(sizeof(InferenceOutputs));
if (!vm->last_inference_outputs) { vm->error = 1; return; } if (!vm->last_inference_outputs) {
log_message(LOG_ERROR, "INFER-RUN: allocation failed for InferenceOutputs");
vm->error = 1;
return;
}
memset(vm->last_inference_outputs, 0, sizeof(InferenceOutputs)); memset(vm->last_inference_outputs, 0, sizeof(InferenceOutputs));
} }