Skip to content

fix(stack): 아무것도 안 잰 검증이 ALL OK 를 냈다 — 공허참 통과 차단 - #58

Merged
bhyi4 merged 1 commit into
mainfrom
fix/vacuous-pass-empty-config
Aug 18, 2026
Merged

fix(stack): 아무것도 안 잰 검증이 ALL OK 를 냈다 — 공허참 통과 차단#58
bhyi4 merged 1 commit into
mainfrom
fix/vacuous-pass-empty-config

Conversation

@bhyi4

@bhyi4 bhyi4 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

무엇이 문제였나

원장을 하나도 선언하지 않은 설정으로 부르면 스택 검증기가 통과를 냈다.

$ echo '{"mm_ledgers": {}}' > empty.json
$ python3 stack/verify_all.py --config empty.json
=== Mirror Stack verify-all (orchestrator) ===
⚠️ [L2 witness] (skipped) — no witness ledger configured; ...
=== verdict: ALL OK (0/0) ===
$ echo $?
0

stack/verify_all.py 의 판정줄이 "ALL OK" if n_ok == len(results) 인데, 빈 실행에서는 0 == 0 이다.

형식검증에서 1997년부터 vacuous pass(vacuity detection) 라 부르는 실패 모양이다 — 반증할 것이 없어서 참인 판정. 교과서 예: "모든 요청은 언젠가 승인된다"는 요청이 한 번도 안 오는 모델에서 참이다.

왜 이게 걸리는가

이 판정줄은 발화 게이트다. 측정한 수치를 말하기 전에 돌리는 검사이고, 자동화는 그 종료코드로 && 를 잇는다.

부분적 정직 신호는 있었다 — 생략된 L2 계층이 ⚠️ 를 찍는다. 그런데 사람과 자동화가 실제로 보고 행동하는 두 가지, 판정줄과 종료코드는 둘 다 통과였다. 경고는 그 사이에서 읽히지 않는다.

무엇을 고쳤나

stack/verify_all.py "전부 통과" 와 "잰 게 없음" 을 가른다. 후자는 NOTHING VERIFIED + 종료코드 2
stack/verify_self.py 이 CLI 로는 도달 불가였다(linkage 가 항상 보고하므로 결과가 비지 않는다). 다만 동일한 모양을 갖고 있어 같이 막았다 — 리팩터가 다시 열지 못하도록
mm verify_chain: seals valid 잰 개수를 같이 찍는다. 분모 없는 초록줄은 "뒤에 아무것도 없는 초록줄" 과 구별되지 않는다
tests/test_vacuous_pass.py 회귀 시험 3종

실측

# 빈 선언
=== verdict: NOTHING VERIFIED (0/0) — no ledger was checked ===
exit=2

# 정상 설정 (회귀 확인)
=== verdict: ALL OK (17/17) ===
exit=0

# seals valid 줄
✅ [L1 chain] compute_governor: mm verify_chain: seals valid (37 entries checked)

기존 시험 466건 전부 통과 + 신규 3건.

출처

형제 레인이 무관한 게이트를 돌리다 발견해 재현과 함께 넘겼다. 고치는 법은 새로 만드는 게 아니라 이식이었다 — 같은 and total 가드가 내부 도구에 이미 있었다. 없던 것은 기제가 아니라 그 기제의 사정거리다.

⚠️ 범위: 이 PR 은 빈 선언이 통과로 읽히는 것 만 막는다. 무엇을 범위에 넣을지(선언된 원장이 전체의 일부라는 문제)는 별건이고 아직 미결이다.

`verdict = "ALL OK" if n_ok == len(results)` 는 빈 실행에서 `0 == 0` 이다.
원장을 하나도 선언 안 한 설정으로 부르면 verify_all.py 가
`=== verdict: ALL OK (0/0) ===` 를 찍고 **종료코드 0** 으로 끝났다.

    $ echo '{"mm_ledgers": {}}' > empty.json
    $ python3 stack/verify_all.py --config empty.json
    === verdict: ALL OK (0/0) ===
    $ echo $?
    0

