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 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-11 08:35:58 -04:00
co-authored by Claude Sonnet 5
parent eefe765f00
commit 859381640b
3 changed files with 111 additions and 38 deletions
+111 -38
View File
@@ -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 `<Name>)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 M1M6 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.4i4.4l.** Geometry only — not the
- [ ] **4.4p — Three-arch screendump verification of 4.4l4.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.44.4p)
### 27.8 REPL: prompt, text path, CANVAS geometry (4.44.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.4c4.4e (and, once 4.4g lands, the ANSI-colored
printed reaches both. This is the standard 4.4c4.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.