Skip to content

chore(hygiene): 제어문자 가드를 NUL → C0/C1 전반으로 확장 + 판정식 자기검사 - #290

Open
pdw96 wants to merge 1 commit into
masterfrom
chore/ctrl-char-gate
Open

chore(hygiene): 제어문자 가드를 NUL → C0/C1 전반으로 확장 + 판정식 자기검사#290
pdw96 wants to merge 1 commit into
masterfrom
chore/ctrl-char-gate

Conversation

@pdw96

@pdw96 pdw96 commented Aug 12, 2026

Copy link
Copy Markdown
Owner

요약

제어문자 가드의 문자 범위를 NUL → C0/C1 전반으로 넓힌다. #251 PR3c(#289) 리뷰에서 드러난 실측 공백의
후속이고, 그 PR 과 축이 다르므로 분리했다(가드는 레포 전역 위생 · PR3c 는 워크벤치 복구 판정).

왜 (실측)

PR3c 가 recovery.tsU+0001 을 실어 착지시켰고 npm run verify 7게이트가 전부 통과했다.
발견자는 게이트가 아니라 외부 리뷰어(CodeRabbit) 였다. 문자별 프로브로 기존 가드의 경계를 그렸다 —
src/ 아래에 문자를 하나씩 심은 파일을 만들고 repo-hygiene 게이트를 돌린 결과:

문자 확장 전 확장 후
U+0000 (NUL) RED RED
U+0001 통과(무신호) RED
U+001F 통과(무신호) RED
U+007F (DEL) 통과(무신호) RED

즉 「원시 NUL 0건」 가드는 NUL 만 보고 있었다. ⚠ PR3c 진행 중 내가 「verify 는 NUL 을 보지 않는다」고
적었던 것은 거짓이며(그 PR 에서 자기반박·정정 완료), 정확한 경계는 위 표다.

NUL 이 아닌 제어문자는 diff 를 바이너리로 접지는 않지만 소스에서 보이지 않는다 — 리뷰어는
join('') 으로 읽는데 실제로는 다른 구분자가 돌고, 문자열 상수·정규식 리터럴에 섞이면 값이 조용히
달라진다. 「보이지 않는 바이트가 의미를 바꾼다」는 축은 NUL 과 같다.

무엇을

  • 판정 범위 = C0/C1 전반, 허용은 탭·LF·CR 뿐(CR 은 win32 CRLF 체크아웃 때문에 필수)
  • 위반 보고는 파일:줄 U+XXXX — 「몇 건」만으로는 고칠 수 없다
  • 판정식 자기검사(양성 통제) 신설 — 레포가 깨끗하면 전수 스캔은 항진이라 판정식이 망가져도
    초록이다. 그 vacuous-GREEN 을 막으려고 11개 코드포인트(PR3c 가 실제로 흘린 U+0000·U+0001 포함)를
    회귀 핀으로 두고, 탭·CRLF·한글·이모지·전각 오탐 0 도 함께 고정한다
  • 패턴은 이스케이프 문자열로 만든다 — 문자 클래스에 raw 제어문자를 적으면 가드 자신이 오염원
    된다(PR3c 에서 그 규율을 적는 편집이 실제로 8건을 재생산했고, 그때 만든 스캐너가 그것을 잡았다)
  • no-control-regex그 한 줄에서만 끈다(규칙의 목적과 이 줄의 목적이 정반대 · config 에서 끄면
    나머지 레포가 방어를 잃는다)

스캔 루트·확장자·순회는 기존 것을 그대로 재사용한다 — 신설 스크립트도, verify 체인 변경도 없다.

품질 게이트 (AGENTS.md — 변경 후 필수)

  • npm run verify green (skills:lint·brain:check·format:check·typecheck·lint·test·build 집계 = 로컬 == CI)
  • preload/IPC 변경 시 npm run dev 재시작 확인 — 해당 없음
  • 코어 코드 변경 시 npm run brain 갱신 — 해당 없음(scripts/ 만 변경)

리뷰

  • Codex 봇 자동리뷰 대기 · 반영

비고

레포 전역 위반 0건(추적 450 파일)이라 이 PR 은 현재 상태를 고정하는 회귀 가드다. 남은 인접 축
(BOM·zero-width·bidi override 문자)은 비목표로 둔다 — 같은 「보이지 않는 바이트」 계열이지만 오탐
경계가 다르고(정당한 사용례가 있다) 별도 판단이 필요하다.

🤖 Generated with Claude Code

https://claude.ai/code/session_011pxajtC8CmcTrD19P5WPA5

#251 PR3c 가 recovery.ts 에 U+0001 을 실어 착지시켰고 `npm run verify` 7게이트가
전부 통과했다. 발견자는 게이트가 아니라 외부 리뷰어(CodeRabbit)였다.

문자별 프로브로 기존 가드의 경계를 실측했다(src 아래에 문자를 하나씩 심고 실행):
  확장 전 — U+0000 RED · U+0001 통과 · U+001F 통과 · U+007F 통과
  확장 후 — 네 문자 전부 RED
즉 「원시 NUL 0건」 가드는 **NUL 만** 보고 있었다. NUL 이 아닌 제어문자는 diff 를
바이너리로 접지는 않지만 **소스에서 보이지 않아** 리뷰어가 읽는 것과 실제 값이
갈린다(문자열 상수·정규식 리터럴에 섞이면 의미가 조용히 달라진다).

- 판정 범위 = C0/C1 전반, 허용은 탭·LF·CR 뿐(CR 은 win32 CRLF 체크아웃 때문에 필수)
- 위반 보고는 `파일:줄 U+XXXX` — 「몇 건」만으로는 고칠 수 없다
- **판정식 자기검사(양성 통제) 신설**: 레포가 깨끗하면 전수 스캔은 항진이라 판정식이
  망가져도 초록이다. PR3c 가 실제로 흘린 U+0000·U+0001 을 포함해 11개 코드포인트를
  회귀 핀으로 두고, 탭·CRLF·한글·이모지 오탐 0 도 함께 고정한다
- 패턴은 **이스케이프 문자열**로 만든다 — 문자 클래스에 raw 를 적으면 가드 자신이
  오염원이 된다(PR3c 에서 그 규율을 적는 편집이 실제로 8건을 재생산했다)
- `no-control-regex` 는 그 한 줄에서만 끈다(규칙 목적과 이 줄의 목적이 정반대 ·
  config 에서 끄면 나머지 레포가 방어를 잃는다)

verify EXIT=0 · repo-hygiene 14 tests pass · 레포 전역 위반 0건(450 파일).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pxajtC8CmcTrD19P5WPA5
@pdw96

pdw96 commented Aug 12, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@pdw96, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 1 minute

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3cf915f3-7d4b-4f54-86f1-479beeb3e6a3

📥 Commits

Reviewing files that changed from the base of the PR and between b92221c and 952b057.

📒 Files selected for processing (1)
  • scripts/repo-hygiene.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 952b057992

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant