DEV Community

Cover image for Where My Automation Stops: Judging Titles, Keywords And Covers By Hand

Where My Automation Stops: Judging Titles, Keywords And Covers By Hand

Where My Automation Stops: Judging Titles, Keywords And Covers By Hand

Last month I ran a batch of 40 sticker packs through my pipeline and one of them shipped with the title "Untitled Asset 27 Copy". A buyer noticed before I did. That was the moment I stopped pretending the whole chain could run unattended, because it can't, and the parts that can't are the parts reviewers actually look at.

Here is where the line sits between what my scripts do and what I still do with my own eyes.

The CSV headers are solved. The judgment is not.

make_metadata.py writes the exact headers the three platforms demand: Adobe's 5-column format, Vecteezy's 4-column, Dreamstime's 15-column. Get one header wrong and the upload rejects instantly, so automating that was worth every hour. The script never fails on headers.

But a valid CSV full of garbage still gets rejected, just slower. The script can title-case a filename, and the filename is a fine first pass, but I replace it before every submission. Reviewers on stock platforms reject for keyword stuffing, for titles that read like keyword lists, for descriptions that don't match the image. No script I can write judges that reliably. So the workflow is: script builds the CSV, I read every row. For 40 packs that's maybe 90 minutes. It's the most valuable 90 minutes in the whole process.

Double-posting is automated to be impossible. What counts as "done" is not.

upload_tracker.py keeps a ledger of what I've already posted, so a re-run never double-posts. This matters because the fastest way to get an account flagged on any stock platform is submitting the same asset twice. The ledger handles that cold.

What it can't handle is the judgment call of whether an asset is worth posting at all. I've deleted entire batches after looking at them. The tracker remembers what I did, not whether I should have.

Covers render at exact sizes. Whether they sell is my problem.

pack_product.py renders a 1280×720 cover and a 600×600 thumbnail with Pillow, and it does it the same way every time. On my 1 vCPU, 2 GB server, that render step runs one file per subprocess so memory goes back to the OS, and I measure peak RSS with resource.getrusage(RUSAGE_SELF).ru_maxrss rather than trusting averages. That discipline is what let the whole pipeline package 39 products, 856 MB of output, on a box with no GPU.

But a technically correct cover and a cover that makes someone click are different things. I look at every cover against the thumbnail size it will actually appear at. If the title is unreadable at 600×600, the render was wasted. That check is mine, every time.

The rendering math is automated. The taste isn't.

The RAM habits generalize: one process at a time on a single core, gc.collect() after each asset, render at the resolution you need (inspecting a preview at 60 dpi beats 300). Those rules came out of 300+ pages of research and a lot of crashed runs, and they're encoded in the scripts now.

What's not encoded: which of my generated images are good. AI image generation costs real money per image, and my hit rate is maybe one keeper per five or six generations. A script can't make that call. I batch-generate, then sit down and pick. This is the slowest human step in the pipeline and I've stopped trying to automate it, because every attempt produced catalogs full of near-misses that got rejected or, worse, sold once and refunded.

The folder structure keeps the judgment cheap

One thing that did help the manual steps: a fixed layout.

project/
  assets/       raw output
  output/       ready-to-submit files + metadata.csv
  packs/        finished zips + covers
  research/     notes and sources
  scripts/      the tools
Enter fullscreen mode Exit fullscreen mode

Keeping research/ forever means my notes on what titles and keywords got accepted are sitting there when I write the next batch. I deleted that folder once to "clean up" and lost the acceptance patterns I'd learned. Never again.

The honest split

So here's the actual division of labor in my pipeline. The scripts handle: metadata CSVs with exact platform headers, double-post prevention, Markdown to styled PDF via reportlab, packaging with covers and thumbnails, and all of it runs on 1 vCPU and 2 GB RAM with two third-party packages total (Pillow and reportlab). The metadata and tracker scripts need nothing but the standard library.

I handle: reading every title, checking every keyword list against the image, looking at every cover at thumbnail size, and picking keepers from generations. Roughly 90 minutes per batch of 40. That's the irreducible human cost, and I've made peace with it.

Everything I learned building that division, the scripts, the RAM rules, the folder layout, the platform header formats, went into the ai sticker factory playbook. It's the tool built from this work, not a description of it. If you want the automation to cover everything except the judgment, which is where it should stop anyway, it's there.

Get ai sticker factory playbook


Building digital products? Free guides & kits for digital product sellers.

Top comments (1)

Collapse
 
octyn profile image
OCTYN •

The line you drew is the right one, and "Untitled Asset 27 Copy" is a useful way to sharpen it. That one was not a judgment failure. It was a string pattern a script can catch: title still equals the filename, contains Untitled or Copy, keywords empty. Those checks are cheap, and they turn your 90 minutes of reading into confirmation instead of detection. The eyeball time then goes to the rows the flags did not catch, which are the ones that actually need taste.