FABRIC.md: insert 4.4c (wire console_fb_init into boot), renumber 4.4c-4.4o to 4.4d-4.4p

Found while screendump-verifying the prefix fix (now 4.4d): kernel_main.c
deliberately never calls console_fb_init(), so vt100_init() never runs and
vt100_putc() no-ops on every call -- no console output has ever reached the
framebuffer, only fb_init()'s own corner self-test blocks. ROADMAP.md's
obsolete M8 section claimed this path was already live; that was never
actually screendump-verified.

Records Captain Bob's stated end goal (2026-08-11): framebuffer console and
serial console must be functional identically. 4.4c wires that in.

Only uncommitted items were renumbered; 4.4/4.4a/4.4b keep their IDs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-11 07:56:07 -04:00
co-authored by Claude Sonnet 5
parent d187c87671
commit bf89b8239f
+82 -39
View File
@@ -4981,7 +4981,7 @@ document and committing that amendment as its own item.*
*added above this marker.)* *added above this marker.)*
- [x] **4.4 — Design-only: lock the prompt format and color values.** No code. Write down the - [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.4o — and the exact exact target string — `[VM name] ok>` for now, `(user)` added later per 4.4p — and the exact
color values for the bracketed VM name and for `ok>` against 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 [`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 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 > 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 > 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. > (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.4d to consume directly; no > These are literal `FB_RGB()`-equivalent values for 4.4a/4.4e to consume directly; no
> implementation performed by this item, per its own "no code" scope. > 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 - [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]` 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 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 lines) and `repl.c`'s prompt-suffix `<Name>)ok>` (`sk_repl_run()`/`sk_repl_step()`) — with
`[VM name] ok>`, no color yet (4.4d). VM attach itself needs no new work: `USE` `[VM name] ok>`, no color yet (4.4e). 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()` (`mama_forth_words.c:1108`) already sets both `g_repl_active_vm` and `console_set_vm_name()`
— this item is a *display* change only. — this item is a *display* change only.
*Done when:* all three architectures boot to a bracketed `[Hera] ok>` prompt (replacing *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 > untouched — this is a display-only change, the ACL bypass semantics are identical to
> before. > before.
> >
> **Known, intentional gap until 4.4o:** the old prompt distinguished `zuse)ok>` from bare > **Known, intentional gap until 4.4p:** the old prompt distinguished `zuse)ok>` from bare
> `ok>` textually. That distinction is not yet visible in the new unified prompt — it moves > `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.4o. The underlying > to the `(user)` segment, which is explicitly scoped-but-blocked at 4.4p. The underlying
> `zuse_session`/`emergency_console` mechanics are unchanged; only the on-screen indicator is > `zuse_session`/`emergency_console` mechanics are unchanged; only the on-screen indicator is
> temporarily gone. > temporarily gone.
> >
@@ -5043,35 +5043,62 @@ document and committing that amendment as its own item.*
> >
> **Caveat found afterward, not fixed here:** that verification is serial-log-only — > **Caveat found afterward, not fixed here:** that verification is serial-log-only —
> `[VMName]` never actually reaches the framebuffer (`console.c`'s `emit_prefix()` is > `[VMName]` never actually reaches the framebuffer (`console.c`'s `emit_prefix()` is
> serial-only by construction). Given its own item, 4.4c, rather than silently rolled into > serial-only by construction). Given its own item, 4.4d, rather than silently rolled into
> this one. > this one.
- [x] **4.4b — Resolve: does prompt color depend on 4.4f?** Investigation, not implementation. - [x] **4.4b — Resolve: does prompt color depend on 4.4g?** Investigation, not implementation.
Read the REPL's actual output path (`console_puts()` → ... → `vt100_putc()` Read the REPL's actual output path (`console_puts()` → ... → `vt100_putc()`
`draw_cursor_glyph()`, all currently `font_8x16.c`) to determine whether a single `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 hardcoded-color prompt segment can call `TTF-TEXT` directly, independent of the general
ANSI/SGR retarget (4.4f), or whether all REPL output — prompt included — shares one ANSI/SGR retarget (4.4g), or whether all REPL output — prompt included — shares one
rendering pipeline that requires 4.4f to land first before *any* TTF output reaches the rendering pipeline that requires 4.4g to land first before *any* TTF output reaches the
screen. screen.
*Done when:* the dependency question is answered in writing here, based on reading the *Done when:* the dependency question is answered in writing here, based on reading the
actual call chain, not assumed. actual call chain, not assumed.
*Refs:* §27.8. *Refs:* §27.8.
> **DONE 2026-08-11 — answer: no dependency on 4.4f.** `draw_cursor_glyph()` > **DONE 2026-08-11 — answer: no dependency on 4.4g.** `draw_cursor_glyph()`
> (`vt100.c:125`) already calls `fb_draw_glyph(px, py, ch, f, b)` with `f`/`b` taken from > (`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* > `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. > `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: > `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[38;2;R;G;Bm` sets foreground RGB directly (not limited to the 16/256-color palette),
> `ESC[39m` resets to default. So 4.4d does not need to wait on 4.4f/4.4e at all — it can > `ESC[39m` resets to default. So 4.4e does not need to wait on 4.4g/4.4f at all — it can
> send `ESC[38;2;255;165;0m` (4.4's locked orange) before the bracket, `ESC[39m` after, and > 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()` > `ESC[38;2;85;255;255m` (4.4's locked cyan) before `ok> `, all through `console_puts()`
> exactly as it works today. TTF (4.4e/4.4f) changes *what draws the glyph*, not *whether > exactly as it works today. TTF (4.4f/4.4g) changes *what draws the glyph*, not *whether
> color reaches the screen* — those are orthogonal, confirmed by reading the call chain > color reaches the screen* — those are orthogonal, confirmed by reading the call chain
> rather than assumed. > rather than assumed.
- [ ] **4.4c — Fix: `[VMName]` prefix never reaches the framebuffer.** Found while scoping - [ ] **4.4c — Wire `console_fb_init()` into the boot path.** Found while verifying 4.4d
4.4d, given its own item per §25.0 rule 3 rather than folded in silently. `console.c`'s (below) by screendump — not a bug in 4.4a/4.4b, a pre-existing, deliberate gap.
`kernel_main.c:830-834` has an explicit comment: *"console.c / vt100.c are superseded by
the Console drawing-fabric redesign (FABRIC.md §27) and are deliberately not invoked
here... `fb_init()` wires the raw GOP framebuffer directly... nothing else touches it."*
Only raw `fb_init()` runs; `console_fb_init()` (which calls `vt100_init()`) is never
called anywhere in the boot sequence. Consequence, confirmed by screendump: `vt100_putc()`
no-ops on every call (`if (!g_vt.initialized) return;`), so **no console output has ever
reached the framebuffer** — not REPL text, not POST/boot logs, nothing except the
framebuffer driver's own corner self-test blocks (`fb_draw_orientation_test()`) and
whatever TTF probes have drawn directly. ROADMAP.md's now-obsolete M8 section claimed this
path was "already live" — that was never actually screendump-verified and turned out to be
wrong.
**End goal, stated by Captain Bob 2026-08-11:** the framebuffer console and the serial
console must be functional **identically** — every character reaching one reaches the
other. `console_putc()` already implements exactly that split for ordinary characters
(`raw_putc()` for serial, `vt100_putc()` for framebuffer, unconditionally paired); the only
thing missing is turning the framebuffer half on at all.
**Fix:** call `console_fb_init(&boot_info->framebuffer, fb_fmt)` in `kernel_main.c`,
replacing or immediately following the existing raw `fb_init()` call, so `vt100_init()`
actually runs.
*Done when:* three-arch screendump shows live boot/POST/REPL text actually rendered on the
framebuffer (not just the corner test blocks) — matching what the serial log already shows;
three-arch QEMU boot + logs per CLAUDE.md.
*Refs:* §27.8.
- [ ] **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
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) `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 writes its `[VMName] ` characters directly via `raw_putc()` — serial only, per its own
comment ("no recursion into `console_putc`"). It never calls `vt100_putc()`, so the comment ("no recursion into `console_putc`"). It never calls `vt100_putc()`, so the
@@ -5086,14 +5113,14 @@ document and committing that amendment as its own item.*
logs per CLAUDE.md. logs per CLAUDE.md.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4d — Apply color to the prompt.** Depends on 4.4c (coloring a bracket that isn't - [ ] **4.4e — 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 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.4f completing first. `TTF-TEXT` call with the color from 4.4, or gated on 4.4g completing first.
*Done when:* three-arch screendump shows `[VM name]` and `ok>` in the colors locked at 4.4; *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. three-arch QEMU boot + logs per CLAUDE.md.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4e — Verify the VT100 CSI/SGR parser's glyph-draw call site is cleanly separable.** - [ ] **4.4f — 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 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()` 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. confirm nothing else in the parser depends on `font_8x16.c`-specific assumptions.
@@ -5107,8 +5134,8 @@ document and committing that amendment as its own item.*
compatibility question is answered from the actual font data, in writing here. compatibility question is answered from the actual font data, in writing here.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4f — Retarget the glyph-draw call site from `font_8x16.c` to `TTF-TEXT`.** Depends - [ ] **4.4g — Retarget the glyph-draw call site from `font_8x16.c` to `TTF-TEXT`.** Depends
on 4.4e. **Boundary, corrected 2026-08-11:** `font_8x16.c`/VT100 keeps rendering everything on 4.4f. **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 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 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 is up (it hashes the loaded Mama capsule dictionary, per CLAUDE.md), so "before the capsule
@@ -5129,7 +5156,7 @@ document and committing that amendment as its own item.*
> preference"). The actual early-boot/POST fallback is `font_8x16.c` specifically, not "the > preference"). The actual early-boot/POST fallback is `font_8x16.c` specifically, not "the
> stroke font" generically. > stroke font" generically.
- [ ] **4.4g — Live-verify ANSI color end-to-end.** Depends on 4.4f. Inject an SGR color - [ ] **4.4h — Live-verify ANSI color end-to-end.** Depends on 4.4g. Inject an SGR color
escape sequence (`ESC[3xm`/`ESC[9xm`/256-color) over serial and confirm it visibly changes 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 `TTF-TEXT`-rendered glyph color in a screendump — the parser and the retargeted draw call
working together, not just each existing independently. working together, not just each existing independently.
@@ -5137,49 +5164,49 @@ document and committing that amendment as its own item.*
three architectures; three-arch QEMU boot + logs per CLAUDE.md. three architectures; three-arch QEMU boot + logs per CLAUDE.md.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4h — Confirm actual booted framebuffer resolution, all three architectures.** - [ ] **4.4i — Confirm actual booted framebuffer resolution, all three architectures.**
Investigation only. amd64 already confirmed this session: 1280×800 (QEMU/OVMF GOP default, 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. read directly off the 2026-08-11 verification screendump). aarch64/riscv64 unconfirmed.
*Done when:* resolutions for all three architectures are recorded here from real *Done when:* resolutions for all three architectures are recorded here from real
screendumps or boot logs, not assumed. screendumps or boot logs, not assumed.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4i — Decide REPL-strip pixel height.** Currently undefined anywhere in this document - [ ] **4.4j — Decide REPL-strip pixel height.** Currently undefined anywhere in this document
or the code. Once 4.4f lands, REPL text renders via `TTF-TEXT` at some chosen point/pixel or the code. Once 4.4g 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, 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. 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 *Done when:* a REPL text size (px) and a resulting strip height (px) are both decided and
recorded here. recorded here.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4j — CANVAS rectangle definition, per architecture.** Screen height (4.4h) minus REPL - [ ] **4.4k — CANVAS rectangle definition, per architecture.** Screen height (4.4i) minus REPL
strip height (4.4i) minus the small fixed gap (exact pixel value chosen here) between CANVAS strip height (4.4j) minus the small fixed gap (exact pixel value chosen here) between CANVAS
and the strip. and the strip.
*Done when:* a CANVAS rectangle (top-left, width, height) is computed and recorded for each *Done when:* a CANVAS rectangle (top-left, width, height) is computed and recorded for each
architecture. architecture.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4k — 640×480 scroll-box centering math within CANVAS.** Layout math computed on top - [ ] **4.4l — 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, 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 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() - 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.4j's CANVAS-relative rectangle y`, verified by amd64 screendump). This item translates 4.4k's CANVAS-relative rectangle
into that same physical-framebuffer space. into that same physical-framebuffer space.
**Open, blocking question, not assumed:** if any architecture's CANVAS height (4.4j) is **Open, blocking question, not assumed:** if any architecture's CANVAS height (4.4k) is
smaller than 480, this item cannot center the box as specified and must stop and report per 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. §25.0 rule 5, not silently shrink it.
*Done when:* box top-left coordinates are computed for each architecture, or the item stops *Done when:* box top-left coordinates are computed for each architecture, or the item stops
and reports which architecture's CANVAS is too small. and reports which architecture's CANVAS is too small.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4l — Three-arch screendump verification of 4.4h4.4k.** Geometry only — not the - [ ] **4.4m — Three-arch screendump verification of 4.4i4.4l.** Geometry only — not the
toggle or scrollback. toggle or scrollback.
*Done when:* screendump on all three architectures shows the 640×480 box centered within *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; CANVAS at the computed coordinates, with the fixed gap above the REPL strip visible;
three-arch QEMU boot + logs per CLAUDE.md. three-arch QEMU boot + logs per CLAUDE.md.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4m — Scrollback, ~1000 lines.** A circular buffer of prior scroll-box lines, target - [ ] **4.4n — Scrollback, ~1000 lines.** A circular buffer of prior scroll-box lines, target
depth approximately 1000 (Captain Bob's own qualification: "something along those lines," 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) not a hard-locked spec number). Storage mechanism (`kmalloc` ring buffer vs. static array)
is this item's own implementation call. is this item's own implementation call.
@@ -5188,16 +5215,16 @@ document and committing that amendment as its own item.*
+ logs per CLAUDE.md. + logs per CLAUDE.md.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4n — Toggle word: hide/show the scroll box.** A FORTH word that hides the 640×480 - [ ] **4.4o — 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 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.4k/4.4l (geometry) and the scroll-box content undisturbed, no scrollback loss. Depends on 4.4l/4.4m (geometry) and
4.4m (scrollback) all being done first. 4.4n (scrollback) all being done first.
*Done when:* toggling off then on again, verified by screendump, shows the CANVAS drawing *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; area unobstructed while off and the exact prior scroll-box content restored when back on;
three-arch QEMU boot + logs per CLAUDE.md. three-arch QEMU boot + logs per CLAUDE.md.
*Refs:* §27.8. *Refs:* §27.8.
- [ ] **4.4o — `(user)` prompt segment — scoped, blocked, not started.** Extends 4.4's prompt - [ ] **4.4p — `(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` 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 (`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`, ACL system today (confirmed by reading `capsules/zuse.4th`, `capsules/ACL.4th`,
@@ -6009,7 +6036,7 @@ direct-arena reference — 4.3.7b's own call) behind that lookup.
*Refs:* §25.5 (punch list), GAP-B2. *Refs:* §25.5 (punch list), GAP-B2.
### 27.8 REPL: prompt, text path, CANVAS geometry (4.44.4o) ### 27.8 REPL: prompt, text path, CANVAS geometry (4.44.4p)
Scoped 2026-08-11, in conversation with Captain Bob, replacing `docs/lithosananke/ROADMAP.md`'s 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: M8 section entirely (marked OBSOLETE there, kept for history only). Original visual reference:
@@ -6036,7 +6063,23 @@ 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 per-line `[Name]` prefix on non-prompt output is unaffected (out of scope, not mentioned by
Captain Bob, not touched here). Captain Bob, not touched here).
- **Stroke-font color.** `TEXT ( c-addr u x y size color -- )` (§27.6.6) already takes a color - **Stroke-font color.** `TEXT ( c-addr u x y size color -- )` (§27.6.6) already takes a color
argument — confirmed before assuming 4.4f would need to add one. argument — confirmed before assuming 4.4g 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
TTF path) are built to.
**Found while verifying 4.4d by screendump — not future work, a pre-existing gap:** the whole
VT100-on-framebuffer pipeline this series assumed was live (parser, cell grid,
`draw_cursor_glyph`) has never actually been connected to the boot sequence.
`kernel_main.c:830-834` deliberately skips `console_fb_init()` (comment: "superseded by the
Console drawing-fabric redesign... deliberately not invoked here"), so `vt100_init()` never
runs and `vt100_putc()` no-ops on every call. No console output — not REPL text, not
boot/POST logs — has ever reached the framebuffer; only the framebuffer driver's own corner
self-test blocks have. ROADMAP.md's now-obsolete M8 section claimed this path was "already
live"; that was never actually screendump-verified, and turned out to be wrong. Given its own
item, 4.4c, ahead of 4.4d, which depends on it.
**Found, changes the shape of "VT100 is obsolete":** `vt100.c` is a complete ANSI/VT100 **Found, changes the shape of "VT100 is obsolete":** `vt100.c` is a complete ANSI/VT100
terminal state machine — CSI parameter parsing, cursor tracking, full SGR color support terminal state machine — CSI parameter parsing, cursor tracking, full SGR color support
@@ -6044,7 +6087,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()`). 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 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 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.4e/4.4f). This is not a reversal of the one glyph-draw call site from `font_8x16.c` to `TTF-TEXT` (4.4f/4.4g). This is not a reversal of
the obsolescence call — the VT100 *console text path as currently wired* (feeding 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 `font_8x16.c`-rendered REPL text) is still going away for user-facing text; the parser
underneath it is what survives, repointed. underneath it is what survives, repointed.
@@ -6061,8 +6104,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 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 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 640×480 scroll box centered within the region above the REPL strip — is a separate layout
computation (4.4k) that translates into that same physical-framebuffer coordinate space before 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.4k's layout calling `TTF-TEXT`. The primitive doesn't know about CANVAS or the REPL strip; 4.4l's layout
math does. math does.
*Refs:* §25.5 (punch list), §27.6, §27.7. *Refs:* §25.5 (punch list), §27.6, §27.7.