Skip to content

feat(review-remediate): 리뷰 리포트를 1회 소비해 처분을 확정하는 커맨드 신설 - #141

Open
Nharu wants to merge 14 commits into
masterfrom
feat/review-remediate
Open

Nharu wants to merge 14 commits into
masterfrom
feat/review-remediate

Conversation

@Nharu

@Nharu Nharu commented Aug 13, 2026

Copy link
Copy Markdown
Owner

리뷰 리포트를 소비해 발견별 처분을 확정하는 경로가 설계된 적이 없어, 분류 지시문이 자유 텍스트 인자로 설계 커맨드에 밀입국하고 있었다. 이 PR은 그 경로를 신설한다.

무엇이 문제였나

리뷰 루프가 발산한 것이 아니다. 사이클당 이득을 세 독립 경로(심각도 추이 비율·항목 분류·회전율 역산)로 재면 모두 1 미만으로 수렴하고, 156개 체인이 전부 종료했으며 최대 길이는 8이다.

실제 결함은 종료 조건이 이 과정이 도달할 수 없다고 증명된 상태를 요구했다는 것이다 — 써 온 기준이 156개 체인 중 **81개(52%)**에서 한 번도 성립하지 않았다. 리뷰어 민감도가 1 미만인 한 바뀌지 않은 코드를 다시 읽어도 새 발견이 나오므로 고정점은 0이 아니다. 수렴하는 신호(P1, 6배 붕괴)와 수렴하지 않는 바닥(P3, 점유율 67%에서 평평)이 서로 다른 채널인데 종료 기준이 후자까지 읽고 있었다.

무엇을 넣었나

새 슬래시 커맨드 /cc-cmds:review-remediate — 리뷰 리포트(및 PR 리뷰 코멘트)를 1회 소비해 발견별 처분을 확정하고, 반영 항목의 완화 설계를 함께 저작하며, 이연분을 이슈로 등록한 뒤 문서를 구현 커맨드에 인계한다. 재리뷰 없음·에이전트 팀 없음의 단일 결정론적 패스다.

  • 처분 5 arm 폐쇄 집합 — 차단 대역에서 이연·제외가 불가한 것은 심각도가 아니라 종료 조건에서 파생된다. 종료 술어가 그 대역을 읽는 이상 판단만으로 그것을 비우는 arm은 곧 종료 기울기다. 그리고 어떤 영구 처분 arm도 이연보다 비싼 증거를 요구할 수 없다 — 값싼 경로가 백로그뿐이면 예산 압박 아래 모든 것이 백로그로 흐른다.
  • 비대칭 레벨 선택자 파서 — 전수 374파일·826 섹션·5,507 발견에서 도출했다. 33개 표본이 정했던 이전 규약은 정상 입력 7.1%에서 하드 스톱해 반증됐다. 발견 탐지를 형태 열거에서 그룹 안의 레벨 선택으로 강등하고, 그 대가로 남는 미계측 잔여(형제가 전부 비대괄호인 서브트리의 조용한 붕괴)를 계약 본문에 함께 적는다.
  • 정지 팔 셋 — 섹션 단위 가드는 코퍼스 발화가 0건이라 상시 가드로 두되 fail closed라 이름 붙이지 않는다(갖지 않은 속성으로 이름 붙은 가드는 건강한 입력에서 위반처럼 읽히고, 위반처럼 읽히는 줄은 무시된다). 실제로 정지시키는 구조적 검사와 선언적 검사는 어느 하나도 단독으로는 조용한 0건을 다 덮지 못한다.
  • 행 키 함수 — 서수를 폴백이 아니라 무조건 성분으로 두어 5,507 블록 전량에서 사이클 내 충돌 0건. 재출현 키는 줄 번호(연속 버전 간 79.7% 표류)와 서수를 빼고, claim_key를 행 키에서 파생하는 것을 금지한다 — 파생하면 그 휘발성이 재출현 키로 조용히 재수입된다.
  • 배수구 세 장치 — 상한은 트래커별 독립, 자동정지는 전역이다. 전역 행동을 가진 레포별 장치는 어느 해상도에서도 비정합이기 때문이다. 자동 만료로 닫힌 이슈는 상한의 분자에서 뺀다 — 포함하면 커맨드가 포기하는 속도만큼 입금하게 되고, 포기는 해결이 아니다.

리뷰 시 눈여겨볼 곳

바이트 0짜리 행위 변경이 하나 있다. 산출물이 ## 구현 시 검증 항목을 담는 순간 구현 커맨드의 검증 게이트가 켜진다. 이 PR은 그 커맨드를 한 바이트도 고치지 않으므로 그 활성화는 diff에서 보이지 않는다 — 이 본문이 그것의 유일한 공개 표면이다.

교차 스킬 편집은 1건이고 그것이 선행 조건이다. 공유 검증 계약의 작성자 열과 잔여 항목 탄생 경로(3→4)에 이 커맨드를 추가했다. 편집 없이 저작하면 산출물의 검증 항목이 계약이 인정하지 않는 작성자가 쓴 것이 되고, 구현 커맨드의 게이트가 출처 없는 잔여 항목 위에서 열린다. 교차 스킬 비용은 편집한 파일 수가 아니라 소비한 계약 수로 센다 — 남의 계약을 어기는 가장 흔한 방법은 그 파일을 고치는 것이 아니라 열어 보지 않은 채 그것이 허락하지 않는 일을 하는 것이고, 그 위반은 diff에 나타나지 않는다.

알고 출하하는 것

  • v1은 이연이 사실상 도달 불가한 상태로 출하된다. 배수구가 라벨 스코프 인구 위에 정의돼 있는데 그 인구가 비어 있어 상한이 모든 트래커에서 0이고, 라우팅이 리포트 헤더 리터럴 하나로 좁혀지며 이연 인구의 약 28.5%가 떨어진다. 부트스트랩 값을 지어내지 않는 대가이며, 커맨드는 그 0이 왜 0인지를 첫 사용자가 보는 자리에 인쇄한다.
  • 팀 없음은 데이터 없이 출하된다. 살아남는 근거는 리뷰어가 이미 선택지를 공급했다는 것뿐이고(차단 대역 존재율 99.6%), 그것은 종료할 것이라 기대할 근거이지 종료한다는 측정이 아니다. 산출물의 완화 출처 계측기가 그 빈칸을 메우기 시작한다.
  • 리뷰어의 수정 제안이 옳은지는 재지 않았고 그렇게 주장하지도 않는다. 존재율은 템플릿이 제안을 의무화한 결과라 준수율이자 존재의 상한이지 품질이 아니며, 커맨드는 그 값을 산출물에 인쇄하지 않는다.

검증

  • 새 핀 lint + 픽스처 10종(정상 1 · 결함 9) — 상수 블록·검증 시점 enum·산출물 헤딩 정확 일치·루프 기계 금지 목록을 고정하고, 다섯 구획 펜스(단일 질문 호출 지점·에이전트 스폰 0·경계/후보 어휘의 진부분집합·예산 선택지·라우팅 단일 신호)를 마커 구획에 대해 검사한다. 전체 파일 검색은 정당한 산문에 발화하므로 구획화가 선행 조건이다.
  • make lint 전량 통과, make test 125건 전량 통과.
  • 구현 시점에 정산해야 하는 검증 항목 7건을 전부 실행해 통과시켰다 — 파서의 코퍼스 재현성, 키 함수 충돌 부재, 헤딩 정확 일치, 이슈 경로의 최상위 대역 부재, 호출 지점 펜스, 두 어휘의 진부분집합 관계, 라우팅 신호 단일성.

리뷰 소비 — P1 다섯 건 반영

이 PR에 대한 4인 리뷰가 P0 0 · P1 5 · P2 25 · P3 24를 냈다. P1 다섯 건과 승인된 승격분을 같은 브랜치에 반영했다. P2·P3의 반영분은 후속 PR 셋으로 나간다.

다섯 중 셋의 뿌리가 구현이 아니라 설계 쪽 산문이었다 — 구현은 그것을 충실히 옮겼고 옮긴 것이 틀렸다. 그래서 상류 세 줄도 같은 사이클에서 고쳤다.

# 무엇이 깨져 있었나
P1-1 이 커맨드가 내는 잔여 항목 중 게이트가 되는 것이 하나도 없었다. 어휘를 맨 형태로 닫았는데 소비자의 값 팔은 비어 있지 않은 괄호를 요구한다 — 맨 형태는 존재 검사만 통과하고 어느 값 팔에도 걸리지 않아 어휘 밖 값이 된다. lint의 부분 문자열 검사가 두 형태를 구별하지 못해 깨진 값을 정상 핀으로 인증했다
P1-2 서브헤딩 형태의 발견이 흔적 없이 사라졌다. 발견 emit이 섹션 최상위에서도 서브트리 플래그를 세우는데 닫기가 그것을 지우기 전에 반환해 플래그가 섹션 경계까지 넘어갔다. 그 발견은 발견으로도 플래그로도 처리되지 않는다
P1-3 조인이 어긋나는 모든 경로가 종료 0에 키 0행으로 끝났다. 철자가 같아도 경로에 공백이 있으면 같은 결과가 나며 진짜 발견 0건과 구별되지 않는다
P1-4 되돌릴 수 없는 공개 쓰기 둘이 --dry-run에서 억제되지 않았다. 그리고 어느 목록에도 없는 여섯째가 있었다 — 중복 검사가 기존 이슈에 코멘트를 다는 경로로, 공개 트래커 쓰기이고 알림을 발생시킨다
P1-5 스킬이 자기가 저작하는 스키마를 한 번도 열지 않았다. 필드명이 필드 형태로는 0회 등장하고 그 파일을 Read하는 지시도 없어, 저작 시점에 필드 집합을 확인할 경로가 없었다

회귀 검사 공백 — 한정과 함께

이번 PR의 파서·키 수리에는 red 경로가 없다. lint 아홉 종·테스트 열 종 어느 것도 두 awk 파일을 열지 않으며 두 파일을 삭제해도 CI는 초록이다. 정확성의 근거는 저장소 밖 코퍼스 실행 기록이고 그 코퍼스는 측정 중에 변한다.

한정이 하중을 진다 — 공백은 두 awk 파일에 한정된다. lint 쪽에는 red 경로를 만들었다(맨 형태를 심은 픽스처, 소비자 부재 대조, 베이스라인 동일성 단언). 한정 없이 「회귀 검사 없이 출하」라고 적으면 그것은 거짓이고 그대로 공개 표면으로 나간다.

이 PR은 그 공백을 좁히지 않는다 — 좁힐 파서 회귀 픽스처 둘이 그것을 돌릴 러너가 저장소에 없다는 이유로 후속 PR로 내려갔다. 러너 없는 픽스처는 아무것도 검사하지 않으므로 여기 넣어도 회귀를 잡지 못한다.

실측

  • P1-2 — 동결한 합집합 476파일에서 발견 7,325 → 7,326, 소실 0, 인접 다섯 팔과 하드 스톱 전부 불변. 되살아난 것은 실제로 소실되던 그 서브헤딩 발견 1건이다. 설계가 명시한 좁은 루트로 좁히면 델타 0인데, 그것은 수리가 아무것도 하지 않는다는 뜻이 아니라 그 코퍼스에 사례가 없다는 뜻이다.
  • P1-3 — 공백이 든 경로에서 수리 전 종료 0 · 키 0행, 수리 후 키 12행. 코퍼스 476파일에서 테이프 발견 7,326 = 발행 키 7,326.
  • 빈 테이프 가드 — 진짜 발견 0건 리포트에서 미발화(위양성 0), 빈 테이프에서만 종료 3. 조인 불일치는 종료 4로 갈린다. 두 사유를 합치지 않은 이유는 합치면 「테이프가 없다」와 「조인이 어긋났다」가 구별되지 않아 진단 해상도가 이 수리가 겨냥한 자리에서 다시 낮아지기 때문이다.
  • 픽스처 — 11벌이 각각 정확히 하나의 검사에만 발화하고 그 검사의 이름이 겨냥한 것과 일치한다. 핀을 좁히는 순간 열 벌이 전부 깨지고 실패 픽스처 아홉 벌이 겸발화 상태가 되는 것이 실측됐다 — 의도한 검사가 죽어도 통과가 유지되는 상태다.

