← 목록으로

SEO/GEO 야간 작업 완료보고 — 2026-08-28

02:18 → 05:40 KST · 5개 도메인 · 전부 라이브 재측정 완료

한 줄

이 머신에 있는 4개 도메인은 전부 FAIL 0 이다. heyreci 는 저장소를 찾아 고쳐뒀지만
Vercel 프로덕션이라 배포는 승인 대기.

금액으로 제일 큰 건은 notes 유료 제품 40장이 봇에게 344자였던 것 — 카피는 이미 있었는데
JS 로만 그려서 검색엔진·LLM 이 못 읽고 있었다. 1,681자로 늘렸다.

그리고 이번 작업의 가장 큰 소득은 사이트가 아니라 자(尺) 였다 —
우리 점검기가 틀린 게 8가지였고, 그동안 우리가 본 숫자는 사이트 상태가 아니라 점검기 상태였다.


1. 결과

도메인 FAIL 전 → 후 warn 전 → 후 상태
the-moment.us (apex) 2 → 0 0 → 0 ✅ 배포 완료
cue.the-moment.us 15 → 0 16 → 4 ✅ 배포 완료
mark.the-moment.us 3 → 0 4 → 3 ✅ 배포 완료
notes.the-moment.us 7 → 0 28 → 2 ✅ 배포 완료
heyreci.com 12 → 12 11 ⚠️ 고쳐뒀으나 미배포 — 승인 필요

남은 warn 9건은 전부 정체가 확인된 것이다 — 새로 발견된 문제가 아니다:
- cue 2 · notes 1 = author.sameAs / author 가 Person 이 아님 → 형 결정 대기(6절 ②)
- cue 2 = 홈의 공고 수치 갱신용 fetch (본문 렌더가 아니다 — cue/CLAUDE.md 에 이미 기록된 알려진 것)
- mark 3 = /explore·/find 의 클라이언트 필터 + /insights description 39자
- notes 1 = /insights 목록 480자 (글이 아직 적다)

cue 의 "15" 는 처음 잰 "0" 이 아니다. 자를 고치고 나서 나온 진짜 숫자다(§3 참조).


2. 무엇을 고쳤나

cue — 원형(原型). 여기서 만든 틀을 나머지가 복사한다

mark — 773 URL 짜리 멀쩡한 사이트였다

/explore·/find·/start 에 h1 이 아예 없었고, 전 페이지가 Organization 하나만 내보내고 있었다.
→ h1 3개 신설 + 페이지 유형별 스키마 5종(src/config/pageld.ts 한 곳에서 생성) + AI 봇 5종 + twitter:description.

notes — 봇에게 안 보이던 페이지들

/guide·/use-cases·/business·/about 이 서버 HTML 본문 0자였다(SPA 껍데기).
→ SPA 에 이미 있는 카피를 그대로 서버에서도 낸다(화면과 다른 걸 봇에게 보이면 클로킹이다).
/orders 는 개인 구매내역 조회 페이지라 본문을 채우는 게 아니라 noindex 로 빼는 게 정답 — sitemap 에서도 제외.
글 목록에 author·dateModified 추가.

그리고 제일 큰 건이 여기서 나왔다 — 유료 제품 40장이 봇에게 344자였다.
제품 상세의 실제 카피(2,409자)는 R2 의 _page.html 에 있고, SPA 는 그걸 fetch 해서 화면에 주입한다.
사람은 보는데 봇은 못 보는 상태였다 — 클로킹이 아니라 §5 프리렌더 누락이다.
서버에서도 같은 내용을 내보내게 고쳤다: /p/diary5y 344자 → 1,681자. 40개 제품 전부 적용.
매출이 나는 페이지들이라 이번 밤 작업 중 금액으로 가장 큰 항목이다.

apex — 제일 건강했다

랜딩에 h1 이 0개였다(제품 카드가 전부 h2). sr-only h1 하나로 해결. warn 까지 0.


3. 가장 큰 발견 — 점검기가 8군데 틀려 있었다

하룻밤에 seo_check.py 결함 8개가 나왔다. 전부 "통과인데 통과가 아닌" 종류다.

