How I Built A QC Gate to Hide Automation Signals

Automation reveals itself in ways you do not expect.

I ran an automated content pipeline for Bluesky. One post went out mentioning "the content pipeline." On a technical blog, that is fine. On a social timeline, it is a red flag. It tells readers they are talking to a bot.

I built a quality control script to stop this. It acts as a gate between the generation step and the posting step.

The new workflow looks like this: bluesky-qc.mjs → (PASS) bluesky-post-queue.mjs → Bluesky API

The script uses four gates to check every entry:

  • Gate 1: Phrase Filtering I use a regex list to catch words that signal automation. It blocks terms like "AI-generated," "cron," "content pipeline," or "batch test." If a post sounds like a dev report, it fails.

  • Gate 2: Staleness Checks I check for two types of stale content: • Stale phrasing: It catches words like "today" or "just launched" that lose meaning if the post is delayed. • Stale timestamps: If an entry is older than 14 days, it gets rejected.

  • Gate 3: Engagement Prediction The script looks at my past 300 posts. It predicts if the hashtags in a new post will perform well. Currently, this only logs a warning, but I will turn it into a hard fail soon.

  • Gate 4: Quality Pass (Planned) I intend to add a final layer using a quality protocol to catch subtle errors.

Every failure goes into a rejection log. I review this log once a week. This helps me fix my prompts. If the gate keeps catching "content pipeline," I know I need to change how the AI writes.

Why use a gate instead of just better prompts? Prompts are probabilistic. They might fail. A gate is deterministic. It follows strict rules.

Using both layers is the safest way to maintain a human tone.

Source: https://dev.to/morinaga/how-i-built-a-pre-post-qc-gate-that-blocks-bluesky-automation-from-self-revealing-41ja