리뷰 시 눈여겨볼 곳

  • lint 중단 복구는 한 줄이 아니다. 미보호 파이프가 엄격 모드 아래 스크립트를 끝내고 있었고, 죽은 분기가 정확히 그 파이프가 실패해야 할 자리였다. 러너는 종료 코드만 보므로 그 픽스처는 오늘까지 통과로 보고됐다. 파이프 보호와 분기 복원이 함께 가야 그 자리가 살아난다.
  • P2-08은 편집 0줄이다. 「레벨 선택자가 유일하게 플래그하지 못하는 실패」라 적힌 문장이 P1-2 착지로 참이 됐다 — 그 전에는 무플래그 소실 경로가 둘이라 「유일하게」가 거짓이었다. diff에 나타나지 않으므로 이 줄이 그 검증의 유일한 기록이다.
  • 베이스라인 동일성 단언은 lint가 아니라 테스트 러너에 있다. 스위트 출력을 쓰는 것이 러너뿐이고 러너가 lint의 stdout을 버리므로, lint 쪽에 두면 이 단언이 깨려는 침묵을 그대로 재현한다.

재리뷰 소비 — P1 일곱 건 반영

직전 사이클이 착지시킨 P1 다섯 건에 대한 재리뷰가 33건을 냈다. P1 일곱 건과 반영으로 분류된 코드·계약 편집을 같은 브랜치에 반영했다.

세 증상이 한 기전을 공유한다 — 직전 사이클의 수리가 처방의 헤드라인 기제만 옮겨 싣고, 그 실패를 검출 가능하게 만드는 진단 성분을 떨어뜨렸다. 진단 성분의 부재는 정상 실행에서 보이지 않으므로, 직전 사이클의 검증 항목이 전부 통과하면서 셋 다 빠져나갔다.

# 무엇이 깨져 있었나
P1-1 이 커맨드가 내는 잔여 항목이 게이팅 버킷에 들어간 뒤 영원히 실행되지 않았다. 괄호 안 라벨의 출처가 파일 경로인데 소비자는 그 자리를 phase 이름으로 분할한다 — 경로가 앉은 항목은 어느 phase에도 속하지 않아 호출마다 범위 밖으로 공개되고, 값 팔에는 걸리므로 어휘 밖 값으로 표면화되지도 않는다. 문법적으로 합법이면서 의미적으로 죽어 있다
P1-2 조인 등호의 피연산자를 네 자리에서 「레코드」로 적었다. 키를 만드는 것은 발견 레코드뿐이라 레코드-대-키 등호는 애초에 성립하지 않는다 — 문면대로 구현하면 정상 실행이 전부 정지한다
P1-3 미보호 파이프라인이 엄격 모드에서 lint를 통째로 중단시켰고, 중단 지점이 하필 자기 실패 분기 자리였다. 러너는 종료 코드만 봤으므로 실패해야 할 픽스처가 통과로 보고됐다
P1-4 섹션 가드의 여집합 검사가 원소가 아니라 구분자를 세어, 1원소 여집합과 빈 여집합이 같은 값을 냈다. 정상 형태가 실패로, 가드가 항등 거짓이 되는 형태가 통과로 갈렸다
P1-5 공유 계약 두 곳을 가리키는 줄이 「그대로 쓴다」로만 끝나 읽으라는 명령형이 없었다. 실행자가 계약 파일을 열지 않은 채 기억으로 채워도 문면을 어기지 않는다
P1-6 조인이 수리되지 않고 계측만 됐는데, 출하된 핀은 운영자에게 그 철자가 계약이라고 가르쳤다
P1-7 빈 테이프 가드가 「비어 있음」은 보되 「테이프임」은 보지 않아, 인자를 뒤바꾸면 직전 사이클의 증상이 바이트 단위로 재현됐다 — 종료 0 · 키 0행 · stderr 0바이트

하네스에 넣은 체계적 가드 넷

네 가드는 각각 「무엇을 금지한다」가 아니라 **「무엇을 이름으로 말한다」**로 설계했다. 앞 사이클에서 실제로 떨어진 것이 언제나 기제가 아니라 진단 성분이었기 때문이다.

  • 중단 가드 — 검사되지 않은 비영 종료로 lint가 끝나면 중단한 줄 번호와 종료 코드를 한 줄로 말한다. 중단은 정당한 핀 실패와 똑같이 종료 1이라, 표지가 없으면 돌지도 않은 핀을 고치게 된다. 새 종료 코드를 도입하지 않고 표지 문자열이 구별을 진다.
  • 포섭 가드 — 한 핀 목록 안에서 원소가 다른 원소의 부분 문자열이면 두 리터럴과 목록 이름을 함께 인쇄한다. 짧은 쪽은 혼자 실패할 수 없어 있으나 마나 한 핀이 된다. 인라인이던 두 목록을 명명 배열로 승격한 것이 요점이다 — 이 파일이 가졌던 유일한 실제 포섭이 인라인 쪽에 있었으므로, 명명 배열만 도는 가드는 결함 옆에서 초록이었을 것이다.
  • 파생 원장 — 구획 집합·대조 파일 목록·통과 요약의 구획 수를 전부 파생한다. 손으로 적은 구획 수는 이미 다섯에서 여덟으로 어긋나 있었고 아무 검사도 그것을 몰랐다. 파생 결과가 비면 그 자체를 실패로 다룬다 — 빈 집합은 「없음」이 아니라 「모름」이다.
  • 귀속 가드 — 러너가 종료 코드와 진단 문자열을 짝지어 본다. 출력을 버리던 리디렉션을 지우는 것이 이 부품의 존재 조건이다. 술어는 여섯이며, 귀속은 픽스처마다 손으로 적은 기대 문자열과 대조한다.

파생 원장이 착지하자마자 실재 구멍을 하나 찾았다 — 선언만 되어 있고 어떤 검사도 열지 않던 구획이 있었다. 그 구획의 검사와 실패 픽스처를 함께 넣었다.

스코프가 한 파일 는다

