Development record
The bare-invocation banner: baked identity, half-block livery art, and the exported colour ladder
Summary
spc-41 delivers itd-112: a bare abcd on an interactive TTY greets with a
generated banner — the true-geometry flag hoist from the livery grids in
half-block pixels on the painted panel colour, abcd vX.Y.Z beside it,
tagline and next-action hints beneath — above the unchanged status board.
Machine-consumed streams receive no decoration bytes, per adr-49 and brief
invariant 13. The build ships two new exported primitives (the colour
ladder and the TTY seam) and the identity bake, all drift-gated.
Scope
In: the banner composition and its wiring at the CLI root; the identity
bake (generator → Go constant, drift test, itd-102 surface registration);
the colour ladder (truecolor/256/16/mono with the ruled precedence) and
stdout TTY seam as exported primitives; pinned 256/16 ANSI tables in
internal/livery with parity tests; the root-local --no-color flag; a
CHANGELOG entry.
Out (per the intent): the managed-repo generator (itd-134); styling other surfaces (itd-110 consumes the primitives later); terminal-width detection; Windows (no shipped binary).
Approach
- Identity bake. A generator (the livery/gen pattern) reads the
canonical identity block and writes title + tagline into a generated Go
file; a test regenerates and byte-compares (drift gate), and the
generated file is registered as a
regexppositioning surface soabcd identitysees banner drift. The banner never reads the cwd's block — an installed abcd in a foreign repo must not wear that repo's tagline. Baked text is trusted; nothing on the banner path reads repo-controlled bytes at runtime, so termsafe's contract is untouched. - ANSI tables beside the palette.
internal/liverygains pinned 256- and 16-colour tables keyed identically to the hex palette, with a key-set parity test; truecolor renders38;2;r;g;bstraight from hex. The 'k' substitution rule (TransparentEyeColor) is honoured by the terminal renderer exactly as documented onPalette(). - Pure renderer, thin emitter. Grid → composed-lines rendering
(half-block pairing, render-time padding of the five-row strip to even
height, panel background painting, glyph selection for transparent
halves) is a pure function returning
[]string, testable without a terminal; the CLI root owns the emission decision. The canonical grids are never mutated (itd-133's geometry and drift gates stay green). - Ladder and seam. Colour detection is a pure resolver over an explicit
environment map — table-tested for the ruled precedence (
--no-color> NO_COLOR present-and-non-empty > TERM dumb/unset > COLORTERM > 256 > 16) — and the TTY check is one exported stdout-facing seam (a package-var seam per the repo's established pattern), consolidating the two existing hand-rolled stdin checks rather than adding a third copy. Both are exported, banner-independent; itd-110 carriesbuilds_on: [itd-112]. - Wiring. The banner renders only in the root command's bare-invocation
path, gated on args-empty, not-
--json, and the TTY seam; one test asserts the status board's bytes are unchanged when the banner is off, and one asserts captured non-TTY output contains no escape bytes (the adr-49 machine-stream assertion). Mono renders the five-row shade-block form; a non-UTF-8 locale gets the text lines only. - Version. The version segment renders the build-stamped
core.Version;"dev"/empty rendersabcd (dev build). No repo read.
Acceptance criteria → how satisfied
- Banner over unchanged board — root-path wiring plus the board-bytes-unchanged test; fixed ≤66-column layout.
- Machine streams clean — the TTY seam defaults off under test; the no-escape-bytes assertion runs on captured non-TTY output.
- Ladder precedence + mono art — table-tested resolver; mono renders the shade-block form; locale check falls back to text-only.
- Baked identity + dev build — generator, drift test, positioning surface registration; version render rule.
- Tables beside palette, grids immutable — parity test; render-time padding; itd-133 gates untouched.
- Records and edges — adr-49 + invariant 13 (landed with the planning
interview); ladder/seam exported; itd-110
builds_onwritten.
Frontmatter
| id | spc-41 |
|---|---|
| type | spec |
| lifecycle | closed |
.abcd/development/specs/closed/spc-41-bare-abcd-opens-with-a-generated-banner.md
open on GitHub ↗ · commit history ↗
References1
- itd-112A bare abcd on an interactive terminal opens with a generated banner: the flag hoist in half-block colour on its painted panel, version beside it, tagline beneath — identity baked in at build time, full colour ladder, never a byte on a machine-consumed streamimplements
mentions8
- adr-49Terminal emission discipline — decoration only on interactive TTYs, machine streams undecorated, untrusted text always sanitised
- itd-29Domain Experts Run A Spec Autonomously And Recover From Anything Without Touching Git
- itd-49Flow-State Drift Becomes Visible Before It Compounds
- itd-102**Your repo says the same thing about itself everywhere — because abcd asked you once and holds every surface to it.** A project's positioning fragments silently: the README strapline, the package or plugin manifest description, and the agent conventions file are each edited at different moments, and soon three surfaces tell three stories about what the project is. When abcd prepares a repo it interviews the user for the project's identity — title, tagline, and a short elevator pitch — and records the answers in one canonical home in the development record. Every surface rendering derives from that home, and a deterministic positioning check compares the surfaces against it on every audit: a mismatch is highlighted with the exact drifted line, and the fix is either re-render from the record or a deliberate, recorded identity change — never a silent extra variant, and never a silent rewrite by abcd. "I changed my tagline once, in one place, and abcd chased it everywhere else," said Alice, a solo founder. "When a stray edit crept into the README, the next audit pointed at the exact line instead of letting the drift settle in."
- itd-110The grill interview renders with clear structure and colour instead of a wall of prose: each question visually separated, the decision point, options, and the recommended answer distinctly styled, progress through the design tree visible, so the person being grilled always knows what is being asked and where they are
- itd-133abcd has a face: one pixel-grid identity — duckling mascot, signal-flag logo, lifeboat mark — generated, drift-gated, ready for every surface
- itd-134Every abcd-managed CLI greets like abcd does: one command scaffolds a banner for a managed repo, rendered from that repo's canonical identity block — name, tagline, version — as a committed, language-neutral artefact (the generator emits the rendered banner, not code), so a CLI in any language opens with its own identity without hand-drawing anything. Split out of itd-112 at its 2026-08-21 grill: itd-112 keeps abcd's own banner and the colour ladder; this intent carries the managed-repo generator and the per-repo accent question.
- spc-2609230613206687The banner fits 66 columns