본문으로 건너뛰기

Docusaurus + GitHub Pages 출판 가이드

출판 스택 결정 (현행)​

영역도구
정적 사이트 생성기Docusaurus 3.10.x (classic preset, docs only)
배포GitHub Pages — gh-pages 브랜치 배포 (2026-08-10 전환). 이전: Actions workflow
배포 트리거로컬 빌드 → gh-pages 브랜치 push → Pages 빌드 요청 (아래 §배포 방식 전환)
단일 출처manuscript/articles/*.md
빌드 변환docs-docusaurus/scripts/copy-from-manuscript.mjs

영입 원본: book-happtalk 의 multi-tool hub 패턴. 이 프로젝트는 단일 도구만 사용해 hub 패턴을 생략했다 — Docusaurus 산출물이 곧 사이트.

사이트 컨셉 — 톡브릿지 테크 블로그 (2026-09-14 전환)​

같은 URL(blumnai-studio.github.io/tech-writing-harness/)을 유지한 채 사이트의 얼굴을 TalkBridge Tech Blog 로 바꿨다. 이 하네스로 글을 쓰고, 같은 방식으로 제품(톡브릿지)을 만들고, 톡브릿지를 잘 쓰는 데 보탬이 되는 AI 테크 소식을 소개하는 블로그다.

요소결정위치
브랜드 톤talkbridge.io 따름 — 카카오 옐로 #FEE500(강조 배경 전용), 잉크 #0B0B0B, 크림 #F8F3E7, Wanted Sans Variable(jsDelivr)src/css/custom.css
링크색라이트 = 어두운 골드 #7A6400(흰 바탕 대비), 다크 = 옐로같은 파일
로고talkbridge.io logo-animated.svg 의 마지막 프레임만 뽑은 정적 SVG(2KB) + 다크용 반전본, favicon 은 talkbridge.io 것static/img/talkbridge-mark*.svg, favicon.ico
홈 레이아웃해피톡 CX 인사이트(blog.happytalk.io) 참고 — 배너 → 최신 글 4편(큰 카드 1 + 곁 목록 3) → 카테고리 칩 + 지난 글 3열 그리드(9편씩 더 보기) → 패밀리 사이트src/pages/index.tsx
상단 메뉴좌: 글 목록·하네스 정원 / 우: 톡브릿지·해피톡 인사이트·블룸AI 스토리(패밀리 교차 소개)docusaurus.config.ts FAMILY_SITES
카테고리 라벨talkbridge→톡브릿지 활용, harness→하네스, product→제품, tool→도구, field-note→현장 노트. 새 카테고리는 CATEGORY_LABEL 에 추가(없으면 원문 표시)index.tsx
  • 표현 규칙: 톡브릿지 소개는 "블룸에이아이 — 카카오 공식 상담톡 딜러사"로만 적는다. "1급 연동"·"유일"·경쟁 비교 금지.
  • 푸터 「만든 방법」에는 외부에서 열리는 링크만 둔다. 이 저장소(BlumnAI-Studio/tech-writing-harness)는 internal 이라 비로그인 404 → 공개 샘플 저장소 소개 https://blumnai-playground.github.io/talk-bridge/ 로 대체(2026-09-14). Harness Kakashi 저장소는 공개(200)라 유지.

조직 루트 대문 — blumnai-studio.github.io 저장소 (2026-09-14)​

루트 주소 https://blumnai-studio.github.io/ 는 이름이 정확히 <조직>.github.io 인 저장소만 서빙할 수 있다. 이 저장소(프로젝트 Pages)로는 /tech-writing-harness/ 아래만 제어된다.

저장소역할
BlumnAI-Studio/blumnai-studio.github.io (internal)표지판만. index.html·404.html 이 /tech-writing-harness/ 로 리다이렉트
BlumnAI-Studio/tech-writing-harness원고·하네스·사이트 코드·배포 전부
  • 상태: Pages 미활성. 조직 정책이 internal 저장소의 공개 Pages 를 막아 422. 정책이 풀리면 gh api -X POST repos/BlumnAI-Studio/blumnai-studio.github.io/pages -f build_type=legacy -f "source[branch]=main" -f "source[path]=/"
  • 사이트가 없는 저장소에 PUT .../pages 는 404 — 최초 생성은 POST

URL 구조​

https://blumnai-studio.github.io/tech-writing-harness/
└─ baseUrl
  • url: https://blumnai-studio.github.io — GitHub organization Pages 도메인
  • baseUrl: /tech-writing-harness/ — 저장소명 그대로
  • organizationName: BlumnAI-Studio
  • projectName: tech-writing-harness

저장소 이름이 변경되면 docusaurus.config.ts 의 세 곳을 동시에 갱신해야 한다.

글 링크 체계 — M코드 공식 링크 + 한글 링크 호환 (v1.6.1)​

한글 slug URL은 공유 시 percent-encoding 으로 길고 깨지기 쉬워, 글마다 짧은 M코드를 공식 링크로 쓴다.

층값역할
공식 링크/articles/M011frontmatter code 에서 생성 — 공유·클릭 이동의 정본
한글 링크/articles/110-자비스-라운드테이블기존 공유분 호환 — 정적 리다이렉트 스텁이 M코드로 보냄

동작 구조:

  1. 원고 frontmatter 의 code: MNNN ([[manuscript-conventions]] §frontmatter) 이 단일 출처
  2. copy-from-manuscript.mjs 가 code 를 Docusaurus slug/id 로 주입하고, 한글 파일명 slug → M코드의 링크 호환 맵을 src/data/article-redirects.json 으로 생성 (gitignored)
  3. @docusaurus/plugin-client-redirects 가 맵을 읽어 구 한글 경로마다 정적 HTML 스텁(meta refresh + canonical + JS, query/hash 보존)을 빌드에 심는다 — GitHub Pages 는 서버 리다이렉트가 없으므로 이것이 정적 호스팅의 권장 방식
  4. 본문 상호 링크는 파일 상대 형식(./NNN-슬러그.md)으로 쓰면 빌드가 M코드 URL 로 자동 재작성한다 — URL 상대 형식(../NNN-슬러그)은 금지 (030/040/050 에서 일괄 정정된 전력)

새 글 추가 시 code 누락이면 copy 스크립트가 경고를 내고 한글 slug 로 발행된다 — lint 대상.

빌드 흐름​

manuscript/articles/*.md ← 사람이 작성
│
│ npm run copy:manuscript
│ (MANUSCRIPT_STATUS_FILTER=published 가 CI 기본)
▼
docs-docusaurus/docs/articles/ ← 자동 생성 (gitignored)
│
│ npm run build (docusaurus build)
▼
docs-docusaurus/build/ ← 정적 사이트 산출물 (gitignored)
│
│ actions/upload-pages-artifact → actions/deploy-pages
│ (트리거: git tag v* push)
▼
GitHub Pages

게시용 이미지 변환 — webp (2026-09-16)​

원고 이미지가 장당 2~3MB(1536px PNG)라 편당 10장이면 25MB다. 사이트 산출물이 432MB까지 커져 Pages 빌드가 간헐 실패했고, 독자 쪽 트래픽도 커졌다. 빌드 산출물에서만 줄인다 — manuscript/ 원본은 보존.

  • 구현: copy-from-manuscript.mjs가 sharp로 리사이즈 + webp 변환하고 본문 참조를 .webp로 재작성. 카드 표지도 같이 변환
  • 적용 범위: IMAGE_WEBP_RECENT — 기본 all(전체). 숫자를 주면 order 내림차순 최신 N편만, 0이면 끔 (2026-09-16 전체 적용으로 전환: 최신 5편으로 먼저 돌려 화질 저하가 눈에 띄지 않는 것을 확인한 뒤 확대)
  • 기본값: 가로 1280px, 품질 72
  • sharp가 없으면 경고 후 원본 복사 — 빌드는 멈추지 않는다
  • 실측: 최신 5편 50장 108.0MB → 6.0MB(-94%) → 전체 211장 416.0MB → 24.0MB(-94%), 사이트 432MB → 39MB. 한 편을 읽을 때 받는 이미지는 12.6MB → 0.5MB

배포 방식 전환 — 태그 Actions → gh-pages 브랜치 (2026-08-10)​

왜 바꿨나 — 조직 IP allow list가 Actions 러너를 차단​

2026-08-10 v1.21.0(190편) 배포 시, 태그가 워크플로우를 정상 발동했으나 actions/checkout 의 git fetch 가 403 으로 실패:

remote: The repository owner has an IP allow list enabled,
and 172.190.93.128 is not permitted to access this repository.
fatal: unable to access '.../tech-writing-harness/': 403
  • 근본 원인: 조직(BlumnAI-Studio)에 IP allow list 가 v1.20.0(2026-07-25 성공) 이후 새로 켜졌고, GitHub 클라우드 러너 IP는 목록에 없어 checkout 단계부터 차단. 빌드는 시작도 못 함.
  • 계정·태그 문제 아님 — 실패한 v1.21.0과 성공한 v1.20.0의 actor가 둘 다 smpark-luna로 동일했고, 태그는 워크플로우를 정상 발동시켰다.
  • 클라우드 러너 IP는 동적이라 allow list 고정 등록이 사실상 불가 → 러너를 쓰지 않는 브랜치 배포로 전환 (조직 보안 목록 유지, 사용자 결정 2026-08-10).

현행 배포 절차 (gh-pages 브랜치)​

로컬(=allow list 허용 IP)에서 빌드해 정적 산출물을 gh-pages 브랜치 루트로 올린다. Pages 는 그 브랜치를 러너 없이 서빙한다.

# 1) 원고 승급(published) 후 로컬 빌드
cd docs-docusaurus
npm run build # prebuild 가 copy-from-manuscript(published 필터) 자동 수행
touch build/.nojekyll # 필수 — _ 접두 경로가 Jekyll에 먹히지 않게

# 2) build/ 를 gh-pages 브랜치 루트로 force push (build/ 는 gitignored → 중첩 git 사용)
cd build
git init -q && git checkout -b gh-pages
git config user.name smpark-luna && git config user.email smpark@blumn.ai
git add -A && git -c core.autocrlf=false commit -q -m "deploy: vX.Y.Z — <요약>"
git push -f "https://github.com/BlumnAI-Studio/tech-writing-harness.git" gh-pages
rm -rf .git # 중첩 git 정리

# 3) Pages 빌드 요청 (소스 전환 직후/이후 공통 — 브랜치 push가 자동 트리거 안 될 때)
gh api -X POST repos/BlumnAI-Studio/tech-writing-harness/pages/builds
# 상태: gh api repos/BlumnAI-Studio/tech-writing-harness/pages/builds/latest --jq .status → built
  • Pages 소스는 이미 gh-pages/legacy 로 전환됨 (gh api -X PUT .../pages build_type=legacy, source.branch=gh-pages). 재전환 불필요.
  • 태그(git tag vX.Y.Z)는 버전 이력·릴리스 마킹 용도로만 유지 — 더 이상 배포를 트리거하지 않는다(워크플로우는 IP allow list로 계속 실패). harness/docs 버전축과 별개.
  • .github/workflows/deploy-docusaurus.yml 은 휴면 상태. 조직이 러너 IP를 허용하게 되면(사실상 어려움) 되살릴 수 있으나, 현재 정본은 브랜치 배포.
  • 빌드 검증과 커밋을 한 명령에 잇지 않는다 — npm run build | grep … && git commit … 처럼 이으면 grep 이 ERROR 줄을 잡아 성공으로 끝나 실패한 빌드 위에 커밋·태그가 나간다(2026-09-16 v2.1.2에서 발생). 빌드를 먼저 돌려 [SUCCESS]를 눈으로 확인한 뒤 커밋한다. 이미지를 대량 생성한 직후 빌드가 한 번 실패하는 경우가 있는데, 같은 입력으로 재실행하면 통과했다.
  • Pages 빌드가 errored 로 끝나면 같은 커밋으로 한 번 재요청한다 — 2026-09-16 v2.1.1 배포에서 상세 없는 Page build failed. 뒤 재요청 한 번에 73초 만에 built. 산출물이 422MB(이미지 354MB)로 커진 뒤 나타난 간헐 실패로 보인다. 두 번 연속 실패하면 그때 크기·파일 문제를 본다.
  • 라이브 검증: curl -s -o /dev/null -w "%{http_code}" 로 루트·M코드·한글 slug(퍼센트 인코딩) 확인. 한글 slug 는 curl 에서 반드시 URL 인코딩(미인코딩 시 404 아티팩트).

같은 allow list가 로컬 IP도 막을 때 (2026-09-13 관찰)​

브랜치 배포로 바꾼 뒤에도 같은 목록이 발목을 잡을 수 있다. 로컬 IP가 바뀌면(가정·사무실 공인 IP 재할당, VPN 전환) 그 IP는 목록에 없으므로 push·gh api·git ls-remote가 전부 403이 된다.

remote: The repository owner has an IP allow list enabled,
and <현재 IP> is not permitted to access this repository.
fatal: ... The requested URL returned error: 403
  • 404(Repository not found)는 계정 문제(gh 활성 계정 전환으로 해결), 403 + 위 문구는 IP 문제다. 둘을 혼동해 계정을 계속 바꾸지 않는다
  • 조치: 조직 Settings → Authentication security → IP allow list 에 현재 IP 추가, 또는 허용된 네트워크로 이동. 사용자만 할 수 있다
  • 그동안 커밋·태그·빌드는 로컬에 그대로 남으므로, 접근이 풀리면 git push origin main && git push origin vX.Y.Z → gh-pages push → Pages 빌드 요청 순서로 이어서 진행하면 된다
  • 재시도를 남발하지 않는다 — IP가 등록되기 전에는 몇 번을 눌러도 같은 403이다

(참고) 이전 방식 — 태그 기반 Actions (휴면)​

main push 만으로는 배포되지 않았고 v* git tag 가 워크플로우를 발동했다 — 사이트 게시를 명시적 결정으로 끌어올린 의도. IP allow list 차단으로 2026-08-10 부로 브랜치 배포에 자리를 넘김.

태그 컨벤션 (semver)​

자리언제 올리는가
MAJOR (v1.0.0 → v2.0.0)사이트 구조 전면 개편, 도구 교체 (Docusaurus → 다른 SSG)
MINOR (v1.0.0 → v1.1.0)새 글 published, 사이드바 구조 변경
PATCH (v1.0.0 → v1.0.1)오탈자 수정, 이미지 교체, 표기 통일 같은 작은 보정

본 프로젝트 내부 하네스 버전(harness/docs/vX.Y.Z.md)과 사이트 태그(vX.Y.Z)는 별도 축으로 흘러간다. 하네스는 정원이 자라는 속도, 사이트 태그는 발행물의 누적 속도.

출판 절차​

# 1) 원고 작업 + 검수 + manuscript-architect 가 status: published 로 승급
# (publication-pipeline 의 Stage 1~4)

# 2) main 으로 commit + push (배포 미발동 — 작업 백업만)
git push origin main

# 3) 사이트 발행 결정 — 새 태그 생성
git tag v1.0.0 -m "첫 글 게시 — 010-문서시스템-하네스도입"
git push origin v1.0.0
# → GitHub Actions deploy-docusaurus.yml 가 발동

# 4) 워크플로우 상태 확인
gh run list --workflow=deploy-docusaurus.yml --limit 3

# 5) 성공 후 사이트 URL 확인 (run summary 또는 repo Settings → Pages)

긴급 수동 배포​

태그 없이 즉시 배포해야 할 때 (예: 핫픽스 검증):

gh workflow run deploy-docusaurus.yml --ref main

workflow_dispatch 트리거가 발동된다. 단, 정상 출판 흐름은 태그를 통하는 것이 원칙.

copy-from-manuscript.mjs 동작​

  1. manuscript/ walk → .md 파일 수집
  2. frontmatter 파싱 → status 가 필터값에 포함되어야 통과
  3. 파일명에서 slug 추출 → frontmatter 에 id / slug 명시 주입 (Docusaurus 가 prefix 010- 을 자동 제거하는 동작 차단)
  4. order → sidebar_position 매핑
  5. 상대경로 이미지: manuscript/ 바깥이면 docs-docusaurus/docs/_assets/<parent>/ 로 복사 + 경로 재작성
  6. {{변수}} → 백틱 inline code (MDX JS 평가 회피)

환경변수​

변수기본효과
MANUSCRIPT_STATUS_FILTERpublished콤마 구분. 예: draft,review,published

CI는 기본값 그대로. 로컬 미리보기 시 작성자가 토글.

GitHub Pages 활성화 (저장소 처음 셋업 시)​

  1. GitHub repo → Settings → Pages
  2. Source: GitHub Actions 선택 (Deploy from a branch 가 아님!)
  3. Pages visibility: 저장소가 internal / private 인 경우 별도로 Public 선택 (GitHub Enterprise Cloud 기능 — 코드는 비공개 유지하면서 Pages만 공개 게시)
  4. 첫 워크플로우 실행: Actions 탭 → Deploy · Docusaurus → GitHub Pages → Run workflow
  5. 성공 후 환경 URL 확인 (workflow summary 의 deployment URL)

본 프로젝트(BlumnAI-Studio/tech-writing-harness)는 internal 가시성으로 운영하면서 Pages 만 Public 으로 게시한다. 소스는 조직 내부에서만 보이고, 발행물은 누구나 읽을 수 있다.

권한​

워크플로우의 permissions 블록이 필수:

permissions:
contents: read
pages: write
id-token: write

조직 정책에서 Actions Pages 배포가 차단되어 있으면 organization → Settings → Actions → General 에서 허용.

트러블슈팅​

빌드 단계​

증상진단조치
npm install 의존성 해석 실패Node 버전 확인setup-node 의 node-version: '22' 과 로컬 일치
copy-from-manuscript.mjs 가 0개 복사status 필터 mismatchMANUSCRIPT_STATUS_FILTER 환경변수 확인. manuscript 에 status: published 글이 실제로 있는지
Broken link warn내부 링크의 상대경로 오류같은 articles/ 의 다른 글로 가는 링크는 ./<slug> 형태. onBrokenLinks: 'warn' 이라 빌드는 통과하나 사이트에서 404
Broken markdown image warnmanuscript의 이미지 src 가 존재하지 않음copy 스크립트의 [copy] WARN image not found 로그에서 누락 파일 식별
MDX 파서 오류 (Unexpected token)본문에 <...> 또는 {...} 형태 텍스트.md 만 사용 + {{변수}} 는 자동 escape 됨. 그래도 깨지면 백틱으로 명시 escape

워크플로우 등록/파싱 단계 (v1.0.0 사이클에서 학습)​

증상진단조치
워크플로우가 gh run list 에 name: .github/workflows/<>.yml (파일 경로) 으로 표시YAML 파싱 실패 — GitHub Actions 가 name: 필드를 읽지 못함로컬 python -c "import yaml; yaml.safe_load(open(...))" 로 정확한 줄·열 식별
step name: 에 (status filter: published) 같이 콜론+공백이 들어가면 즉시 실패YAML 매핑 키:값으로 잘못 파싱step name 을 큰따옴표로 감싼다: name: "Copy manuscript to docs (status filter: published)"
워크플로우는 등록됐는데 job 이 0초만에 실패, annotation 에 is not allowed to deploy to <environment> due to environment protection rulesenvironment 의 deployment branch policy 가 태그를 허용하지 않음gh api -X POST repos/<owner>/<repo>/environments/<env>/deployment-branch-policies -f name='v*' -f type='tag'
gh api .../pages 가 "public": false 인데 발행물을 공개하고 싶다internal/private repo 의 Pages 기본 가시성gh api -X PUT repos/<owner>/<repo>/pages -f public=true — Enterprise Cloud 기능

배포 단계​

증상진단조치
401/403 deploy 실패Pages 권한 누락repo Settings → Pages → Source: GitHub Actions
페이지 404 (URL은 맞는데)baseUrl mismatchbaseUrl: '/tech-writing-harness/' 와 실제 저장소명 일치 확인
asset 404 (이미지 깨짐)_assets/ 복사 실패 또는 경로 깨짐빌드 산출물의 build/articles/<slug>/_assets/ 존재 확인
사이트가 옛 버전 그대로캐시 또는 워크플로우 실패Actions 탭에서 최근 실행 상태 확인. concurrency 그룹 pages 가 cancel 되었는지

Pages 환경 (cosmetic)​

증상조치
다크모드가 시스템 설정 무시themeConfig.colorMode.respectPrefersColorScheme: true 확인
한국어 검색 불가기본 검색만 제공. Algolia DocSearch 도입 검토
사이드바가 어색sidebars.ts 의 카테고리 라벨 및 dirName 수정

채택 의사결정 기록​

결정이유
Docusaurus만 사용 (multi-tool hub 안 함)단일 사이트로 충분. hub 패턴은 도구가 2개 이상일 때만 가치
버전 디렉터리 없음 (docs-docusaurus/v1/ 가 아님)아직 다중 버전 필요 없음. 필요해지면 그때 docs-docusaurus/v2/ 추가하고 hub 패턴 검토
docs preset (블로그 X)manuscript-architect 의 frontmatter/status/order 흐름이 docs 와 잘 맞음. 글이 시간순 정렬이 본질이면 blog preset 으로 전환 검토
routeBasePath: '/'사이트의 root 가 곧 문서. /docs/ 접두사 없음

전환을 검토할 신호:

  • 글의 발견이 시간순이 더 자연스러워질 때 → blog preset
  • 다국어/다중 버전 도입 → hub 패턴 영입
  • 검색 만족도가 낮을 때 → Algolia DocSearch

노션 북 채널 — 제2 출판 채널 (2026-08-09 개설)​

GitHub Pages 와 별개로, 사내 노션 워크스페이스(happytalk)에 시리즈 전편을 북 형태로 출판한다.

항목값
루트 페이지"블룸 정원의 하네스" (3b7c0b11-04dd-80ea-9aed-ffd8f7426138)
파이프라인docs-notion/publish-notion-book.mjs (Node 18+, 의존성 0)
상태 파일docs-notion/notion-book.state.json — 편별 pageId·해시·내비 블록 id (커밋 대상)
시크릿.secret/notion.json — internal-doc-tools 와 공유 (integration "쌤전용")
API 버전2022-06-28 (file_upload·cover·inline DB 프로브 검증: 2026-08-09)

구조​

블룸 정원의 하네스 (루트)
├── 📚 시리즈 목차 — 인라인 DB "하네스 테크라이팅 시리즈"
│ 속성: 제목("NN · 제목") / 순번 / 게시일 / 카테고리 / 코드 / 요약 / 상태
│ 각 행 = 편 페이지: 커버(히어로) + 아이콘 🌿 + TOC + 본문(이미지 인라인 업로드)
│ + 하단 내비(← 이전편 | 📖 목차 | 다음편 →)
└── 🕘 업데이트 이력 — 인라인 DB (최초출판/추가/수정, 일시·상세)

실행 (증분 sync)​

node docs-notion/publish-notion-book.mjs sync [--dry-run] [--limit N] [--status published,review]
  • 기본은 status: published 원고만 대상 — review 편은 승급 후 다음 sync 에서 자동 등재
  • --status published,review 로 검수 전 편도 선출판 가능 — 이 경우 시리즈 DB 상태가 검수중으로 표기되고, 이후 원고가 published 로 승급되면 frontmatter 변경이 해시를 바꿔 다음 기본 sync 에서 자동 재출판 + 상태 '게시' 갱신 (2026-08-09 19편 선출판이 첫 사례)
  • 해시 동일 → skip / 신규 → 행 생성 / 변경 → 본문 블록 전량 교체 + 속성·커버 갱신
  • 내비는 매 sync 재계산 — 새 편이 붙으면 직전 편의 "다음편" 링크가 자동 갱신됨
  • 이력 DB 에 최초출판/추가/수정 행 자동 기록

변환 규칙 (Docusaurus 채널과의 차이)​

원고 요소노션 처리
H1 (제목)제거 — 페이지 제목이 대신
히어로 이미지 (hero.png)본문에서 빼고 페이지 커버로 승격 (갤러리 카드 미리보기)
"3줄 요약" 인용💡 파란 콜아웃으로 승격
절 이미지Notion File Upload API 로 직접 업로드 + alt → 캡션
내부 상호 링크 (./NNN-*.md)노션 편 페이지 URL 로 재작성 (미등재 편이면 링크 제거, 텍스트 유지)
GFM 표 / 코드펜스 / 인용Notion table / code / quote 블록

수동 1회 설정 (API 미지원 영역)​

  • 시리즈 DB 의 뷰를 갤러리로 전환 + 카드 미리보기 = "페이지 커버", 정렬 = 순번 오름차순 — Notion API 는 뷰 생성/변경을 지원하지 않아 최초 1회 사람이 전환
  • 제목의 NN · 접두어 덕에 기본 정렬로도 출판순이 유지된다

주의​

  • 통합 토큰은 워크스페이스 단위 + 페이지별 공유 — 루트 페이지에 integration 이 연결되어 있어야 하위 전체 접근 가능
  • 파일 업로드 id 는 발급 후 1시간 내 attach 필요 — 파이프라인이 업로드 직후 attach 하므로 정상 흐름에선 문제 없음
  • 재출판(변경) 은 기존 블록을 전량 삭제 후 재적재 — 블록 수 × ~300ms 소요, 대량 개정 시 시간 감안
  • GitHub Pages 채널과 이 채널은 독립 — 사이트 태그 배포와 노션 sync 는 서로를 트리거하지 않는다