birchholt 직접 해보고 남기는 기록

한 페이지가 저자를 둘 선언하고 있었습니다 — 플랫폼이 이미 넣어주는 것을 또 넣었습니다

발행 자동화로 굴리는 블로그가 둘 있습니다. 맛집 쪽 47편, 여행 쪽 41편, 합쳐서 공개 글 88편입니다. 오래된 글까지 전수로 점검하다가 글 페이지 하나가 저자를 둘 선언하고 있는 것을 봤습니다. 그리고 그 두 이름이 서로 달랐습니다.

버그가 아니라 전제가 원인이었습니다. 발행 파이프라인이 「글 페이지에는 저자 구조화 데이터가 없으니 넣어야 한다」를 전제하고 본문에 한 벌을 심고 있었는데, 플랫폼은 그걸 이미 넣고 있었습니다.

아래 숫자는 전부 2026-09-09 15:14~15:16 KST에 두 사이트맵에서 뽑은 88개 주소를 캐시 무력화 쿼리스트링을 붙여 다시 받아 잰 값입니다. 88편 전부 HTTP 200이었습니다. 같은 88편을 다른 각도로 훑은 전수 스캔 기록에서 배운 대로, 편수와 응답 코드를 같은 줄에 함께 찍어두지 않으면 0이 무슨 뜻인지 알 수 없습니다.

플랫폼은 이미 넣고 있었습니다

ld+json 블록을 파싱해서 세어봤습니다. 플랫폼이 <head>에 자동으로 넣는 BlogPosting88편 전부에 있었고, 그 안에 author 가 이미 들어 있었습니다.

"author": {"@type": "Person", "name": "체크인 커맨더", "logo": null}

제가 아무것도 안 해도 모든 글이 저자를 선언하고 있었다는 뜻입니다. 그 위에 파이프라인이 본문 맨 아래에 저자 박스(마이크로데이터 Person)를 한 벌, 글에 따라 본문 인라인 @graphArticleauthor 를 또 한 벌 얹었습니다.

재는 것편수
사이트맵의 공개 글88 (47 + 41)
플랫폼이 자동으로 넣은 BlogPosting(저자 포함)88 / 88
파이프라인이 넣은 저자 박스 (itemtype=".../Person")85
파이프라인이 넣은 본문 @graphArticle62
한 페이지의 저자 이름 선언 수 = 362
선언 수 = 223
선언 수 = 1 (플랫폼 것만)3
선언된 이름이 서로 어긋나는 글69

마지막 줄이 핵심입니다. 선언이 여러 개인 것 자체는 중복일 뿐인데, 69편에서는 그 이름들이 서로 다른 사람을 가리킵니다. 플랫폼 쪽은 블로그에 설정해둔 필명을 그대로 씁니다. 파이프라인 쪽은 기본값 자리표시자인 「블로그 운영자」를 그대로 내보내고 있었습니다.

독자가 보는 이름은 틀린 쪽이었습니다

여기서 한 번 더 나빴습니다. 스크립트와 스타일을 걷어내고 사람이 실제로 읽는 텍스트만 남겨서 다시 셌습니다.

제 스킨의 글 헤더에는 작성자 표시가 아예 없습니다. 스킨 파일에서 날짜 치환자 한 줄만 쓰고 있고 작성자 자리는 만든 적이 없습니다. 그래서 맞는 이름은 기계만 읽고, 사람이 눈으로 보는 이름은 틀린 쪽입니다. 페이지 맨 아래 「블로그 운영자」가 이 블로그의 저자 표시로 읽힙니다.

그 박스가 오래 살아남은 이유도 여기 있습니다. 라이브 페이지 88편 어디에도 .author-box 를 잡는 CSS 규칙이 0건이고, 두 스킨의 style.css 를 라이브에서 받아 author 를 세도 양쪽 다 0입니다. 스타일이 없으니 본문 끝의 평범한 제목 한 줄과 문단 두 줄로 보입니다. 눈에 띄게 깨지는 대신 본문인 척 섞여 있었습니다.

스키마 정의를 직접 받아봤습니다

박스는 이렇게 생겼습니다.

<aside class="author-box" itemscope itemtype="https://schema.org/Person">
  <h3 itemprop="name">블로그 운영자</h3>
  <p itemprop="description">다양한 주제를 깊이 있게 다루는 블로그입니다.</p>
  <time datetime="2026-07-21" itemprop="datePublished">2026년 7월 21일 발행</time>
</aside>

PersondatePublished 가 달려 있습니다. 이상해서 어휘 정의를 직접 받았습니다 (schema.org/version/latest/schemaorg-current-https.jsonld, HTTP 200, 2026-09-09 재확인). 각 속성이 어떤 타입에 붙을 수 있는지는 domainIncludes 가 말해줍니다.

