<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Derek Vance</title>
    <description>The latest articles on DEV Community by Derek Vance (@derek_vance_8f2cd0c05dcac).</description>
    <link>https://dev.to/derek_vance_8f2cd0c05dcac</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4124141%2Ff93e7713-e60e-41ce-b8d9-357fc392a8b9.png</url>
      <title>DEV Community: Derek Vance</title>
      <link>https://dev.to/derek_vance_8f2cd0c05dcac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/derek_vance_8f2cd0c05dcac"/>
    <language>en</language>
    <item>
      <title>How We Built a Human-in-the-Loop Pipeline for AI-Generated Coloring Pages</title>
      <dc:creator>Derek Vance</dc:creator>
      <pubDate>Mon, 14 Sep 2026 08:26:42 +0000</pubDate>
      <link>https://dev.to/derek_vance_8f2cd0c05dcac/how-we-built-a-human-in-the-loop-pipeline-for-ai-generated-coloring-pages-3329</link>
      <guid>https://dev.to/derek_vance_8f2cd0c05dcac/how-we-built-a-human-in-the-loop-pipeline-for-ai-generated-coloring-pages-3329</guid>
      <description>&lt;p&gt;EarlyHue is a free library of printable coloring pages for preschoolers, ages 3 to 5. Every page is a print-ready US Letter PDF, there is no account or email wall, and the library spans animals, shapes, numbers, alphabet, colors, weather, vehicles, dinosaurs, and seasonal themes.&lt;/p&gt;

&lt;p&gt;We are a small team, so we use an AI image model to generate artwork at a scale we could never draw by hand. But the audience is a four-year-old with a crayon, and the pages sit in a children's education category. That combination means we cannot "just generate and publish." A stray detail, an inconsistent line weight, a garbled shape, or an image with unclear rights is a real problem when the reader is a preschooler and the buyer is a parent or teacher.&lt;/p&gt;

&lt;p&gt;This is how we built a pipeline that lets AI do the heavy lifting while keeping a human accountable for every page that ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with "just generate it"
&lt;/h2&gt;

&lt;p&gt;Naive AI generation fails for a children's product in a few predictable ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inconsistent difficulty.&lt;/strong&gt; One image comes back with bold, simple shapes; the next has tiny details a three-year-old cannot color inside.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Silent defects.&lt;/strong&gt; Occasionally a generation produces a malformed limb, a merged shape, or stray text-like marks that look like garbled letters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Style drift.&lt;/strong&gt; Across hundreds of pages, the "house style" (thick outlines, large open areas) drifts unless something enforces it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rights ambiguity.&lt;/strong&gt; For a free public library, we need to know the origin and usage rights of every asset, not assume them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are acceptable when the page is going to a classroom. So we treat generation as the &lt;em&gt;start&lt;/em&gt; of the pipeline, not the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two gates, not one
&lt;/h2&gt;

&lt;p&gt;The core design decision is simple: an illustration only becomes a public printable after it passes &lt;strong&gt;two independent gates&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automated screening&lt;/strong&gt; catches objective defects before a human spends time on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mandatory human review&lt;/strong&gt; makes a person accountable for age suitability, quality, originality, and rights.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We publish only what clears both. We would rather release fewer pages than skip a review, and the codebase is structured so that skipping is not the easy path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 0: structured briefs and recorded provenance
&lt;/h2&gt;

&lt;p&gt;Every illustration starts as a &lt;strong&gt;structured brief&lt;/strong&gt;, not a one-line prompt. The brief describes the subject, the composition, and the style constraints for young children: bold outlines, simple shapes, no tiny details. An AI image model (we use Seedream) generates candidate artwork from that brief.&lt;/p&gt;

&lt;p&gt;Critically, we record the origin of every candidate. Each published illustration keeps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the prompt and generation details,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a reference to the source asset file,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a &lt;strong&gt;SHA-256 hash of the source artwork&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hash gives us content-addressable provenance. If a source file ever changes, the hash changes, and we know the published record no longer matches the asset it claims to describe. It makes audits and lineage checks cheap and deterministic instead of archaeological.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 1: automated screening
&lt;/h2&gt;

&lt;p&gt;Before any person looks at a candidate, it goes through automated screening. The checks look at line quality, composition, and consistency with the brief. Candidates that fail are rejected or regenerated rather than pushed forward.&lt;/p&gt;

