Media pipeline
The site uses three deliberately separate media lanes. The distinction is about ownership and rebuildability, not aesthetics.
1. Authored article images
New images uploaded through Writer are source files and live in Git:
assets/uploads/articles/YYYY/MM/article-slug/
Example:
assets/uploads/articles/2026/09/ban-oblique-kicks/
cover.webp
rampage-kick.webp
These are the authored originals for that article. Existing legacy files under assets/uploads/ keep their current URLs and are not moved.
2. Generated image derivatives
Responsive variants are machine output:
assets/generated/posts/
Legacy source images continue using the existing flat generated filenames so their public URLs do not change.
For the Stage 2 article hierarchy, new responsive output mirrors article ownership:
source
assets/uploads/articles/2026/09/ban-oblique-kicks/cover.webp
generated
assets/generated/posts/2026/09/ban-oblique-kicks/
cover-480.webp
cover-720.webp
cover-768.webp
cover-960.webp
cover-1600.webp
The mapping is generated by scripts/media-paths.mjs and consumed by scripts/optimize-post-images.mjs.
_data/responsive_images.yml remains the lookup table used by Jekyll. Templates should continue asking the manifest for the preferred generated URL rather than constructing derivative paths themselves.
Generated variants are rebuildable outputs. Source images are not.
3. Article video
Writer-uploaded video never belongs in the repository.
The Writer stages video temporarily through the Netlify backend and publishes it as a GitHub Release asset under a monthly release:
writer-media-YYYY-MM
The article stores the resulting Release URL. Temporary upload chunks are deleted after publishing.
Direct external video URLs may still be embedded when appropriate, but the Writer no longer presents assets/uploads/ as a video-storage option.
Enforcement
npm run check:media
The media check verifies:
- article-owned source paths use the Stage 2 hierarchy;
- article-owned generated paths use the matching generated hierarchy;
- tracked video files are rejected from
assets/; - Writer still targets article-owned image storage;
- responsive generation uses the shared media-path planner;
- the Writer video backend still targets GitHub Releases.
This check runs as part of Site Quality.