형식검증에서 1997년부터 **vacuous pass**(vacuity detection)라 부르는 그 모양이다 —
반증할 것이 없어서 참인 판정. 교과서 예: *"모든 요청은 언젠가 승인된다"* 는
요청이 한 번도 안 오는 모델에서 참이다.

이게 걸리는 이유는 이 판정줄이 **발화 게이트**라서다. 측정한 수치를 말하기 전에
돌리는 검사이고, 자동화는 그 종료코드로 `&&` 를 잇는다. 부분적 정직 신호는
있었다(생략된 L2 계층이 `⚠️` 를 찍는다). 그런데 **사람과 자동화가 실제로 보고
행동하는 두 가지** — 판정줄과 종료코드 — 는 둘 다 통과였다.

수리:
· 두 검증기가 "전부 통과"와 "잰 게 없음"을 가른다. 후자는 종료코드 **2**.
· verify_self.py 는 이 경로로 도달 불가였지만(linkage 가 항상 보고한다) 같은
  모양을 갖고 있어 같이 막았다. 리팩터가 다시 열지 못하게 못을 박는다.
· `mm verify_chain: seals valid` 가 **잰 개수**를 같이 찍는다. 분모 없는 초록줄은
  "뒤에 아무것도 없는 초록줄"과 구별되지 않는다.
· 회귀 시험 3종 추가(tests/test_vacuous_pass.py). 기존 466건 전부 통과.

발견은 형제 레인이 무관한 게이트를 돌리다 재현과 함께 넘겼다. 고치는 법은
**이식**이었다 — 같은 `and total` 가드가 내부 도구에 이미 있었다. 없던 것은
기제가 아니라 그 기제의 사정거리다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bhyi4

bhyi4 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

대장님 승인 머지 — B(중대 변경). #57이 폭로한 stack_verify_all 공허참(빈 config→ALL OK exit 0) 차단·분모 출력. 버전 0.38.0→0.38.1·의존성 변경 0·CI 4/4 그린·이상 적신호 0. ⚠️후속: v0.38.1 릴리스 태그는 대장님이 커트(봇 안 함).

@bhyi4
bhyi4 merged commit 8789b09 into main Aug 18, 2026
4 checks passed
@bhyi4
bhyi4 deleted the fix/vacuous-pass-empty-config branch August 18, 2026 21:13
bhyi4 added a commit that referenced this pull request Aug 19, 2026
`test_catalog_counts_match_the_tree` 가 두 파일을 도는 *모양*이었다:

    for name in ("README.md", "README_KO.md"):
        for claimed in {... re.findall(r'(\d+) real sealed cases', txt)}:
            assert claimed == total

실측: 루트 `README_KO.md` 에 그 영문 문구는 **0건**이다(KO 는 "사례 N표본"을 쓴다).
⇒ `findall` 이 `[]` 라 **KO 차례는 안쪽 몸통이 한 번도 안 돌고 조용히 지나간다.**
두 파일을 덮는 것처럼 읽히는데 실제로 그 시험이 덮는 루트 파일은 **영문 하나**다.

**오늘은 구멍이 아니다** — 루트 KO 는 `test_readme_ko_catalog_count_matches_the_tree`
가 따로 덮는다. 위험한 건 나중이다: 누가 *"저 루프가 KO 도 도니까 저 시험은 중복"* 이라
읽고 지우면 **가드가 스위트를 초록으로 유지한 채 사라진다.**

이건 #58 에서 막은 **vacuous pass 의 반복문 판**이고 처방도 같다 —
**빈 결과를 통과로 세지 말 것.** 루프를 영문 파일 하나로 좁히고, 문구를 못 찾으면
**실패**하게 했다(문구가 바뀌면 조용히 통과하는 대신 울린다).

조작검증: `74 real sealed cases` → `74 sealed specimens` 로 바꾸니 격발한다.
스윕: 이 파일의 `findall`/`search` **9곳 전부** 빈 결과 검사가 붙어 있다(미검사 0).
발견 = [자생] (오늘 도감 표본 출하하다 이 모양을 짚었다).

Co-authored-by: Mother Seara <bhyi4@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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