교차 스킬 편집에 design/SKILL.md가 새로 든다. 잔여 항목의 탄생 경로를 「정확히 세 경로」라 적고 그 셋을 괄호 안에 열거하던 문장이, 경로가 넷으로 늘어난 뒤 낡아 있었다. 숫자를 넷으로 고치지 않고 수사 자체를 지웠다 — 다섯째가 생기는 날 같은 방식으로 다시 낡기 때문이다. 사본 쪽은 열거를 공유 계약의 해당 절을 가리키는 포인터로 바꿨다. 같은 수사가 계약 본문에도 있어 두 자리를 함께 닫았다 — 한 자리만 닫으면 남은 하나가 정확히 같은 감사에서 다시 나온다.

릴리스 번호가 2.2.0으로 올라간다

master가 2026-08-18에 팀 예산 릴리스로 2.1.0을 발행했고, 이 브랜치는 머지된 적 없는 2.1.0을 들고 있었다 — 같은 번호가 서로 다른 릴리스를 가리키던 상태다. 이 브랜치의 항목을 2.2.0으로 올리고 master의 2.1.0을 그대로 뒀으며, 버전 SOT도 같은 값으로 맞췄다. master를 브랜치로 들여 그 충돌과 Makefile의 lint·test 타깃 목록(양쪽이 같은 자리에 줄을 더한 것이라 둘 다 남긴다)을 정리했다.

그 충돌이 있는 동안 GitHub은 이 PR의 머지 커밋을 만들지 못해 pull_request 워크플로를 아예 생성하지 않았다 — 8월 17일 이후 이 PR에 체크가 한 건도 등록되지 않은 이유이며, 그 사이의 「초록」은 전부 로컬 실행 결과였다.

머지 후 1회 수동 실행이 필요한 검증 하나

--dry-run의 억제 자리 여섯이 런타임에 실제로 쓰기를 막는지는 실행으로만 갈린다. 선언하는 쪽과 억제하는 쪽의 이름 집합이 서로의 차집합을 남기지 않는다는 것은 출하 lint가 기계로 지키지만, 각 자리가 정말로 건너뛰어지는지는 커맨드를 한 번 돌려야 관측된다. 그 관측의 입력은 머지 전에 존재하지 않으므로 이 PR은 그것을 주장하지 않는다 — 머지 후 --dry-run으로 1회 수동 실행해 확인한다.

실측

  • 픽스처 14벌(정상 2 · 결함 12)이 각각 정확히 한 검사에만 발화하고, 그 검사의 이름이 겨냥한 것과 일치한다. 이번에 전량을 출하본 사본 + 변이 하나로 다시 만들었다 — 다수가 최근 편집 이후 낡아 의도하지 않은 차이를 세 군데씩 안고 있었고, 그 차이는 아직 어떤 핀에도 걸리지 않아 조용했다.
  • 네 가드를 전부 반대 방향으로 확인했고, 그중 둘은 확인 자체를 하네스에 박았다. 중단 가드와 포섭 가드의 피검사체는 lint 자신의 제어 흐름과 리터럴 배열이라 픽스처 트리로는 닿을 수 없다 — 픽스처는 review-remediate/ 디렉터리이고 거기 무엇을 두든 lint의 배열에 들어가지 않는다. 그래서 lint 사본에 주입하는 영구 자가 검사 둘을 스위트에 넣었다(스위트 단언 16건 = 픽스처 14 + 자가 검사 2). 포섭 가드에는 특히 필요하다 — 이 레포가 가졌던 유일한 실제 포섭을 이 변경의 열거 축소가 없앴으므로, 자가 검사가 없으면 잡을 것도 없고 잡을 수 있는 것도 없는 채로 초록이다. 나머지 둘(파생 집합 비우기 · 기대 문자열 어긋내기)은 실행으로 확인했고, 귀속 가드는 그 확인 과정에서 러너 자신의 버그도 하나 잡았다.
  • 여집합 경계 — 1원소 형태가 통과 입력으로, 빈 여집합이 실패 입력으로 각각 고정된다. 임계값만 낮추면 빈 형태를 받아들이므로 교정이며 복원이 아니다.
  • 비-테이프 첫 인자 — 인식되지 않은 줄의 개수·첫 인자 경로·인식되지 않은 첫 줄을 축자로 인쇄한다. 조인 진단은 파일별 귀속 행을 잘림 없이 낸다(배열 순회 순서가 비결정적이라 상위 N만 인쇄하는 형태를 쓰지 않는다).
  • make lint · make test · make check 전량 통과. 마지막 것을 반드시 포함한다 — 직전 사이클이 정확히 이 격차로 CI를 깨뜨렸다.

알고 남기는 것

  • 파서·키의 코드 회귀 검사 공백은 이 PR에서도 좁혀지지 않는다. 두 awk 파일을 여는 lint·테스트가 여전히 없다.
  • 로케일 코드 수리는 넘겼다. 문자 모델 변경이고 회귀 픽스처가 0개이며, 리뷰를 거치지 않은 변경을 심사 중인 PR에 얹으면 리뷰 표면이 다시 열린다.
  • 파생 원장의 한쪽은 자기 자신을 grep한다. 그 자기참조를 지키는 가드는 없고, 빈 집합을 실패로 다루는 것이 완화의 전부다 — 숨기지 않고 코드 주석에 적어 두었다.

리뷰 리포트를 소비해 발견별 처분을 확정하는 경로가 설계된 적이 없어, 분류
지시문이 자유 텍스트 인자로 설계 커맨드에 밀입국하고 있었다.

문제는 리뷰 루프가 발산한다는 것이 아니다. 사이클당 이득을 세 독립 경로로
재면 모두 1 미만으로 수렴하고 156개 체인이 전부 종료했다. 실제 결함은 종료
조건이 이 과정이 도달할 수 없다고 증명된 상태를 요구했다는 것이다 — 써 온
기준이 156개 체인 중 81개(52%)에서 한 번도 성립하지 않았다. 리뷰어 민감도가
1 미만인 한 바뀌지 않은 코드에서도 새 발견이 나오므로 고정점은 0이 아니고,
수렴하는 신호와 수렴하지 않는 바닥이 서로 다른 채널인데 종료 기준이 후자까지
읽고 있었다.

- 처분 5 arm 폐쇄 집합. 차단 대역에서 이연·제외가 불가한 것은 심각도가 아니라
  종료 조건에서 파생된다 — 종료 술어가 그 대역을 읽는 이상 판단만으로 그것을
  비우는 arm은 곧 종료 기울기다. 어떤 영구 처분 arm도 이연보다 비싼 증거를
  요구할 수 없다
- 비대칭 레벨 선택자 파서. 전수 374파일·826 섹션·5,507 발견에서 도출했으며,
  33개 표본이 정했던 이전 규약은 정상 입력 7.1%에서 하드 스톱해 반증됐다.
  발견 탐지를 형태 열거에서 그룹 안의 레벨 선택으로 강등하고, 그 대가로 남는
  미계측 잔여를 계약 본문에 함께 적는다
- 정지 팔 셋. 섹션 단위 가드는 코퍼스 발화가 0건이라 fail closed라 이름 붙이지
  않는다 — 갖지 않은 속성으로 이름 붙은 가드는 건강한 입력에서 위반처럼 읽히고
  위반처럼 읽히는 줄은 무시된다. 실제로 정지시키는 구조적 검사와 선언적 검사는
  어느 하나도 단독으로는 조용한 0건을 다 덮지 못한다
- 행 키 함수. 서수를 폴백이 아니라 무조건 성분으로 두어 5,507 블록 전량에서
  사이클 내 충돌 0건. 재출현 키는 줄 번호와 서수를 빼고, claim_key를 행 키에서
  파생하는 것을 금지한다 — 파생하면 그 휘발성이 재출현 키로 재수입된다
- 배수구 세 장치. 상한은 트래커별 독립이고 자동정지는 전역인데, 전역 행동을
  가진 레포별 장치는 어느 해상도에서도 비정합이기 때문이다. 자동 만료로 닫힌
  이슈는 상한의 분자에서 뺀다 — 포함하면 포기하는 속도만큼 입금하게 된다
- 핀 lint와 픽스처 10종. 상수 블록·검증 시점 enum·산출물 헤딩 정확 일치·루프
  기계 금지 목록을 고정하고, 다섯 구획 펜스를 마커 구획에 대해 검사한다. 전체
  파일 검색은 정당한 산문에 발화하므로 구획화가 선행 조건이다
- 공유 검증 계약의 작성자 열과 잔여 항목 탄생 경로에 이 커맨드를 추가. 편집
  없이 저작하면 산출물의 항목이 계약이 인정하지 않는 작성자가 쓴 것이 되고,
  소비자의 게이트가 출처 없는 잔여 항목 위에서 열린다

v1은 이연이 사실상 도달 불가한 상태로 출하된다 — 배수구가 라벨 스코프 인구
위에 정의돼 있는데 그 인구가 비어 있어 상한이 모든 트래커에서 0이고, 라우팅이
헤더 리터럴 하나로 좁혀지며 이연 인구의 약 28.5%가 떨어진다. 부트스트랩 값을
지어내지 않는 대가이며, 커맨드는 그 0이 왜 0인지를 첫 사용자가 보는 자리에
인쇄한다.
@Nharu Nharu self-assigned this Aug 13, 2026
Nharu added 13 commits August 17, 2026 19:41
리뷰가 낸 P1 다섯 건 중 둘과 그에 딸린 승격 항목이다.

- P1-2: 발견 emit이 섹션 최상위에서도 서브트리 플래그를 세우는데 서브트리
  닫기가 그것을 지우기 전에 반환해, 플래그가 다음 서브트리와 섹션 경계까지
  넘어간다. 그 발견은 발견으로도 플래그로도 처리되지 않아 공개 표면에 아무
  흔적을 남기지 않는다. 플래그의 수명을 파일이 아니라 서브트리에 맞춰 여는
  지점에서 리셋한다. 동결한 합집합 476파일에서 발견 7,325 → 7,326, 소실 0,
  인접 다섯 팔과 하드 스톱 전부 불변
- P1-3: 테이프와 리포트의 조인이 원시 파일명 문자열 일치라 어긋나면 침묵한다.
  철자가 같아도 경로에 공백이 있으면 기본 구분자가 파일 필드를 쪼개 같은 결과가
  나며, 진짜 발견 0건과 구별되지 않는다. 패스 분할을 인자 위치 동일성으로,
  구분자를 탭으로 고정하고, 정합 검사를 등호로 요구한다. 경로 정규화는 넣지
  않는다 — 인자 위치 동일성이 철자 차이를 무의미하게 만들어 덮을 잔여가 없고,
  넣으면 서로 다른 두 파일이 같은 것으로 접힐 위험만 는다
- 빈 테이프 가드: 조인 수리를 전량 넣어도 빈 테이프는 종료 0·키 0행·stderr
  0바이트로 통과한다. 정합 검사가 빈 배열을 0회 순회하기 때문이다. 첫 인자의
  레코드를 세고 0이면 비영 종료한다. 「레코드」이지 「발견」이 아니다 — 발견만
  세면 진짜 발견 0건 리포트에서 위양성이 난다
- 두 사유는 서로 다른 비영 종료 코드와 각자의 stderr를 갖는다. 합치면 「테이프가
  없다」와 「조인이 어긋났다」가 구별되지 않아 진단 해상도가 이 수리가 겨냥한
  바로 그 자리에서 다시 낮아진다
- 호출 명령행을 스킬 본문에 핀으로 박는다. 로케일 고정을 포함해 — 호출 형태가
  계약에 고정되지 않으면 구현이 고쳐져도 호출부가 되돌아간다

패스 분할은 인자 목록에서 잡는다. 레코드 기반 파일 카운터는 `NR == FNR`과 같은
구멍을 갖는다 — 레코드가 0건인 파일은 어떤 규칙도 발화시키지 않아 카운터가
오르지 않고 다음 파일이 그 자리를 차지한다.
P1-1과 그에 딸린 픽스처 작업이다.

- 이 생산자가 내는 잔여 항목 중 게이트가 되는 것이 하나도 없었다. 스킬이 검증
  시점 어휘를 맨 형태로 닫는데 소비자의 값 팔은 비어 있지 않은 괄호를 요구한다.
  맨 형태는 존재 검사만 통과하고 어느 값 팔에도 걸리지 않아 어휘 밖 값으로
  분류되며, 남은 다른 값은 계약상 비실행 공개 항목이라 애초에 게이트가 아니다.
  괄호 안 라벨은 완화 명세의 착지 필드에서 그대로 가져온다 — 이 생산자가 이미
  갖고 있는 유일한 결정론적 라벨이라 발명이 아니다
- 표면은 셋이라 셋 다 고친다. 스킬 본문만 고치면 P1-5가 새로 Read하도록 배선한
  공유 계약이 금지된 값을 계속 가르친다
- 구획된 emit 영역에서 기본값을 축자로 거부한다. 이전 검사는 우회 표현을 요구해
  거부되는 값이 한 번도 나타나지 않아도 통과했다 — 값을 적지 않으면 무엇을
  거부하는지 검사할 자리가 없다
- 핀은 긍정 선언을 고정 문자열로 pin하는 형태다. 맨 부분 문자열을 금지하면
  구획이 맨 형태를 산문으로 설명하는 것까지 막혀 설명 문장 자체가 red가 된다
- 소비자 대조 둘을 넣는다. 값 팔 형태는 레포 고정 경로로 pin하고 부재를 실패로
  다룬다 — 픽스처 기준으로 해소하면 모든 픽스처 실행이 조용한 skip이 되어 이
  검사가 닫으려는 실패 모드를 검사 자신이 재현한다. 헤딩 티어는 집합 동등성이
  아니라 한 방향 포함으로 검사한다 — 생산자에만 있는 넷은 소비자가 티어를
  부여하지 않는 섹션이라 정상이고, 동등성으로 두면 거짓 실패 넷이 나 정상 섹션을
  지우는 수리를 유도한다
- 픽스처 10벌을 재동기화하고 각 벌이 정확히 하나의 검사에만 발화하게 좁힌다.
  겸발화는 의도한 검사가 죽어도 통과가 유지되는 상태다
- 맨 형태를 심은 red 픽스처 1종 신설
- 베이스라인 동일성 단언을 테스트 러너에 넣는다. lint가 아니라 러너인 이유는
  스위트 출력을 쓰는 것이 러너뿐이고 러너가 lint의 stdout을 버리기 때문이다.
  정의역은 베이스라인 한 벌 — 실패 픽스처는 설계상 스킬과 달라야 한다
P1-4·P1-5와 계약 한 줄 셋, 그리고 lint 중단 복구다.

- P1-4: 되돌릴 수 없는 공개 쓰기 둘이 --dry-run에서 억제되지 않았다. 실행되는
  억제 목록이 Safety 선언이 declare한 것보다 좁았고, 어느 목록에도 없는 여섯째가
  따로 있었다 — 중복 검사가 기존 이슈에 코멘트를 추가하는 경로다. 공개 트래커
  쓰기이고 알림을 발생시킨다. 여섯 자리를 실행 시맨틱이 소유하고 Safety 선언이
  그것을 인용하는 방향으로 고정한다. 두 목록의 출처가 갈리면 한쪽을 다른 쪽에
  맞추는 것만으로는 재발이 막히지 않는다
- 억제 목록을 겨냥하는 핀을 신설한다. 이름으로 구속하며 개수로 구속하지 않는다 —
  개수만 보면 다섯 대 다섯으로도 참이 되어 절반 미이행이 통과한다. 이 핀은 소비자
  대조를 갖지 않으며 그 예외를 스크립트에 적는다. 억제 목록의 소비자는 이 커맨드
  자신의 실행 경로라 대조할 외부 산출물이 없다
- P1-5: 스킬이 자기가 저작하는 스키마를 한 번도 열지 않았다. 저작 단계에 절 이름을
  지정한 스코프 Read를 넣고 소비 행렬에 등재한다. 필드명은 열거하지 않는다 —
  열거하면 동결 리터럴의 사본이 되고 계약이 금지한 유지 의무를 새로 만든다.
  Read로 대체되지 않는 둘만 본문에 적는다
- 계약 한 줄 셋: 자동 만료 조항이 억제 목록의 세 번째 자리임을 명시, 카디널리티
  등호 팔 추가, 인용 형태 정렬. 등호 팔은 기존 부등호를 바꾸는 것이 아니라 더하는
  것이다 — 부등호는 원장과 테이프의 쌍에서 옳고 뚫린 곳은 테이프와 키의 쌍이다
- 원장 사유 칸에 재현 가능한 관측만 적도록 규약에 못박는다. 없으면 등급 주장을
  적는 순간 대역 열은 그대로인 채 재부여의 효과만 발생한다
- lint 중단 복구: 미보호 파이프가 엄격 모드 아래 스크립트를 끝내 이후 검사들이
  실행되지 않았다. 죽은 분기는 정확히 그것이 발화해야 할 자리였고, 러너는 종료
  코드만 보므로 그 픽스처가 통과로 보고됐다. 파이프 보호와 죽은 분기 복원이 함께
  가야 그 자리가 실제로 살아난다
- 픽스처 11벌이 각각 정확히 하나의 검사에만 발화하며 그 검사의 이름이 겨냥한 것과
  일치한다. 어휘 픽스처는 분기 복원 뒤 겸발화 2건이 되어 변이 형태를 좁혔다

P2-08 무편집 검증: 「레벨 선택자가 유일하게 플래그하지 못하는 실패」라 적힌 문장이
참이 됐다. 서브트리 닫기의 분기가 전수적이고, 플래그가 서브트리 열림에서 리셋되므로
그 서브트리 안의 발견 emit으로만 참이 된다. 무플래그 소실 경로는 비대괄호 형제
붕괴 하나만 남으며 그것이 그 문장의 주장이다. 편집 0줄이라 diff에 나타나지 않는다.
P1-4가 frontmatter의 Safety 선언을 고쳤는데 README를 재생성하지 않아 CI의
README 최신성 검사가 실패했다. README는 그 frontmatter에서 생성된다.
v2 재리뷰의 P1 셋이다. 셋 다 직전 사이클이 처방의 헤드라인 기제만 옮겨 싣고
진단 성분을 떨어뜨린 자리다.

