ci(blog): 블로그 cross-check 게이트 (Sprint 177 #18)#307
Merged
Conversation
added 4 commits
May 20, 2026 19:09
블로그 글(KR/EN)을 머지 전에 결정론적으로 검증하는 CI hard gate 신규 작성. 사람 눈 확인에 의존하던 블로그 정합성 검증을 quality-docs 잡에 자동화한다. - scripts/check-blog-crosscheck.mjs (신규): 의존성 0(node 내장 모듈 + 경량 frontmatter 파서). 검증 3축 — ① KR↔EN 정합(slug 양방향 짝 + date/category/ order/tags/series/seriesOrder 일치, title/excerpt 제외) ② frontmatter 스키마 (필수 필드/category enum/date 형식/order 유일) ③ 내부 링크 무결성(파일시스템 이탈·OS 절대 경로 거부 + /posts·/en/posts 대상 존재). 기본/--lint(WARN)/ --strict(exit 1) 모드. 회고록 시점 도메인 사실은 검증 제외(false-positive 방지). - dogfood: sliding-window-agent-context.mdx KR/EN 의 파일시스템 이탈 링크 (../../../../Desktop/...) → /adr/sprints/151/ · /en/adr/sprints/151/ 로 교체. - ci.yml: docs paths-filter + quality-docs 스텝(--strict) 배선.
Critic(Codex) P2 2건 + dogfood 전제 무효 수정.
- P2-1 (코드펜스 미제외 false-positive): stripCode 헬퍼 신규 — 링크 추출 전
펜스드 코드 블록(``` / ~~~, info string 포함)과 인라인 코드 스팬(단일/멀티
백틱)을 제거한다. 코드 영역 텍스트는 렌더 앵커가 아니라 예시이므로 배포
사이트 404를 만들 수 없다 → 무결성 검사 대상에서 제외.
- P2-2 (order 전역 유일성 false-positive): order 유일성 판정을 locale 전역에서
"동일 date 내"로 한정(키 ${date}::${order}). getAllPosts(posts.ts)가 date
내림차순 우선 정렬 후 동일 date 안에서만 order를 tiebreaker로 쓰므로, 다른
date 글의 order 재사용은 정상이다. 위반 메시지에 date 포함.
- dogfood revert: 대상이던 sliding-window-agent-context.mdx line 239는
```markdown 코드펜스 내부의 예시 텍스트였고 실제 404가 아니었다. P2-1
수정으로 자동 무시되므로 잘못된 전제의 콘텐츠 편집을 main 기준으로 되돌림.
Sprint 177 #18.
Critic R2 P2 2건(false-negative) 수정.
- R2-P2-1 (locale-leak 미검출): classifyLink/checkPostRoute 에 locale 전파.
글은 자기 locale 의 post 라우트로만 링크해야 한다 — KO 글은 /posts/<slug>,
EN 글은 /en/posts/<slug>. 교차-locale 라우트는 누수 위반으로 차단하고,
같은 locale 이면 대상 .mdx 존재까지 검증. /adr/... 등 비-post 루트절대 통과.
+ EN dogfood: posts-en/toward-model-agnostic-harness.mdx 의 [When Baekjoon
Vanished] 가 KO 라우트(/posts/baekjoon-gone)를 가리키던 실제 누수 →
/en/posts/baekjoon-gone 으로 교체(KO 글의 동일 링크는 올바르므로 유지).
- R2-P2-2 (비문자열 date 우회): date 형식 검사를 'string AND match' 에서
'present 한데 (non-string OR not-match)' 로 변경. 경량 파서가 따옴표 없는
숫자(date: 20260409)를 number 로 파싱해 형식 검증을 통째로 우회하던
false-negative 차단. undefined 는 필수필드 검사가 담당(중복 미보고).
Sprint 177 #18.
Critic R3 P2 1건(false-negative) 수정. - R3-P2 (fragment/query 우회): checkPostRoute 가 `$` 앵커 정규식으로 슬러그를 매칭해, `/posts/missing#section` · `/en/posts/missing?ref=foo` 처럼 fragment/query 가 붙은 링크를 미매칭→통과시켰다. 그 결과 존재하지 않는 슬러그를 가진 깨진 in-page 내부 post 링크가 --strict 를 우회했다. 진입부에서 `href.split(/[#?]/)[0]` 로 path 를 정규화한 뒤 슬러그 매칭·존재 검증·locale 누수 판정을 수행하도록 변경. 빈 슬러그(/posts/)는 자연 미매칭으로 통과(현행 동작 유지). Sprint 177 #18.
Coverage ReportCoverage directory not found at /home/runner/work/AlgoSu/AlgoSu/coverage — no services changed, skipping coverage gate. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 내용
블로그 글(KR/EN)을 머지 전 결정론적으로 cross-check 하는 CI hard gate 신규 추가 (Sprint 177 #18 — Sprint 157부터 7스프린트 이월 시드 회수). 의존성 0(node 내장만), 회고록 시점 고정 도메인 사실(스프린트 수·테스트 수·커버리지)은 의도적 제외(false-positive 방지) — 구조적 검증만.
게이트 3축 (
scripts/check-blog-crosscheck.mjs,--strict):posts.ts) + date 형식(YYYY-MM-DD, 비문자열 거부) + order 동일 date 내 유일dogfood: Critic 교차 리뷰 과정에서
posts-en/toward-model-agnostic-harness.mdx의 실제 locale-leak(/posts/baekjoon-gone→/en/posts/baekjoon-gone) 1건 발견·수정.변경 유형
필수 체크리스트
--strict현행 콘텐츠 0 위반 exit 0 + tamper 회귀(parity/schema/link 각 위반→exit1, 원복→exit0)보안 체크리스트
신규 산출물 (채택 ≠ 소비)
scripts/check-blog-crosscheck.mjs소비처 명시:.github/workflows/ci.ymlquality-docs잡--strict스텝 +docs:paths-filter 등록 (blog/content/**/*.mdx변경 시 자동 트리거)문서/ADR 변경
Critic 교차 리뷰 (Codex)
머지 직전
codex review --base main4라운드:019e44e8-edb2-7ad2-bf1a-be76f5ffaa45