Skip to content

Verification and gates

Right before publishing, a post clears two gates in series: the Phase 3 quality verdict and the Phase 4 AI-smell score. Both have to pass before it reaches the Blogger upload. This section covers what each gate looks at, and the security baseline underneath them.

quality-check reads the Korean and English versions together and judges across four axes. The report lands at _workspace/briefs/{slug}-quality.md.

  • AdSense policy — low-value content signals, policy-violation risk. It pairs with the separate adsense-optimization review.
  • SEO — meta tags, schema, hreflang cross-references, keyword density.
  • E-E-A-T — experience, expertise, authority, trust signals. Whether first-person experience and source citations are actually present.
  • ko/en parity — core message, H2 structure correspondence, data match, hreflang cross-reference, slug match.

If the verdict is FAIL, it stops before publishing. If NEEDS_REVIEW, it fixes the Phase 2 outputs and runs Phase 3 again. It has to be PASS to move to the next gate.

The quality report compares the Korean character count and English word count against the brief’s mode (long 10000–12000 characters, short 5000–7000), and lists the citation count and H2 section count alongside. Because the length standard is defined in one place, the Phase 2 length policy in AI_AUTOMATION.md, the report references that value rather than setting its own.

ai-pattern-check scans the Korean and English versions under _workspace/posts/new/ and scores them from 0 to 100. The higher the score, the heavier the AI flavor. Most categories are counted automatically with Grep patterns, while spots that need a manual read, like structural uniformity, are looked at separately.

VerdictScoreAction
PassUnder 30Proceed to blog-publish
Warn30 to 60Fix the obvious spots first; proceed only if full automation was requested, and record the reason
FailOver 60Block publishing. Ask production-agent for a rewrite, up to twice. If it still fails, hand back to the user

The spots the categories catch are things like these. Template phrases (“정리하면,” “핵심은,” “독자 여러분”), enumeration patterns (“첫째/둘째/셋째”), overuse of AI as a subject (“I asked the AI” several times in one post), English boilerplate (“In summary,” “It’s important to”), next-episode teasers at the end, structural uniformity (every H2 the same length, every paragraph three to five lines), decisive connectives (“결국,” “즉,” “다만” clustered), and conclusion-form boilerplate (sentences ending in “~에 있다” repeated). Each hit adds points, and when the sum crosses the threshold a verdict drops. The exact patterns and scores live in the ai-pattern-check skill.

The score thresholds are the same in blog-orchestrator and AI_AUTOMATION.md. Neither side redefines them.

Where the gate is enforced at the code level

Section titled “Where the gate is enforced at the code level”

Blocking a failing post isn’t a promise the orchestrator makes; it’s what the script does. scripts/deploy_to_blogger.py re-checks the AI-smell and quality gates right before upload and refuses to upload if it fails. That’s why calling the script directly to bypass the orchestrator still gets blocked. --skip-gate is an exit kept only for republishing or urgent situations.

Eight lines planted in AI_AUTOMATION.md. Each is enforced in a different place.

CodeRuleEnforced at
S1Google OAuth credentials.json/token.json and API keys are not git-tracked.gitignore
S2No modifying or deleting files outside _workspace/. Infrastructure only after human approvalagent definitions
S3Back up before overwriting an output. Preserve the prior version on republishblog-publish
S4External search (research) only on explicit user requestresearch
S5Posts that might trip AdSense policy publish only after passing reviewadsense-optimization
S6Auto-detect real names, phone numbers, real addresses and recommend masking. No automatic maskingquality-check
S7API keys and OAuth tokens are never planted in plaintext in bodies, logs, or outputsall agents
S8A post that fails the AI-smell gate is blocked from Blogger uploadscripts/deploy_to_blogger.py

S1 and S7 handle credentials, and S5 and S8 are publishing gates. S6 leaves it to a human rather than masking automatically, so whether to publish a post containing a real name is the user’s call.

The next section is publishing. It covers where the Blogger OAuth credentials live, how scripts/deploy.sh splits between staging, dry-run, and the publish command, and where it stops when credentials are missing.