- P1-2: 네 자리에 조인 검사의 팔이 여섯 있고 그중 넷이 피연산자를 다른 카운터
  이름으로 적어, 문면대로 구현하면 정상 실행이 전부 정지한다. 자리가 아니라 팔
  단위로 내려 넷을 고치고 둘은 건드리지 않는다 — 부등호 팔은 원장과 테이프가
  열화를 허용하는 쌍이라 옳고, exit 3 팔은 문면과 코드가 이미 일치한다.
  폐쇄 근거를 2부로 적는다: 키를 만드는 것은 FIND 레코드뿐이라 레코드-대-키
  등호는 애초에 성립하지 않으며, 등호의 양변은 서로 다른 패스에서 나온다
- P1-7: 빈 테이프 가드가 「비어 있음」은 보되 「테이프임」은 보지 않아, 인자를
  뒤바꾸면 수리 이전 증상이 바이트 단위로 재현된다. 테이프 레코드 종류를 세고
  하나도 없으면 별도 종료 코드로 갈린다. 옛 메시지를 빌려 쓰지 않는다 —
  빌려 쓰면 탐지는 생기고 귀속은 생기지 않는다. 진단 성분 둘을 함께 낸다:
  인식되지 않은 줄의 개수와 첫 인자 경로, 그리고 인식되지 않은 첫 줄을 축자로
- P1-6·P3-07: 조인이 수리되지 않고 계측만 됐다. 파일별 집계 배열을 삭제가
  아니라 진단에 배선한다. 총계 둘만 찍으면 다중 파일 입력에서 일부만 어긋났을
  때 어느 파일인지 말하지 않는다. awk 배열 순회 순서가 비결정적이므로 파일별
  출력을 자르지 않는다 — 자르면 매 실행마다 다른 파일이 보고된다
- D6: 로케일 사유 문장이 실측된 두 기전 중 어느 것도 아니었다. 요란한 쪽(정규식
  미컴파일)과 조용한 쪽(발견 전량 소실)을 이름으로 가른다. 조용한 쪽이 떨어지면
  에러가 안 보이니 로케일이 괜찮다고 읽는 독자가 정확히 그 사고를 만난다
- 티어 열거 추출의 미보호 파이프라인이 엄격 모드에서 lint를 통째로
  중단시켰다. 중단 지점이 하필 자기 실패 분기 자리라, 실패해야 할
  픽스처가 통과로 보고됐다. 대입을 보호하고, 추출 결과가 비면 범위
  앵커 문면을 담아 요란하게 실패하도록 단언을 넣는다.
- 섹션 가드의 여집합 검사가 원소가 아니라 구분자를 세고 있었다.
  1원소 여집합과 빈 여집합이 같은 값을 내어 정상 형태가 실패로,
  가드가 항등 거짓이 되는 형태가 통과로 갈렸다. 중괄호 본문으로
  스코프를 좁힌 뒤 공백 아닌 토큰을 센다.
- 경계 두 입력을 픽스처로 고정한다 — 1원소는 통과, 빈 여집합은 실패.
- 베이스라인 픽스처를 출하 스킬과 다시 맞춘다.
- 이 생산자가 괄호에 넣을 수 있는 유일한 결정론적 라벨은 완화 명세의
  `착지`인데 그 값은 파일 경로다. 소비자는 `구현 중(<phase>)`을 phase
  이름으로 분할하므로, phase 자리에 경로가 앉은 항목은 어느 phase에도
  속하지 못해 호출마다 범위 밖으로 공개된 뒤 영원히 실행되지 않는다.
  값 팔에는 걸리므로 어휘 밖 값으로 표면화되지도 않는다 — 문법적으로
  합법이면서 의미적으로 죽은 항목이다. 관측 창이 열리지 않았다고
  정직하게 적는 쪽이 낫다.
- 축소가 공유 계약의 저작 조건을 이 경로에 한해 달리 읽게 만든다는
  사실을 계약과 생산자 산문 양쪽에 명시한다. 이 조건에는 grep 표면이
  없으므로 값을 옮겨 적는 자리와 같은 문단에 둔다.
- 핀을 축소된 선언 하나로 재작성하고, 이름이 더 이상 대상을 가리키지
  않게 된 픽스처를 ritem-enum으로 개명한다.
- 픽스처 전량을 출하본 사본 + 변이 하나로 다시 만든다. 다수가 최근
  편집 이후 낡아 의도하지 않은 차이를 세 군데씩 안고 있었고, 그 차이는
  아직 어떤 핀에도 걸리지 않아 조용했다. 이제 각 픽스처는 베이스라인과
  훅 하나만 다르고 정확히 한 검사만 발화한다.
- 사이드카 쓰기 프로토콜과 AUQ 하드 제약을 가리키는 두 줄이 「그대로
  쓴다」·「그대로 적용한다」로만 끝나 있었다. 무엇을 따르라는 지시는
  있고 그것을 읽으라는 지시가 없어, 실행자가 계약 파일을 열지 않은 채
  기억으로 채워도 문면을 어기지 않는다.
- 같은 절에 이미 출하된 형태를 따라 두 줄에 Read 명령형을 넣는다.
  사이드카는 절 이름을 지정한 스코프 Read, AUQ 스펙은 파일 전량 Read다
  — 후자는 파일 전체가 제약 집합이고 형제 스킬도 전량으로 읽는다.
- 소비 대조표의 두 확인 결과 칸을 같은 편집에서 맞춘다. 필드명·제약
  열거는 넣지 않는다 — 열거는 계약이 금지한 동결 리터럴 사본이 된다.
경로가 셋에서 넷으로 늘어난 뒤에도 두 문장이 「세 경로」라고 적고
있었다. 수를 넷으로 고치면 다섯째가 생기는 날 같은 방식으로 다시
낡으므로, 수사 자체를 지운다.

- 공유 계약은 개수 없이 「탄생 경로」로만 가리킨다.
- design 스킬의 사본은 괄호 안 세 경로 열거를 지우고 계약의 해당 절을
  가리키는 포인터로 대체한다. 한 자리만 닫으면 남은 하나가 정확히 같은
  감사에서 다시 나온다.
네 가드는 각각 「무엇을 금지한다」가 아니라 「무엇을 이름으로 말한다」로
설계했다. 앞 사이클에서 실제로 떨어진 것은 언제나 처방의 기제가 아니라
그 실패를 알아볼 수 있게 만드는 진단 성분이었기 때문이다.

