Skip to content

Define the console glyph vocabulary: replace kaomoji with a width-aware icon set #557

Open

Description

@ChrisonSimtian

Problem

The inherited NUKE glyph vocabulary is arbitrary. The build outcome line ends in kaomoji (src/Fallout.Build/Host.cs:176-179):

Build succeeded on 26/07/2026 22:49:03. \(^ᴗ^)/
Build failed on 26/07/2026 22:49:45. (╯°□°)╯︵ ┻━┻

Elsewhere: ☢ in the logo tagline (deliberate, keep), » as a selection marker, ¬ as a confirmation marker (#555). Target status in the summary table is carried by colour alone — green Succeeded, yellow NotRun, red Failed — with no glyph.

There is no vocabulary: no rule for which glyph means what, no fallback for terminals that cannot render one, and no width handling.

Outcome

A defined, documented icon set where each glyph is self-explaining, renders at a known width, and degrades to ASCII when the terminal cannot show it. Status is legible without colour.

Acceptance criteria

  • A single internal source of truth maps semantic states (succeeded / failed / skipped / not-run / aborted / warning / running) to glyphs
  • Every glyph has an ASCII fallback, selected by a capability probe rather than assumed
  • Glyph rendering goes through display-width measurement, not string.Length
  • Kaomoji removed from the build outcome line
  • NO_COLOR is honoured, and status stays distinguishable with colour off
  • The vocabulary is documented so tool wrappers and plugins use the same glyphs

Design constraints

1. Column alignment breaks twice over. Host.WriteTargetOutcome pads with PadRight/PadLeft over string.Length — UTF-16 code units. Emoji break both halves of that assumption:

Glyph Code units Display cells
✅ U+2705 1 2
⚠️ U+26A0 U+FE0F 2 2
✔ U+2714 1 1
☢ U+2622 1 1

PadRight over-pads narrow glyphs and under-pads wide ones. This is why the item belongs to the Spectre migration: Spectre.Console measures display width and owns the table layout. Doing it on the current PadRight code means hand-rolling a width table.

2. Terminal capability is a matrix, not a boolean. Console.OutputEncoding = Encoding.UTF8 is already set (src/Fallout.Build/Execution/BuildManager.cs:39), so encoding is fine — but legacy conhost with a raster font renders emoji as boxes. The existing capability check is a single bad sniff (TERM starts with xterm, src/Fallout.Build/Logging.cs:21), which reports no ANSI support on Windows Terminal. A real probe is a prerequisite, not an afterthought.

3. Emoji do not take colour. Status is conveyed by ANSI colour today. Presentation-form emoji ignore SGR, so the glyph column and the colour scheme have to be designed together. Treat the glyph as the accessibility win — colour-blind readers, NO_COLOR, piped logs, CI log viewers — rather than decoration.

4. Two glyph classes, different rules. Narrow single-cell symbols (✔ ✖ ✱ » ‣) can sit inside padded columns and take colour. Wide emoji (✅ ❌ ⚠️ ⏭️) cannot sit in a padded column without width-aware measurement, and are best kept to non-tabular lines (the outcome line, block headers).

Open questions

  • Narrow symbols everywhere, or wide emoji on non-tabular lines and narrow symbols in the table?
  • Is the glyph additive to the status word, or does it replace it?
  • Does the CI-host path get glyphs at all, or do GitHub Actions / TeamCity annotations carry that already?

Notes

Sub-issue of #391 — depends on Spectre owning the table layout and display-width measurement. The ¬ confirmation marker (#555) is fixed independently as a plain bug; this issue defines the vocabulary it should eventually draw from.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions