Skip to content

docs(skills): add blog-figures skill with Dynamo Dark figure system - #10359

Closed
dagil-nvidia wants to merge 16 commits into
mainfrom
dagil-nvidia/blog-figures-skill
Closed

docs(skills): add blog-figures skill with Dynamo Dark figure system#10359
dagil-nvidia wants to merge 16 commits into
mainfrom
dagil-nvidia/blog-figures-skill

Conversation

@dagil-nvidia

@dagil-nvidia dagil-nvidia commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the blog-figures skill for creating Dynamo blog and digest figures, under docs/skills/blog-figures/. The skill routes each figure task to the right pathway (Python + Plotly, D2, hand-crafted SVG, dynamo-svg, or HTML+CSS to PNG), enforces one canonical design system from machine-readable tokens, and runs a mandatory render-and-critique loop.

It stays a Claude skill: SKILL.md keeps its frontmatter (name, description, license: Apache-2.0, metadata). No plugin or bundle conversion.

Design System: Dynamo Dark

The skill documents a single house figure family, Dynamo Dark, anchored on the canonical design_tokens.yaml. There is no longer a Family 1 / Family 2 split. The one differentiator is scale, which selects the title treatment:

  • Display / Hero Title: Helvetica Neue Light (Helvetica Neue, Helvetica, Arial, sans-serif), weight 300, title case, with a muted Helvetica subtitle.
  • Compact / Chart Title: Arial, 18 px, weight 700, uppercase, 0.08em letter-spacing (the canonical token title).

