MUDRA KNIGHT
Book a Consultation
← Back to Case Studies
Digital PublishingFDE Engineering

“200MB Docker image savings, 6× more cover candidates, 0 regressions — in one session.”

Client Context

EBookr is an AI-native publishing platform that generates complete books for the Amazon KDP marketplace. Independent authors and publishing houses use it to produce everything from low-content journals to full-length nonfiction — across multiple niches and storefronts. The platform already had a working cover generation pipeline: an LLM wrote a prompt, Gemini generated an image, and a Node.js renderer (Chromium headless via render.mjs) composited the typography over the art.

The problem was a ceiling that engine tuning could not fix. The Node/Chromium compositor dumped 200MB onto every Docker image. The cover critic had no scoring rubric — it rubber-stamped the single cover it received. The prompt was unstructured prose that Gemini interpreted freely. The platform optimized for throughput (one cover, fast) when it needed to optimize for selection (six covers, then pick the best). EBookr engaged Mudra Knight to break through that ceiling.

The Illegibility Audit

Before a single line of production code, we audited the system across four diagnostic areas. What we found was a pipeline optimized for the wrong thing.

Data Provenance

cover_analysis.json existed on disk — the market intelligence layer had already analyzed 20 competitor covers and extracted hex codes, composition types, and art mediums. Nobody was reading it. The prompt engineer worked from intuition, not data. The data existed. The pipeline ignored it.

Legacy Constraints

The compositor was Node.js + Chromium headless. Every render launched a full browser instance, consumed 200MB per image, and operated within the limits of CSS-based typography (limited drop shadows, no proper gradient overlays, no region-aware contrast logic). The technology stack was dictating the typography quality, not the designer's intent.

Workflow Reality

The pipeline generated exactly one cover per run. The VLM critic received that single image, scored it against nothing, and approved it. There was no batch, no selection, no comparison. The workflow was a conveyor belt with no quality gate — it produced output, not curated output. The operator had no choice but to accept whatever the single seed produced.

Incentive Alignment

The pipeline was optimized for speed — one LLM call, one render, one pass through the critic. Speed was the metric. Quality was assumed. But in book cover design, quality requires iteration. The architecture rewarded fast generation of mediocre covers over deliberate generation of excellent ones. The incentive was misaligned with the business goal: conversion rates depend on cover quality, not generation speed.

What We Built

We delivered two coordinated specs (PIK-045 + PIK-046) in a single session. Together they replaced the cover generation pipeline from prompt to compositor — 850 lines of production Python, zero Node.js, zero Chromium.

L1Market Data Foundation

The cover-analyzer VLM process now feeds cover_analysis.json directly into the prompt engineer. The structured analysis — hex palettes from top-performing competitor covers, composition classifications, art medium prevalence — is no longer a file that exists in isolation. It is the first stage of every cover generation run. The prompt engineer writes for a specific market position, not generic “best practices.”

L2Structured Prompt Schema

The old pipeline wrote a paragraph prompt. The new pipeline writes a CoverPromptSchema — a Pydantic model with five structured fields: Subject, Environment, Art Style, Color Palette, and Composition. The LLM consumes this JSON deterministically. No interpretation, no creative license. The schema forces the model to produce art that leaves deliberate negative space for the compositor. Engine C reads the schema and renders accordingly.

L3Batch + Select Generation

A single --seeds N flag controls how many variations Engine C generates — N images from N different seeds, all from the same structured prompt. Each image includes a latent seed ID embedded in its metadata. The batching orchestrator tracks every seed, supports resume on interrupted runs, and outputs all N images for the critic to evaluate. One run now produces 6 cover candidates instead of 1. No additional prompt work required.

L4Pillow Compositor + VLM Critic

The Node.js + Chromium compositor is gone. compositor.py (~700 lines, Python/Pillow) renders drop shadows via GaussianBlur, gradient overlays, typography bands, and region-aware contrast. It ships with 33 OFL fonts and 26 genre-specific font pairings. After compositing, critic_vlm.py scores each cover on 10 dimensions — 5 aesthetic (layout, contrast, typography quality, color harmony, art coherence) and 5 standout (metadata display, genre signaling, readability at thumbnail, emotional response, purchase intent). The best cover wins. A COVER_COMPOSITOR=pillow|legacy toggle provides safe rollback.

