← Corpus / lossless-monorepo / agent-skill
Three New Skills — Crawl-Fetch-Ingest, Maintain DESIGN.md, Generate Consistent OG Images
Codified three workflows the team had been doing freehand: VC firm metadata crawls (crawl-fetch-ingest), agent-readable project visual-identity contracts following Google Stitch's open spec (maintain-design-md), and consistent share-imagery generation via the Ideogram v3 API with WhatsApp/iMessage as the primary target (generate-consistent-og-images). The OG-images skill picked up an empirical refinement this session — empty space has to be declared as a first-class rendered subject, not left as residue — that pushed the BannerTall composition from a chronic 85% subject-fill to a clean 40-65%.
- Path
- agent-skills/changelog/2026-05-11_01.md
- Authors
- Michael Staton
- Augmented with
- Claude Opus 4.7 (1M context)
- Tags
- Skills · DESIGN-MD · Google-Stitch-Spec · Ideogram-API · OG-Images · WhatsApp-Share · VC-Firm-Crawl · Empty-Space-Prompting
Three New Skills — Crawl-Fetch-Ingest, Maintain DESIGN.md, Generate Consistent OG Images
Why Care?
The Lossless skills tree gained three first-party skills since the last changelog entry. Each one started from a real workflow the team was doing by hand or by re-implementation per project, and each one promotes that workflow into something an agent will load and apply consistently across our 10+ Astro sites, our Obsidian plugin family, and our fundraise-deck work.
All three skills share a posture worth naming: codify before you copy. Each captures a pattern that had already been used 2–3 times across different projects before becoming a skill. None of them are speculative — they encode discoveries that paid for themselves in earlier sessions.
The third skill — generate-consistent-og-images — picked up an empirical refinement during this session that’s worth flagging at the top because it’s the kind of finding you can’t get from training data: when generating share imagery with empty space reserved for SVG text overlay, leading the prompt with the empty region (and giving it concrete content) defeats the “subject grows up into the overlay zone” failure mode that plagued our earlier runs. Details below.
What’s New?
Skill 1 — crawl-fetch-ingest/
The team’s workflow for filling in team and portfolio metadata for VC firms (and similar org-level work). Crawl a firm’s site, fetch structured data + brand assets for the people and companies referenced in a deck or PDF, ingest as canonical .md files with YAML frontmatter. Encodes:
- The four-checkpoint cascade — VC team → advisors → portfolio companies → portco CEOs — each gate a human-confirmation step before paid crawls fire.
- Cross-tool fallback pattern — Firecrawl → Tavily → OpenGraph.io, in priority order, so any single rate-limited or down provider doesn’t stall the cascade.
- Global-cache-per-firm convention — raw API responses land at
~/.claude/skills/crawl-fetch-ingest/cache/{firm-slug}/so the same firm’s data is reused across multiple decks/memos without re-paying. - The loose canonical schema that sites converge toward on refactor — not enforced on ingest, because the goal is fast filling, not strict modeling.
Use when an investment memo, fundraise deck, or fund one-pager needs its team/advisor/portfolio sections recreated cleanly from a PDF + a firm URL. Use when the input is “here’s a PDF, give me a clean dataset of who’s in it.” Setup (~/.secrets for API keys, MCP server registration) documented in the skill’s setup.md.
Skill 2 — maintain-design-md/
How to author and maintain a DESIGN.md file at the root of any Lossless project — site, splash page, plugin landing, fundraise deck — following Google Stitch’s open spec. The skill owns:
- The spec mapping — the five frontmatter token groups (
colors,typography,rounded,spacing,components) and the eight prose sections in canonical order (Brand & Style → Colors → Typography → Layout → Elevation → Shapes → Components → Do’s and Don’ts). - The bootstrap discipline — read the runtime CSS first; copy the shape of
content-farm/splash/DESIGN.md(the Lossless reference implementation) but re-author the values per project. Don’t invent values out of thin air. - Maintenance triggers — a table of 9 code-side changes that should bounce back into the doc (new CSS custom property in
:root, renamed token, new mode, new reusable component, refreshed palette, etc.), plus a 4-step drift audit. - Source-of-truth discipline — runtime CSS wins when the two disagree; never “design in the doc.”
- The precedent for off-spec extensions —
imagery:block (owned bygenerate-consistent-og-images),modes:block (owned bytheme-system). The Stitch spec’s “Consumer Behavior for Unknown Content” table guarantees safety; this skill codifies where extensions slot in (aftercomponents:in frontmatter, before## Do's and Don'tsin prose).
Use whenever a project needs a DESIGN.md from scratch, or when the runtime CSS / component vocabulary has evolved past what’s documented. Sibling to theme-system (architecture) and generate-consistent-og-images (which reads the imagery: extension).
Skill 3 — generate-consistent-og-images/
How to generate share-imagery — OpenGraph banners, portraits, squares, tall WhatsApp/iMessage cards — for any Lossless site so the resulting images form a coherent visual family. Locks every parameter on the Ideogram v3 request except prompt and aspect_ratio; the rest (style reference, color palette weights, negative prompt, seed, rendering speed, magic_prompt flag) lives in the project’s DESIGN.md imagery: block.
What the skill ships:
templates/imagery-block.yaml— drop-inimagery:recipe for any project’sDESIGN.md. Three ★-marked project-specific fields (style_reference.path,color_palette.members,defaults.seed); everything else copies verbatim.templates/ideogram-request.sh— canonical curl invocation that reads locked values from the project’sDESIGN.md, varies onlypromptandaspect_ratioper call, downloads the response immediately (Ideogram URLs expire), saves response JSON alongside for prompt/seed/resolution echo.- The six-format aspect-ratio enum —
banner(16:9),banner_tall(3:4 — Lossless WhatsApp/iMessage default),banner_tall_max(2:3),portrait(4:5),portrait_tall(9:16),square(1:1). Format names are cross-project canon; Ideogram values match the v3 API. - The naming convention —
ogimage__{Site}--{Format-Or-Variant}.jpg, lands in<project>/public/. - The “WhatsApp / iMessage first” stance — Lossless ships tall variants as first-class deliverables, not afterthoughts, because chat-preview is our primary share surface.
- The when-to-break-the-rules carve-out — page-specific or component-specific illustrative imagery may legitimately depart from the OG canon; the skill documents the naming separation (
illustration__/hero__prefix instead ofogimage__) to keep the share-imagery set uncontaminated. - Preservation discipline — raw candidates auto-archive into timestamped
<project>/.ideogram-candidates/<aspect>-<timestamp>/directories; canonical JPEGs archive on replacement into<project>/.ogimage-archive/ogimage__{Site}--{Format}--{YYYY-MM-DD}.jpg. Never overwrite without preserving. The unfurler URL stays stable; the byte history survives.
Uses IDEOGRAM_API_KEY from ~/.secrets (same pattern as crawl-fetch-ingest). No MCP server required — direct HTTPS multipart upload.
What Changed in Approach
The OG-images skill was authored on May 10 with what felt like comprehensive composition guidance: “frame composition positively, not negatively — state where the subject lives, never where the negative space goes.” The Perplexed OG run today exposed that as incomplete. Two iterations of subject-first prompting produced subjects at 75–85% canvas height, swallowing the SVG overlay zone every time. The third iteration flipped the framing and worked. The refinement is now codified in both DESIGN.md and the skill:
| Pattern this rejects | Pattern this adopts |
|---|---|
| Subject-first prompt with composition as soft trailing modifier (“…in the lower third of the frame, top two-thirds open”) | Empty-region-first prompt as two clauses (“Top 1/3 of frame is empty negative space, dark gradient sky. Bottom 2/3 contains {subject}.”) |
| Soft proportions (“lower portion”, “below the horizon”) | Explicit numeric splits (“top 1/3 / bottom 2/3”) |
| Empty space as residue left over after rendering the subject | Empty space as a first-class renderable thing with its own concrete content (a “dark gradient sky”) |
negative_prompt as a generic “exclude bad stuff” list | negative_prompt as a place to put the specific observed failure mode (subject in top half) |
style_type: DESIGN paired with style_reference_images | style_type: AUTO whenever a style reference is uploaded — the v3 API explicitly rejects DESIGN/REALISTIC/FICTION in that combination |
The generalizable lesson: empty space won’t be left as residue. It has to be declared, named, and given content. A sky is just as describable as a quill — and once the model is told the sky has to be rendered, the subject can’t grow into it.
A second discipline came out of the same session, more workflow-shaped:
- Preservation, not replacement. Every Ideogram run lands in a fresh timestamped directory (
.ideogram-candidates/<aspect>-<timestamp>/), never overwriting prior raw candidates. Canonical JPEGs (public/ogimage__{Site}--{Format}.jpg) archive their previous version to.ogimage-archive/with a date suffix before being replaced. The unfurler URL stays stable; the byte history survives. Encoded as a “Preservation discipline” section in the skill.
Updates to Existing Skills
Three pre-existing skills got light updates while the new skills landed:
git-conventions/— added a “Push-output gotchas” section with one item codifying that GitHub’s Dependabot vulnerability banner ingit pushoutput is unreliable noise (drifts from the alerts UI, fires even when Dependabot is disabled, doesn’t update after resolving the underlying advisories). Don’t surface it to the user as actionable on unrelated pushes. (User’s empirical observation from working through stale advisories.)open-graph-share-seo-geo/— picked up two new references files (llms-txt-implementation.md,sitemap-implementation.md) — exposing the implementation detail of two patterns the skill already described.astro-knots/— minor updates (TBD diff inspection).
Files Changed
context-v/skills/
├── README.md (added 3 new skill rows; slotted next to composing siblings)
├── changelog/
│ └── 2026-05-11_01.md (this file)
├── crawl-fetch-ingest/ (new — full skill: SKILL.md, setup.md, future-work.md, cache/, examples/, routines/, schema/, scripts/)
├── generate-consistent-og-images/ (new)
│ ├── SKILL.md
│ └── templates/
│ ├── imagery-block.yaml (drop-in recipe for project DESIGN.md frontmatter)
│ └── ideogram-request.sh (canonical curl invocation)
├── maintain-design-md/ (new)
│ ├── SKILL.md
│ └── templates/
│ └── design-md-scaffold.md (empty-file scaffold)
├── astro-knots/SKILL.md (minor updates)
├── git-conventions/SKILL.md (added "Push-output gotchas" section)
└── open-graph-share-seo-geo/
├── SKILL.md (updated)
└── references/
├── llms-txt-implementation.md (new)
└── sitemap-implementation.md (new)
Reference
- Lossless reference implementation:
content-farm/splash/DESIGN.md— full canonical example of aDESIGN.mdwith both the standard Google Stitch sections and the off-specimagery:extension. - Empirical evidence (the empty-space wisdom): the Perplexed OG generation pass produced 28 raw candidates across three prompt iterations; iter1/iter2 subject-first prompts produced 75–85%-tall subjects, iter3 empty-region-first prompts produced 40–65%-tall subjects with clean overlay zones. The 6 final canonical JPEGs ship from
content-farm/splash/public/ogimage__Perplexed--*.jpg. - Google Stitch spec: https://github.com/google-labs-code/design.md
- Ideogram v3 API: https://developer.ideogram.ai/ideogram-api/api-overview
- Cross-skill ties:
maintain-design-md+theme-system(composes on architecture) +generate-consistent-og-images(composes viaimagery:extension).crawl-fetch-ingestis independent — pairs withdeck-iteration-workflowfor fundraise-deck filling.