Everything else (black surfaces, NVIDIA-green #76b900 accents, the token palette and borders, border-radius: 0) is shared across both scales.

What's Included

Skill Files (docs/skills/blog-figures/)

  • SKILL.md — workflow and pathway-selection decision tree
  • DESIGN.md — cite-able source of truth: type system, palette, layout, forbidden anti-patterns
  • aesthetic.md — diagram aesthetic guidance
  • plotting.md — chart craft (annotations, delta brackets, hero title-subtitle stacks)
  • html-to-png.md — HTML+CSS authoring recipes

Runnable Example Generators (docs/skills/blog-figures/examples/)

Six self-contained generators, each rendering a representative figure in the correct Dynamo Dark treatment, with build.sh, a README.md gallery, and the canonical design_tokens.yaml + plotly_dynamo.py helpers:

  • gen_fig_2_architecture.py — data-flow diagram with green replay edge
  • gen_fig_5_decision_cascade.py — cascade with a horizontal delta bracket
  • gen_fig_6_tuning_loop.py — pipeline with phase tags and a calibration loop
  • gen_fig_concurrency_sweep.py — dual-panel concurrency sweep + Pareto curve
  • gen_fig_throughput_bars.py — compact horizontal-bar scoreboard
  • gen_fig_cards.py + fig-cards.html — HTML+CSS to PNG comparison cards (Playwright)

Sample data is deterministic and representative (fixed seed), documented in each header, not measured benchmark results.

DynoSim Hero Exemplar (docs/digest/dynosim/)

  • dynosim-hero.png re-rendered to the Dynamo Dark display treatment
  • tools/gen_hero.py (+ build.sh, README.md, tokens, helpers) so the hero is regenerable

Figure Reference Set (Manifest)

Adds a browsable, machine-readable catalog of every reusable figure generator across this branch, so someone building a new figure can scan by kind, find the closest exemplar, and pull that generator as a starting template.

  • docs/skills/blog-figures/reference/figure-manifest.yaml: 16 generators (the 7-figure ModelExpress cold-start set, 6 skill examples, 3 digest generators). Each entry records its kind, renderer, title_treatment, outputs, data provenance (real vs illustrative), measured lint_score, source_ref, and a use_when hint. A controlled-vocabulary kinds: block (13 kinds across four families: chart.*, diagram.*, hero.*, cards.*) keeps kind values consistent.
  • docs/skills/blog-figures/reference/README.md: the human index. Covers how to pull from the manifest, the kinds vocabulary, and a per-collection table (kind, title, renderer, generator path, lint score).
  • SKILL.md: one-line pointer to the reference set under Example Scripts.

Lint scores are the linter's measured overall_measured, captured per generator against its sibling design_tokens.yaml. Every generator measures 100/100: the ModelExpress set, all six examples, the DynoSim hero, and the two flash-indexer digest generators (whose off-token series and colorscale colors were mapped to design tokens). Non-figure helpers (plotly_dynamo.py, design_tokens.yaml, build.sh, lint_figures.py) are intentionally excluded.

Not Published to the Docs Site

The skill lives under docs/skills/ and is intentionally kept out of the published Fern docs site by nav-omission (never added to docs/index.yml), so it is never rendered or served. This PR touches no .github/workflows/ files, so the container-build matrix does not run. All docs link checks (lychee, broken-markdown-links, Fern) pass.

History

Originally landed in PR #9847 (dagil-nvidia/agent-skills-initial) as commit 16ad32d19c, split out into its own PR for review independence. Iterated from skills/blog-figures/ to docs/skills/blog-figures/, unified into the single Dynamo Dark system, and extended with runnable example generators and the re-rendered hero exemplar.

Test Plan

  • Review skill content and structure
  • Confirm SKILL.md frontmatter is intact (valid Claude skill)
  • Confirm the Dynamo Dark type treatments are consistent across all five files
  • Run examples/build.sh and confirm each generator renders in the correct treatment
  • Confirm the skill is absent from the published Fern nav
  • Confirm docs link checks pass (no file:// / broken links)
  • Confirm reference/figure-manifest.yaml parses and every generator + output path resolves

@github-actions github-actions Bot added feat documentation Improvements or additions to documentation labels Jun 5, 2026
@grahamking

Copy link
Copy Markdown
Contributor

the post-flip canonical skill directory

What does that mean?

@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot added the Stale label Jul 12, 2026
@dagil-nvidia
dagil-nvidia marked this pull request as ready for review July 14, 2026 17:39
@dagil-nvidia
dagil-nvidia requested a review from a team as a code owner July 14, 2026 17:39
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 8 potential issues.

Open in Devin Review

Comment thread skills/blog-figures/SKILL.md Outdated

## The Seven Non-Negotiables (Dynamo Dark Aesthetic Ladder)

1. **Pure black background.** `#0a0a0a` or `#000000`. Never transparent. Never `#111111` "soft black" — readers' monitors lie.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Background color rule contradicts itself across the two authoritative files

The acceptable background color list includes #0a0a0a (skills/blog-figures/SKILL.md:61) but the canonical source of truth explicitly forbids that same value (skills/blog-figures/DESIGN.md:11), so an agent following one file will violate the other.

Impact: Figures may be produced with a background color that the design system explicitly bans, causing audit failures.

Contradiction details

SKILL.md line 61 says: "Pure black background. #0a0a0a or #000000." — listing #0a0a0a as an acceptable value.

DESIGN.md line 11 says: "Ground | #000000 | Canvas background. No exceptions, no #0a0a0a 'soft black'." — explicitly naming #0a0a0a as forbidden.

SKILL.md itself at line 85 declares DESIGN.md as "the cite-able source of truth", so SKILL.md should not contradict it.

Suggested change
1. **Pure black background.** `#0a0a0a` or `#000000`. Never transparent. Never `#111111` "soft black" — readers' monitors lie.
1. **Pure black background.** `#000000`. Never transparent. Never `#0a0a0a` or `#111111` "soft black" — readers' monitors lie.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread skills/blog-figures/aesthetic.md Outdated

| Role | Family | Size (px) | Weight | Transform | Letter-Spacing |
|---|---|---|---|---|---|
| Title | `'NVIDIA Sans', Arial, Helvetica, sans-serif` | 18 | 700 | uppercase | 0.08em |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Flash-indexer title font weight contradicts between the two spec files

The flash-indexer title weight is specified as 600 in the source of truth (skills/blog-figures/DESIGN.md:59) but as 700 in the aesthetic reference (skills/blog-figures/aesthetic.md:89), so figures will render with inconsistent boldness depending on which file the author consults.

Impact: Flash-indexer titles may appear with wrong font weight, breaking visual consistency across figures.

Contradiction details

DESIGN.md line 59: "Title | 18 px, ALL CAPS, weight 600"
aesthetic.md line 89: "Title | 'NVIDIA Sans', Arial, Helvetica, sans-serif | 18 | 700 | uppercase | 0.08em"

Both describe the same role (flash-indexer family title) but disagree on weight (600 vs 700). The html-to-png.md template at line 73 uses font-weight: 700, matching aesthetic.md but not DESIGN.md.

Prompt for agents
The flash-indexer title weight is 600 in DESIGN.md line 59 but 700 in aesthetic.md line 89 and 700 in html-to-png.md line 73. Decide on one canonical weight and update all three files to match. DESIGN.md is declared as the source of truth, so either update aesthetic.md and html-to-png.md to use 600, or update DESIGN.md to use 700 if 700 is the intended value.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread docs/digest/blog-figures/aesthetic.md Outdated
| Label | `Geist, Inter, 'Helvetica Neue', Arial, sans-serif` | 13 | 300 | none | `#cdcdcd` |
| Annotation | `Geist, Inter, 'Helvetica Neue', Arial, sans-serif` | 11 | 300 | none | `#cdcdcd` |
| Code / ticks / numbers | `'Geist Mono', 'JetBrains Mono', 'Roboto Mono', 'SF Mono', Menlo, Consolas, monospace` | 11-13 | 400 | none | varies |
| Callout-card label (in floating annotation boxes) | `Geist, Inter, 'Helvetica Neue', Arial, sans-serif` | 13-14 | 700 | none | `#ffffff` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Callout-card label font weight contradicts between the two spec files

The callout-card label weight is specified as 600 in the source of truth (skills/blog-figures/DESIGN.md:78) but as 700 in the aesthetic reference (skills/blog-figures/aesthetic.md:106), so callout cards will render with inconsistent boldness.

Impact: Callout-card labels may appear with wrong font weight depending on which file the author follows.

Contradiction details

DESIGN.md line 78: "Callout-card labels | weight 600 (only place weight ≥ 500 appears outside mono)"
aesthetic.md line 106: "Callout-card label | ... | 13-14 | 700 | none | #ffffff"

Both describe the same role (Family 2 callout-card labels) but disagree on weight (600 vs 700).

Prompt for agents
The callout-card label weight is 600 in DESIGN.md line 78 but 700 in aesthetic.md line 106. Decide on one canonical weight and update both files to match. DESIGN.md is declared as the source of truth.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread docs/skills/blog-figures/SKILL.md Outdated

## Common Failure Modes

The render-and-critique loop catches most issues. These six come up often enough across blogs to deserve naming explicitly — walk this list once before declaring a figure done:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Failure mode count says "six" but the list contains eight items

The introductory sentence says "these six come up often enough" (skills/blog-figures/SKILL.md:147) but the numbered list that follows contains eight items (numbered 1 through 8), so the count is wrong.

Impact: Readers may stop reading after item 6, missing the last two failure modes.

Count mismatch details

Line 147: "These six come up often enough across blogs to deserve naming explicitly"
Lines 149-156: Items numbered 1 through 8.

The list was likely extended from six to eight items without updating the introductory count.

Suggested change
The render-and-critique loop catches most issues. These six come up often enough across blogs to deserve naming explicitly — walk this list once before declaring a figure done:
The render-and-critique loop catches most issues. These eight come up often enough across blogs to deserve naming explicitly — walk this list once before declaring a figure done:
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread docs/digest/blog-figures/aesthetic.md Outdated

Sentence-case titles only (capitalize first word + proper nouns). The takeaway clause lives in the subtitle after an em-dash: "Hardware spec / config / model — narrative takeaway with the punchline." Bold is reserved for callout-card labels.

Use for hero figures, headline artifacts, and any figure that anchors a full page width. Canonical exemplars at [the canonical DynoSim figure set](the canonical DynoSim figure set).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Reference links for the DynoSim figure set point to themselves instead of a real URL

The canonical exemplar links use the display text as the URL (skills/blog-figures/aesthetic.md:110), producing a broken markdown link that resolves nowhere, so readers cannot find the referenced figures.

Impact: Authors cannot locate the canonical DynoSim reference figures, defeating the purpose of the reference section.

Broken link details

Line 110: [the canonical DynoSim figure set](the canonical DynoSim figure set) — the URL is just the display text repeated, not an actual path.

Line 327: Same broken link pattern repeated.

All other reference links in the file use file:// paths (e.g., lines 322-324), so these should follow the same pattern with an actual file path.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

:root {
/* From design_tokens.yaml -- mirror, do not invent */
--bg-primary: #000000;
--bg-surface: #1a1a1a;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 HTML template card surface color doesn't match the design system source of truth

The HTML template sets card background to #1a1a1a via --bg-surface (skills/blog-figures/html-to-png.md:35), but the source of truth specifies card surface as #0f0f0f (skills/blog-figures/DESIGN.md:12), so cards rendered via this template will be visibly lighter than intended.

Impact: HTML-to-PNG figures will have card backgrounds that don't match figures produced via other pathways.

Color mismatch details

html-to-png.md line 35: --bg-surface: #1a1a1a; — used by .card at line 103 via background: var(--bg-surface).

DESIGN.md line 12: "Card surface | #0f0f0f | Container fills (cards, panels, plot areas)."
DESIGN.md line 137: "Fill | #0f0f0f for primary cards"
SKILL.md line 113: "Card surfaces | #0f0f0f fill"

aesthetic.md line 22 defines background.surface as #1a1a1a, but this is the D2 container fill token, not the card surface token. The HTML template appears to have used the wrong token — background.surface (#1a1a1a) instead of the card surface (#0f0f0f) from DESIGN.md.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread docs/digest/blog-figures/aesthetic.md Outdated

Use for inline body-prose charts, dense data dashboards, heatmaps, and any figure that needs to pack many marks per inch. Canonical exemplars at [docs/digest/flash-indexer/images/](file://docs/digest/flash-indexer/images/).

### Family 2 — Mocker (display-scale headline figures)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Family 2 has three different names across the documentation files

Family 2 is called "Digital Twin / DynoSim" in skills/blog-figures/DESIGN.md:67 and skills/blog-figures/SKILL.md:68, but "Mocker" in skills/blog-figures/aesthetic.md:97. SKILL.md line 65 also uses "mocker" in lowercase. While SKILL.md line 68 does say "also called DynoSim", the name "Mocker" is never introduced or explained in DESIGN.md or SKILL.md. An agent reading aesthetic.md would see "Mocker family" and might not realize it's the same as "Digital Twin family" from DESIGN.md. Consider standardizing on one canonical name with aliases explicitly listed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread docs/digest/blog-figures/aesthetic.md Outdated
| Annotation | `'NVIDIA Sans', Arial, Helvetica, sans-serif` | 10 | 400 | none | 0 |
| Code / ticks / numbers | `'Roboto Mono', 'SF Mono', Menlo, Consolas, monospace` | 10-12 | 400 | none | 0 |

Use for inline body-prose charts, dense data dashboards, heatmaps, and any figure that needs to pack many marks per inch. Canonical exemplars at [docs/digest/flash-indexer/images/](file://docs/digest/flash-indexer/images/).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Reference paths use two different directory prefixes (docs/digest/ vs docs/blogs/)

The file layout section in skills/blog-figures/SKILL.md:163 specifies docs/blogs/<slug>/ as the directory structure, and the bootstrapping section at line 207 uses the same. However, skills/blog-figures/aesthetic.md:95 references docs/digest/flash-indexer/images/ and lines 322-324 reference docs/digest/agentic-inference/. If docs/digest/ and docs/blogs/ are different directory trees, the cross-references are consistent but the naming is confusing. If they should be the same, one set of paths is wrong. Worth verifying which directory actually contains the canonical exemplars.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Added comprehensive documentation for Dynamo blog-figure design, authoring workflows, HTML-to-PNG rendering, reproducible builds, and chart construction standards.

Changes

Blog figure authoring guidance

Layer / File(s) Summary
Design language and visual tokens
skills/blog-figures/DESIGN.md, skills/blog-figures/aesthetic.md
Defines canonical colors, typography, layout, semantic encodings, diagram classes, anti-patterns, and shipping checks.
Authoring workflow and validation
skills/blog-figures/SKILL.md
Documents pathway selection, render-and-critique loops, geometry and data rules, blog layouts, reproducible builds, bootstrapping, and completion checks.
HTML-to-PNG rendering pathway
skills/blog-figures/html-to-png.md
Adds fixed-size HTML templates, Playwright and Satori workflows, output conventions, build integration, and validation rules.
Chart construction and annotation rules
skills/blog-figures/plotting.md
Specifies axis hygiene, labeling, sorting, annotations, uncertainty, chart composition, title/subtitle rules, and anti-patterns.

Estimated code review effort: 2 (Simple) | ~15 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is detailed, but it does not follow the required template and omits the Reviewer Start and Related Issues sections. Add the missing Overview/Details/Where should reviewer start sections in template form, and include the required Related Issues block with an issue link or no-issue confirmation.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the new blog-figures skill and its Dynamo Dark figure system.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
skills/blog-figures/plotting.md (1)

25-37: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Make the canonical tick policy deterministic.

The rules prohibit relying on auto-picked tick locations, but this snippet only sets tickformat; it does not constrain tick positions. Add explicit tickvals/dtick, or state that rendered output must be verified and corrected when Plotly chooses non-canonical ticks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/plotting.md` around lines 25 - 37, Update the figure
layout in the plotting example to enforce deterministic, canonical tick
positions on both log-scaled axes by adding explicit tickvals or dtick alongside
the existing tickformat settings. Ensure the rendered output cannot rely on
Plotly’s automatic tick-location selection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/blog-figures/aesthetic.md`:
- Around line 3-5: Replace all invalid documentation and exemplar links with
repository-relative targets: in skills/blog-figures/aesthetic.md lines 3-5, 95,
110, 197, and 322-327, link to the canonical token/theme files, image directory,
real DynoSim exemplar, and both valid exemplars, adding trailing slashes for
directory links; in skills/blog-figures/html-to-png.md lines 21-24, replace the
file:// token reference with its repository-relative path. Ensure every target
exists in the repository and avoid links depending on main-only files.

In `@skills/blog-figures/DESIGN.md`:
- Around line 7-17: Resolve the conflicting blog-figures design contract by
keeping DESIGN.md#L7-L17 authoritative. Update aesthetic.md#L1-L5, `#L17-L32`, and
`#L81-L110` to mirror its tokens, backgrounds, borders, family names, and
typography; update SKILL.md#L59-L69 with the canonical background and opacity
rules; and update html-to-png.md#L21-L24 and `#L32-L50` to use matching
terminology, CSS variables, and font stacks.

In `@skills/blog-figures/html-to-png.md`:
- Around line 135-145: Replace the fabricated benchmark values in the “Two
Approaches at a Glance” section with clearly marked placeholders, and add an
adjacent comment requiring measured values before export. Update the values for
both cards and the comparison text while preserving the existing labels and
descriptions.

In `@skills/blog-figures/plotting.md`:
- Around line 328-360: Add a text language identifier to each of the four
standalone formula code fences in the documented horizontal and vertical
position formulas, including the worked examples, so all fences satisfy
markdownlint MD040 while preserving their contents.
- Line 22: Update all three gen_throughput.py links in
skills/blog-figures/plotting.md at lines 22, 78, and 453 to use the correct
relative path for docs/digest/flash-indexer/tools/gen_throughput.py, replacing
the stale file://docs/blogs/... target while preserving each link’s surrounding
context.
- Around line 280-295: Resolve the contradiction between Rule 10 and the
flash-indexer canonical title: update the canonical title to state the chart’s
specific takeaway rather than merely describing achieved versus offered
throughput, while preserving the required comparison context and interpretation
guidance.

In `@skills/blog-figures/SKILL.md`:
- Around line 189-203: Pin the Playwright and Chromium versions used by the
HTML-to-PNG pipeline, document the required fonts, and update the build
instructions in skills/blog-figures/SKILL.md (lines 189-203) and
skills/blog-figures/html-to-png.md (lines 155-160) to use and describe those
pinned dependencies. Preserve the build contract’s reproducibility claim.

---

Nitpick comments:
In `@skills/blog-figures/plotting.md`:
- Around line 25-37: Update the figure layout in the plotting example to enforce
deterministic, canonical tick positions on both log-scaled axes by adding
explicit tickvals or dtick alongside the existing tickformat settings. Ensure
the rendered output cannot rely on Plotly’s automatic tick-location selection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8aebf1e2-821c-4e27-964e-a9c98c34a4b2

📥 Commits

Reviewing files that changed from the base of the PR and between f68be6d and 41ac572.

📒 Files selected for processing (5)
  • skills/blog-figures/DESIGN.md
  • skills/blog-figures/SKILL.md
  • skills/blog-figures/aesthetic.md
  • skills/blog-figures/html-to-png.md
  • skills/blog-figures/plotting.md

Comment thread skills/blog-figures/aesthetic.md Outdated
Comment on lines +3 to +5
Self-contained reference for palette, typography, semantic color, D2 classes, and diagram anti-patterns. Mirrors [`design_tokens.yaml`](file://docs/blogs/flash-indexer/tools/design_tokens.yaml) and [`theme.d2`](file://docs/blogs/flash-indexer/tools/theme.d2) verbatim so this file can be read without leaving the skill.

When tokens drift in the canonical source, update this file too.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Replace invalid documentation links with repository-relative targets.

The file:// links and the placeholder “canonical DynoSim figure set” targets fail Markdown link checking. Replace them with actual relative paths; do not link to files that only exist on main.

  • skills/blog-figures/aesthetic.md#L3-L5: use relative links to the canonical token/theme files.
  • skills/blog-figures/aesthetic.md#L95-L95: replace the file:// image-directory link with a valid repository-relative directory link.
  • skills/blog-figures/aesthetic.md#L110-L110: replace the placeholder DynoSim link with the real exemplar path.
  • skills/blog-figures/aesthetic.md#L197-L197: replace the file:// theme link with a relative link.
  • skills/blog-figures/aesthetic.md#L322-L327: fix both exemplar links and add trailing slashes for directories.
  • skills/blog-figures/html-to-png.md#L21-L24: replace the file:// token reference with a relative link.

Based on learnings, Markdown under skills/** should use relative links to newly added documentation so pre-merge link checking can resolve them.

📍 Affects 2 files
  • skills/blog-figures/aesthetic.md#L3-L5 (this comment)
  • skills/blog-figures/aesthetic.md#L95-L95
  • skills/blog-figures/aesthetic.md#L110-L110
  • skills/blog-figures/aesthetic.md#L197-L197
  • skills/blog-figures/aesthetic.md#L322-L327
  • skills/blog-figures/html-to-png.md#L21-L24
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/aesthetic.md` around lines 3 - 5, Replace all invalid
documentation and exemplar links with repository-relative targets: in
skills/blog-figures/aesthetic.md lines 3-5, 95, 110, 197, and 322-327, link to
the canonical token/theme files, image directory, real DynoSim exemplar, and
both valid exemplars, adding trailing slashes for directory links; in
skills/blog-figures/html-to-png.md lines 21-24, replace the file:// token
reference with its repository-relative path. Ensure every target exists in the
repository and avoid links depending on main-only files.

Sources: Learnings, Linters/SAST tools

Comment thread docs/digest/blog-figures/DESIGN.md Outdated
Comment on lines +7 to +17
## Background and Surfaces

| Token | Hex | Use |
|---|---|---|
| Ground | `#000000` | Canvas background. No exceptions, no `#0a0a0a` "soft black". |
| Card surface | `#0f0f0f` | Container fills (cards, panels, plot areas). |
| Card surface, secondary | `#0a0a0a` | Inset/nested surfaces where a subtler step than `#0f0f0f` is needed. |
| Card border, hairline | `#2a2a2a` | 1 px border on cards, panels, frames. |
| Card border, accent | `#74b711` or `#76b900` | 1.5–2 px border on the single accented element only. |

Rounded corners are never used. `border-radius: 0` everywhere.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Resolve the conflicting canonical design contract.

These files claim to describe one canonical system but disagree on surfaces, typography, and family naming. For example, DESIGN.md specifies #0f0f0f cards and forbids #0a0a0a, while SKILL.md permits #0a0a0a; aesthetic.md uses #1a1a1a; and the HTML template claims to mirror the canonical tokens while using those conflicting values.

  • skills/blog-figures/DESIGN.md#L7-L17: retain the authoritative token values.
  • skills/blog-figures/aesthetic.md#L1-L5: generate or update the mirror from the canonical source instead of maintaining divergent values.
  • skills/blog-figures/aesthetic.md#L17-L32: align backgrounds and borders with DESIGN.md.
  • skills/blog-figures/aesthetic.md#L81-L110: align family names and typography with DESIGN.md/SKILL.md.
  • skills/blog-figures/SKILL.md#L59-L69: use the canonical background and opacity rules verbatim.
  • skills/blog-figures/html-to-png.md#L21-L24: link to the canonical source with matching terminology.
  • skills/blog-figures/html-to-png.md#L32-L50: update CSS variables and font stacks to match the resolved contract.
📍 Affects 4 files
  • skills/blog-figures/DESIGN.md#L7-L17 (this comment)
  • skills/blog-figures/aesthetic.md#L1-L5
  • skills/blog-figures/aesthetic.md#L17-L32
  • skills/blog-figures/aesthetic.md#L81-L110
  • skills/blog-figures/SKILL.md#L59-L69
  • skills/blog-figures/html-to-png.md#L21-L24
  • skills/blog-figures/html-to-png.md#L32-L50
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/DESIGN.md` around lines 7 - 17, Resolve the conflicting
blog-figures design contract by keeping DESIGN.md#L7-L17 authoritative. Update
aesthetic.md#L1-L5, `#L17-L32`, and `#L81-L110` to mirror its tokens, backgrounds,
borders, family names, and typography; update SKILL.md#L59-L69 with the
canonical background and opacity rules; and update html-to-png.md#L21-L24 and
`#L32-L50` to use matching terminology, CSS variables, and font stacks.

Comment thread docs/skills/blog-figures/html-to-png.md Outdated
Comment on lines +135 to +145
<h1>Two Approaches at a Glance</h1>
<div class="grid">
<div class="card">
<div class="label">Naive Nested Map</div>
<div class="value mono">4M ops/s</div>
<p>Single-threaded, single-writer-single-reader. Simple, correct, slow.</p>
</div>
<div class="card accent">
<div class="label">Concurrent Positional Indexer</div>
<div class="value mono">170M ops/s</div>
<p>Multi-writer multi-reader with positional jump search. 40x faster.</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove fabricated benchmark values from the template.

The example contains 4M ops/s, 170M ops/s, and 40x faster without a source of truth. SKILL.md explicitly forbids invented measurements; replace these with placeholders and a comment requiring measured values before export.

Proposed fix
-        <div class="value mono">4M ops/s</div>
+        <div class="value mono">N ops/s</div>
...
-        <div class="value mono">170M ops/s</div>
+        <div class="value mono">M ops/s</div>
-        <p>Multi-writer multi-reader with positional jump search. 40x faster.</p>
+        <p>Replace with measured values from the figure's source of truth.</p>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<h1>Two Approaches at a Glance</h1>
<div class="grid">
<div class="card">
<div class="label">Naive Nested Map</div>
<div class="value mono">4M ops/s</div>
<p>Single-threaded, single-writer-single-reader. Simple, correct, slow.</p>
</div>
<div class="card accent">
<div class="label">Concurrent Positional Indexer</div>
<div class="value mono">170M ops/s</div>
<p>Multi-writer multi-reader with positional jump search. 40x faster.</p>
<h1>Two Approaches at a Glance</h1>
<div class="grid">
<div class="card">
<div class="label">Naive Nested Map</div>
<div class="value mono">N ops/s</div>
<p>Single-threaded, single-writer-single-reader. Simple, correct, slow.</p>
</div>
<div class="card accent">
<div class="label">Concurrent Positional Indexer</div>
<div class="value mono">M ops/s</div>
<p>Multi-writer multi-reader with positional jump search. Replace with measured values from the figure's source of truth.</p>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/html-to-png.md` around lines 135 - 145, Replace the
fabricated benchmark values in the “Two Approaches at a Glance” section with
clearly marked placeholders, and add an adjacent comment requiring measured
values before export. Update the values for both cards and the comparison text
while preserving the existing labels and descriptions.

Comment thread skills/blog-figures/plotting.md Outdated

### Canonical Snippet

The pattern from [`gen_throughput.py`](file://docs/blogs/flash-indexer/tools/gen_throughput.py) for log-scale ticks with SI suffix formatting:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use one correct relative path for every gen_throughput.py reference.

All three links use the stale file://docs/blogs/... path, while the implementation is under docs/digest/flash-indexer/tools/gen_throughput.py.

  • skills/blog-figures/plotting.md#L22-L22: update the canonical snippet link.
  • skills/blog-figures/plotting.md#L78-L78: update the corpus-pattern link.
  • skills/blog-figures/plotting.md#L453-L453: update the reference link.

Based on learnings, prefer relative links so pre-merge link checking resolves files on the PR branch.

📍 Affects 1 file
  • skills/blog-figures/plotting.md#L22-L22 (this comment)
  • skills/blog-figures/plotting.md#L78-L78
  • skills/blog-figures/plotting.md#L453-L453
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/plotting.md` at line 22, Update all three
gen_throughput.py links in skills/blog-figures/plotting.md at lines 22, 78, and
453 to use the correct relative path for
docs/digest/flash-indexer/tools/gen_throughput.py, replacing the stale
file://docs/blogs/... target while preserving each link’s surrounding context.

Source: Learnings

Comment thread docs/skills/blog-figures/plotting.md Outdated
Comment on lines +280 to +295
## Rule 10: Title Carries the Takeaway

The chart title is the headline of the figure. It states what the chart proves, not what the chart shows.

- Bad: "GPU Scaling"
- Good: "Throughput Plateaus at 4 GPUs"

- Bad: "Latency Distribution"
- Good: "P99 Latency Doubles Above 100 QPS"

- Bad: "Indexer Comparison"
- Good: "Concurrent Positional Indexer Wins by 40x"

If you cannot write a declarative one-line title, you do not yet know what the chart is for. Stop and figure it out before you ship.

The flash-indexer canonical title is `"ACHIEVED VS. OFFERED THROUGHPUT (HIGHER IS BETTER)"` — note the all-caps, the parenthetical that orients the reader's interpretation, and the comparison framing that telegraphs the takeaway.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the canonical title with Rule 10.

Rule 10 says titles should state what the chart proves and labels “Indexer Comparison” as bad, but the canonical title is similarly descriptive: "ACHIEVED VS. OFFERED THROUGHPUT (HIGHER IS BETTER)". Either revise the rule to allow descriptive comparison titles or replace the canonical title with the actual takeaway.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/plotting.md` around lines 280 - 295, Resolve the
contradiction between Rule 10 and the flash-indexer canonical title: update the
canonical title to state the chart’s specific takeaway rather than merely
describing achieved versus offered throughput, while preserving the required
comparison context and interpretation guidance.

Comment thread docs/skills/blog-figures/plotting.md Outdated
Comment on lines +328 to +360
```
paper_x = (title_x_container * figure_width - margin_l) / plot_width
```

Worked example (`width=1240`, `margin_l=80`, plot width = 1240 - 80 - 40 = 1120, title at container `x=0.02`):

```
paper_x = (0.02 * 1240 - 80) / 1120
= (24.8 - 80) / 1120
= -55.2 / 1120
= -0.049
```

So the subtitle annotation gets `x=-0.049, xref="paper"` to line up under the title's left edge. Re-derive per figure when `margin_l` or `width` changes.

**Vertical position formula.** Same pattern — title uses container coords, annotation uses paper coords. To place the subtitle top ~5 px below the title bottom:

```
title_top_px = (1 - title_y_container) * figure_height
title_bottom_px = title_top_px + (title_font_size * 0.80) # empirical bbox, weight 300
subtitle_top_px = title_bottom_px + 5
paper_y = 1 + (margin_t - subtitle_top_px) / plot_height
```

The `* 0.80` constant comes from measuring the rendered Helvetica Neue Light title at 42pt; the visible bbox is shorter than the line-height of 42 * 1.2 = 50px because Plotly anchors `yanchor="top"` near the cap-height line rather than the EM-box top. Tune empirically per figure: render at 2x, measure the gap, adjust.

Worked example (`height=620`, `margin_t=130`, plot height = 420, title at container `y=0.96`, title font 42):

```
title_top = 0.04 * 620 = 24.8
title_bottom = 24.8 + 33.6 = 58.4
subtitle_top = 58.4 + 5 = 63.4
paper_y = 1 + (130 - 63.4) / 420 = 1.158

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add language identifiers to formula fences.

The four standalone formula blocks at Lines 328, 334, 345, and 356 trigger markdownlint MD040. Mark them as text (or another appropriate language) to keep documentation CI clean.

🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 328-328: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 334-334: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 345-345: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 356-356: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/plotting.md` around lines 328 - 360, Add a text language
identifier to each of the four standalone formula code fences in the documented
horizontal and vertical position formulas, including the worked examples, so all
fences satisfy markdownlint MD040 while preserving their contents.

Source: Linters/SAST tools

Comment thread docs/skills/blog-figures/SKILL.md Outdated
Comment on lines +189 to +203
## Build Pipeline Contract

Every blog with figures has two required files in `tools/`:

- `build.sh` — one-shot rebuild that produces every figure from sources. Re-runnable without args. `--d2` flag to also re-render D2 sources first.
- `README.md` — figure inventory table (file → description), prerequisites (rsvg-convert, plotly, kaleido, pyyaml, d2), and per-figure reproduction commands.

**Render conventions:**

- Source SVGs render to 2x PNG via `rsvg-convert -z 2 source.svg -o image.png`.
- Plotly figures write SVG and PNG directly with `fig.write_image(svg)` and `fig.write_image(png, scale=3)`.
- D2 sources render with `d2 --layout tala` (or `--layout elk` for tree-shaped layouts) to a `*-raw.svg`, then post-process with a `*.py` injector.
- HTML sources render via Playwright to PNG; the HTML stays in `tools/`, the PNG lands in `images/`. See [html-to-png.md](html-to-png.md).

**The build must be reproducible from a fresh clone.** If you cannot rebuild every figure with `cd tools && ./build.sh`, the blog is broken.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== skills/blog-figures/SKILL.md ==\n'
cat -n skills/blog-figures/SKILL.md | sed -n '175,215p'

printf '\n== skills/blog-figures/html-to-png.md ==\n'
cat -n skills/blog-figures/html-to-png.md | sed -n '140,185p'

printf '\n== Playwright-related refs ==\n'
rg -n --hidden --glob '!**/.git/**' -e 'playwright|chromium|font|rsvg-convert|kaleido|d2 --layout|reproducible' skills/blog-figures

Repository: ai-dynamo/dynamo

Length of output: 10458


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in skills/blog-figures/SKILL.md skills/blog-figures/html-to-png.md; do
  echo "== $f =="
  sed -n '175,215p' "$f"
  echo
done

echo "== search =="
rg -n --hidden --glob '!**/.git/**' -e 'playwright|chromium|font|reproducible|deterministic|byte-for-byte|build.sh|install chromium' skills/blog-figures

Repository: ai-dynamo/dynamo

Length of output: 9578


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
find skills/blog-figures -maxdepth 2 \( -name 'requirements*.txt' -o -name 'package*.json' -o -name 'Pipfile*' -o -name 'poetry.lock' -o -name 'uv.lock' -o -name 'playwright*.json' -o -name 'Dockerfile*' \) | sort

echo
echo "== version-ish refs =="
rg -n --hidden --glob '!**/.git/**' -e '==|~=|playwright install chromium|playwright==|chromium.*version|fonts?' skills/blog-figures

Repository: ai-dynamo/dynamo

Length of output: 4581


Pin the HTML toolchain for reproducible builds. pip install playwright && playwright install chromium pulls moving browser/runtime versions, so PNG output can drift; either pin Playwright/Chromium and document any required fonts, or soften the reproducibility claim in the build contract.

📍 Affects 2 files
  • skills/blog-figures/SKILL.md#L189-L203 (this comment)
  • skills/blog-figures/html-to-png.md#L155-L160
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/blog-figures/SKILL.md` around lines 189 - 203, Pin the Playwright and
Chromium versions used by the HTML-to-PNG pipeline, document the required fonts,
and update the build instructions in skills/blog-figures/SKILL.md (lines
189-203) and skills/blog-figures/html-to-png.md (lines 155-160) to use and
describe those pinned dependencies. Preserve the build contract’s
reproducibility claim.

@dagil-nvidia
dagil-nvidia force-pushed the dagil-nvidia/blog-figures-skill branch from 41ac572 to 0c8e65e Compare July 14, 2026 18:05
@dagil-nvidia
dagil-nvidia requested review from a team as code owners July 14, 2026 18:05
@dagil-nvidia dagil-nvidia changed the title feat(skills): add blog-figures skill docs(digest): add blog-figures authoring guide Jul 14, 2026
@github-actions github-actions Bot added backend::vllm Relates to the vllm backend docs and removed feat labels Jul 14, 2026
@dagil-nvidia
dagil-nvidia force-pushed the dagil-nvidia/blog-figures-skill branch 2 times, most recently from f891d07 to bf03624 Compare July 14, 2026 18:16
@dagil-nvidia dagil-nvidia changed the title docs(digest): add blog-figures authoring guide docs(skills): add blog-figures skill under docs/digest Jul 14, 2026
@dagil-nvidia
dagil-nvidia requested a review from a team as a code owner July 14, 2026 21:04
@datadog-official

This comment has been minimized.

@dagil-nvidia dagil-nvidia changed the title docs(skills): add blog-figures skill under docs/digest docs(skills): add blog-figures skill with Dynamo Dark figure system Jul 14, 2026
@dagil-nvidia
dagil-nvidia requested a review from a team as a code owner July 16, 2026 16:52
@dagil-nvidia
dagil-nvidia force-pushed the dagil-nvidia/blog-figures-skill branch from 7d2631a to 664c3d1 Compare July 16, 2026 21:56
@copy-pr-bot

copy-pr-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Relocate the blog-figures skill (SKILL.md + DESIGN.md + aesthetic.md +
plotting.md + html-to-png.md) to docs/digest/blog-figures/, keeping the
skill format (SKILL.md frontmatter) intact. Align path references with
the docs/digest/ layout on main, convert file:// links to repo-relative
paths so the docs link check passes, and fix DESIGN.md contradictions
flagged in review (background color, flash-indexer title weight).

Signed-off-by: Dan Gil <dagil@nvidia.com>
Quality-gate pass on the blog-figures skill:
- Set flash-indexer title weight to 700 in DESIGN.md, aesthetic.md, and
  the html-to-png.md h1 to match the canonical design_tokens.yaml
  (weight: 700), which aesthetic.md mirrors verbatim.
- Add license and metadata (author, tags) to SKILL.md frontmatter so it
  conforms to the repo skill-frontmatter convention while remaining a
  valid Claude skill.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Consolidate the two figure families (flash-indexer + DynoSim/Mocker/
Digital-Twin) into a single house family, Dynamo Dark, anchored on the
canonical design_tokens.yaml:

- Remove the Family 1 / Family 2 split across all five files; one family,
  one type treatment, scaled by canvas/title size only.
- Reconcile every color and font to design_tokens.yaml (surfaces
  #1a1a1a/#2a2a2a/#3a3a3a, hairline/accent borders #3a3a3a/#76b900, title
  weight 700 in the Arial + Roboto Mono token stack); drop non-token
  values (#0f0f0f, #0a0a0a card surface, #74b711, #9ed649, Helvetica Neue,
  Geist, NVIDIA Sans).
- Repoint the stale DynoSim exemplar reference to files that exist
  (dynosim-hero.png, dynosim-pareto-frontier.md).

SKILL.md stays a Claude skill: frontmatter name/description + license and
metadata block intact.

Signed-off-by: Dan Gil <dagil@nvidia.com>
…x DynoSim hero title

Task A — relocate the internal blog-figures skill out of the published
digest tree:
- git mv docs/digest/blog-figures/ -> docs/skills/blog-figures/, keeping
  the Claude skill format (SKILL.md frontmatter + license/metadata).
- Exclude docs/skills/ from the Fern publish pipeline (rsync excludes in
  the dev-sync and release-snapshot steps + the release-validate find) and
  from the lychee crawl. It was never in docs/index.yml nav, so Fern never
  rendered it; these make the exclusion explicit.
- Repoint the skill's corpus links (../ -> ../../digest/).

Task B — re-render docs/digest/dynosim/dynosim-hero.png in the unified
Dynamo Dark aesthetic with the corrected hero title:
- Add a deterministic, regenerable generator (docs/digest/dynosim/tools/:
  gen_hero.py + build.sh + README + copied canonical design_tokens.yaml
  and plotly_dynamo.py).
- Hero/display title is Helvetica Neue Light, title case (not uppercase
  Arial); muted Helvetica subtitle; token colors, border-radius 0. The
  explored-config cloud is a deterministic representative reproduction
  (the original sweep data is not in the repo); documented in the tools
  README.

Reconcile the skill so all five files document two title treatments in one
Dynamo Dark family: display/hero (Helvetica set, weight 300, title case)
vs compact/chart (Arial, 18px, weight 700, uppercase).

Signed-off-by: Dan Gil <dagil@nvidia.com>
…low edits

Materialize every example generator the skill prose names, so the references
resolve to real, runnable files under docs/skills/blog-figures/examples/:
- gen_fig_2_architecture.py    — data-flow diagram + squared green replay edge
- gen_fig_5_decision_cascade.py — decision cascade + green delta bracket
- gen_fig_6_tuning_loop.py      — phase tags + squared dashed feedback loop
- gen_fig_concurrency_sweep.py  — dual-panel concurrency sweep + Pareto curve
- gen_fig_throughput_bars.py    — compact bar scoreboard (compact title)
- gen_fig_cards.py + fig-cards.html — HTML->PNG comparison cards (Playwright)
Plus build.sh, a README with a rendered gallery, and copied canonical
design_tokens.yaml + plotly_dynamo.py. Each renders in the correct Dynamo
Dark treatment (display Helvetica title or compact Arial title); sample data
is deterministic and representative, not measured benchmarks.

Wire the SKILL.md / aesthetic.md / plotting.md / html-to-png.md prose
references to the now-real files.

Revert the earlier .github/workflows/ edits (fern-docs.yml rsync excludes +
docs-link-check.yml lychee exclude) so this PR no longer modifies any
workflow file and stops triggering the container-build matrix. The skill
stays unpublished via nav-omission (never in docs/index.yml) under
docs/skills/.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Add a runnable linter/scorer bundled with the blog-figures skill:
- tools/lint_figures.py statically checks the example generators and
  fig-cards.html against design_tokens.yaml: raw-hex (ERROR),
  forbidden/unknown font families, WCAG-AA contrast on the token
  text/surface pairs, and font weights. Emits LintMessage findings + a
  human report and --json; non-zero exit on ERROR so it can gate.
- --score computes the measured half of a 0-100 design rating (palette,
  typography, contrast, variety, label-structure). Judged dimensions
  (data-ink, single-accent, composition, before/after, title-takeaway)
  are printed but never given a fabricated number.
- RATINGS.md documents the five-dimension rubric, the >=85 ship gate, the
  measured-vs-judged split, and a score-to-fix guide.

Wire the linter into examples/build.sh (runs after rendering, fails on
ERROR) and into the SKILL.md render-and-critique loop; cross-link from
DESIGN.md. On the six example generators: 0 findings, measured score
100/100, all seven WCAG contrast pairs pass.

Ported only the figure-agnostic logic (WCAG contrast, raw-hex /
palette-token and font checks, the weighted 0-100 score shape). Did not
port the manifest geometry scorer, violation counter, or CP-SAT autofix
— those are specific to structured-SVG layouts and do not apply to
Plotly/HTML rasters. Written fresh; no internal repo names or paths.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Six restyled figures (fig-1..6) for the ModelExpress cold-start blog,
each self-contained (generator, build.sh, design_tokens.yaml,
plotly_dynamo.py) with rendered PNGs (+ SVGs for fig-3/4/5). All six
pass the blog-figures linter with 0 errors and a 100/100 measured
design score.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Bring the six ModelExpress / cold-start figures onto one color convention,
anchored by fig-1 (green = the peer-to-peer data-plane weight-transfer flow)
and fig-4 (gold = the warmup phase).

- fig-3: recolor the data-plane weight-transfer flows (GPUDirect RDMA,
  ModelStreamer, GDS) green to match fig-1 and fig-3's own docstring, and give
  the MX Client / MX Server boxes a neutral elevated structural surface instead
  of green fills. Metadata store stays cpu_blue. Docstring + README reconciled.
- fig-6: recolor the cold JIT-cache warmup cluster from coral to gold to match
  fig-4's warmup phase; the MX P2P weight load stays the single green accent.
  In-bar labels are black-on-gold for WCAG AA. Restore the full subtitle
  (fp8 KV cache detail + fuller prose tail) that had been trimmed.
- fig-1, fig-2, fig-4, fig-5: verified against the convention; semantics
  unchanged (green is the hero flow / MX win only; coral is the baseline).
- Emit an SVG for every figure (fig-1 / fig-2 / fig-6 added) for set parity.

Green is now reserved set-wide for the hero data-plane weight-transfer flow /
ModelExpress win; warmup is gold in both fig-4 and fig-6. All six lint at
0 errors, 100.0 / 100.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Display-treatment hero (Helvetica Neue Light, title case) headlining the
ModelExpress cold-start set: coral baseline vs green RDMA fast-path
weight-transfer collapse. Self-contained, regenerable via build.sh; lints
100.0/100 (0 errors). Consistent with the harmonized set color convention
(green = hero data-plane flow only).

Signed-off-by: Dan Gil <dagil@nvidia.com>
Bind the ModelExpress peer-to-peer weight-load phase name and its 11s
value into one above-bar callout ("Model load via MX P2P · 11s"),
anchored to the green marker + leader line, so the single green accent
is unmistakably read as "model load via MX P2P = 11s" without needing
the legend. The phase name uses the light text token (AA on black) and
the value stays green to echo the segment; mirrors the in-bar "name · Xs"
pattern used by the wide phases. Data unchanged.

Signed-off-by: Dan Gil <dagil@nvidia.com>
…tat annotations)

Blend of the fast-path flow-diagram concept with editorial stat annotations:
a green RDMA spine (Source GPU to New GPU) labeled "Model load via MX P2P - 11s"
versus a dim coral cold object-store detour (70s), with a light-weight green 6.4x
naming the win (59s reclaimed). Self-contained + regenerable; lints 100/100.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Catalog every reusable figure generator in the branch as a browsable,
machine-readable reference set. reference/figure-manifest.yaml records
each generator's kind (controlled vocabulary), renderer, title treatment,
outputs, data provenance, measured lint score, and a use-when hint, grouped
by collection (modelexpress cold-start set, skill examples, digest).
reference/README.md is the human index with a per-collection table, and
SKILL.md gains a one-line pointer. Someone building a new figure can scan
by kind, find the closest exemplar, and pull that generator as a template.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Map the two off-token raw-hex literals in the flash-indexer digest
generators to design tokens, re-render, and refresh the manifest.

- gen_throughput.py: series color #969696 -> #8c8c8c (Medium Gray token)
- gen_heatmap.py: colorscale stops #c89a00 / #5aaa00 -> muted fluorite /
  muted green chart-fill tokens (semantic gold<->green direction preserved)

Both generators now measure 100/100 with 0 raw-hex errors (throughput
97 -> 100, heatmap 85 -> 100). Data, chart types, and WCAG contrast pairs
are unchanged. Manifest lint_score set to 100.0 and lint_flags cleared for
both entries; reference README index updated to match.

Signed-off-by: Dan Gil <dagil@nvidia.com>
…examples

Relocate the ModelExpress cold-start figure set out of the top-level drafts/
directory and into the blog-figures skill's examples area at
docs/skills/blog-figures/examples/modelexpress-coldstart/ so nothing
figure-related lives under drafts/ anymore. Every figure (fig-1..6 + the
blended hero) keeps its per-figure generator, build.sh, images/, and
self-contained design_tokens.yaml + plotly_dynamo.py.

- Drop the _pngs-for-slack/ scratch bundle: all 7 PNGs were byte-identical
  duplicates of the per-figure images/*.png, so they dedupe to the per-figure
  copies (no unique image lost).
- Fix the linter path in every build.sh and README lint command that broke
  under the two-level-deeper move (../../../docs/skills/blog-figures/tools ->
  ../../../tools), and update fig-2's repo-root drafts/ paths.
- Update reference/figure-manifest.yaml and reference/README.md so every
  generator + output path points at the new examples location; zero drafts/
  references remain anywhere in the skill.

All seven figures re-lint at 100.0/100 (measured, SHIP-READY).

Signed-off-by: Dan Gil <dagil@nvidia.com>
- SKILL.md: fix stale "six" → "eight" (numbered list runs 1–8)
- html-to-png.md: replace fabricated benchmark numbers in the
  metric-card template with placeholders (N ops/s, M ops/s), and
  swap the "40x faster" line for a source-of-truth prompt to honor
  the skill's own "Never Invent Numbers" rule
- MD040: tag five bare code fences (four formula/worked-example
  fences in plotting.md, one directory-tree fence in SKILL.md) with
  the `text` language
- Soften absolute reproducibility claims in SKILL.md ("must be
  reproducible from a fresh clone" / "regenerates byte-for-byte")
  to acknowledge renderer and font version drift, and add a short
  note near the Playwright install line in html-to-png.md that
  unpinned Playwright/Chromium and system font versions affect
  exact pixel output
- plotting.md Rule 10: add a half-sentence noting the flash-indexer
  canonical title's parenthetical + comparison framing is the
  "telegraphed takeaway" exception to the declarative-verb form

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia
dagil-nvidia force-pushed the dagil-nvidia/blog-figures-skill branch from d46dfa9 to 13adca3 Compare July 21, 2026 20:49
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

Closing as filed.

Three reasons. It lands at docs/skills/blog-figures/ rather than the canonical .agents/skills/, so it bypasses validate_skills.py entirely. It carries roughly 3,970 lines of duplication - ten byte-identical copies of plotly_dynamo.py and ten of design_tokens.yaml. And the working copy of this skill has since moved ahead of the branch, adding a data-driven figures section and growing the anti-pattern list from 8 to 12.

@grahamking's question about the canonical skill directory has been open for seven weeks and is the real blocker; that needs answering before this is worth re-cutting.

If it belongs in-repo, the right shape is a fresh PR into .agents/skills/blog-figures/ with the shared assets factored out and an AGENTS.md index entry, which validate-skills requires.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

actions backend::vllm Relates to the vllm backend docs documentation Improvements or additions to documentation size/XXL Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants