Sprint 4주차 회고 — AdSense 신청 직전 1주, 13 PR을 머지하며
자가점검에서 발견한 5 FAIL을 시작점으로 1주 동안 13 PR을 머지하고 AdSense 신청 직전 상태로 사이트를 정리한 W22 회고. P0 보안·인프라 5건, P1 콘텐츠 구조 2건, UX·E-E-A-T 3건. 자동으로 가능한 것의 한계와 사용자 수동 4건의 무게.
지난 일요일 AdSense 가이드 글을 쓰고 자가점검했더니 5 FAIL을 발견한 회고를 적었다. 그 글의 마지막 줄에서 "다음 한 주는 fix-everything 1주"라고 약속했다. 오늘이 그 약속을 닫는 날이다. 1주 동안 13개 PR을 머지했고, 사이트는 이제 AdSense 신청 직전 상태에 있다. 이 글은 그 13 PR에서 무엇이 가능했고 무엇이 끝까지 사용자 수동으로 남았는지에 대한 짧은 회고다.
시작점 — 자가점검 5 FAIL + 11 WARN + 광고 인프라 0건
지난주 회고를 다시 펼쳐 보면 발견된 문제는 크게 셋이었다. broken link·image 5건 (apple-shortcuts·claude-4-sonnet·perplexity·obsidian 2편), AdSense 인프라 0건 (ads.txt 404 + 광고 스크립트 미노출), 사이트 구조 약점 다수 (Topic Cluster Pillar 백링크 누락·중복 URL·고아 글·FAQ 형식 오류). 거절 사유 7가지 중 4~5가지가 동시에 걸리는 상태였다.
해야 할 일을 우선순위 3단계로 묶었다. P0 자동 가능한 항목 11개, P1 콘텐츠 구조 4건, P1 UX·E-E-A-T 5건. 총 20+ 항목. 이걸 1주에 끝내려면 가장 큰 함정은 "PR 하나에 너무 많이 묶는 것"이라는 걸 알고 있었다. 그래서 단일 책임 PR 원칙을 처음부터 끝까지 지키기로 했다.

