init: company-haness 설계
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""P1-A: lens 다양성 ≠ domain/sub-specialty 커버리지 (리뷰 finding #12).
|
||||
|
||||
lens_cap이 2축(lens 다양성 × sub-specialty 커버리지)으로 판정하는지 검증한다.
|
||||
- 아키텍트 7명(전부 LENS-TECH지만 distinct sub-specialty)이 standard에서 통과(정확한 회귀).
|
||||
- 같은 role 2회는 여전히 위반(같은/미분화 sub-specialty 중복).
|
||||
- tier distinct-sub-specialty 상한 초과는 위반(fan-out 폭 가드).
|
||||
- heavy는 permissive.
|
||||
- case-insensitive (registry는 UPPER, 호출은 어느 case든).
|
||||
|
||||
실행: CLAUDE_PROJECT_DIR="$PWD" python3 .claude/tests/test_p1_lens.py
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
ROOT = os.environ.get("CLAUDE_PROJECT_DIR") or os.path.dirname(
|
||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
)
|
||||
HOOK = os.path.join(ROOT, ".claude", "hooks", "lens_cap.py")
|
||||
|
||||
_fail = 0
|
||||
|
||||
|
||||
def check(name, cond):
|
||||
global _fail
|
||||
print(("ok " if cond else "FAIL ") + "- " + name)
|
||||
if not cond:
|
||||
_fail += 1
|
||||
|
||||
|
||||
def rc(tier, roles):
|
||||
return subprocess.run(
|
||||
[sys.executable, HOOK, "--tier", tier, "--roles", roles],
|
||||
capture_output=True, text=True,
|
||||
).returncode
|
||||
|
||||
|
||||
print("== P1-A lens_cap 2축(lens × sub-specialty) ==")
|
||||
|
||||
ARCH7 = "arch-ea,arch-solution,arch-app,arch-tech,arch-it,arch-sysanalyst,arch-swat"
|
||||
|
||||
# 1) 정확한 회귀: 아키텍트 7명(전부 LENS-TECH, 서로 다른 sub-specialty) → standard 통과.
|
||||
check("7 distinct architects @ standard -> 0 (finding #12 회귀, was 2)",
|
||||
rc("standard", ARCH7) == 0)
|
||||
# case-insensitive: 대문자 role-id도 동일하게 통과.
|
||||
check("7 distinct architects (UPPER) @ standard -> 0 (case-insensitive)",
|
||||
rc("standard", ARCH7.upper()) == 0)
|
||||
|
||||
# 2) 같은 role 2회 → 같은 sub-specialty 중복 → 여전히 위반.
|
||||
check("same role twice @ standard -> 2 (undifferentiated duplicate)",
|
||||
rc("standard", "arch-app,arch-app") == 2)
|
||||
check("distinct pair + one dup role @ standard -> 2",
|
||||
rc("standard", "arch-app,arch-tech,arch-app") == 2)
|
||||
|
||||
# 3) tier distinct-sub-specialty 상한 초과 → 위반 (light 상한=3, standard 상한=8).
|
||||
check("3 distinct sub-specialties @ light (cap 3) -> 0 (경계 이내)",
|
||||
rc("light", "arch-ea,arch-solution,arch-app") == 0)
|
||||
check("4 distinct sub-specialties @ light (cap 3) -> 2 (상한 초과)",
|
||||
rc("light", "arch-ea,arch-solution,arch-app,arch-tech") == 2)
|
||||
check("9 distinct LENS-TECH sub-specialties @ standard (cap 8) -> 2",
|
||||
rc("standard", ARCH7 + ",arch-data,data-engineer") == 2)
|
||||
|
||||
# 4) heavy → permissive(무엇이든 통과).
|
||||
check("heavy same role twice -> 0 (permissive)",
|
||||
rc("heavy", "arch-app,arch-app") == 0)
|
||||
check("heavy 9 distinct LENS-TECH -> 0 (permissive)",
|
||||
rc("heavy", ARCH7 + ",arch-data,data-engineer") == 0)
|
||||
|
||||
# 5) 서로 다른 lens는 서로 영향 없음.
|
||||
check("distinct lenses (PROD-PM + UX-RESEARCHER) @ standard -> 0",
|
||||
rc("standard", "prod-pm,ux-researcher") == 0)
|
||||
|
||||
# 6) 같은 lens라도 서로 다른 sub-specialty 2명은 통과(진짜 중복 아님).
|
||||
# (이 케이스가 test_enforcement.py의 'standard dup-lens SEC-ENGINEER,SEC-APPSEC->2'를 뒤집는다: 이제 0.)
|
||||
check("2 distinct security sub-specialties @ standard -> 0 (진짜 중복 아님)",
|
||||
rc("standard", "sec-engineer,sec-appsec") == 0)
|
||||
check("2 distinct product sub-specialties (PM vs TPO) @ standard -> 0",
|
||||
rc("standard", "prod-pm,prod-tpo") == 0)
|
||||
check("2 distinct design sub-specialties (product vs platform) @ standard -> 0",
|
||||
rc("standard", "des-prod,des-platform") == 0)
|
||||
|
||||
# 7) 미등록 role은 lens 판별 불가·무시 → 위반 아님(위반 전용은 아님).
|
||||
check("unknown role ignored @ standard -> 0",
|
||||
rc("standard", "not-a-real-role,arch-app") == 0)
|
||||
|
||||
print()
|
||||
if _fail:
|
||||
print(f"FAILED: {_fail}")
|
||||
sys.exit(1)
|
||||
print("ALL PASS")
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user