&lt;p&gt;One check worth calling out is a &lt;strong&gt;text-semantics pass&lt;/strong&gt;. Coloring pages should be pure line art, so we run OCR over the candidate and flag anything that resolves to stray or garbled text. It is a surprisingly effective proxy for "something went wrong in generation," because malformed shapes often produce text-like artifacts. (We run this locally with Apple's Vision framework on macOS; the interesting part is not the tool but that a pure-line-art page should have &lt;em&gt;no&lt;/em&gt; readable text, so any hit is a signal.)&lt;/p&gt;

&lt;p&gt;Automated screening does not decide what ships. It decides what is worth a human's attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 2: mandatory human review
&lt;/h2&gt;

&lt;p&gt;No artwork becomes a public printable without human approval. A reviewer confirms four things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Age suitability&lt;/strong&gt; for the 3 to 5 range,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Originality and rights&lt;/strong&gt;,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visual quality&lt;/strong&gt; (clean lines, correct shapes, no defects),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency with EarlyHue's style.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The approval is recorded as structured data, not a checkbox in someone's head. Each review batch has a manifest with an explicit status (&lt;code&gt;pending-human-review&lt;/code&gt; or &lt;code&gt;approved&lt;/code&gt;), an approval record (&lt;code&gt;reviewedBy&lt;/code&gt;, &lt;code&gt;reviewedAt&lt;/code&gt;, &lt;code&gt;notes&lt;/code&gt;), and a rights record. The rights status is an enum with real meaning, for example &lt;code&gt;original-owned&lt;/code&gt;, &lt;code&gt;ai-generated-commercial-use&lt;/code&gt;, or &lt;code&gt;licensed&lt;/code&gt;, plus an evidence field. Reviewers work through a local review app that presents each candidate with its brief and provenance so the decision is informed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gating the render, not just the workflow
&lt;/h2&gt;

&lt;p&gt;Here is the part that removes a whole class of bugs. The function that resolves an artwork's public lifecycle only returns a "reviewed" state when the batch manifest is &lt;strong&gt;approved&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; carries both an approval record and a rights record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;manifest&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;approved&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;approval&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rights&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;placeholderLifecycle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any of those are missing, the page falls back to a clearly-marked placeholder provenance. In other words, unreviewed content &lt;strong&gt;structurally cannot masquerade as approved&lt;/strong&gt; at render time. The gate is enforced in the data layer, not just in a process document someone might skip on a busy day. For a static site, this means the guarantee is baked into the build: a page cannot render a "human-reviewed" provenance claim unless the underlying manifest actually proves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  From approved art to a printable
&lt;/h2&gt;

&lt;p&gt;Once approved, the artwork is prepared as a &lt;strong&gt;US Letter PDF&lt;/strong&gt; formatted for standard home printers and classroom copiers, with a descriptive title and Alt text. Alt text and titles are generated as part of the pipeline, not added later by hand, so accessibility and SEO metadata stay consistent across hundreds of pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release governance in CI
&lt;/h2&gt;

&lt;p&gt;The pipeline is wrapped in release governance that runs in CI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Content validation&lt;/strong&gt; checks that every printable's data is well-formed and consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Release preflight&lt;/strong&gt; verifies a batch is ready before it is promoted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lineage verification&lt;/strong&gt; confirms a published asset traces back to an approved, hashed source.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Promotion and rollback&lt;/strong&gt; scripts move a reviewed batch live, or reverse it cleanly if something is wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is that "publish" is a controlled, reversible operation with an audit trail, not a manual file copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js with React and TypeScript, statically generated for fast, SEO-friendly pages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hosting:&lt;/strong&gt; Vercel (global CDN).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Artwork:&lt;/strong&gt; AI generation (Seedream) plus the documented human review pipeline above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documents:&lt;/strong&gt; automated US Letter PDF generation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Analytics:&lt;/strong&gt; GA4 with consent-aware configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quality:&lt;/strong&gt; automated content validation and production monitoring in CI.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Static generation is a good fit here precisely because the content is governed: the build reads the review manifests and refuses to render unapproved provenance, so the guarantee travels with the generated output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for a kids' product
&lt;/h2&gt;

&lt;p&gt;For a generic image site, an occasional odd generation is noise. For a free library that parents and teachers print for preschoolers, it is a trust problem, and trust is the whole product. The two-gate model plus manifest-gated rendering means the site can make an honest public claim — every page is AI-generated &lt;em&gt;and&lt;/em&gt; human-reviewed — and the code enforces that claim rather than hoping the workflow was followed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trade-offs and lessons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Human review is the bottleneck, on purpose.&lt;/strong&gt; It caps throughput. That is the point: the constraint is what makes the library trustworthy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provenance is cheap insurance.&lt;/strong&gt; Recording a SHA-256 per source asset costs almost nothing and turns "where did this come from?" into a lookup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enforce gates in the data layer.&lt;/strong&gt; A rule that lives only in a document gets skipped. A rule that lives in the render path does not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Structured briefs beat clever prompts.&lt;/strong&gt; Constraining the input (bold outlines, simple shapes, no tiny details) prevents more defects than any downstream fix.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are shipping AI-generated content into a context where quality or safety actually matters, the lesson generalizes: let the model produce volume, but put a deterministic provenance record and a mandatory human gate between generation and publication, and make the "approved" state something the code verifies, not something a person asserts.&lt;/p&gt;

&lt;p&gt;You can see the reader-facing version of this process at &lt;a href="https://earlyhue.com" rel="noopener noreferrer"&gt;EarlyHue&lt;/a&gt;, and the plain-language summary lives on the &lt;a href="https://earlyhue.com/how-our-coloring-pages-are-made/" rel="noopener noreferrer"&gt;How our coloring pages are made&lt;/a&gt; page.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nextjs</category>
      <category>typescript</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
