From 859381640b79d2068edd76913b79c14522dec1ca Mon Sep 17 00:00:00 2001 From: Robert Allan James Date: Tue, 11 Aug 2026 08:35:58 -0400 Subject: [PATCH] FABRIC.md: insert 4.4e/4.4f/4.4g (found verifying 4.4c/4.4d), renumber 4.4e-4.4p to 4.4h-4.4s 4.4c/4.4d's fix was screendump-verified on amd64: the framebuffer console mechanism works and [VMName] genuinely reaches the screen for the first time. Verifying that screendump surfaced three more issues, each given its own item per SS25.0 rule 3 rather than folded in silently: - 4.4e (fixed this session, see prior commit): console_putc() forwarded raw '\n' to vt100_putc() without '\r', corrupting line-start columns. - 4.4f (open, not root-caused): character glyphs render vertically flipped. - 4.4g (open, not root-caused): most of the framebuffer stays blank despite hundreds of lines of boot output that should have scrolled through it. Confirmed via a second screendump after the 4.4e fix that 4.4f and 4.4g are both independent of the \r/\n bug -- unchanged before and after. Added evidence/ as a new tracked location for durable proof screenshots, distinct from the existing gitignored fb/ (disposable local eyeballing, per the 2026-08-07 decision to stop tracking it). Linked from the relevant 4.4c/4.4d/4.4e/4.4f/4.4g entries. 4.4c and 4.4d remain unchecked -- their Done-when criteria require a three-arch screendump match against the serial log, not yet attempted on aarch64/riscv64. Co-Authored-By: Claude Sonnet 5 --- FABRIC.md | 149 +++++++++++++----- ...creenshot-20260811-081837-pre-4.4e-fix.png | Bin 0 -> 6510 bytes ...reenshot-20260811-082822-post-4.4e-fix.png | Bin 0 -> 6401 bytes 3 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png create mode 100644 evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png diff --git a/FABRIC.md b/FABRIC.md index e76d63e..d32df6b 100644 --- a/FABRIC.md +++ b/FABRIC.md @@ -4981,7 +4981,7 @@ document and committing that amendment as its own item.* *added above this marker.)* - [x] **4.4 — Design-only: lock the prompt format and color values.** No code. Write down the - exact target string — `[VM name] ok>` for now, `(user)` added later per 4.4p — and the exact + exact target string — `[VM name] ok>` for now, `(user)` added later per 4.4s — and the exact color values for the bracketed VM name and for `ok>` against [`repl-mockup.png`](repl-mockup.png). Captain Bob's spoken values (orange, cyan) were both qualified as tentative/uncertain — this item is where they become specific RGB or ANSI SGR @@ -5001,14 +5001,14 @@ document and committing that amendment as its own item.* > classic 16-color ANSI palette (checked — `FB_ANSI_PALETTE` has none), so this is a fresh > literal value, not a reused constant. `TTF-TEXT`'s `color` argument is a raw RGB value > (not an ANSI palette index), so this is not a constraint — any RGB is valid. - > These are literal `FB_RGB()`-equivalent values for 4.4a/4.4e to consume directly; no + > These are literal `FB_RGB()`-equivalent values for 4.4a/4.4h to consume directly; no > implementation performed by this item, per its own "no code" scope. - [x] **4.4a — Build `[VM name]` bracket text in the prompt, monochrome.** Replace the two existing, mutually inconsistent VM-identity conventions — `console.c`'s per-line `[Name]` prefix (`console_set_vm_name()`/`g_active_vm_name`, unaffected/out of scope for non-prompt lines) and `repl.c`'s prompt-suffix `)ok>` (`sk_repl_run()`/`sk_repl_step()`) — with - `[VM name] ok>`, no color yet (4.4e). VM attach itself needs no new work: `USE` + `[VM name] ok>`, no color yet (4.4h). VM attach itself needs no new work: `USE` (`mama_forth_words.c:1108`) already sets both `g_repl_active_vm` and `console_set_vm_name()` — this item is a *display* change only. *Done when:* all three architectures boot to a bracketed `[Hera] ok>` prompt (replacing @@ -5031,9 +5031,9 @@ document and committing that amendment as its own item.* > untouched — this is a display-only change, the ACL bypass semantics are identical to > before. > - > **Known, intentional gap until 4.4p:** the old prompt distinguished `zuse)ok>` from bare + > **Known, intentional gap until 4.4s:** the old prompt distinguished `zuse)ok>` from bare > `ok>` textually. That distinction is not yet visible in the new unified prompt — it moves - > to the `(user)` segment, which is explicitly scoped-but-blocked at 4.4p. The underlying + > to the `(user)` segment, which is explicitly scoped-but-blocked at 4.4s. The underlying > `zuse_session`/`emergency_console` mechanics are unchanged; only the on-screen indicator is > temporarily gone. > @@ -5046,27 +5046,27 @@ document and committing that amendment as its own item.* > serial-only by construction). Given its own item, 4.4d, rather than silently rolled into > this one. -- [x] **4.4b — Resolve: does prompt color depend on 4.4g?** Investigation, not implementation. +- [x] **4.4b — Resolve: does prompt color depend on 4.4j?** Investigation, not implementation. Read the REPL's actual output path (`console_puts()` → ... → `vt100_putc()` → `draw_cursor_glyph()`, all currently `font_8x16.c`) to determine whether a single hardcoded-color prompt segment can call `TTF-TEXT` directly, independent of the general - ANSI/SGR retarget (4.4g), or whether all REPL output — prompt included — shares one - rendering pipeline that requires 4.4g to land first before *any* TTF output reaches the + ANSI/SGR retarget (4.4j), or whether all REPL output — prompt included — shares one + rendering pipeline that requires 4.4j to land first before *any* TTF output reaches the screen. *Done when:* the dependency question is answered in writing here, based on reading the actual call chain, not assumed. *Refs:* §27.8. - > **DONE 2026-08-11 — answer: no dependency on 4.4g.** `draw_cursor_glyph()` + > **DONE 2026-08-11 — answer: no dependency on 4.4j.** `draw_cursor_glyph()` > (`vt100.c:125`) already calls `fb_draw_glyph(px, py, ch, f, b)` with `f`/`b` taken from > `g_vt.fg`/`g_vt.bg` — color support is already wired all the way through the *existing* > `font_8x16.c` pipeline, completely independent of which font renders the glyph shape. > `apply_sgr()` (`vt100.c:337-348`) already parses true 24-bit-color SGR: > `ESC[38;2;R;G;Bm` sets foreground RGB directly (not limited to the 16/256-color palette), - > `ESC[39m` resets to default. So 4.4e does not need to wait on 4.4g/4.4f at all — it can + > `ESC[39m` resets to default. So 4.4h does not need to wait on 4.4j/4.4i at all — it can > send `ESC[38;2;255;165;0m` (4.4's locked orange) before the bracket, `ESC[39m` after, and > `ESC[38;2;85;255;255m` (4.4's locked cyan) before `ok> `, all through `console_puts()` - > exactly as it works today. TTF (4.4f/4.4g) changes *what draws the glyph*, not *whether + > exactly as it works today. TTF (4.4i/4.4j) changes *what draws the glyph*, not *whether > color reaches the screen* — those are orthogonal, confirmed by reading the call chain > rather than assumed. @@ -5096,8 +5096,16 @@ document and committing that amendment as its own item.* three-arch QEMU boot + logs per CLAUDE.md. *Refs:* §27.8. + > **amd64 mechanism confirmed 2026-08-11**, three-arch still pending: + > [evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png](evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png) + > shows real boot/REPL text on the framebuffer for the first time (not just the corner + > blocks) — the fix's core mechanism works. Not marked done: verifying this screendump + > surfaced three further bugs, tracked as 4.4e/4.4f/4.4g below, and 4.4c's own *Done when* + > requires a clean three-arch match with the serial log, not yet attempted on + > aarch64/riscv64. + - [ ] **4.4d — Fix: `[VMName]` prefix never reaches the framebuffer.** Depends on 4.4c (the - framebuffer console must be live before this matters). Found while scoping 4.4e, given its + framebuffer console must be live before this matters). Found while scoping 4.4h, given its own item per §25.0 rule 3 rather than folded in silently. `console.c`'s `emit_prefix()` (called from `console_putc()` at line-start when `g_active_vm_name` is set) writes its `[VMName] ` characters directly via `raw_putc()` — serial only, per its own @@ -5113,14 +5121,79 @@ document and committing that amendment as its own item.* logs per CLAUDE.md. *Refs:* §27.8. -- [ ] **4.4e — Apply color to the prompt.** Depends on 4.4d (coloring a bracket that isn't + > **amd64 mechanism confirmed 2026-08-11**, three-arch still pending: same evidence as + > 4.4c — [evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png](evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png) + > shows `[Hera] ok>` genuinely on screen, not just in the serial log. Not marked done for + > the same reason as 4.4c: three-arch not yet attempted, and 4.4e/4.4f/4.4g were found + > verifying this same screendump. + +- [ ] **4.4e — Fix: `console_putc()` forwards `\n` to `vt100_putc()` without `\r`, corrupting + line starts.** Found while verifying 4.4c/4.4d by screendump — code is pre-existing, not + introduced by either item, just invisible until 4.4c turned the framebuffer console on. + `console.c`'s `raw_putc()` auto-injects `\r` before `\n` for the serial path (line + ~176-186); `console_putc()` forwards the *same* raw `\n` to `vt100_putc()` with no + accompanying `\r` (console.c:232-233). `vt100_putc()`'s `\n` handler (vt100.c:464-469) + only increments the row, never resets the column. Consequence, confirmed by screendump: + every line after the first starts at whatever column the previous line happened to end + on, not column 0 — text scatters diagonally across the screen instead of forming a + left-aligned column. + **Fix:** emit `\r` to `vt100_putc()` alongside `\n` wherever `console_putc()` mirrors to + the framebuffer, matching what `raw_putc()` already does for serial. + *Done when:* three-arch screendump shows every REPL/boot text line starting at column 0; + three-arch QEMU boot + logs per CLAUDE.md. + *Refs:* §27.8. + + > **Fix applied and amd64-confirmed 2026-08-11**, three-arch still pending: + > [evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png](evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png) + > shows every line starting at column 0, compared against the pre-fix screendump above + > where lines started at scattered x-positions. 4.4f (glyph flip) and 4.4g (missing lines) + > are both still present, unchanged, in this same screendump — confirming they are + > independent bugs, not caused by the `\r`/`\n` issue. Not marked done: three-arch not yet + > attempted. + +- [ ] **4.4f — Bug, not root-caused: character glyphs render vertically flipped on the + framebuffer.** Found while verifying 4.4c/4.4d by screendump. `[Hera] ok>` is legible in + content and position but every glyph appears upside-down under 6× zoom. Not yet traced to + a call site — candidate location is the glyph row-blit loop in `font_8x16.c` / + `fb_draw_glyph()`, unverified. + *Done when:* root cause identified and three-arch screendump shows glyphs in correct + orientation; three-arch QEMU boot + logs per CLAUDE.md. + *Refs:* §27.8. + + > **Evidence, amd64, 2026-08-11:** + > [evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png](evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png) + > — zoom in on `[Hera] ok>`; every glyph reads upside-down. Confirmed present both before + > and after the 4.4e fix, so it's independent of the `\r`/`\n` issue. + +- [ ] **4.4g — Anomaly, not root-caused: hundreds of lines of boot output never reach the + framebuffer.** Found while verifying 4.4c/4.4d by screendump. amd64 at 1280×800/scale=1 + has room for 50 character rows, but the captured screendump shows content in only ~6-8 + rows near the top; the rest of the screen is untouched background despite `log_message()` + (vm/host/shim.c:283-331) routing ANSI-colored HADES/ECW trace output plus Stadium/ + self-test text through `console_puts()` → `console_putc()` → `vt100_putc()` hundreds of + times during boot. `fb_scroll_rows()` (framebuffer.c:257) was read and appears + structurally sound on inspection — not ruled out, just not implicated by inspection alone. + Not caused by 4.4e's cursor-column bug: the anomaly is confirmed unchanged in the + post-4.4e-fix screendump, same row count, same blank region. Possibly the CSI/SGR parser's + handling of the heavy stream of embedded color-code escapes; not confirmed. + *Done when:* root cause identified and three-arch screendump shows the full boot/REPL + transcript visibly scrolled/filled on the framebuffer, matching the serial log; + three-arch QEMU boot + logs per CLAUDE.md. + *Refs:* §27.8. + + > **Evidence, amd64, 2026-08-11:** + > [evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png](evidence/amd64/qemu-screenshot-20260811-082822-post-4.4e-fix.png) + > — compare the ~780px of untouched black background below the visible text against the + > 50-row capacity computed from 1280×800 at scale=1. + +- [ ] **4.4h — Apply color to the prompt.** Depends on 4.4d (coloring a bracket that isn't drawn on screen accomplishes nothing). Per 4.4b's finding: either an independent - `TTF-TEXT` call with the color from 4.4, or gated on 4.4g completing first. + `TTF-TEXT` call with the color from 4.4, or gated on 4.4j completing first. *Done when:* three-arch screendump shows `[VM name]` and `ok>` in the colors locked at 4.4; three-arch QEMU boot + logs per CLAUDE.md. *Refs:* §27.8. -- [ ] **4.4f — Verify the VT100 CSI/SGR parser's glyph-draw call site is cleanly separable.** +- [ ] **4.4i — Verify the VT100 CSI/SGR parser's glyph-draw call site is cleanly separable.** Verification only, no code change. `vt100.c`'s CSI/SGR state machine (escape parsing, cursor tracking, 16/256-color SGR) calls `draw_cursor_glyph()` from a single site in `put_char()` — confirm nothing else in the parser depends on `font_8x16.c`-specific assumptions. @@ -5134,8 +5207,8 @@ document and committing that amendment as its own item.* compatibility question is answered from the actual font data, in writing here. *Refs:* §27.8. -- [ ] **4.4g — Retarget the glyph-draw call site from `font_8x16.c` to `TTF-TEXT`.** Depends - on 4.4f. **Boundary, corrected 2026-08-11:** `font_8x16.c`/VT100 keeps rendering everything +- [ ] **4.4j — Retarget the glyph-draw call site from `font_8x16.c` to `TTF-TEXT`.** Depends + on 4.4i. **Boundary, corrected 2026-08-11:** `font_8x16.c`/VT100 keeps rendering everything through and including **POST** (the parity/dictionary-hash self-test) — not just the pre-bootstrap M1–M6 messages originally scoped here. POST runs *after* the capsule/VM system is up (it hashes the loaded Mama capsule dictionary, per CLAUDE.md), so "before the capsule @@ -5156,7 +5229,7 @@ document and committing that amendment as its own item.* > preference"). The actual early-boot/POST fallback is `font_8x16.c` specifically, not "the > stroke font" generically. -- [ ] **4.4h — Live-verify ANSI color end-to-end.** Depends on 4.4g. Inject an SGR color +- [ ] **4.4k — Live-verify ANSI color end-to-end.** Depends on 4.4j. Inject an SGR color escape sequence (`ESC[3xm`/`ESC[9xm`/256-color) over serial and confirm it visibly changes `TTF-TEXT`-rendered glyph color in a screendump — the parser and the retargeted draw call working together, not just each existing independently. @@ -5164,49 +5237,49 @@ document and committing that amendment as its own item.* three architectures; three-arch QEMU boot + logs per CLAUDE.md. *Refs:* §27.8. -- [ ] **4.4i — Confirm actual booted framebuffer resolution, all three architectures.** +- [ ] **4.4l — Confirm actual booted framebuffer resolution, all three architectures.** Investigation only. amd64 already confirmed this session: 1280×800 (QEMU/OVMF GOP default, read directly off the 2026-08-11 verification screendump). aarch64/riscv64 unconfirmed. *Done when:* resolutions for all three architectures are recorded here from real screendumps or boot logs, not assumed. *Refs:* §27.8. -- [ ] **4.4j — Decide REPL-strip pixel height.** Currently undefined anywhere in this document - or the code. Once 4.4g lands, REPL text renders via `TTF-TEXT` at some chosen point/pixel +- [ ] **4.4m — Decide REPL-strip pixel height.** Currently undefined anywhere in this document + or the code. Once 4.4j lands, REPL text renders via `TTF-TEXT` at some chosen point/pixel size (also not yet chosen) — strip height derives from that size's line height plus padding, not from `font_8x16.c`'s fixed 8×16 cell. *Done when:* a REPL text size (px) and a resulting strip height (px) are both decided and recorded here. *Refs:* §27.8. -- [ ] **4.4k — CANVAS rectangle definition, per architecture.** Screen height (4.4i) minus REPL - strip height (4.4j) minus the small fixed gap (exact pixel value chosen here) between CANVAS +- [ ] **4.4n — CANVAS rectangle definition, per architecture.** Screen height (4.4l) minus REPL + strip height (4.4m) minus the small fixed gap (exact pixel value chosen here) between CANVAS and the strip. *Done when:* a CANVAS rectangle (top-left, width, height) is computed and recorded for each architecture. *Refs:* §27.8. -- [ ] **4.4l — 640×480 scroll-box centering math within CANVAS.** Layout math computed on top +- [ ] **4.4o — 640×480 scroll-box centering math within CANVAS.** Layout math computed on top of `TTF-TEXT`'s own coordinate primitive, which is simpler and already fixed: Cartesian, origin at the bottom-left of the **physical framebuffer** (not CANVAS-relative — resolved and implemented ahead of this item, 2026-08-11, `ttf_words.c`'s `baseline_y = fb_height() - - y`, verified by amd64 screendump). This item translates 4.4k's CANVAS-relative rectangle + y`, verified by amd64 screendump). This item translates 4.4n's CANVAS-relative rectangle into that same physical-framebuffer space. - **Open, blocking question, not assumed:** if any architecture's CANVAS height (4.4k) is + **Open, blocking question, not assumed:** if any architecture's CANVAS height (4.4n) is smaller than 480, this item cannot center the box as specified and must stop and report per §25.0 rule 5, not silently shrink it. *Done when:* box top-left coordinates are computed for each architecture, or the item stops and reports which architecture's CANVAS is too small. *Refs:* §27.8. -- [ ] **4.4m — Three-arch screendump verification of 4.4i–4.4l.** Geometry only — not the +- [ ] **4.4p — Three-arch screendump verification of 4.4l–4.4o.** Geometry only — not the toggle or scrollback. *Done when:* screendump on all three architectures shows the 640×480 box centered within CANVAS at the computed coordinates, with the fixed gap above the REPL strip visible; three-arch QEMU boot + logs per CLAUDE.md. *Refs:* §27.8. -- [ ] **4.4n — Scrollback, ~1000 lines.** A circular buffer of prior scroll-box lines, target +- [ ] **4.4q — Scrollback, ~1000 lines.** A circular buffer of prior scroll-box lines, target depth approximately 1000 (Captain Bob's own qualification: "something along those lines," not a hard-locked spec number). Storage mechanism (`kmalloc` ring buffer vs. static array) is this item's own implementation call. @@ -5215,16 +5288,16 @@ document and committing that amendment as its own item.* + logs per CLAUDE.md. *Refs:* §27.8. -- [ ] **4.4o — Toggle word: hide/show the scroll box.** A FORTH word that hides the 640×480 +- [ ] **4.4r — Toggle word: hide/show the scroll box.** A FORTH word that hides the 640×480 scroll box, revealing the rest of CANVAS beneath it for drawing; showing it again restores - the scroll-box content undisturbed, no scrollback loss. Depends on 4.4l/4.4m (geometry) and - 4.4n (scrollback) all being done first. + the scroll-box content undisturbed, no scrollback loss. Depends on 4.4o/4.4p (geometry) and + 4.4q (scrollback) all being done first. *Done when:* toggling off then on again, verified by screendump, shows the CANVAS drawing area unobstructed while off and the exact prior scroll-box content restored when back on; three-arch QEMU boot + logs per CLAUDE.md. *Refs:* §27.8. -- [ ] **4.4p — `(user)` prompt segment — scoped, blocked, not started.** Extends 4.4's prompt +- [ ] **4.4s — `(user)` prompt segment — scoped, blocked, not started.** Extends 4.4's prompt to `[VM name] (user) ok>`, e.g. `[Hera] (zuse) ok>`. **Blocked:** `zuse_session` (`include/vm.h:393`) is a boolean only — no username/identity string exists anywhere in the ACL system today (confirmed by reading `capsules/zuse.4th`, `capsules/ACL.4th`, @@ -6036,7 +6109,7 @@ direct-arena reference — 4.3.7b's own call) behind that lookup. *Refs:* §25.5 (punch list), GAP-B2. -### 27.8 REPL: prompt, text path, CANVAS geometry (4.4–4.4p) +### 27.8 REPL: prompt, text path, CANVAS geometry (4.4–4.4s) Scoped 2026-08-11, in conversation with Captain Bob, replacing `docs/lithosananke/ROADMAP.md`'s M8 section entirely (marked OBSOLETE there, kept for history only). Original visual reference: @@ -6063,11 +6136,11 @@ actually read — all found by checking the tree per §25.0 rule 4, not by assum per-line `[Name]` prefix on non-prompt output is unaffected (out of scope, not mentioned by Captain Bob, not touched here). - **Stroke-font color.** `TEXT ( c-addr u x y size color -- )` (§27.6.6) already takes a color - argument — confirmed before assuming 4.4g would need to add one. + argument — confirmed before assuming 4.4j would need to add one. **End goal, stated by Captain Bob 2026-08-11, applies to every item in this series:** the framebuffer console and the serial console must be functional **identically** — anything -printed reaches both. This is the standard 4.4c–4.4e (and, once 4.4g lands, the ANSI-colored +printed reaches both. This is the standard 4.4c–4.4h (and, once 4.4j lands, the ANSI-colored TTF path) are built to. **Found while verifying 4.4d by screendump — not future work, a pre-existing gap:** the whole @@ -6087,7 +6160,7 @@ terminal state machine — CSI parameter parsing, cursor tracking, full SGR colo glyph-drawing call is a single, separate site (`put_char()` → `draw_cursor_glyph()`). Captain Bob's "completely 100% obsolete" instruction, read against this, resolves to: keep the CSI/SGR engine (it's exactly the "ANSI colorization throughout" mechanism wanted), retarget only - the one glyph-draw call site from `font_8x16.c` to `TTF-TEXT` (4.4f/4.4g). This is not a reversal of + the one glyph-draw call site from `font_8x16.c` to `TTF-TEXT` (4.4i/4.4j). This is not a reversal of the obsolescence call — the VT100 *console text path as currently wired* (feeding `font_8x16.c`-rendered REPL text) is still going away for user-facing text; the parser underneath it is what survives, repointed. @@ -6104,8 +6177,8 @@ the *physical framebuffer*, decoupled from REPL-strip sizing (resolved via `AskU 2026-08-11, implemented in `ttf_words.c` ahead of this item, verified by amd64 screendump showing y=60/400/700 rendering bottom/middle/top respectively). CANVAS-relative placement — the 640×480 scroll box centered within the region above the REPL strip — is a separate layout -computation (4.4l) that translates into that same physical-framebuffer coordinate space before -calling `TTF-TEXT`. The primitive doesn't know about CANVAS or the REPL strip; 4.4l's layout +computation (4.4o) that translates into that same physical-framebuffer coordinate space before +calling `TTF-TEXT`. The primitive doesn't know about CANVAS or the REPL strip; 4.4o's layout math does. *Refs:* §25.5 (punch list), §27.6, §27.7. diff --git a/evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png b/evidence/amd64/qemu-screenshot-20260811-081837-pre-4.4e-fix.png new file mode 100644 index 0000000000000000000000000000000000000000..cd294920eae23667d7103a90ed013634a5abb940 GIT binary patch literal 6510 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