Silence routine diagnostic noise; fix a real CRLF double-submit bug

Two separate fixes, found and closed together after task 3.9/prompt-
format landed (Captain Bob: "finish the work first then we'll do
cleanup before 3.10 begins").

1. Logging noise (confirmed live via QMP screendump): three sources
   were cluttering ordinary interactive console sessions.
   - INFERENCE "Output validation failed, ignoring results"
     (vm_runtime.c, kernel; vm_time.c, hosted mirror) and xhci "CSW
     status = FAILED"/"unit not ready -- retrying" (xhci.c) were
     already log_message(LOG_WARN/LOG_ERROR, ...) calls, just visible
     at the default runtime LOG_WARN level -- downgraded to LOG_INFO,
     all three fire routinely and self-resolve (xhci.c's own existing
     comment already documents the retry as expected SCSI UNIT
     ATTENTION behavior, not a driver defect).
   - Stadium: dispatch cell=... (stadium.c's stadium_dispatch()) was a
     genuine defect: an unconditional console_puts()/console_println()
     sequence with no level gating at all, printing on every single
     dispatch. Rewritten through log_message(LOG_DEBUG, ...).

2. CRLF double-submit (found while investigating why the cleaned-up
   noise still didn't look like a normal single-VM session):
   sk_console_readline() (repl.c) breaks on '\r' OR '\n' as independent
   terminators, so a line sent as both bytes submits twice -- the real
   line, then an immediate empty-line submit on the second byte, each
   printing its own " ok". Pre-dates Stage D entirely, not an async-
   relay artifact. Fixed with a single non-blocking peek-and-discard
   for the paired byte right where the line terminates.

Verified live on all three architectures for both fixes: zero UNKNOWN
WORD, dict_hash identical to every prior acceptance run in this
document (both changes are display/interaction-only).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-09-22 16:33:29 -04:00
co-authored by Claude Sonnet 5
parent 5c07745c18
commit d4f8a568ee
22 changed files with 73490 additions and 17 deletions
+20
View File
@@ -1306,6 +1306,26 @@ int sk_console_readline(char* buf, int size, VM* active_vm, int reanchor_prompt)
if (c == '\r' || c == '\n') {
console_fb_erase_cursor(); /* leaving this cell without drawing a char over it */
console_putc('\n');
/* CRLF pairing, found live 2026-09-22: a terminator sent as
* both bytes (a real terminal in CRLF mode, or any scripted
* sender writing "\r\n") used to submit TWICE -- this line
* on the '\r' (or '\n'), then an immediate empty line on the
* OTHER byte the next time this function is called, each
* producing its own " ok" -- confirmed live as the doubled
* "ok" this project's own session interaction showed, not an
* async-relay artifact as first suspected. Non-blocking peek
* for the paired byte right here, before returning -- discard
* it if present, push it back via g_console_pending_key
* (already the mechanism sk_console_key_available() uses for
* exactly this "peeked but not this call's to consume" case)
* if it's unrelated input for the NEXT line. A byte that
* hasn't arrived yet by this point is not waited for --
* matches every other non-blocking read in this function. */
{
int pair = (c == '\r') ? '\n' : '\r';
int next = sk_console_getc_raw();
if (next >= 0 && next != pair) g_console_pending_key = next;
}
break;
}