속성domainIncludesPerson 에 쓸 수 있나
nameThing가능 (PersonThing 의 하위)
descriptionThing가능
jobTitlePerson가능
birthDatePerson가능
datePublishedCertification, CreativeWork불가
dateModifiedCreativeWork, DataFeedItem불가

PersonCertificationCreativeWork 도 아닙니다. 그러니까 저 한 줄은 **「이 사람은 2026년 7월 21일에 발행되었다」**를 선언하고 있었습니다. 같은 속성이 85편에 들어 있습니다.

스킨부터 의심한 것이 틀렸습니다

이 글에서 제가 제일 크게 틀린 지점입니다.

박스를 처음 봤을 때 저는 스킨을 의심했습니다. 스킨은 제가 직접 만들어 쓰는 것이고, 최근에 손댄 것도 스킨이었기 때문입니다. 두 스킨의 skin.htmlstyle.css 를 전부 뒤졌습니다. author 라는 문자열이 네 파일 통틀어 0건이었습니다.

날짜 쪽도 같은 방향으로 틀렸습니다. 스킨이 헤더에 찍는 날짜가 플랫폼이 내보내는 구조화 날짜와 어긋나 있을 거라 생각했는데, 88편을 대조하니 88 / 88 완전 일치였습니다.

스킨은 두 축 모두 무죄였습니다. 「최근에 내가 만진 곳」이 「지금 깨진 곳」과 같을 거라는 추측에 30분을 썼습니다.

두 번째로 틀린 것은 판정의 범위입니다. 저는 저 박스가 통째로 잘못된 스키마라고 적어뒀는데, 정의를 받아보니 아니었습니다. namedescriptionThing 에 달려 있어서 Person 에서 완전히 합법입니다. 틀린 칸은 datePublished 하나뿐이었습니다. 「전부 틀렸다」로 적어두면 고칠 때 다 지우게 되는데, 실제로는 한 칸만 빼면 되는 문제였습니다.

이미 고쳐둔 16편이 더 이상했습니다

박스의 이름을 필명으로 갈아둔 글이 16편 있습니다. 그 16편은 해결된 줄 알았는데, 박스 안의 description 을 뽑아 세어보니 이랬습니다.

여행 쪽 10편의 Person 설명은 그 블로그 홈의 소개문 「주소 하나 어긋나면 하루가 통째로 밀립니다…」와 바이트 단위로 동일합니다. 이름은 사람 것으로 고쳤는데 설명은 사이트 소개문이 들어가 있습니다. 사람을 선언해놓고 사람이 아니라 블로그를 설명하는 상태라, 고친 쪽이 안 고친 쪽보다 나은지 저는 판단하지 못하겠습니다.

날짜도 같은 구조였습니다

이름에서 본 것이 날짜에서 그대로 반복됩니다.

재는 것
한 페이지의 발행일 선언 수 3 / 2 / 162 / 23 / 3
선언된 날짜가 서로 어긋나는 글84
전부 일치하는 글1
최대 격차50일
가장 흔한 격차2일 (25편), 그다음 38일 (15편)
헤더의 보이는 날짜 == 플랫폼 구조화 날짜88 / 88
박스 날짜가 플랫폼 날짜보다 84편 (뒤인 경우 0편)

여기서 세 번째로 틀렸습니다. 저는 이 두 날짜를 같은 사건에 대한 독립된 두 기록으로 보고, 「둘 중 하나가 망가진 것이니 어느 쪽이 원본인지 찾자」로 접근했습니다. 글을 편집해 다시 저장하면 플랫폼이 발행일을 저장 시각으로 갈아엎기 때문에, 당연히 박스 쪽이 원본일 거라고 봤습니다.

재보니 독립된 기록이 아니었습니다. 박스 날짜와 본문 @graph 날짜는 둘 다 있는 62편에서 62 / 62 일치합니다. 한 출처가 두 번 찍힌 것이지 증인이 둘인 게 아닙니다. 그리고 플랫폼 날짜는 헤더에 보이는 날짜와 88 / 88 일치합니다. 즉 이 페이지의 날짜 출처는 셋이 아니라 둘이고, 제 쪽 날짜는 84편 전부에서 플랫폼보다 앞이며 뒤인 경우가 한 건도 없습니다.

한쪽이 항상 앞이라면 그건 같은 사건의 두 기록이 아니라 다른 시점을 재는 두 값입니다. 가장 흔한 격차 2일(25편) 중 8편은 플랫폼 쪽 시각이 00:00:0X 였습니다 — 자정에 실행된 예약 발행 자국입니다. 나머지 17편이 왜 2일인지는 확인하지 못했습니다. 어느 쪽을 발행일 정본으로 삼을지도 아직 정하지 못했습니다.

아직 안 고쳤습니다

파일은 하나도 고치지 않았습니다. 방향만 적어둡니다.

정리