ADR 0055 — claim_validator 를 PR 게이트로 (개선-주장 통계적 정직성)
ADR 0055 — claim_validator 를 PR 게이트로 (개선-주장 통계적 정직성)
- Status: Accepted
- Implemented: #965 (2026-05-18) —
scripts/validate_claim.py, wired as PR gate in.github/workflows/pr-eval.yml - Date: 2026-05-18
- Authors: Hyunsoo Kim
- Related: ADR 0050 (ALLOW_REGRESSION pattern), ADR 0053 (distinguishing-power gauge), ADR 0054 (conditional-on-substantive-answer scorer semantics — paired pairs filter)
- Augments: Phase 4 audit (
docs/audits/eval-framework-phase4-audit.md, PR #963) item 3 supply - Issue: #964
Context
Phase 4 audit (PR #963 / e65f792) 의 item 3 진단 — claim_validator.py 부재 (✗ absent). find . -name 'claim_validator*' 0건, grep claim_validator|validate_claim 0건. PR body 의 “+X.Xpp SIG/NS” 표기 convention (e.g. PR #956 body 의 “−0.046 SIG (−0.084, −0.011)” 형식) 은 작성자 손으로 paired-CI 부호 확인 + SIG 라벨 부여 — 자동 게이트 부재.
최근 main PR 빈도 (~25 PR / 1주, #939~#963 기준) 를 고려하면 도입 지연 1주 = 25 PR 의 improvement claim 통계 정직성이 사람 spot check 에만 의존.
ADR 0050 (corpus 확장) / ADR 0054 (scorer semantics 변경) 가 의도적 regression 의 [ALLOW_REGRESSION] escape 를 도입한 것과 대칭의 반대 방향 — improvement claim (positive shift) 의 자동 검증. ALLOW_OVERCLAIM 대칭 escape 는 의도적 미도입 (§Consequences).
Decision
- PR body convention 도입 — improvement claim 은 다음 한 줄 (multi-line 지원, 각 metric 별 1줄):
Claim: <metric>=<+X.Xpp> # 예: Claim: accuracy=+4.0pp, Claim: groundedness=-2.5ppregex (
scripts/validate_claim.py:CLAIM_PATTERN):r"^Claim:\s+(?P<metric>\w+)\s*=\s*(?P<sign>[+-])(?P<value>[\d.]+)pp\s*$"Code fence 안의 라인은 skip (예시/문서 illustration 보호).
- 자동 검증 4 조건 (
scripts/validate_claim.py:validate_one_claim) — 4 개 모두 통과해야 PASS:- (a) CI 가 0을 가로지르지 않음 (
ci_lo와ci_hi부호 동일) - (b) effective sample size (post-None-skip, ADR 0054 substantive-only) ≥
--min-sample(default 200) - (c)
sign(claim) == sign(mean_diff)(방향 일치) - (d)
|claim| ≤ |optimistic CI edge|(over-claim 차단; positive claim 은ci_hi, negative claim 은ci_lo)
- (a) CI 가 0을 가로지르지 않음 (
-
pr-eval.ymlstep 추가 — 신규 step “Validate improvement claims”,if: contains(github.event.pull_request.body, 'Claim:')조건부 실행.Claim:라인 0건이면 skip → 기존 PR 패턴 0 영향. -
재사용 — 신규 helper 작성 금지 —
eval/bootstrap.py:78-104paired_bootstrap_ci(values_a, values_b, *, num_resamples=1000, alpha=0.05, seed=17)그대로 사용. 단 argument 순서:(candidate, baseline)(mean_diff = candidate − baseline → positive = improvement, Claim: 부호와 일치). - ADR 0054 None-pair 처리 —
case_id페어링 후 어느 한 쪽이라도 None 인 페어 drop. effective_n = 살아남은 페어 수. ADR 0054 의 substantive-answer-only 의미 유지.
Why these specific choices
| 결정 | 근거 |
|---|---|
| convention 강제 X (opt-in) | 기존 PR body 의 Claim: regex 매칭 0건 (gh pr list --state merged --limit 100 검증) → backward-compatible. convention 강제는 별 ADR 후보 (e.g. PR template 의 Claim: placeholder 도입). |
--min-sample 200 default |
ADR 0044 / 0052 trajectory 의 n=221 에 fit. real n 보다 더 큰 sample 요구는 false negative. |
ALLOW_OVERCLAIM 미도입 |
ALLOW_REGRESSION 은 의도적 trade-off (corpus 확장, scorer 변경) 의 acknowledged 비용 → escape 정당. OVERCLAIM 은 통계적 정직성 의 escape → 정당화 어려움. ADR 0055 가 차단함으로써 portfolio claim 의 외부 검증 가능성 유지. |
| code fence skip | 본 ADR 자체가 ADR 본문에 Claim: accuracy=+4.0pp 예시 포함 — 검증 대상 안 됨. 모든 docs PR 도 동일 보호. |
pp (percentage point) 단위 강제 |
% 와 pp 혼동 위험. SIG/NS 표기 convention 도 pp 사용. |
Consequences
Positive
- 모든 future improvement claim 의 통계 검증 자동화 — PR 당 SIG/NS 수동 확인 → 자동 게이트. 시간 적분 ROI 큼 (25 PR/주 × 평균 2 claim/PR ≈ 50 claim/주 자동 검증).
- Portfolio narrative 강화 — recruiter / reviewer 가 PR body 의 “+X.Xpp” claim 을 CI badge 와 함께 검증 가능. “이 PR 의 +4.0pp 가 통계적으로 의미있나?” 가 fast verifiable.
- 5-step closure narrative (시퀀스 A) 의 step 5 (= claim_validator 도입) 가 본 ADR 으로 land. portfolio blog 1편 작성 시 “audit → 발견 → fix → 측정 표면 audit → 자동 게이트 도입” 5-step 완성.
- ADR 0054 와의 시너지 — None-pair drop 이 substantive-answer-only 의미를 PR-gate layer 까지 전파. ADR 0054 의 scorer fix 가 PR-gate 자동화의 prerequisite 였음이 가시화.
Negative
Claim:미명시 PR 은 검증 skip — 작성자가 잊으면 보호 미작동. convention 강제 (PR templateClaim:placeholder) 는 별 ADR 후보.- opt-in convention 의 학습 비용 — 신규 contributor 가 convention 모름 시 누락. ADR 0055 본 문서 + README 의 contributing 섹션 (별 PR) 에 명시.
- CI walltime ~5-10초 추가 —
Claim:있는 PR 만. paired_bootstrap_ci num_resamples=1000 기준 metric 당 ~2초.
Invariance check
- ADR 0001 (naive_baseline byte-identical): 유지. validate_claim 은 read-only — production code path 0 영향.
- ADR 0003 (answer contract schema_version=2): 유지. prediction dict / case_results schema 변경 없음.
- ADR 0005 (eval split public/private): 유지. validate_claim 은 CI 의
pr/reports/eval_summary.json(ADR 0005 의 ephemeral artifact) 를 read — aggregate boundary 무영향. - ADR 0050 (ALLOW_REGRESSION): 직교. ALLOW_REGRESSION 은 regression escape, ADR 0055 는 improvement claim 게이트. 둘은 반대 방향의 서로 다른 surface.
- ADR 0054 (conditional-on-substantive-answer): 활용 — None-pair drop 으로 substantive-answer-only 의미 전파.
Out of scope (별 PR / 별 ADR)
- PR template 의
Claim:placeholder 추가 — convention 강제. ADR 0056 후보. ALLOW_OVERCLAIMescape 도입 — 의도적 미도입 (위 §Why).- claim 의
pp외 단위 (%, ratio, raw) —pp한정. 확장 시 별 ADR. - per-PR 자동 claim suggester (“이 PR 의 측정 결과로 자동 Claim: 행 생성”) — 별 PR scope, validate_claim 와 별개.
- 시퀀스 A 의 다음 step (3c trace v2, 3b rationality judge, blog, Phase 5 audit) — 본 ADR 의 scope 외.
Verification
References
- Phase 4 audit (
docs/audits/eval-framework-phase4-audit.md, PR #963) — 본 ADR 의 motivation. - ADR 0054 (
docs/adr/0054-conditional-on-answer-scorer-semantics.md) — None-pair drop 의미의 source. - ADR 0050 / 0054 의 ALLOW_REGRESSION pattern — 본 ADR 의 대칭 반대 방향.
eval/bootstrap.py:78-104paired_bootstrap_ci— 재사용 entrypoint.- PR #956 body — 사람 손으로 작성된 SIG/NS 표기의 대표 사례 (“−0.046 SIG (−0.084, −0.011)”).