- 중단 가드: 검사되지 않은 비영 종료로 lint가 끝나면 중단한 줄 번호와
  종료 코드를 stderr 한 줄로 말한다. 중단은 정당한 핀 실패와 똑같이
  exit 1이라, 표지가 없으면 돌지도 않은 핀을 고치게 된다. 새 종료 코드를
  도입하지 않고 표지 문자열이 구별을 진다. errtrace는 붙이지 않는다 —
  붙이면 명령 치환 서브셸이 트랩을 상속해 같은 중단이 두 줄로 나온다.
- 포섭 가드: 한 핀 목록 안에서 원소가 다른 원소의 부분 문자열이면
  두 리터럴과 목록 이름을 함께 인쇄한다. 짧은 쪽은 혼자 실패할 수 없어
  있으나 마나 한 핀이 된다. 인라인이던 두 목록을 명명 배열로 승격했다 —
  이 파일이 가졌던 유일한 실제 포섭이 인라인 쪽에 있었으므로, 명명 배열만
  도는 가드는 결함 옆에서 초록이었을 것이다.
- 파생 원장: 구획 집합과 베이스라인 대조 파일 목록을 양쪽에서 파생하고,
  통과 요약의 구획 수도 파생한다. 손으로 적은 수는 이미 5에서 8로
  어긋나 있었고 아무 검사도 그것을 몰랐다. 파생 결과가 비면 그 자체를
  실패로 다룬다 — 빈 집합은 「없음」이 아니라 「모름」이다. 이 가드가
  곧바로 검사 없이 선언만 되어 있던 호출 핀 구획을 찾아내, 그 구획의
  검사와 실패 픽스처를 함께 넣었다.
- 귀속 가드: 러너가 종료 코드와 진단 문자열을 짝지어 본다. 출력을 버리던
  리디렉션을 지우는 것이 이 부품의 존재 조건이다. 술어는 여섯 —
  중단 표지 / 종료 코드 / 진단 존재 / 단일 발화 / 귀속 / 통과 요약이며,
  귀속은 픽스처마다 손으로 적은 기대 문자열 파일과 대조한다.
- Safety 선언의 자리 불릿이 다섯인데 요약은 「위 여섯 자리」라고 적었다.
  다섯째가 산출물 저작과 원장 기록 둘을 합쳐 담고 있었으므로, 수를
  낮추지 않고 여섯째 불릿으로 가른다 — 출하 lint가 억제 자리 여섯을
  이름으로 고정하므로 수를 낮추면 산문이 lint와 어긋난다.
- `--dry-run` 옵션 설명이 옛 3범주를 그대로 적어, 가장 많이 읽히는
  표면에서 라벨 생성과 자동 종료가 빠진 것처럼 보였다. 목록을 다시
  베끼는 대신 본문 실행 시맨틱의 여섯 자리를 가리키게 한다.
- 반증 관측 기록의 분류를 둘로 좁히는 근거가 실행 표면만 들어, 셋째
  가능성인 트리 밖 드라이버를 배제하지 못했다. 그것은 스폰도 워크트리도
  요구하지 않아 그물을 빠져나가고 관측 기록이 조용히 탈락한다. 근거를
  실행 표면이 아니라 정의역으로 다시 쓴다.
- 원장의 사유 열 근거가 스키마에 없는 열을 가리켰다. 이 원장에 심각도
  열이 아예 없다는 사실로 바꿔 적는다.
- awk 호출부에 「종료 코드가 0이 아니면 정지」를 적는다. 코드 번호는
  운영자가 무엇을 고칠지 읽는 자리이지 분기 조건이 아니므로 갈라 읽지
  않는다.
- 템플릿 부재를 한 자리에서 판정한다. 두 검사가 각자 판정해 한쪽은
  요란하게 실패하고 다른 쪽은 조용히 건너뛰어, 같은 결측이 어느 검사를
  보느냐에 따라 치명적이거나 보이지 않았다. 이제 한 번 실패하고 그로
  인해 돌지 않는 검사들을 미실행 원장에 이름으로 남긴다.
- 러너 요약이 종료 코드와 어긋나지 않게 한다. 베이스라인 드리프트는
  픽스처를 하나도 실패시키지 않고 스위트를 실패시키므로, 마지막 줄이
  「0 failed」인 채 1로 끝나고 있었다.
- 억제 자리 여섯 핀에 실패 픽스처가 없었다. 하나 신설한다.
두 가드의 피검사체는 lint 자신의 리터럴 배열과 제어 흐름이라 픽스처
트리로는 닿을 수 없다. 그래서 lint 사본에 주입하는 자가 검사로 둔다.

이 레포가 가졌던 유일한 실제 포섭은 같은 변경의 열거 축소가 없앴으므로,
이것이 없으면 포섭 가드는 잡을 것도 없고 잡을 수 있는 것도 없는 채로
출하된다 — 이 하네스가 내내 거부해 온 눈먼 가드 형태다.

- 포섭: 모든 긴 토큰이 담고 있는 짧은 사유 토큰을 주입하고, 진단이 두
  리터럴과 목록 이름을 함께 말하는지 본다.
- 중단: 검사되지 않은 비영 종료를 주입하고, 중단한 줄 번호가 인쇄되는지
  본다. 중단은 정당한 핀 실패와 똑같이 1로 끝나므로 표지 문자열이
  구별의 전부다.
master가 2026-08-18에 팀 예산 릴리스로 `2.1.0`을 발행했고, 이 브랜치는
머지된 적 없는 `2.1.0`(2026-08-14)을 들고 있었다. 같은 번호가 서로 다른
릴리스를 가리키던 상태다.

- 이 브랜치의 릴리스 항목을 `2.2.0`으로 올리고 master의 `2.1.0`을 그대로
  둔다. 버전 SOT인 plugin.json도 같은 값으로 맞춘다.
- Makefile의 lint·test 타깃은 양쪽이 같은 자리에 줄을 더한 것이므로 둘
  다 남긴다.
- 나머지는 전부 자동 머지된다.

충돌 상태에서는 GitHub이 머지 커밋을 만들지 못해 pull_request 워크플로를
아예 생성하지 않았고, 그래서 이 PR에는 8월 17일 이후 체크가 한 건도
등록되지 않았다.
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