W22 1주 13 PR — 각 PR이 단일 책임을 지키도록 분리한 결과
P0 자동 처리 — 보안·인프라·SEO schema (5 PR)
처음 사흘은 사람 결정 없이 끝낼 수 있는 항목부터 정리했다. Next.js를 16.2.3에서 16.2.6으로 올리면서 HIGH CVE 7건과 MODERATE 4건이 한 번에 해소됐다. pnpm-lock.yaml 재생성 과정에서 packages/blog-core의 peer 의존성이 16.2.3 스냅샷에 묶여 있어 한 번 막혔는데, devDependency로 명시 추가해서 풀었다. favicon.ico·manifest.ts 양쪽 앱에 추가, 영문 카테고리 매핑 누락 해소, FAQ + BreadcrumbList JSON-LD 보강까지 5 PR.
이 중 가장 미세한 사고는 FAQ JSON-LD가 처음에 라이브에 안 떴던 것이다. 정규식 \b 워드 경계가 한국어 글자 뒤에서 매칭에 실패했고, JS에 없는 \Z anchor를 그대로 썼다. Python 정규식이면 동작했을 패턴이었다. JavaScript 환경에서는 (?:^|\n)과 (?=\n## |$) 같은 명시적 lookahead만 안전하다는 걸 다시 확인했다.
P1 콘텐츠 구조 — AI 코딩 Pillar 신규 + 카테고리 통합 (2 PR)
가장 큰 변화는 새 Pillar 한 편을 작성한 것이다. AI 코딩 cluster에 보조 글 4편(claude-code-flutter·claude-mcp-guide·obsidian-claude-code-mcp·claude-code-vs-cursor)이 쌓여 있는데 Pillar가 없는 상태였다. 신규 Pillar ai-coding-complete-guide-2026을 9,326자로 작성하고 matplotlib 차트 5장을 자동 생성해 발행했다. 이제 4 cluster + 1 Pillar 구조가 완성됐다.
같은 PR 묶음에서 카테고리 통합도 끝냈다. 글 1편짜리 카테고리 5개(LLM·AI 검색·코딩 도구·생산성·LLM)를 3개 상위 카테고리로 흡수하고, next.config.ts에 301 redirect 4건을 박았다. categories.ts는 한글 10개 카테고리에서 6개로 정리됐고, 영문 alias 2개는 EN 글 매칭을 위해 유지했다. 한 달 전 디버깅 회고에서 다룬 매핑 문제가 이번엔 사전 차단 모드로 들어왔다.
P1 UX·E-E-A-T — 404·About·image lazy (3 PR + 1 hot fix)
가장 시간이 걸린 건 마지막 단계였다. 404 페이지를 양쪽 앱에 신규 작성하고, GA4 광고 시그널 옵션을 명시하고, About 페이지에 운영자 경력·리뷰 신뢰도 단락 2개를 추가했다. MDX 본문 이미지에 loading="lazy" + decoding="async" 자동 주입을 blog-core 컴포넌트 매핑 한 줄로 끝냈다. 5월 신작 3편의 백링크 0건도 같이 정리해 고아 글 0편 상태에 도달했다.
처리 중 한 번 사고가 났다. PR #41이 ESLint react/no-unescaped-entities 룰로 verify CI에서 차단됐다. About 페이지의 인용부호 "..." 4건이 JSX 안에서 escape되지 않은 것. 한국어 코드 작업 중 "를 그대로 쓰던 습관이 lint에 잡힌 순간이다. “...”로 escape하는 lint fix commit을 추가 push해서 머지를 풀었다. 같은 commit이 머지될 때 GitHub squash 과정에서 conflict markers가 main에 그대로 들어갈 뻔한 더 큰 사고도 있었는데, git checkout --theirs + rebase로 정상 fix 적용 상태를 확인했다.
자동으로 가능한 것의 한계 — 사용자 수동 4건만 남았다
1주 동안 자동 가능한 항목은 거의 다 처리됐지만, 끝까지 Claude Code 단독으로는 불가능한 항목이 4건 남았다.
- Vercel Settings에서
NEXT_PUBLIC_ADSENSE_ID환경변수 설정 — AdSense 콘솔에서 게시자 ID 발급받은 후 직접 추가 - AdSense 콘솔에서 사이트 추가 + 신청 클릭
- publisher ID 수령 후
ads.txtplaceholder 한 줄 교체 + push contact@aigrit.dev메일 inbox 라우팅 (Cloudflare Email Routing 등 — 선택)
이 4건의 공통점은 모두 외부 서비스 콘솔과 시크릿 입력이 필요하다는 점이다. AdSense·Vercel 둘 다 사용자 인증이 필요한 영역이고, CLI나 코드에서 직접 건드릴 수 있는 부분이 아니다. 자동화의 경계는 결국 "외부 서비스의 사용자 계정 안쪽"에서 멈춘다.
이번 sprint를 통해 자동화 가능한 것과 그렇지 않은 것의 경계가 더 분명해졌다. 사이트 구조·콘텐츠·코드·SEO 메타·라이브 검증까지는 코드 작업으로 끝낼 수 있다. 그러나 게시자 ID·결제 정보·계정 인증이 끼는 순간 사람의 시간이 필요해진다. 이 4건이 5분짜리 작업이지만, 그 5분이 1주 자동 작업과 동등한 무게를 갖는다.
마무리 — 신청 버튼 직전
오늘 저녁 또는 내일 아침에 AdSense 신청 버튼을 누른다. 거절되면 사유에 맞게 추가 보강을 한다. 1차 통과되면 W23은 신규 글 발행 + SNS 자산 생성 + 영문 번역 우선순위 글로 채운다. 3주차 회고에서 "발행 속도가 빨라진 만큼 점검 빈도가 따라잡지 못했다"고 적었던 게 지금 풀린 셈이다. 점검 1주를 통째로 비우는 것이 발행 속도를 다시 정직하게 만든다.
이 글이 끝나면 13 PR이 라이브에 모두 안착하고 GSC URL Inspection으로 정책 페이지 색인 상태만 한 번 확인한 뒤 AdSense 콘솔로 들어간다. 다음 회고는 신청 결과를 받은 뒤에 적는다.
공식 출처는 Google AdSense 정책·게시자 정책.
관련 글
1인 빌더의 하루 — GentleLab·AIGrit·babipanote 3개를 운영하는 법
GentleLab 시리즈(앱 3개)·AIGrit 블로그·babipanote 허브 3-브랜드를 동시에 운영하는 1인 빌더의 실제 하루 루틴. 05:30~23:00 시간 블록, 제품별 주간 시간 배분, 도구 스택 22개, 번아웃 관리 규칙까지 공개.
AdSense 체크리스트 글을 쓰고 내 사이트 점검했다 — 5 FAIL 발견한 날
AIGrit에 AdSense 승인 체크리스트 13항목을 정리해 발행한 직후, 같은 기준으로 내 블로그 18편을 점검했더니 5편이 FAIL이었다. ads.txt 부재·broken 링크·이미지 0장. 가이드를 쓴다는 건 자기 자신부터 통과시켜야 한다는 뜻이라는 걸 W21에 깨달았다.
PKM 스택 전체 공개 — Obsidian + Craft + Claude 하이브리드 (Pillar)
Obsidian·Craft·Claude를 한 도구로 묶지 않고 역할별로 분리해 1년간 굴린 PKM 스택을 그대로 공개한다. 도구별 역할 분담, 실제 워크플로우, MCP 자동화 파이프라인, 1년치 노트 3,200·문서 178·MCP 호출 2,400회의 지표까지 적은 PKM 허브 글.