# Glyph Library Small, reusable SVG primitives that several sub-patterns draw *inside* their boxes or *on top of* their connectors: status circles on an arrow, checkboxes in a TODO list, queue slots inside a worker box, a document icon inside a shared-state store, a labeled annotation circle halfway along an arrow. These are intentionally *shared across types*. A status circle belongs in a flowchart (Generator-Verifier) and also in a structural advisor diagram. A checkbox belongs in a structural "TODOs vs Tasks" comparison and also in an illustrative "agent task list" subject. Keeping them in one place keeps the visual vocabulary consistent across diagrams. ## Hard rules Every glyph in this file obeys **all** of the design system's hard rules (`design-system.md` → "Hard rules"). In particular: - **SVG primitives only.** Every glyph is composed of ``, ``, ``, ``, ``, or ``. No ``, no ``, no emoji characters. - **No hardcoded colors on text or strokes that need dark-mode response.** Every glyph uses the existing CSS classes (`c-{ramp}`, `arr-{ramp}`, `arr-alt`, `box`, `t`/`th`/`ts`). This means both light and dark mode are handled automatically — zero template changes required. - **No rotated text.** (Glyphs are small enough that horizontal text always fits.) - **Sentence case** on any labels. If a new glyph seems to require a hardcoded color or a new CSS rule, stop and reconsider — the shape is probably wrong, or it belongs in one of the existing ramps. ## Coordinate convention Every glyph block below is drawn with its **top-left anchor at (0, 0)**, then wrapped in a `` to place it in the diagram. The glyph's *bounding box width × height* is listed in each subsection so you can reserve space and pick `x, y` from the parent layout. ```svg ``` All `x`/`y`/`cx`/`cy`/`d` values in the snippets below are **relative to the glyph origin**, not the diagram origin. Don't edit them — just translate the wrapper group. --- ## Status circles A circle placed on or near an arrow to tag the outcome of a decision. Three variants: ✓ success, ✗ failure, ● in-progress. **Bounding box.** 24 × 24. Place the center of the circle at `(12, 12)` inside the glyph origin. When placed on a diagram, translate so that `(12, 12)` lands at the desired anchor — usually the midpoint of an arrow or just past a gate node. **Where they're used.** - Flowchart (Generator-Verifier, Agent Teams, gate patterns): tag the two branches out of a verifier or judge node. - Structural (advisor, TODOs→Tasks): mark individual task outcomes inside a state box. **Color rules.** Status carries semantic color — not negotiable: - `check` → `c-green` / `arr-green` (accept, pass, done) - `x` → `c-coral` / `arr-coral` (reject, fail, blocked) - `dot` → `c-amber` / `arr-amber` (in-progress, busy, running) **Dark mode.** All three use the existing ramp classes, so both the circle fill and the inner stroke invert automatically. ### status-circle-check ```svg ``` ### status-circle-x ```svg ``` ### status-circle-dot ```svg ``` The nested small circle shares the ramp but is visually distinct because it sits on top of its own border stroke, reading as a filled dot against the paler ring. ### Placement on an arrow A status circle placed *on* an arrow replaces that arrow's tail: ``` status-circle-check (center at x=360, y=160) │ (start)────arrow 1──→ ◎ ────arrow 2──→(end) ``` Split the original arrow into two segments, both with `marker-end="url(#arrow)"`. The circle sits in the gap. Arrow 1 stops at `circle_cx − 14` (2px before the circle border). Arrow 2 starts at `circle_cx + 14`. **Pitfall.** Don't layer the circle on top of a single continuous line — the arrow renders behind the circle and looks as if it pierces straight through. Always split into two segments. --- ## Checkboxes A 14 × 14 checkbox glyph for task lists. Two variants: checked (filled green with check) and empty (neutral outline). **Bounding box.** 14 × 14. **Where they're used.** - Structural (TODOs → Tasks comparison, checklist interiors inside a subsystem container): one per task row. - Illustrative (task list subject, sparingly): only if the task list is the whole mechanism being shown. **Color rules.** - `checked` → `c-green` (task done) - `empty` → `c-gray` (task pending) For an "in-progress" task, substitute `status-circle-dot` at half scale, or just leave it empty. Don't invent a third checkbox color. ### checkbox-checked ```svg ``` ### checkbox-empty ```svg ``` ### Checklist rows A row of checklist items is laid out with the checkbox on the left and a 14px `t`-class label to its right: ```svg Draft the outline ``` Row pitch: 22px (14px checkbox height + 8px vertical gap). Label `y = checkbox_y + 11` for vertical centering against the 14px box. **Row width budget.** Inside a 315-wide subsystem container with 20px interior padding, the label has `315 − 20 − 20 − 14 − 8 = 253` px of width. At 8px/char (14px Latin) that caps the label at **~31 characters**; at 15px/char (CJK) that caps at **~16 characters**. Longer labels must be truncated or wrapped across two rows. --- ## Queue slots A row of small filled/empty squares that represents a work queue or a buffer. Not to be confused with checklists — queue slots are *undifferentiated items*, checklists are *named tasks*. **Bounding box per slot.** 16 × 16. Row pitch: 20 (16 + 4 gap). Typical row: 6–8 slots max per row. **Where they're used.** - Flowchart (Agent Teams, task-queue hub node): show the queue of pending work *inside* a source node. - Structural (any box representing a worker pool with a buffer): same purpose, different frame. **Color rules.** - `filled` → `c-amber` (work waiting in queue) - `empty` → `c-gray` (slot available) ### queue-slot-filled ```svg ``` ### queue-slot-empty ```svg ``` ### Queue row inside a box For a two-line box (`title + queue row`), the queue row goes at `rect_y + 28` (below the title baseline), starting at `rect_x + 12`: ```svg Task queue ``` Box height for this variant: **52px** (title row + queue row + vertical padding). Don't reuse the default 44 or 56 heights — the queue row needs its own budget. **Row width budget.** `slots × 20 − 4 ≤ rect_width − 24`. For a 160-wide rect that's `(160 − 24 + 4) / 20 = 7` slots maximum. Above 7, split into two rows or widen the host rect. --- ## Document & terminal icons Decorative icons that go *inside* a box (usually illustrative or structural) to hint at what kind of thing the box represents: a document store, a terminal/computer, a code script. These are **not allowed in flowchart or sequence diagrams** — label the rect instead. **Why only illustrative / structural.** In a flowchart, the reader is tracking sequence; an icon is visual noise competing with the arrow flow. In a structural diagram showing containment, an icon inside a container cell reinforces *what that cell is* and doesn't interrupt any flow. In an illustrative diagram the icon *is* part of the intuition (a document glyph inside a "Shared state" box tells you it's storing artifacts, not messages). ### doc-icon **Bounding box.** 24 × 28. Place it in the lower half of a box that's at least 80 tall. ```svg ``` The outer silhouette is a rectangle with a folded corner; the three short horizontal lines suggest paragraphs. **Placement inside a box.** For a box at `(box_x, box_y)` with width `box_w` and height `box_h ≥ 80`, place the icon's origin at `(box_x + box_w/2 − 12, box_y + box_h − 36)`. This centers horizontally and leaves 8px below. ### terminal-icon **Bounding box.** 24 × 24. ```svg ``` A framed box containing a `>` prompt chevron and a short input line. **Dark mode.** The `box` class provides a contrast frame that reads correctly in both modes; the inner chevron and cursor line use `arr` which also inverts. ### script-icon **Not a fixed-size glyph.** The "script" pattern in image #12 (Programmatic tool calling) is a tall rect that contains multiple horizontal colored dividers and a `{ }` label at the top, representing an inline script that wraps several tool calls. Because the rect's height depends on how many tool calls it wraps, the script-icon is parameterized — build it inline using this recipe: ```svg { } ``` `script_h = 48 + N × 36` for N wrapped calls; `bandK_y = script_y + 48 + (K-1) × 36`. See `sequence.md` → "Parallel independent rounds" for the full pattern this participates in. --- ## Code braces Inline `{ }` as a label on a connector or inside a small label rect to signal "code" or "programmatic" handoff. ```svg { } ``` **Width estimate.** 14px, ~16 char-px. Treat as 2 chars when budgeting for a rect container. **Where used.** Only in illustrative or structural diagrams that distinguish "data flow" from "code flow" — usually paired with a `script-icon` or a `c-gray` pill labeled "Programmatic". --- ## Annotation circle on connector A labeled circle that sits on an arrow to name *the thing that mediates the exchange* — for example, "Skill" sitting on the Claude ↔ Environment arrow in image #13. **Bounding box.** 64 × 64 around the circle. The inner pill is ~52 × 20. **Where used.** Illustrative only. This is a "the action on this arrow is X" label, which in a flowchart or sequence would be a simple arrow label — in an illustrative diagram, we promote it to a visual node because the mediator *is* the subject. ```svg Skill ``` **Placement.** Center the glyph on the arrow's midpoint: `translate(arrow_midx − 32, arrow_midy − 32)`. The arrow must be split into two segments on either side of the glyph (same rule as status circles), each stopping 32px before the center. **Label length.** The inner pill caps at ~8 Latin chars at 14px (`8 × 8 = 64`, minus 8px padding each side, gives ~48px of label room — 6 chars is a comfortable fit; "Skill" at 5 chars is ideal). For CJK, cap at 3 characters. **Pitfall.** Don't use `c-teal` on the outer circle — that double-fills the ramp and the label pill disappears. Keep the outer ring on `box`, the inner pill on a ramp. --- ## Dashed future-state rect Used in "TODOs → Tasks" (image #4) to show a task that hasn't been scheduled yet — the node exists in the plan but not in the active DAG. ```svg ``` Reuses the existing `arr-alt` class — it already provides `fill: none`, `stroke-width: 1.5`, `stroke-dasharray: 5 4`, and dark-mode stroke override. No inline attributes needed. **Text inside.** Label with `ts` class (12px, muted) — future-state nodes are always visually demoted relative to active ones: ```svg Task 4 ``` **Pitfall.** Do *not* create a new `.box-future` CSS class. The `arr-alt` class handles it — adding a new class is template bloat. **Pitfall.** Don't align the dashed rect's center with an active `c-{ramp}` rect's center if their heights differ — the visual baseline looks off. Match the top edge instead, or match the baseline of the label text. --- ## Publish/subscribe arrow pair Two parallel offset arrows between a node and a bus bar — one labeled "Publish" going down, one labeled "Subscribe" going up. Used in the bus topology pattern (`structural.md` → "Bus topology"). **Not a static glyph.** It's a pair of straight arrows with an 8px horizontal offset between them, each with its own label. Write this inline where you use it: ```svg Publish Subscribe ``` The 8px offset is the documented spacing — wider looks like two unrelated arrows, narrower looks like a single fat arrow. **Label placement.** The two labels go in the gap between the agent and the bar, one flush against the left arrow (anchor `end`) and one flush against the right arrow (anchor `start`). If the agent's bottom and the bar's top are closer than 40px, move the labels to the *side* of the pair rather than between them. **Color.** Both arrows use `arr` (default gray). If the pattern needs to highlight one specific agent's channel, upgrade that pair to `arr-{ramp}` where `{ramp}` matches the agent's box — but only that one pair, not all of them. --- ## Concept-to-shape conventions Before drawing any node, decide what shape it should be. baoyu-diagram is a **flat-rect aesthetic** — almost every concept maps to a labeled rectangle. The table below is the canonical lookup so you don't invent a new icon shape inline and so you don't reach for mermaid/plantuml-style iconography that clashes with the design system. | Concept | Use this shape | Notes | |----------------------------|--------------------------------------------------------|-------------------------------------------------------| | User / human / actor | Labeled rect with `ts` subtitle "(user)" or similar | No stick figure. In sequence, an actor header rect. | | LLM / model | Labeled rect, optionally `c-teal` or `c-purple` | No brain icon. Label with the model name. | | Agent / orchestrator | Labeled rect, often the centerpiece of the diagram | If it's the mechanism's name, use `.title` class for the whole diagram title instead. | | Tool / function | Labeled rect; or compact tool card with `tool-card-*` icon in phase-band diagrams | No gear icon in standard diagrams. Phase-band exception: see "Tool card icons" section. | | API / gateway / endpoint | Labeled rect | No hexagon. Label with the route or service name. | | Memory (short-term) | Rect with dashed border via `class="arr-alt"` inline | Dashed = ephemeral. See `svg-template.md` → `.arr-alt`. | | Memory (long-term) / DB | Rect with `doc-icon` inside (structural/illustrative) | No cylinder. In flowchart/sequence, label with "(DB)". | | Vector store | Rect labeled with dimensions ("768d") + doc-icon | No cylinder with grid lines. | | Queue / buffer | Rect containing `queue-slot-filled` / `-empty` glyphs | See glyphs → "Queue slots". | | Task list / checklist | Rect containing `checkbox-checked` / `-empty` rows | See glyphs → "Checkboxes". | | External service | Labeled rect inside a dashed-border container | The dashed container communicates "not ours". | | Decision point | Rotated square (diamond), flowchart only | See `flowchart.md` → diamond decision nodes. | | Process / step | Rounded rect (`rx="6"`) | The default shape. Reach for this first. | | Start / End boundary | Pill (rounded rect with `rx = height/2`) | See `flowchart.md` → "Pill terminal node". ≤2 per diagram. | | State in state machine | Rounded rect with title | See `flowchart.md` → "State-machine sub-pattern". | | Initial / final state | Filled 8px circle / 12px hollow circle with inner 8px | State-machine exception to the "rect only" rule. | | Class (UML) | 3-compartment rect (name / attrs / methods) | See `class.md`. | ### Rejected shapes — never use these These shapes look great in mermaid/plantuml/fireworks-style diagrams but break baoyu's flat-rect aesthetic and its dark-mode color contract. If the diagram seems to demand one, the *label* is wrong — fix the label. - **Stick figure** (for users / actors). Use a labeled rect. - **Brain glyph** (for LLMs). Use a labeled rect with the model name. - **Gear / cog glyph** (for tools). Use a labeled rect with the tool name. - **Cylinder** (for databases). Use a rect with `doc-icon` or a "(DB)" suffix in the label. - **Cloud silhouette** (for external services). Use a dashed-border container. - **Disk / drum / tape-reel** (for storage). Same as cylinder — use a rect. - **Briefcase, folder, envelope, magnifying glass** (for everything else). Use a rect. The rationale for each: these glyphs all require either hardcoded fills (breaking dark mode), or non-rectangular paths that don't compose with the 44/56 row heights and the `c-{ramp}` stroke conventions, or visual weight that competes with the actual information in the box labels. baoyu's readability comes from consistent typography and color — not from pictograms. **When in doubt, ask: "does the shape carry information the label doesn't?"** If the answer is no, it's decoration and you should drop it. If yes, the label is missing the information and you should add it. ## Glyph checklist before saving When you include any glyph in a diagram, verify: 1. **Class check** — every shape in the glyph uses one of `c-{ramp}`, `arr-{ramp}`, `arr`, `arr-alt`, `box`, or a text class (`t`/`th`/`ts`). No inline `fill="#..."` or `stroke="#..."` on anything that needs dark-mode inversion. 2. **Positioning check** — the glyph is wrapped in `` and the anchor math lands it where the parent layout expects (box center, arrow midpoint, checklist row). 3. **No-collision check** — for status circles and annotation circles, the arrow they sit on has been split into two segments leaving a gap for the glyph, not routed *through* it. 4. **Ramp meaning check** — status colors (`c-green` for pass, `c-coral` for fail, `c-amber` for in-progress) are not overridden by the surrounding diagram's color budget. Status semantics always win over the "≤2 ramps" rule. 5. **Icon scope check** — `doc-icon`, `terminal-icon`, and `script-icon` only appear in illustrative or structural diagrams. A flowchart that wants to show "this is a document" uses the label, not the icon. `tool-card-*` icons only appear inside compact tool cards in phase-band diagrams. --- ## Tool card icons Small 24 × 24 icons for use **exclusively inside compact tool card nodes** in phase-band diagrams (see `references/flowchart-phase-bands.md`). Each icon supplements—never replaces—the text label on the card. Without the label the icon has no meaning; without the icon the label still works fine. **Scope rule.** These icons are not allowed in any other diagram type. They require the compact tool card node template below — dropping a tool icon directly into a standard 44px flowchart node looks wrong and breaks the icon-to-card sizing contract. **Dark-mode rule.** All strokes use `class="arr"` (inherits the template's stroke color). `fill="none"` on any outer shape is safe. No inline hex colors. **Bounding box:** 24 × 24 for all icons. Place the icon origin so the glyph center lands at the top-center of the card (see compact tool card template below). --- ### icon-scan Concentric target rings — communicates "scanning / finding". ```svg ``` The small tick line at the top-right angle reads as "aim" without being a literal crosshair. --- ### icon-search Document face with text lines — communicates "reading / querying" without using a magnifying glass (which is prohibited as a shape replacement for labels in standard diagrams). ```svg ``` --- ### icon-data Three vertical bars of different heights — bar chart shape for "data analysis / metrics". ```svg ``` --- ### icon-code Angle brackets with a slash — `` pattern for "code / script analysis". ```svg ``` --- ### icon-exploit Lightning bolt — communicates "attack / execution / injection". ```svg ``` --- ### icon-callback Two arrows in a circle (↩ motif) — communicates "callback / round-trip / webhook". ```svg ``` --- ## Compact tool card node template **Used only in phase-band diagrams.** A 80 × 80 node that shows a 24 × 24 icon above a two-line text label. The icon provides visual differentiation at a glance; the label provides the actual meaning. **Bounding box:** 80 × 80 (or wider if the label is longer — see sizing rule below). **Sizing rule:** ``` card_w = max(line1_chars × 7, line2_chars × 7, 24) + 24 card_w = round up to nearest 8, minimum 72, maximum 128 card_h = 80 (fixed) ``` For a single-line label (e.g., "Scan"): ``` card_w = max(4 × 7, 24) + 24 = max(28, 24) + 24 = 52 → round to 72 (minimum) ``` For a two-word label split over two lines (e.g., "Search" / "tool"): ``` card_w = max(6×7, 4×7) + 24 = 42 + 24 = 66 → round to 72 (minimum) ``` For a longer label (e.g., "Code" / "analysis"): ``` card_w = max(4×7, 8×7) + 24 = 56 + 24 = 80 → round to 80 ``` **Template (two-line label, 80-wide card):** ```svg Scan tool ``` For a single-line label (when the full name fits in ≤10 chars): ```svg Scanner ``` **Color rules.** - Use `c-gray` for all tool cards by default. Color encodes meaning, not tool identity — don't give each tool a different ramp. - If **one specific tool** is the subject of the diagram (e.g., the exploitation tool that's being analyzed), promote just that one card to a semantic ramp (`c-coral` for attack tools, `c-amber` for analysis tools). All other cards stay `c-gray`. **Row packing.** Align cards in a horizontal row inside the phase band's main flow zone. The gap between cards is **8px minimum**: ``` row_width = N × card_w + (N−1) × 8 required: row_width ≤ 380 (main flow zone width inside a band) ``` | Cards | card_w | row_width | Fits? | |-------|--------|-----------|-------| | 4 | 80 | 352 | ✓ | | 5 | 72 | 388 | ✗ — use card_w=72 with 6px gap: 5×72+4×6=384 ✓ | | 6 | 64 | 408 | ✗ — split into two rows of 3 | To center a row of N cards: ``` row_start_x = band_x + band_padding + (main_flow_w − row_width) / 2 card[i].x = row_start_x + i × (card_w + gap) ``` --- ## Operator icons Larger icons (32 × 40) for the **left operator column** of a phase-band diagram — the human or AI actor that initiates the operation. These appear once per diagram, outside (to the left of) the phase band containers. --- ### operator-human A simplified head + shoulders silhouette. 32 × 40. ```svg ``` Place the icon's origin at `(operator_x, operator_y)`. The icon's visual center is at `(16, 24)`. Add a `ts` label below: `y = operator_y + 44`. --- ### operator-ai An asterisk-in-circle — six spokes radiating from center, with an outer ring. 32 × 32. ```svg ``` For a six-spoke variant (closer to the Anthropic asterisk): ```svg ``` --- **Placement in a phase-band diagram:** Both operator icons sit in the left margin at `x=20`, vertically positioned to align with the band they feed into (usually Phase 1): ``` operator-human: x=20, y=phase1_band_y + (band_h / 2) − 20 − 44 − 16 operator-ai: x=20, y=phase1_band_y + (band_h / 2) − 16 + 16 label under each: ts at (36, icon_y + icon_h + 8), text-anchor="middle" ``` The stacked human → ai pair is typical (human provides the target; ai runs the operation). Connect them with a short `arr` line, then connect the ai icon to the band's first card with an arrow entering the left edge of the band. If any check fails, fix the SVG before saving. See `pitfalls.md` entries #19–#28 for the full list of glyph-related failure modes and their fixes.