Image Optimization Pipeline Config
Concept of the skill
What it is: The build-time contract for turning source images into responsive, compressed, format-specific outputs.
Mental model: The pipeline is a deterministic compiler stage: source image plus config produces a known set of artifacts.
Why it exists: Image quality, file size, and fallback support have to be reviewed before they become user-visible performance or fidelity regressions.
What it is NOT: It is not runtime <picture> markup, layout design, or incident debugging after a build fails.
Adjacent concepts: Responsive breakpoints, format negotiation, compression quality, transparency preservation.
One-line analogy: It is the recipe card the image build step follows for every asset.
Common misconception: Smaller output is always better; preserving transparency, fallback coverage, and layout fit are part of correctness.
Coverage
- The format-negotiation table — which output formats the pipeline produces (AVIF + WebP + JPEG fallback is the canonical shape) and the priority order browsers should request
- Srcset breakpoints — the widths the pipeline emits per image role (hero, content, thumbnail) and how those align with the site's CSS layout breakpoints
- Per-format compression quality — JPEG at 80, WebP at 75, AVIF at 65 is a defensible default; anything more aggressive needs visual A/B verification
- Transparency preservation — the pipeline must detect alpha channels in source PNGs and disable lossy formats (or fall back to lossless WebP / AVIF) for those specific images
- Idempotency — the pipeline must not reprocess already-optimized outputs on every build (cache invalidation by source-file hash, not timestamp)
- Source-format coverage — what the pipeline accepts as input (PNG, JPEG, WebP source) and what it explicitly rejects (HEIC, RAW, video formats)
Philosophy of the skill
A build-time image pipeline is a config-defined contract between the source-of-truth images in content/ and the bandwidth-optimized variants the browser receives. Bugs here are silent: a misconfigured srcset doesn't crash the build, it just sends a 4MB hero image to a phone. The discipline is to encode every choice — breakpoints, formats, quality, transparency rules — explicitly in the config, with a comment naming the constraint that drove each choice. Pipeline behavior should be derivable from the config without reading the build script.
Key Files
| File |
Purpose |
lib/images/pipeline.config.ts |
The canonical config: breakpoints, formats, quality settings, source-format allowlist |
scripts/build-images.ts |
The build entrypoint that reads the config and walks content/ — should be a thin runner with no embedded policy |
lib/images/format-negotiation.ts |
The runtime helper that maps a request's Accept: header to the right pre-built variant |
Verification
Before merging any change to the pipeline config:
Do NOT Use When
| Use instead |
When |
| (a frontend image-rendering skill) |
The task is choosing the right <picture> / <img srcset=...> markup at the component level |
debugging |
A specific image is failing to optimize and you need to reproduce from build logs |
documentation |
The task is writing a contributor doc explaining how the pipeline works |
refactor |
The task is restructuring the pipeline code without changing the config contract |
1---2# name: stable skill identifier. Match the skill directory name or the final namespace segment.3# Lowercase letters/numbers with hyphen, slash, or colon separators.4name: image-optimization-pipeline-config5# description: routing-facing summary of what the skill covers and when it activates.6# Include concrete triggers and an explicit negative boundary; keep routing semantics out of prose-only ambiguity.7description: "Use when authoring or reviewing the build-time image pipeline config — defining responsive srcset breakpoints, picking output formats (AVIF / WebP / JPEG fallback), tuning compression quality per format, and ensuring the pipeline never produces a lossy artifact for source PNGs with transparency. Activate this skill whenever the task touches `lib/images/pipeline.config.ts`, `scripts/build-images.ts`, or any code path that resizes or recompresses content images. Do NOT use for runtime image rendering choices (use a frontend skill) or for chasing a specific build failure (use debugging)."89# === v8 Classification (subject + public; polyhierarchy via subjects[]) — see ADR-0017 ===10# subject: primary browse shelf — what the skill teaches. One of twelve closed values:11# backend-engineering / frontend-engineering / software-architecture / data-engineering / agent-ops / ai-engineering /12# quality-assurance / design / reasoning-strategy / software-engineering-method / knowledge-organization / product-domain.13subject: backend-engineering14# public: publishability/private-data gate. Boolean.15# true = publishable/shareable; false = private and excluded from public export.16# Project anchoring is carried separately by non-empty `project[]` plus `grounding`.17public: false18# taxonomy_domain: optional hierarchical sub-path within `subject`. Slash-delimited19# lowercase kebab-case segments. rename of the original v8 `domain`. Remove when the flat20# `subject` is sufficient.21taxonomy_domain: content/build/images22# scope: free-text PRD-style statement of what the skill teaches and what it excludes.23# (v8 required; not an enum). Mirrors Coverage + Do NOT Use When at frontmatter level.24scope: "Build-time image pipeline configuration for the markdown-static-site example project — srcset breakpoints, format negotiation, transparency preservation, and idempotency."25# stability: lifecycle marker. One of:26# experimental (active development) / stable (production-ready) /27# frozen (no further changes expected) / deprecated.28# When `deprecated`, schema's allOf REQUIRES `superseded_by: <real-skill-name>`.29stability: experimental30# license: SPDX license identifier (e.g., MIT, Apache-2.0).31license: MIT32# compatibility: runtime compatibility object. Prefer structured fields33# (`agent_runtimes`, `node_version`) over free-text `notes`.34compatibility:35 agent_runtimes:36 - node37 node_version: ">=20"38 notes: "sharp ^0.33 or equivalent; output formats AVIF / WebP / JPEG."39allowed-tools: Read Grep Bash40# keywords: semantic phrases for fuzzy router activation. v8 cap: max 10.41# Keep terms a user would actually type when starting a task in this skill's domain.42keywords:43 - image optimization44 - image pipeline45 - srcset breakpoints46 - responsive images47 - AVIF WebP fallback48 - sharp config49 - PNG transparency50 - compression quality51 - image build pipeline52 - format negotiation53 - image resize54# triggers: explicit-match activation phrases the router fires on literally.55# Use when label-based routing is intended; usually keywords + examples are enough.56triggers:57 - image-optimization-pipeline-config58# paths: glob array of code surfaces this skill governs. Supports gitignore-style59# negation. Each glob should map to ONE canonical skill. Omit if purely conceptual.60paths:61 - "lib/images/pipeline.config.ts"62 - "scripts/build-images.ts"63 - "lib/images/format-negotiation.ts"64 - "!**/*.test.ts"65# examples: 2-5 realistic user prompts the skill SHOULD activate for.66# Written in the user's voice. Improves retrieval recall beyond keywords alone.67examples:68 - "configure srcset breakpoints for hero images and thumbnails differently"69 - "review the image pipeline — does it preserve transparency on PNG sources?"70 - "add AVIF output to the pipeline alongside WebP and JPEG"71 - "tune JPEG quality without breaking the AVIF pass"72# anti_examples: near-miss prompts that should route ELSEWHERE.73# Pair with relations.suppresses (or legacy boundary alias) to name the confusable territory's owner.74anti_examples:75 - "pick the right <picture> element markup at runtime"76 - "the build is OOM-killed on the 10MB hero image"77 - "rewrite the pipeline in a different image library"78# relations: typed graph edges to sibling skills. Current fields:79# related (adjacency for browse / co-routing expansion) /80# suppresses (exclude listed skills from co-routing when THIS skill wins; write reason81# as "I own this exclusively over X", not "use X instead") /82# boundary (DEPRECATED alias of suppresses, retained for unmigrated skills) /83# verify_with (cross-check; co-loaded as one-hop expansion) /84# depends_on (composition; transitive — A→B→C loads all three) /85# broader / narrower (SKOS-style generalization) /86# disjoint_with (mutual exclusion for incompatible ownership).87relations:88 related:89 - documentation90 - debugging91 - refactor92 verify_with:93 - testing-strategy94# grounding: required when `project[]` is non-empty. Declares the truth sources95# the skill anchors to and the failure modes those sources prevent. Omit when the96# skill is universal-knowledge. `subject_matter` replaces v8 `domain_object`.97grounding:98 subject_matter: "Build-time image pipeline configuration — the resize/compress/format-negotiation rules that turn source images in `content/` into the responsive variants under `public/images/`"99 grounding_mode: repo_specific100 truth_sources:101 - lib/images/pipeline.config.ts102 - scripts/build-images.ts103 - lib/images/format-negotiation.ts104 failure_modes:105 - lossy_compression_on_png_with_transparency106 - missing_avif_fallback_for_unsupported_clients107 - srcset_breakpoints_dont_match_layout_breakpoints108 - quality_setting_too_aggressive_visible_artifacts109 - pipeline_doesnt_skip_already_optimized_outputs110 evidence_priority: repo_code_first111# project: projects this skill is linked to. Array of {handle, role} objects.112# Non-empty project[] anchors the skill to a project and requires `grounding`.113# Suggested role values: source-of-truth, consumer, mirror. Replaces original v8 `workspace_tags`.114project:115 - handle: markdown-static-site116 role: primary117---118119# Image Optimization Pipeline Config120121## Concept of the skill122123**What it is:** The build-time contract for turning source images into responsive, compressed, format-specific outputs.124**Mental model:** The pipeline is a deterministic compiler stage: source image plus config produces a known set of artifacts.125**Why it exists:** Image quality, file size, and fallback support have to be reviewed before they become user-visible performance or fidelity regressions.126**What it is NOT:** It is not runtime `<picture>` markup, layout design, or incident debugging after a build fails.127**Adjacent concepts:** Responsive breakpoints, format negotiation, compression quality, transparency preservation.128**One-line analogy:** It is the recipe card the image build step follows for every asset.129**Common misconception:** Smaller output is always better; preserving transparency, fallback coverage, and layout fit are part of correctness.130131## Coverage132133- The format-negotiation table — which output formats the pipeline produces (AVIF + WebP + JPEG fallback is the canonical shape) and the priority order browsers should request134- Srcset breakpoints — the widths the pipeline emits per image role (hero, content, thumbnail) and how those align with the site's CSS layout breakpoints135- Per-format compression quality — JPEG at 80, WebP at 75, AVIF at 65 is a defensible default; anything more aggressive needs visual A/B verification136- Transparency preservation — the pipeline must detect alpha channels in source PNGs and disable lossy formats (or fall back to lossless WebP / AVIF) for those specific images137- Idempotency — the pipeline must not reprocess already-optimized outputs on every build (cache invalidation by source-file hash, not timestamp)138- Source-format coverage — what the pipeline accepts as input (PNG, JPEG, WebP source) and what it explicitly rejects (HEIC, RAW, video formats)139140## Philosophy of the skill141142A build-time image pipeline is a config-defined contract between the source-of-truth images in `content/` and the bandwidth-optimized variants the browser receives. Bugs here are silent: a misconfigured srcset doesn't crash the build, it just sends a 4MB hero image to a phone. The discipline is to encode every choice — breakpoints, formats, quality, transparency rules — explicitly in the config, with a comment naming the constraint that drove each choice. Pipeline behavior should be derivable from the config without reading the build script.143144## Key Files145146| File | Purpose |147|---|---|148| `lib/images/pipeline.config.ts` | The canonical config: breakpoints, formats, quality settings, source-format allowlist |149| `scripts/build-images.ts` | The build entrypoint that reads the config and walks `content/` — should be a thin runner with no embedded policy |150| `lib/images/format-negotiation.ts` | The runtime helper that maps a request's `Accept:` header to the right pre-built variant |151152## Verification153154Before merging any change to the pipeline config:155156- [ ] Every output format has an explicit quality setting; no relying on library defaults157- [ ] Srcset breakpoints match (or are a documented superset of) the site's CSS layout breakpoints158- [ ] PNG sources with an alpha channel route to lossless or alpha-preserving lossy formats (WebP-lossless, AVIF) — never to JPEG159- [ ] The pipeline skips already-optimized outputs by source-hash comparison; running the build twice in a row is a no-op on the second run160- [ ] An end-to-end test under `__tests__/images/` exercises a fixture image of each accepted format and asserts the expected variant set is produced161- [ ] The format-negotiation helper has a fallback path for clients that send no `Accept:` header (or one that lists no supported format)162163## Do NOT Use When164165| Use instead | When |166|---|---|167| (a frontend image-rendering skill) | The task is choosing the right `<picture>` / `<img srcset=...>` markup at the component level |168| `debugging` | A specific image is failing to optimize and you need to reproduce from build logs |169| `documentation` | The task is writing a contributor doc explaining how the pipeline works |170| `refactor` | The task is restructuring the pipeline code without changing the config contract |