docs(skills): add blog-figures skill with Dynamo Dark figure system - #10359
docs(skills): add blog-figures skill with Dynamo Dark figure system#10359dagil-nvidia wants to merge 16 commits into
Conversation
What does that mean? |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
|
||
| ## The Seven Non-Negotiables (Dynamo Dark Aesthetic Ladder) | ||
|
|
||
| 1. **Pure black background.** `#0a0a0a` or `#000000`. Never transparent. Never `#111111` "soft black" — readers' monitors lie. |
There was a problem hiding this comment.
🟡 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.
| 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. |
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| | Role | Family | Size (px) | Weight | Transform | Letter-Spacing | | ||
| |---|---|---|---|---|---| | ||
| | Title | `'NVIDIA Sans', Arial, Helvetica, sans-serif` | 18 | 700 | uppercase | 0.08em | |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
| | 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` | |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| ## 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: |
There was a problem hiding this comment.
🟡 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.
| 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: |
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| 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). |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
| :root { | ||
| /* From design_tokens.yaml -- mirror, do not invent */ | ||
| --bg-primary: #000000; | ||
| --bg-surface: #1a1a1a; |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| 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) |
There was a problem hiding this comment.
🔍 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
| | 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/). |
There was a problem hiding this comment.
🔍 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
WalkthroughAdded comprehensive documentation for Dynamo blog-figure design, authoring workflows, HTML-to-PNG rendering, reproducible builds, and chart construction standards. ChangesBlog figure authoring guidance
Estimated code review effort: 2 (Simple) | ~15 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
skills/blog-figures/plotting.md (1)
25-37: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winMake 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 explicittickvals/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
📒 Files selected for processing (5)
skills/blog-figures/DESIGN.mdskills/blog-figures/SKILL.mdskills/blog-figures/aesthetic.mdskills/blog-figures/html-to-png.mdskills/blog-figures/plotting.md
| 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. |
There was a problem hiding this comment.
📐 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 thefile://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 thefile://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 thefile://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-L95skills/blog-figures/aesthetic.md#L110-L110skills/blog-figures/aesthetic.md#L197-L197skills/blog-figures/aesthetic.md#L322-L327skills/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
| ## 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. |
There was a problem hiding this comment.
🗄️ 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-L5skills/blog-figures/aesthetic.md#L17-L32skills/blog-figures/aesthetic.md#L81-L110skills/blog-figures/SKILL.md#L59-L69skills/blog-figures/html-to-png.md#L21-L24skills/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.
| <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> |
There was a problem hiding this comment.
🗄️ 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.
| <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.
|
|
||
| ### 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: |
There was a problem hiding this comment.
📐 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-L78skills/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
| ## 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. |
There was a problem hiding this comment.
📐 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.
| ``` | ||
| 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 |
There was a problem hiding this comment.
📐 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
| ## 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. |
There was a problem hiding this comment.
📐 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-figuresRepository: 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-figuresRepository: 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-figuresRepository: 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.
41ac572 to
0c8e65e
Compare
f891d07 to
bf03624
Compare
This comment has been minimized.
This comment has been minimized.
7d2631a to
664c3d1
Compare
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>
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>
d46dfa9 to
13adca3
Compare
|
Closing as filed. Three reasons. It lands at @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 |
Summary
Adds the
blog-figuresskill for creating Dynamo blog and digest figures, underdocs/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.mdkeeps 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:Helvetica Neue, Helvetica, Arial, sans-serif), weight 300, title case, with a muted Helvetica subtitle.0.08emletter-spacing (the canonical token title).Everything else (black surfaces, NVIDIA-green
#76b900accents, 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 treeDESIGN.md— cite-able source of truth: type system, palette, layout, forbidden anti-patternsaesthetic.md— diagram aesthetic guidanceplotting.md— chart craft (annotations, delta brackets, hero title-subtitle stacks)html-to-png.md— HTML+CSS authoring recipesRunnable 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, aREADME.mdgallery, and the canonicaldesign_tokens.yaml+plotly_dynamo.pyhelpers:gen_fig_2_architecture.py— data-flow diagram with green replay edgegen_fig_5_decision_cascade.py— cascade with a horizontal delta bracketgen_fig_6_tuning_loop.py— pipeline with phase tags and a calibration loopgen_fig_concurrency_sweep.py— dual-panel concurrency sweep + Pareto curvegen_fig_throughput_bars.py— compact horizontal-bar scoreboardgen_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.pngre-rendered to the Dynamo Dark display treatmenttools/gen_hero.py(+build.sh,README.md, tokens, helpers) so the hero is regenerableFigure 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 itskind,renderer,title_treatment,outputs, data provenance (real vs illustrative), measuredlint_score,source_ref, and ause_whenhint. A controlled-vocabularykinds:block (13 kinds across four families:chart.*,diagram.*,hero.*,cards.*) keepskindvalues 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 siblingdesign_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 todocs/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 commit16ad32d19c, split out into its own PR for review independence. Iterated fromskills/blog-figures/todocs/skills/blog-figures/, unified into the single Dynamo Dark system, and extended with runnable example generators and the re-rendered hero exemplar.Test Plan
SKILL.mdfrontmatter is intact (valid Claude skill)examples/build.shand confirm each generator renders in the correct treatmentfile:/// broken links)reference/figure-manifest.yamlparses and every generator + output path resolves