FABRIC-2.md §I.9: fix the terminal phantom-linebreak defect
console_ensure_line_start() (hal/console.c) used to emit its newline
immediately via a path that deliberately skipped the tx-byte counter, so
that sk_repl_idle()'s unconditional per-beat call to it (repl.c, ~1s idle
heartbeat) could force a real newline the REPL's own prompt-reanchor logic
never noticed -- the prompt was never reprinted, and the next real
keystroke echoed onto the now-blank line, indistinguishable from Enter
having already been pressed at a bare prompt. Root-caused in the previous
commit (704573b); this commit applies the fix per explicit go-ahead.
Fix: defer the newline instead of emitting it eagerly.
console_ensure_line_start() now only sets a flag (g_pending_line_close);
the newline is realized -- for real, and counted by g_console_tx_count
like any other output -- on the next actual console_putc() call, or
silently discarded via the new console_cancel_deferred_line_start() if the
caller decides nothing was actually printed. sk_repl_idle() captures
tx_before_idle right after its console_ensure_line_start() call and cancels
the deferred newline at both of its exit points when console_tx_count()
hasn't moved. A beat with nothing to report now leaves the console
untouched; a beat that does print still closes the dangling prompt line
first, properly counted this time. The pre-existing n > 0 mid-edit gate in
sk_console_readline() is untouched -- independent purpose, not the bug.
Verified via the mandatory foreground 3-arch QEMU acceptance boot
(clean qemu, amd64 -> aarch64 -> riscv64, one at a time): all three reached
(zuse) ok>, all echoed the first real input on the same log line as the
prompt rather than a fresh line, all shut down cleanly via BYE. amd64's log
additionally shows live human backspace-correction still glued to the same
prompt line. Logs: logs/20260905-015854 (amd64), logs/20260905-020248
(aarch64), logs/20260905-020552 (riscv64); logs/20260905-015813 is a
foreground-rule-violation retry killed and redone correctly, kept per this
project's "never delete logs/" convention.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
704573bdfc
commit
8edb95b65d
+33
@@ -4716,3 +4716,36 @@ same root cause, not a separately confirmed one.
|
||||
diagnosis is complete and reproducible on demand (QMP `send-key` + a screenshot, no physical
|
||||
keyboard needed, on any of the three architectures); whether and how to fix it is a decision
|
||||
for whoever picks this item up next.
|
||||
|
||||
**FIXED, 2026-09-05, explicit go-ahead given ("Yes, fix it").** Deferred-newline mechanism:
|
||||
`console_ensure_line_start()` (`include/starkernel/console.h`, `src/starkernel/hal/console.c`)
|
||||
no longer calls `console_putc_inner('\n')` immediately. It now only sets a flag
|
||||
(`g_pending_line_close`); the newline is realized — for real, and counted by
|
||||
`g_console_tx_count` like any other output — the next time `console_putc()` actually runs, or
|
||||
silently discarded via the new `console_cancel_deferred_line_start()` if the caller decides it
|
||||
has nothing to print after all. `sk_repl_idle()` (`repl.c`) now captures
|
||||
`tx_before_idle = console_tx_count()` right after its `console_ensure_line_start()` call, and
|
||||
calls `console_cancel_deferred_line_start()` at both of its exit points if
|
||||
`console_tx_count() == tx_before_idle` (nothing was actually printed that beat). This means a
|
||||
beat with nothing to report leaves the console completely untouched — no stray newline, no
|
||||
phantom blank line — while a beat that does print (xhci attach/detach, block-sync notices)
|
||||
still gets the correct "close the dangling prompt line first" behavior, now properly counted so
|
||||
the reanchor logic sees it. The pre-existing `n > 0` mid-edit gate at `sk_console_readline()`
|
||||
(`repl.c`, originally documented at old lines 598-609) is untouched — it serves an independent
|
||||
purpose (deferring bottom-half servicing during active typing) and was never the bug.
|
||||
|
||||
Verified via the mandatory 3-arch QEMU acceptance boot, all foreground, `clean qemu` each
|
||||
(amd64 `logs/20260905-015854/`, aarch64 `logs/20260905-020248/`, riscv64
|
||||
`logs/20260905-020552/`). All three reached `(zuse) ok>` and, per the raw serial log bytes,
|
||||
echoed the first real input on the *same log line* as the prompt — e.g. aarch64's
|
||||
`(zuse) ok> 1 1 + .r CR` and riscv64's `(zuse) ok> 1 1 . CR BYE`, not a fresh `[Hera]`-prefixed
|
||||
line as before the fix — then shut down cleanly via `BYE`. amd64's raw log additionally shows
|
||||
genuine human backspace-correction (`11^H ^H 1 + .`) still glued to the same prompt line,
|
||||
confirming the fix holds under real typing, not just a scripted single keystroke. No separate
|
||||
QMP send-key/screendump re-run was needed — these boots were driven live at the actual QEMU GTK
|
||||
window.
|
||||
|
||||
The secondary, unverified cursor-glyph-staleness observation above was not independently
|
||||
re-checked — out of scope for this fix, and about to be superseded anyway by a separate
|
||||
requested change (blinking `|` cursor instead of a static block), tracked as a new item, not
|
||||
here.
|
||||
|
||||
Reference in New Issue
Block a user