# 결함 무엇을 잘못 말했나
1 라이브 검사가 첫 페이지 1장만 봤다 cue 611장 중 1장. 글 40편은 한 번도 검사된 적이 없었다
2 리다이렉트를 따라가서 200 으로 보고 sitemap 의 /blog(301)를 25일간 '정상'이라고 했다
3 sitemapindex 를 안 따라감 mark 773 URL 을 "1개"로 읽었다 → 정본에 "검색에 낼 표면이 없다"로 잘못 적혔다
4 따옴표 없는 속성(<html lang=ko>)을 못 읽음 notes /insights 를 lang·description·canonical·viewport 4종 전부 없음으로 오판. 넷 다 있었다
5 ROOT스크립트 위치 기준 ~/bin/ 사본으로 돌리면 홈 전체 8,294개 파일을 훑어 FAIL 26,342
6 --uniq나브·푸터를 포함해서 쟀다 /company/* 를 26.9%(발행 금지선 아래)로 오판. 실제는 63.4% — §17 본문은 처음부터 "크롬 제외"였는데 구현이 안 지켰다
7 SPA 검사만 800자가 따로 박혀 있었다 §5 표는 허브 600자다. 같은 도구가 601자 페이지를 통과이면서 동시에 FAIL 로 판정했다 → min_text_for() 공유
8 h1<script> 안까지 셌다 인라인 JS 가 마크업 문자열을 들면 h1 으로 잡힌다. notes 는 DOM h1 1개인 페이지가 8개로 찍혔다 (허위 경고 9건)

🚨 통과를 받으면 통과의 범위를 먼저 의심해라.
cue 는 --pages 1 을 붙이는 순간 FAIL 0 → 15 가 됐다.

다섯 개 전부 고쳐서 momentus/scripts/seo_check.py + ~/bin/ 에 동기화했다.
새 기능 3개도 같이 들어갔다 — --pages(유형별 표본 전수), --uniq(프로그래매틱 고유도), 리다이렉트 정탐.


4. "두번다시 신경 안 쓰게" — 자동으로 도는 것 3개

  1. 신규 글date 는 이미 자동으로 붙고 있었다. 이제 그 값이 스키마·화면 바이라인·sitemap
    lastmod 로 자동 전파된다. 필자도 템플릿 한 곳에서 나온다. 새 글에 손댈 일이 없다.
  2. 배포 직후 자체 점검crawler/crawl.mjs 가 배포 후 --pages 1 을 돌려 FAIL 을 로그에 남긴다.
    🚫 배포를 막지 않는다. SEO 결함으로 사이트를 낡게 두는 게 더 큰 손해다.
    같은 커밋에서 자동 배포 경로가 sync-footer·sync-seo 를 아예 안 부르고 있던 것도 고쳤다
    (사람이 배포할 때만 돌던 단일소스가, 하루 두 번 도는 자동 배포에서는 통째로 빠져 있었다).
  3. 주간 전수 점검 — 매주 월 08:00, 5개 도메인 + 프로그래매틱 고유도.
    로그: cue/crawler/data/seo_weekly.log. 실행 테스트 완료.

정적 HTML 은 cue/scripts/sync-seo.mjs 로 단일소스화했다(푸터와 같은 방식). npm run deploy 가 자동으로 돈다.


5. 정본이 5장 늘었다 — §15~§22

~/Projects/momentus/docs/SEO_GEO.md (538 → 843줄). §1~§14 가 "페이지 한 장이 갖출 것"이라면,
증축분은 "사이트를 운영하는 법" 이다.

§ 지침
§15 필자를 사람으로 만들어라 — authorPerson, 실체 페이지 + sameAs
§16 신선도는 태그가 아니라 프로그램이다 — 분기 갱신 루프. 🚫 날짜만 바꾸기 금지
§17 프로그래매틱은 자로 재고 나눠 내라 — 고유도 40% 경고 / 30% 발행 금지, 50~100장 배치
§18 회귀를 감시해라 — URL 구조를 바꾼 커밋은 sitemap 생성기를 같이 고친 커밋이어야 한다
§19 페이지 유형이 검색 의도와 맞는가(SXO) — 쓰기 전 상위 10개의 유형을 세라
§20 낡은 상식 5개 폐기 — FAQPage 리치결과 2026-05-07 종료 · llms.txt 는 구글에 무효 · 단어 수는 랭킹 요소 아님
§21 제품별 실행계획 + 실측 결과표
§22 점검기 자체의 결함 5종 — 자를 고치면 그 자로 잰 과거 숫자를 전부 다시 재라

전략도 하나 정정했다

기존 §2 는 "SEO 와 GEO 는 다른 게임"이라고 적혀 있었다. 구글 공식 입장은 "AEO·GEO 는 SEO 를 다시 이름 붙인 것" 이다.
다만 결론은 살아남는다 — AI 개요는 순위 종속이지만 AI 모드·ChatGPT·Perplexity 는 별개 표면이라
(AI모드와 AI개요가 같은 URL 을 인용하는 비율 13.7%) 거기선 순위보다 신선도·엔티티·인용 가능한 문단이 이긴다.
§15(사람)·§16(신선도)·§6(인용 문단) 셋이 우리 전부다. 백링크 사냥은 하지 마라(상관계수 0.266).

참고: 이 작업의 계기

AgriciDaniel/claude-seo(⭐15.5k, MIT)를 뜯어 우리가 안 하던 것만 골라냈다.
플러그인은 설치하지 않았다 — 필요한 건 그쪽 기준이지 그쪽 도구가 아니었다.


6. 형 결정이 필요한 것 3가지

① heyreci 배포 (제일 큰 건)

저장소를 찾아(sexyflash/Reci) ~/Projects/heyreci 로 받아뒀다. 고친 것:
- alternates: { canonical: './' } 한 줄로 전 페이지 canonical (지금 0건 → 전부)
- JSON-LD 3종(Organization + WebSite + SoftwareApplication) — 지금 0건
- AI 봇 5종

Vercel 이라 push 가 곧 프로덕션 배포라 손대지 않았다. 매출 도메인이다.
승인만 주시면 FAIL 12 → 0 에 가까워진다.

② 필자의 sameAs 가 비어 있다

실재하는 링크드인·브런치·유튜브 URL 이 있으면 주시라. 없는 걸 지어내지 않았다.
AI 인용은 백링크(상관 0.266)보다 브랜드 언급(유튜브 0.737) 에 3배 붙는데,
sameAs 가 흩어진 언급을 한 사람으로 묶는 페이지 안의 유일한 장치다.

notes 글의 필자는 확정된 바가 없어 Organization 으로 뒀다. 사람으로 세울지 결정이 필요하다.

③ 푸터 단일소스가 이미 깨져 있었다 (제 작업과 무관 · PG 심사 관련)

cue/CLAUDE.md 는 "단일 소스 = sync-footer.mjs, npm run deploy 가 자동으로 돌려서
어긋난 채로 나갈 수 없다"고 적고 있다. 실제로는 아니다.

법정 표기라 임의로 고치지 않았다. CLAUDE.md 문구도 같이 정정해야 한다.


7. 남은 작은 것

묶음 규모 평균 최저
cue/job/* 496 90.0% 59.2%
cue/company/* 49 93.0% 63.4%
cue/role/* 8 91.1% 77.9%
cue/prep/* 8 75.1% 70.5%
mark/insights/* 174 93.9% 64.3%
mark 업종별 랜딩 22 79.9% 65.1%
mark 작업 상세 670 69.4% 56.6%

템플릿을 손볼 일은 없다. 남은 건 "한 번에 500장씩 내지 말 것"이라는 발행 방식뿐이다
(cue /job/* 496장 일괄 발행은 배치 규칙 50~100장 위반이었다).

⚠️ 이 숫자는 하룻밤에 세 번 바뀌었다(39.5% → 48.8% → 59.2%). 앞의 둘은 표본 편향과
크롬 미제외 때문이었다. 자를 못 믿으면 숫자도 못 믿는다 — 그래서 §22 를 남겼다.
- 구글 서치 콘솔 등록 — 여전히 사람만 할 수 있는 1순위다.
49건을 다 고쳐도 GSC 가 없으면 뭐가 좋아졌는지 볼 수가 없다.
the-moment.us 도메인 속성(DNS 인증) 하나면 cue·notes·mark 가 한 번에 커버된다. heyreci 는 별도.

8. 2회차 (03:50~04:55) — 추가로 한 것

9. 03:10 자동 발행 — 검증 완료 ✅

내가 고친 배포 경로를 처음 탄 실행이다. 결과:

[B5] 게이트 통과 (100점). stage=before
[B5] playbook.json 기록: analyze-job-posting-before-interview (총 36편)
[B5] 배포 완료 · [BK] 커밋 + 푸시 완료 · [nightly] 완료 644s

라이브에서 확인한 새 글(사람 손 하나도 안 탄 글):

author : Person 박진이
date   : 2026-08-28T09:00:00+09:00
화면    : 박진이 · 채용·면접 20년 · 2026년 8월 28일 발행

이게 "두번다시 신경 안 쓰게"의 증거다. 새 글이 필자·날짜·스키마·바이라인·sitemap lastmod 를
전부 갖추고 자동으로 나왔다. 야간 배치의 커밋도 콘텐츠 파일만 담았다 — 내 작업 중인 변경은 안 섞였다.

09:10 크롤(배포 직후 자체 SEO 점검이 처음 도는 실행)은 아직 남았다.


부록 — 다시 재는 법

for d in the-moment.us cue.the-moment.us notes.the-moment.us mark.the-moment.us heyreci.com; do
  echo "### $d"; python3 ~/bin/seo_check.py --live --domain $d --pages 1 2>&1 | tail -3
done

python3 ~/bin/seo_check.py --uniq "https://cue.the-moment.us/job/"   # 프로그래매틱 고유도

⚠️ --pages 를 빼먹지 마라. 그게 이번에 15건을 숨기고 있던 것이다.