Results

Before
600MB Docker image

Node.js + Chromium headless bundled per image. Full browser launch overhead per render.

After
400MB Docker image

Python/Pillow replaces Node + Chromium. Zero browser overhead. 200MB saved per image.

Candidates per run
1 → 6

Multi-seed batching produces 6 cover variations. VLM critic selects the best across 10 scoring dimensions.

What was corrected

  • Compositor replacement: 850-line Python/Pillow compositor replaced Node.js + Chromium renderer. Drop shadows via GaussianBlur, gradient overlays, typography bands, region-aware contrast. 33 OFL fonts with 26 genre-specific pairings.
  • Prompt architecture: Unstructured prose prompts replaced by CoverPromptSchema (Pydantic) — Subject, Environment, Art Style, Color Palette, Composition. Engine C reads JSON deterministically. No interpretation.
  • Batching pipeline: --seeds N flag produces N cover candidates per run. Seed-tracking with resume support. VLM critic selects from 6 candidates instead of rubber-stamping 1.
  • Quality gate: critic_vlm.py scores on 10 dimensions — 5 aesthetic + 5 standout. Region-aware contrast module samples text zone luminance independently. WCAG 3.0 fallback forces white or black text.
  • Safe rollback: COVER_COMPOSITOR=pillow|legacy toggle. Zero risk for the deployment. The legacy path remains intact.
  • Tests: 23 new tests (compositor, prompt schema, batching, critic). 140 total passing. Zero regressions.

System Architecture

The Field-Driven Cover Pipeline operates across four layers. Layer 1 feeds structured market data into Layer 2, which produces a deterministic schema for Layer 3 generation. Layer 4 selects and validates the final cover — a quality gate that did not exist in the old pipeline.

📊
L1MARKET INTELLIGENCE

Market Data Foundation

cover-analyzer VLM analyzes 20+ competitor covers. Extracts hex codes, composition types, art mediums. Outputs structured cover_analysis.json that feeds directly into the prompt engineer. No data is ignored.

📐
L2PROMPT FORMULATION

Structured Prompt Schema

CoverPromptSchema (Pydantic) enforces 5-part formula: Subject, Environment, Art Style, Color Palette, Composition. Engine C reads JSON deterministically. Loose paragraph prompts eliminated.

🎨
L3GENERATION + COMPOSITION

Batch + Select Pipeline

--seeds N produces N art-only images from Gemini. No text, no typography — deliberate negative space. compositor.py (Pillow) adds drop shadows, gradients, overlays, genre-paired fonts. Region-aware contrast sampled independently.

L4SELECTION + QUALITY GATE

VLM Critic + Final Curation

critic_vlm.py scores each cover on 10 dimensions (5 aesthetic + 5 standout). Best cover selected. COVER_COMPOSITOR=pillow|legacy toggle for safe rollback. WCAG 3.0 fallback for contrast compliance.

Business Impact

200MB

Docker image reduction

Python/Pillow replaced Node.js + Chromium. Smaller builds, faster deploy, zero browser launch overhead.

More cover candidates per run

Multi-seed batching replaced single-cover generation. VLM critic selects the best from 6 variations.

140 / 140

Tests passing, zero regressions

23 new tests added across compositor, prompt schema, batching, and critic. Zero existing tests broken.

“The secret to professional AI book cover design is treating the AI as an illustrator, not a graphic designer. You prompt for the art, deliberately leaving empty space, and then handle the typography in a separate automated formatting pipeline.”

— AI Book Cover Design Prompting Framework (Gemini, June 2026). This principle drove PIK-045 (compositor split) and PIK-046 (pipeline restructure).

This engagement produced the Field-Driven Cover Pipeline pattern — a six-stage reusable approach for AI-generated book covers. The pattern replaces guesswork with market data, loose prompts with structured schema, single-shot generation with batch+select, and browser rendering with professional Python compositing. Five assets extracted to the Systemized Toolbox: compositor.py, prompt_schema.py, critic_vlm.py, the batching orchestrator, and the region-aware contrast module.

Your AI pipeline generates output. Does it curate it?

Book a Consultation