콘텐츠로 이동

검증과 게이트

발행 직전에 글은 두 게이트를 차례로 통과합니다. Phase 3의 품질 판정과 Phase 4의 AI-smell 점수입니다. 둘 다 통과해야 Blogger 업로드에 닿습니다. 여기서는 각 게이트가 무엇을 보는지와, 그 아래에 깔린 보안 기준선을 봅니다.

quality-check는 한글본과 영문본을 같이 읽고 네 축으로 판정합니다. 보고서는 _workspace/briefs/{slug}-quality.md에 저장됩니다.

  • AdSense 정책: 가치가 낮다는 신호와 정책 위반 가능성을 봅니다. 별도의 adsense-optimization 검수와 짝을 이룹니다.
  • 검색 대응(SEO): 메타 태그와 스키마, hreflang 상호 참조, 키워드 밀도를 봅니다.
  • E-E-A-T: 경험과 전문성, 권위, 신뢰 신호를 봅니다. 1인칭 경험과 출처 인용이 실제로 들어 있는지를 확인합니다.
  • 한영 정합: 핵심 메시지와 H2 구조 대응, 데이터 일치, hreflang 상호 참조, slug 일치를 봅니다.

판정이 FAIL이면 발행 전에 멈춥니다. NEEDS_REVIEW이면 Phase 2 산출물을 고쳐 Phase 3을 다시 돕니다. PASS여야 다음 게이트로 넘어갑니다.

품질 보고서는 한글본 글자 수와 영문본 단어 수를 brief의 mode 기준(long은 1000012000자, short는 50007000자)과 대조하고, 출처 인용 수와 H2 섹션 수를 같이 적습니다. 길이 기준이 AI_AUTOMATION.md의 Phase 2 length policy 한 곳에서만 정의되기 때문에, 보고서는 그 값을 다시 정하지 않고 참조합니다.

ai-pattern-check는 _workspace/posts/new/의 한글본과 영문본을 훑어 0~100점을 매깁니다. 점수가 높을수록 AI가 쓴 티가 강합니다. 대부분의 항목은 Grep 패턴으로 자동 집계되고, 구조 균질성처럼 사람이 판단해야 하는 항목은 따로 봅니다.

판정점수동작
합격30 미만blog-publish로 진행합니다
경고30 ~ 60명백한 문제를 먼저 고치고, 전체 자동화를 요청받은 경우에만 진행하며 사유를 기록합니다
불합격60 초과발행을 차단합니다. production-agent에 다시 쓰기를 최대 2회까지 요청하고, 그래도 실패하면 사용자에게 넘깁니다

항목이 잡아내는 것은 이런 내용입니다. 템플릿 표현(“정리하면”, “핵심은”, “독자 여러분”), 나열 패턴(“첫째/둘째/셋째”), AI 주어 과다(“AI에게 물었다”가 한 글에 여러 번 나오는 경우), 영문 정형구(“In summary”, “It’s important to”), 결말의 다음 편 예고, 구조 균질성(모든 H2가 비슷한 길이이고 모든 문단이 3~5줄인 경우), 결정성 연결어(“결국”, “즉”, “다만”이 몰려 나오는 경우), 결론형 정형구(“~에 있다”로 끝나는 문장의 반복)입니다. 각 발견에 가산점이 붙고, 합이 기준값을 넘으면 판정이 내려집니다. 정확한 패턴과 점수는 ai-pattern-check 스킬에 들어 있습니다.

점수 기준값은 blog-orchestrator와 AI_AUTOMATION.md가 같은 값을 씁니다. 한쪽에서 임의로 다시 정의하지 않습니다.

게이트가 코드 차원에서 강제되는 방식

섹션 제목: “게이트가 코드 차원에서 강제되는 방식”

불합격한 글의 발행 차단은 오케스트레이터의 약속이 아니라 스크립트의 동작입니다. scripts/deploy_to_blogger.py가 업로드 직전에 AI-smell 게이트와 품질 게이트를 다시 확인하고, 불합격이면 업로드를 거부합니다. 오케스트레이터를 우회해 스크립트를 직접 실행해도 막히는 이유가 여기 있습니다. --skip-gate는 재발행이나 긴급 상황을 위한 통로로만 남겨 둔 것입니다.

AI_AUTOMATION.md에 적힌 여덟 줄입니다. 강제되는 위치가 각각 다릅니다.

코드규칙강제 위치
S1Google OAuth credentials.json과 token.json, API 키는 git이 추적하지 않습니다.gitignore
S2_workspace/ 바깥 파일의 수정과 삭제를 금지합니다. 인프라는 사람이 승인한 뒤에만 건드립니다에이전트 정의
S3산출물을 덮어쓰기 전에 백업합니다. 재발행할 때 이전 버전을 보존합니다blog-publish
S4외부 검색(research)은 사용자가 명시적으로 요청할 때만 실행합니다research
S5AdSense 정책을 위반할 가능성이 있는 글은 사전 검수를 통과한 뒤에만 발행합니다adsense-optimization
S6실명과 전화번호, 실제 주소를 자동으로 찾아 마스킹을 권고합니다. 자동으로 마스킹하지는 않습니다quality-check
S7API 키와 OAuth 토큰은 본문과 로그, 산출물에 평문으로 적지 않습니다모든 에이전트
S8AI-smell 게이트에서 불합격한 글은 Blogger 업로드를 차단합니다scripts/deploy_to_blogger.py

S1과 S7은 자격증명을 다루고, S5와 S8은 발행 게이트입니다. S6은 자동으로 마스킹하지 않고 사람의 결정에 맡기므로, 실명이 들어간 글을 발행할지는 사용자가 정합니다.

다음 섹션은 publishing입니다. Blogger OAuth 자격증명을 어디에 두는지, scripts/deploy.sh의 staging과 dry-run과 발행 명령이 어떻게 갈라지는지, 자격증명이 없을 때 어디서 멈추는지를 봅니다.