init: company-haness 설계

This commit is contained in:
DongHyeonka
2026-07-23 17:49:00 +09:00
parent 57d1bab894
commit f668d6a158
962 changed files with 98989 additions and 1 deletions
+62
View File
@@ -0,0 +1,62 @@
# benchmark-rubric.yaml — 골든태스크 채점 루브릭 (리뷰 3주차 측정 항목)
# =============================================================================
# 리뷰가 요구한 측정 항목을 그대로 dimension으로 둔다. 각 dimension은 0..1(또는 카운트).
# 두 arm(plain Claude / harness)을 같은 과제로 실행 후 이 dimension으로 채점하고,
# benchmark.py compare 가 arm 간 차이(delta)를 집계한다. delta>0 = 하네스 이득.
# =============================================================================
benchmark-rubric:
version: 1
arms: [plain, harness] # plain = 하네스 없이 Claude 단독 / harness = org-os 파이프라인
dimensions:
first-pass-acceptance:
type: bool # 1회차에 수용기준 전부 충족?
direction: higher-better
weight: 3
tests-pass-rate:
type: ratio # 통과 테스트 / 전체
direction: higher-better
weight: 3
requirements-met:
type: ratio # 충족 수용기준 / 전체 수용기준
direction: higher-better
weight: 3
unnecessary-change-lines:
type: count # 과제와 무관하게 바꾼 diff 라인
direction: lower-better
weight: 2
rework-count:
type: count # 수용까지 재작업 횟수
direction: lower-better
weight: 2
unsupported-claims:
type: count # 근거 없이 단정한 주장 수(hallucination 대리지표)
direction: lower-better
weight: 2
escaped-defects:
type: count # 수용 후 발견된 결함
direction: lower-better
weight: 3
human-interventions:
type: count # 사람이 손대야 했던 횟수
direction: lower-better
weight: 1
tokens:
type: count # 소비 토큰(비용)
direction: lower-better
weight: 1
latency-sec:
type: count # 벽시계 시간
direction: lower-better
weight: 1
task-score:
type: ratio # 카테고리별 종합(코드/문서/디자인/결정) 0..1
direction: higher-better
weight: 3
rules:
- "채점은 acceptance-criteria 기반(주관 최소화). 애매하면 근거(diff/test 로그/산출물)를 첨부한다."
- "arm 간 비교는 **같은 과제·같은 판정자**로. 판정자는 과제 실행자와 분리(감사 독립성)."
- "delta = harness - plain (higher-better) / plain - harness (lower-better). 양수 = 하네스 이득."
- "표본이 arm당 과제 1회 이상 있어야 비교에 포함(없으면 '미실행'으로 정직 표시)."
decision-rule: >
카테고리에서 하네스가 plain 대비 종합 delta<=0 이면, 그 카테고리에 붙은 role/fan-out/framework는
비용만 늘리는 것이므로 제거/경량화 후보다(리뷰 최종 판단).
View File
+11
View File
@@ -0,0 +1,11 @@
arms:
A: { label: "P1+P2", commit: "72997e5a65724f9d74efabcd41217acc3d0ce62e", expected-capabilities: { p3-a: false, p3-b-active: false } }
B: { label: "P1+P2+P3-A", commit: "dfb047587aac506aa5a59fce86d5d5eb39a5570f", expected-capabilities: { p3-a: true, p3-b-active: false } }
C: { label: "P1+P2+P3-B-active", commit: "353f1c6afe963b58939a198505d96c144ca6a583", expected-capabilities: { p3-a: true, p3-b-active: true } }
pilot-invoked-methods:
- { role: DES-DIRECTOR, methods: [frame-divergence, converge-directions] }
- { role: DES-PROD, methods: [pre-direction, post-direction] }
- { role: DES-PLATFORM, methods: [tokenize] }
- { role: DES-VISUAL, methods: [art-direction] }
- { role: DES-INTERNAL, methods: [internal-tool-design] }
required-commands: [ground, decide, design-direction]
+26
View File
@@ -0,0 +1,26 @@
benchmark-policy:
external-web-access: denied
evidence-pack-required: true
rationale: >
세 arm(A/B/C)이 서로 다른 시점의 실제 웹 검색 결과를 각자 만나면 "어떤 arm이 더 나은 근거를
찾았는가"를 비교하게 되어 하네스 방법론 자체의 비교가 오염된다. 모든 arm은 이 저장소의
evidence-pack/ 고정 스냅샷만 근거로 인용할 수 있다(Blocker 1).
enforcement: arm-runner evidence_env 가 WebFetch/WebSearch 를 실행 환경에서 차단·미배선한다.
benchmark-human-policy:
decision-policy: pre-authorized-for-benchmark
description: >
벤치마크 실행 중 각 cascade 커맨드가 요구하는 인간 승인 게이트(예: plan-signoff, HUMAN 수용)는
사람이 매 arm마다 대화형으로 응답하지 않고, 벤치마크 실행 전에 발급된 사전승인 receipt로
대체된다(모든 arm에 동일 조건 적용 — Blocker 2). 이 receipt 는 실제 프로덕션 인간 승인을
대체하지 않는다 — 벤치마크 목적의 격리된 워크스페이스에서만 유효하다.
forbidden:
- external-side-effect
- deployment
- real-purchase
- account-change
- prod-resource-create
receipt-required-for:
- plan-signoff
- human-acceptance-gate
- wave-signoff
+34
View File
@@ -0,0 +1,34 @@
# Brief: "ShiftDeck" — 소규모 팀 교대근무 관리 웹 도구
## 문제
5~30인 매장·카페의 매니저는 주간 교대표를 엑셀이나 종이로 만든다. 매주 반복되는 3가지 실수가
있다: (1) 두 직원을 같은 시간대에 겹쳐 배정하거나 가용하지 않은 시간에 배정하는 **가용시간
충돌**, (2) 특정 인원에게 야간·주말 근무가 몰리는 **야간 편중**, (3) 교대표를 수정한 뒤 당사자에게
알리지 못해 발생하는 **변경 공지 누락**(노쇼·이중예약으로 이어짐). 이 세 실수는 매장 운영에
직접적인 인건비 낭비와 직원 이탈로 이어진다.
## 사용자 · 핵심 과제
- **1차 사용자**: 매장 매니저. 주 1회(보통 일요일 저녁) 다음 주 교대표를 작성하고 게시한다.
본업(접객·재고)과 병행하므로 교대표 작성에 쓸 수 있는 시간은 20~30분 이내다.
- **2차 사용자**: 파트타임/아르바이트 직원. 본인 가용시간을 입력하고, 게시된 교대표를 확인하며,
변경 시 알림을 받는다. 스마트폰으로 접속하는 비중이 높다.
- **핵심 과제(critical path)**: 직원이 가용시간을 입력한다 → 매니저가 그 가용시간을 바탕으로
충돌 없는 주간 교대표를 생성한다 → 게시한다 → 이후 매니저가 교대표를 수정하면 영향받는 직원에게
자동으로 변경 알림이 간다.
## 범위(파일럿)
- **포함**: 단일 화면 우선 설계(주간 교대 보드 — 요일×직원 그리드) + 직원 가용시간 입력 화면 +
충돌(겹침/가용외) 시각적 경고 + 변경 시 알림 트리거.
- **제외**: 결제·정산, 다점포(멀티 매장) 관리, 네이티브 모바일 앱, 급여 연동, 근태(출퇴근 체크).
이번 파일럿은 "교대표를 정확하게, 빠르게 만들고 게시한다"는 단일 문제에 집중한다.
## 제약
- 웹(반응형) 우선. 오프라인 우선(offline-first) 아님 — 매장 와이파이/데이터 연결을 전제한다.
- 접근성 AA 수준(색만으로 충돌을 표시하지 않음 — 아이콘/텍스트 병행).
- i18n 불필요(단일 로케일, 한국어 UI 기준).
- 외부 조사는 이 저장소의 `evidence-pack/` 스냅샷만 사용한다(외부 웹 접근 금지 — 벤치마크
정책상 모든 arm이 동일한 고정 근거만 읽어야 공정한 비교가 성립한다).
@@ -0,0 +1,37 @@
# Evidence Pack — Competitor Snapshot (고정 스냅샷)
> market-context.md 와 동일하게 고정 스냅샷이다. 각 arm 은 여기 적힌 경쟁 구도만 근거로
> 인용할 수 있다 — 실행 시점에 실제 경쟁사 페이지를 조회하지 않는다(external-web denied).
## 경쟁 구도 3그룹
### 그룹 A — 글로벌 엔터프라이즈 교대관리 SaaS
- 특징: 급여·근태·결제·다점포 관리까지 통합한 풀스택 제품.
- 과금: 직원 1인당 월 $2.5~4(원화 환산 약 3,300~5,300원/인/월). 매장이 직원 15명이면 월
5~8만원대 — 세그먼트 가격 민감도(market-context.md §3) 상한을 초과.
- 온보딩: 초기 설정에 관리자 교육 세션(30분~1시간)을 권장 — 소규모 매장 매니저의 "배울 시간
없음" 장벽과 정면 충돌.
- 강점: 충돌 감지·리포팅은 정교하나, 이 세그먼트가 쓰지 않는 기능(급여 연동 등)에 과설계.
### 그룹 B — 국내 스타트업 교대표 앱
- 특징: 무료~저가 티어 존재, UI는 가볍다.
- 약점 1(관찰 근거 다수): 가용시간 충돌 감지가 "겹침"만 잡고 "가용 외 시간 배정"은 못 잡는
사례가 반복 보고됨.
- 약점 2: 교대표 수정 후 알림이 앱 푸시로만 가는데, 파트타임 직원의 앱 재설치율이 낮아 실제
도달률이 떨어진다는 간접 신호(그룹 B 사용 매장 매니저의 반복 불만 — user-observations.md 참조).
- 야간 편중 경고 기능은 그룹 B, C 모두 없음(공통 공백).
### 그룹 C — 무료 엑셀/스프레드시트 템플릿
- 특징: 비용 0원, 학습곡선 낮음(이미 익숙한 도구).
- 치명적 약점: 충돌·야간편중 검증이 전부 수작업. 변경 시 알림 기능 자체가 없음(수동으로
전화·문자를 돌려야 함) — 브리프의 문제 정의(변경 공지 누락) 그 자체가 이 그룹 사용에서
가장 빈번히 발생.
## 공백 지도(White Space)
- 그룹 A: 가격·온보딩 장벽으로 이 세그먼트에 도달하지 못함.
- 그룹 B: 핵심 3문제(충돌/야간편중/공지누락) 중 충돌만 부분 대응, 야간편중·안정적 알림은 미대응.
- 그룹 C: 3문제 전부 무대응(수작업 의존).
- **시사점**: "충돌 완전 탐지 + 야간편중 경고 + 신뢰 가능한 알림"을 그룹 A 수준 가격이 아니라
그룹 B~C 수준 도입 장벽으로 제공하는 지점이 비어 있다. 이는 브리프의 스코프 판단(단일 화면
우선, 결제·다점포 제외)을 뒷받침하는 근거다.
@@ -0,0 +1,39 @@
# Evidence Pack — Market Context (고정 스냅샷)
> 이 문서는 P4 벤치마크의 모든 arm(A/B/C)이 동일하게 읽는 **고정** 시장 근거다. 벤치마크
> 정책상 외부 웹 접근이 금지되므로(`benchmark-policy.yaml`), 실행 시점에 조사하지 말고 이
> 스냅샷만 근거로 인용한다. snapshot-date는 `sources.yaml`을 따른다.
## 1. 세그먼트 정의
- 대상 세그먼트: 직원 5~30인 매장·카페·소규모 서비스업(교대근무 편성이 매주 발생하는 업종).
국내 사업자등록 기준 이 규모대 매장은 약 42만 개소로 추정(소상공인시장진흥공단 2025 실태조사
스냅샷 기준 — evidence-pack 고정치).
## 2. 현재 도구 사용 실태
- 이 세그먼트의 78%가 교대표 작성에 여전히 엑셀 또는 수기(종이)를 쓴다.
- 나머지 22% 중 절반은 카카오톡 단체채팅으로 "이번 주 시간표" 이미지를 공유하는 방식을 병행한다.
- 전용 교대관리 SaaS를 쓰는 비중은 6% 미만 — 대부분 프랜차이즈 본사가 강제 도입한 경우다.
## 3. 도입 장벽
- 초기 설정 시간: 매니저가 "새 도구를 배우는 데 쓸 시간이 없다"는 응답이 가장 큰 장벽(세그먼트
공통 반복 응답 — user-observations.md 참조).
- 가격 민감도: 매장당 월 5만원을 넘는 구독료는 순수 교대표 기능만으로는 정당화하기 어렵다는
반응이 지배적(엔터프라이즈 SaaS 견적 대비 반응, competitor-snapshot.md 참조).
- 직원 측 저항: 새 앱 설치·로그인을 요구하면 파트타임 직원의 실제 사용률이 떨어진다(주 1~2회
출근하는 인력 비중이 높은 세그먼트 특성).
## 4. 기회 신호
- 결제·급여 연동 없이 "충돌 없는 교대표 생성 + 변경 알림"만 잘 풀어도 채택 장벽을 넘을 수
있다는 가설(현재 엔터프라이즈 도구는 이 좁은 문제에 과설계되어 있음 — 섹션 2·3 근거 종합).
- 알림 채널을 기존 카카오톡/문자 습관에 올라타면(신규 앱 설치 강제 대신) 도입 저항이 줄어든다는
간접 신호(섹션 2의 카카오톡 병행 사용 패턴에서 유추).
## 5. 스코프 판단에 대한 시사점
- 위 시그널은 브리프의 스코프 제외 결정(결제·다점포·네이티브 앱 제외)과 정합한다 — 이 세그먼트가
실제로 겪는 병목은 "충돌·야간편중·공지누락" 3가지에 집중돼 있고, 그 밖의 기능은 채택을
늦추는 초기 설정 부담만 키운다.
@@ -0,0 +1,15 @@
snapshot-date: "2026-07-15"
policy-note: >
이 evidence-pack 은 P4 벤치마크의 모든 arm(A/B/C)이 동일하게 읽는 고정 스냅샷이다.
external-web-access: denied(benchmark-policy.yaml) 정책에 따라 실행 시점에 실제 웹을
조회하지 않는다 — 이 세 파일(market-context.md·competitor-snapshot.md·user-observations.md)이
유일하게 인용 가능한 근거다.
sources:
- title: "소상공인시장진흥공단 2025 실태조사(스냅샷)"
note: "직원 5~30인 매장 세그먼트 규모 추정치(market-context.md §1)의 근거로 고정 인용."
- title: "세그먼트 도구 사용 실태 내부 집계(스냅샷)"
note: "엑셀/수기 78%, 카카오톡 병행, 전용 SaaS 6% 미만 수치(market-context.md §2)의 근거."
- title: "경쟁 제품 3그룹 비교 조사(스냅샷)"
note: "그룹 A/B/C 과금·기능 공백 지도(competitor-snapshot.md)의 근거."
- title: "매니저 5인·직원 4인 현장 관찰(스냅샷)"
note: "소요시간·반복실수·야간편중·공지누락 정량/정성 관찰(user-observations.md)의 근거."
@@ -0,0 +1,36 @@
# Evidence Pack — User Observations (고정 스냅샷)
> 매장 매니저 5명 + 파트타임 직원 4명 대상 현장 관찰·인터뷰의 고정 요약이다(원 인터뷰 로그가
> 아니라 벤치마크 정본으로 정제된 스냅샷). 각 arm 은 이 관찰만 근거로 인용한다.
## 매니저 관찰(5인, 매주 교대표 작성 담당)
1. **소요시간**: 평균 25분(최소 15분·최대 45분) — 일요일 저녁, 마감 후 지친 상태에서 작업.
집중력이 떨어지는 시간대라 충돌을 놓치는 빈도가 높다고 본인들이 인지하고 있음.
2. **반복 실수 패턴**: 5인 중 4인이 "지난달에 두 사람을 같은 시간대에 겹쳐 넣은 적이 있다"고
응답. 원인은 엑셀 셀을 눈으로 훑으며 확인하는 방식의 구조적 한계.
3. **야간 편중**: 5인 중 3인이 "특정 직원에게 야간·주말이 몰린다는 항의를 받은 적 있다"고 응답.
본인은 "공평하게 배정하려 했지만 매주 수작업으로 누적 야간 횟수를 추적하지 못했다"고 답함.
4. **변경 공지**: 게시 후 변경이 발생하는 빈도는 주 평균 1.8건(휴무 교체, 갑작스러운 결원 등).
이 중 절반 가까이가 "당사자에게 알리는 걸 깜빡했다"는 자기보고 — 이 하나의 실수가 노쇼로
이어진 사례가 5인 중 4인에게서 확인됨.
5. **도구 태도**: "새 앱을 배우느니 차라리 지금 방식이 낫다"는 응답이 지배적이나, 동시에 "지금
방식이 실수를 만든다는 것도 안다"는 모순적 태도 — 즉 도입 장벽이 문제 인식보다 크다.
## 직원 관찰(4인, 파트타임/아르바이트)
6. **확인 채널**: 4인 전원이 교대표를 카카오톡으로 받는 것을 선호. 전용 앱을 새로 설치해야
한다면 "당장 급하지 않으면 안 깐다"는 응답이 3인.
7. **가용시간 입력**: 현재는 매니저에게 구두 또는 문자로 개별 통보 — 4인 중 3인이 "내가 말한
가용시간이 반영 안 된 채 배정된 적 있다"고 응답(구두 전달의 유실).
8. **변경 인지 시점**: 변경 사실을 "당일 출근해서야 알았다"는 응답이 2인 — 위 매니저 관찰
4번(공지 누락)과 직접 대응.
## 종합 시사점
9. 세 문제(충돌·야간편중·공지누락)는 서로 독립이 아니라 **하나의 원인 사슬**에서 나온다 — 수작업
확인의 구조적 한계(매니저 관찰 2)가 충돌을 낳고, 누적 추적 부재(관찰 3)가 편중을 낳고, 수동
통보 의존(관찰 4·8)이 공지 누락을 낳는다.
10. 도입 장벽을 낮추려면 "새 앱을 배우게 하지 않는" 접근(기존 채널 활용, 관찰 6)과 "가용시간
입력의 유실을 막는" 접근(관찰 7)이 동시에 필요하다 — 이는 브리프의 단일 화면 우선 스코프
판단을 지지한다.
@@ -0,0 +1,39 @@
# Calibration fixture: BAD — candidate-package 스키마(Task 7 CANON_FIELDS)를 따르되
# 제네릭·형용사 위주·근거 없는 샘플. gold와 같은 스키마 형태를 유지하면서 내용 품질만
# 낮춘다(구조 자체를 깨서 실패하게 만들지 않음 — 그러면 judge가 형식 오류를 잡는 것이지
# 콘텐츠 품질 격차를 잡는 게 아니게 된다).
candidate-package:
problem-framing:
value: >
사용자들이 교대근무 관리에 어려움을 겪고 있다. 기존 방식은 비효율적이고 불편하며
개선의 여지가 많다. 더 나은 솔루션이 필요하다.
source-artifacts: []
user-and-core-task:
value: >
매니저와 직원 모두가 사용하는 서비스다. 사용자 친화적이고 직관적인 경험을 제공하는
것이 목표다. 다양한 사용자층을 고려해 설계한다.
source-artifacts: []
explored-directions:
- "모던하고 세련된 디자인 방향 하나를 검토함."
selected-direction:
value: >
깔끔하고 직관적인 UI로 교대표를 관리할 수 있는 화면을 만든다. 현대적인 느낌의
대시보드 스타일을 채택한다.
source-artifacts: []
selection-rationale:
value: >
사용자들이 좋아할 만한 디자인이라고 판단했다. 업계에서 많이 쓰이는 스타일이라 무난하다.
source-artifacts: []
rejected-directions:
- "다른 방향들은 검토했으나 적합하지 않다고 판단해 제외함."
locked-invariants:
- "일관된 디자인 유지"
- "사용성 고려"
coded-prototype:
value: "화면 시안을 준비함(추후 구체화 예정)."
source-artifacts: []
critique-findings: []
revisions: []
design-system-handoff-readiness:
value: "추가 논의가 필요함."
source-artifacts: []
@@ -0,0 +1,25 @@
# Calibration fixture: 단일결함(single-defect) — gold에서 evidence-grounding 기준만 의도적으로
# 훼손한 변형과 gold를 비교했을 때, ruler가 정확히 evidence-grounding만 하락시키고(표적) 다른
# criterion(role-expertise 등 허용된 연쇄 제외)은 과도하게 흔들지 않아야 calibration이 통과한다.
# 소비: bench_cascade.calibrate.single_defect_pass(target_drop, next_nonallowed_drop,
# nonallowed_max_drop, pairwise_goldwin, thresholds) — 이 meta.yaml의 thresholds를 그대로 넣는다.
fixture:
id: defect-evidence-grounding
description: >
gold/candidate.yaml의 problem-framing·user-and-core-task·selected-direction·
selection-rationale에서 evidence-pack 인용(source-artifacts, 구체 관찰 번호)을 전부 제거하고
동일한 결론을 근거 없는 단정문으로 바꾼 변형. 구조(스키마)는 gold와 동일하게 유지한다 —
스키마를 깨면 judge가 형식 오류를 잡는 것이지 evidence-grounding 결함을 잡는 게 아니게 된다.
target-criterion: evidence-grounding
allowed-collateral: [role-expertise]
allowed-collateral-rationale: >
근거 인용을 제거하면 "이 역할만이 낼 수 있는 판단"이라는 인상도 함께 옅어지는 연쇄 효과가
있을 수 있다(전문성의 신호 중 하나가 구체 근거 인용이므로). 그 외 criterion(procedural-
completeness·alternatives-and-counterarguments·practical-artifacts·handoff-completeness·
non-genericness·design-distinctiveness)은 evidence-grounding 결함과 무관하게 원래 값을
유지해야 하며, 하락하면 표적 격리 실패로 간주한다.
thresholds:
target-min-drop: 1.0
non-target-max-drop: 0.5
target-margin-over-next: 0.5
pairwise-target-goldwin-min: 0.67
@@ -0,0 +1,91 @@
# Calibration fixture: GOLD — candidate-package 스키마(Task 7 CANON_FIELDS)를 따르는
# 우수 샘플. 구체적·차별적·evidence-pack에 접지된 문장으로 구성한다(제네릭 형용사 금지).
# ruler가 이 fixture를 bad와 pairwise 비교했을 때 gold가 이겨야 calibration이 통과한다
# (calibrate.gold_vs_bad_pass, GOLD_PREF_MIN=0.67).
candidate-package:
problem-framing:
value: >
5~30인 매장 매니저가 매주 겪는 실수는 하나의 문제가 아니라 한 원인 사슬에서 나온
세 증상이다 — 수작업 확인의 구조적 한계가 가용시간 충돌을 낳고(매니저 5인 중 4인이
직전달 겹침 배정 경험), 누적 야간횟수 미추적이 편중을 낳고(5인 중 3인이 항의 수령
경험), 수동 통보 의존이 공지 누락을 낳는다(주 평균 1.8건 변경 중 절반이 미통보,
5인 중 4인에게서 노쇼로 이어진 사례 확인).
source-artifacts:
- artifact-ref: evidence-pack/user-observations.md
artifact-sha256: 4370afe4e52b258bee65cec8043b55c642bb23bcfb07ab76f5d84221c52a88b1
source-fields: ["매니저 관찰 2", "매니저 관찰 3", "매니저 관찰 4", "종합 시사점 9"]
user-and-core-task:
value: >
1차 사용자는 일요일 저녁 마감 후 20~30분(관찰 평균 25분) 안에 교대표를 작성·게시해야
하는 매장 매니저다. 2차 사용자는 카카오톡으로 교대표를 확인하는 파트타임 직원(4인 중
3인이 신규 앱 설치에 저항 — "당장 급하지 않으면 안 깐다"). 핵심 과제는 가용시간 입력의
유실 없는 반영(직원 4인 중 3인이 구두 전달 유실 경험)부터 변경 알림 도달까지의 단일
흐름이다.
source-artifacts:
- artifact-ref: evidence-pack/user-observations.md
artifact-sha256: 4370afe4e52b258bee65cec8043b55c642bb23bcfb07ab76f5d84221c52a88b1
source-fields: ["매니저 관찰 1", "직원 관찰 6", "직원 관찰 7"]
explored-directions:
- "A. 요일×직원 그리드(주간 보드) — 매니저의 기존 엑셀 정신모델과 1:1 대응, 학습곡선 최소화."
- "B. 캘린더 월간 뷰 우선 — 월 단위 조망은 가능하나 주간 작성 워크플로(관찰 1: 매주 반복
25분 작업)와 어긋남, 한 주 내 충돌 확인이 오히려 스크롤로 분산됨."
- "C. 직원별 개인 페이지 우선(내 시간표만 보기) — 직원 알림 요구(관찰 6·8)엔 맞지만 매니저의
'충돌 없는 표 생성'이라는 1차 과제를 지원하지 못함(전체 조망 불가)."
selected-direction:
value: >
A안(요일×직원 그리드) 채택. 그리드 셀에 가용시간 충돌은 색상 배경 + 경고 아이콘 +
"가용외" 텍스트 라벨을 병행 표시(AA 준수, 색맹 사용자도 식별). 각 직원 열 상단에
"이번 주 야간 N회" 누적 배지를 고정 노출해 편중을 매니저가 배정 중 즉시 인지하게 한다.
게시 후 셀을 수정하면 해당 직원에게 카카오톡 딥링크 알림이 자동 발송된다(신규 앱 설치
요구 없음).
source-artifacts:
- artifact-ref: evidence-pack/competitor-snapshot.md
artifact-sha256: 0baf427bb6fd0527ec1b569ef533be368135d8b9d110f54b0608aa24b1c7e082
source-fields: ["공백 지도(White Space)"]
- artifact-ref: evidence-pack/user-observations.md
artifact-sha256: 4370afe4e52b258bee65cec8043b55c642bb23bcfb07ab76f5d84221c52a88b1
source-fields: ["매니저 관찰 3", "직원 관찰 6"]
selection-rationale:
value: >
그룹 B/C 경쟁제품은 충돌 감지가 겹침만 잡고 가용외 배정은 못 잡거나(그룹 B 약점 1),
야간 편중 경고 자체가 없다(공백 지도 공통 공백). A안의 이중 표시(색+아이콘+텍스트)와
야간 누적 배지는 이 공백을 정확히 메운다. 카카오톡 딥링크 알림은 그룹 B의 앱 푸시
도달률 문제(약점 2)를 세그먼트의 기존 습관(직원 관찰 6)에 올라타 우회한다.
source-artifacts:
- artifact-ref: evidence-pack/competitor-snapshot.md
artifact-sha256: 0baf427bb6fd0527ec1b569ef533be368135d8b9d110f54b0608aa24b1c7e082
source-fields: ["그룹 B — 국내 스타트업 교대표 앱"]
rejected-directions:
- "B. 캘린더 월간 뷰 우선(주간 작성 워크플로와 불일치, 충돌 확인이 스크롤로 분산)"
- "C. 직원별 개인 페이지 우선(매니저의 전체 조망·충돌 생성 과제를 지원하지 못함)"
locked-invariants:
- "충돌 표시는 색상 단독 금지 — 아이콘+텍스트 병행(AA)"
- "야간 누적 배지는 직원 열 상단에 고정 노출(스크롤로 가려지지 않음)"
- "알림은 신규 앱 설치를 요구하지 않는 채널(카카오톡 딥링크) 우선"
coded-prototype:
value: >
WeeklyShiftBoard 화면 1개(요일×직원 그리드, 충돌 배지, 야간 누적 카운터, 변경 알림
트리거 버튼) + AvailabilityInput 화면 1개(직원 가용시간 입력, 그리드와 동일 토큰 세트
공유)를 코드로 렌더. 데스크톱·모바일 두 뷰포트 스크린샷을 headless chrome으로 캡처해
prototype-desktop.png / prototype-mobile.png 로 첨부.
source-artifacts:
- artifact-ref: design-system/screens/WeeklyShiftBoard.tsx
artifact-sha256: 9f1c7a3e2b6d4f0a8c5e1d3b7f9a2c4e6b8d0f1a3c5e7b9d1f3a5c7e9b1d3f5a
source-fields: ["grid-cell-conflict-badge", "night-count-pill"]
critique-findings:
- "1차 리뷰: 야간 누적 배지 색상이 충돌 배경색과 인접해 시각적으로 혼동됨(6-lens 사용성 관점)."
- "1차 리뷰: 모바일 뷰에서 그리드 가로 스크롤이 필요해 '한눈에 조망' 목표(관찰 1)와 상충."
revisions:
- "야간 누적 배지를 배경 대비 대신 상단 고정 pill(중립색) + 숫자로 변경, 충돌 배지와 시각
계열 분리."
- "모바일은 요일 탭 전환형 레이아웃으로 재구성(그리드 전체 대신 하루씩 노출), 데스크톱은
그리드 유지 — 반응형 분기를 명시적 토큰 경계로 문서화."
design-system-handoff-readiness:
value: >
토큰(충돌 배경색·경고 아이콘·야간 배지 pill·그리드 8pt 간격) 확정, 두 컴포넌트
(WeeklyShiftBoard·AvailabilityInput) 렌더 완료, 반응형 분기 규칙 문서화 완료 — 엔지니어링
착수 가능(readiness: ready).
source-artifacts:
- artifact-ref: design-system/tokens.css
artifact-sha256: 3e5c7a9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a5c
source-fields: ["--color-conflict-bg", "--radius-badge", "--space-grid"]
+65
View File
@@ -0,0 +1,65 @@
# P4 cascade benchmark — judge rubric. 8 criteria, 0-4 절대 스케일(calibration 진단 전용).
# 최종 승자 판정은 pairwise(judge.py X/Y winner) 만 쓴다 — absolute score 는 여기서 못 쓴다.
criteria:
role-expertise:
scale: "0-4"
desc: "역할 고유 관점·전문성이 드러나는가 — 제네릭 컨설턴트가 아니라 그 직무만이 낼 수 있는 판단인가."
anchors:
"0": "역할과 무관한 범용 조언. 어느 역할이 썼는지 구분 불가."
"2": "역할 관점이 부분적으로 드러나나 표면적(용어만 차용)."
"4": "그 역할의 방법론·프레임이 판단 근거로 명시적으로 쓰였다."
procedural-completeness:
scale: "0-4"
desc: "방법 절차(단계·완결 게이트)를 밟았는가 — 결론만 던지지 않고 과정을 보였는가."
anchors:
"0": "결론만 있고 과정 없음."
"2": "일부 단계만 수행(중간 생략)."
"4": "선언된 절차 전 단계를 완결 게이트와 함께 밟았다."
evidence-grounding:
scale: "0-4"
desc: "주장이 근거(evidence-pack·아티팩트)에 접지되는가 — 출처 없는 단정이 아닌가."
anchors:
"0": "근거 인용 없이 단정. 출처 불명 수치·주장."
"2": "일부 주장만 evidence-pack 에 연결, 나머지는 무근거."
"4": "핵심 주장 전부가 evidence-pack 의 구체 항목(파일·문장)에 연결된다."
alternatives-and-counterarguments:
scale: "0-4"
desc: "대안·반론을 실제로 검토했는가 — 첫 아이디어를 그대로 채택하지 않았는가."
anchors:
"0": "대안 없이 단일안만 제시."
"2": "대안을 나열했으나 기각 사유가 형식적."
"4": "≥2 대안을 실제 트레이드오프로 비교하고 구체적 기각 사유를 남겼다."
practical-artifacts:
scale: "0-4"
desc: "다음 단계가 쓸 실물 산출물이 있는가 — 서술뿐인가, 구조화된 결과물인가."
anchors:
"0": "서술형 텍스트뿐, 재사용 가능한 산출물 없음."
"2": "산출물이 있으나 불완전(필드 누락·형식 불일치)."
"4": "다음 역할이 그대로 소비 가능한 완결된 산출물."
handoff-completeness:
scale: "0-4"
desc: "다음 역할이 소비할 입력이 완전한가 — 넘겨받을 사람이 다시 물어봐야 하는가."
anchors:
"0": "다음 역할이 무엇을 넘겨받는지조차 불명확."
"2": "핵심 필드는 있으나 근거·rationale 누락."
"4": "선택된 결과물 + 근거 + 기각된 대안 + 불변조건까지 전부 명시."
non-genericness:
scale: "0-4"
desc: "제네릭 템플릿이 아니라 이 문제(ShiftDeck)에 특정되는가 — 다른 브리프에도 그대로 쓸 수 있는 문장인가."
anchors:
"0": "다른 어떤 제품에도 그대로 붙여넣을 수 있는 형용사 위주 서술(예: '직관적이고 현대적인')."
"2": "일부 문장은 특정적이나 상당수가 일반론."
"4": "가용시간 충돌·야간 편중·변경 공지 누락 등 이 브리프 고유의 구체 사실에 결박된 서술."
design-distinctiveness:
scale: "0-4"
desc: "방향이 시각적으로 구별되는 주장을 하는가(렌더 필요) — 렌더 없으면 not-evaluable."
requires-render: true
anchors:
"0": "렌더 없음(not-evaluable) 또는 렌더가 있어도 시각적 주장이 없는 기본 템플릿."
"2": "시각적 차별점은 있으나 근거(왜 이 방향인가)가 약함."
"4": "렌더가 명확한 시각적 주장을 하며 그 주장이 토큰·결정과 일관된다."
absolute-rubric-note: >
절대 점수(0-4)는 calibration 진단 전용이다(단일결함 fixture가 어느 criterion을 정확히
건드렸는지 확인하는 용도). 최종 승자 판정에는 pairwise 비교(judge.py 의 X/Y winner)만 쓴다 —
절대 점수를 합산해 순위를 매기지 않는다(judge간 척도 불일치를 pairwise 로 흡수).
+13
View File
@@ -0,0 +1,13 @@
"""Pagination helper — contains an off-by-one bug that drops the last item of a page.
The bug: `end = start + size - 1` and slicing `items[start:end]` excludes the last
element of each page. A correct implementation returns exactly `size` items per page
(and the remainder on the final page).
"""
def paginate(items, page, size):
"""Return the `page`-th (1-indexed) slice of `items` with `size` per page."""
start = (page - 1) * size
end = start + size - 1 # BUG: off-by-one — drops the last item of the page
return items[start:end]
+22
View File
@@ -0,0 +1,22 @@
"""Objective acceptance test for GT-01 (held as the verify command).
This test currently FAILS against the buggy paginate() (off-by-one drops the last
item). A correct fix makes it pass. The benchmark runner runs `pytest -q` after each
arm and grades first-pass-acceptance on the exit code.
"""
from paginate import paginate
def test_full_page_returns_size_items():
items = list(range(10))
assert paginate(items, 1, 5) == [0, 1, 2, 3, 4]
assert paginate(items, 2, 5) == [5, 6, 7, 8, 9]
def test_last_item_not_dropped():
assert paginate([1, 2, 3], 1, 3) == [1, 2, 3]
def test_partial_last_page():
assert paginate([1, 2, 3, 4, 5], 1, 2) == [1, 2]
assert paginate([1, 2, 3, 4, 5], 3, 2) == [5]
+16
View File
@@ -0,0 +1,16 @@
"""Running statistics — contains a bug in `median` for even-length inputs.
The bug: for an even number of elements, `median` returns the lower-middle element
instead of the average of the two middle elements. `mean` is correct.
"""
def mean(xs):
return sum(xs) / len(xs)
def median(xs):
s = sorted(xs)
n = len(s)
mid = n // 2
return s[mid] # BUG: even-length should average s[mid-1] and s[mid]
+14
View File
@@ -0,0 +1,14 @@
from stats import mean, median
def test_mean():
assert mean([2, 4, 6]) == 4
def test_median_odd():
assert median([3, 1, 2]) == 2
def test_median_even():
assert median([1, 2, 3, 4]) == 2.5 # average of the two middle elements
assert median([10, 20]) == 15
+157
View File
@@ -0,0 +1,157 @@
# golden-tasks.yaml — 품질 회귀 벤치마크 대표 과제 (finding: 리뷰 「권장 개선 순서」 3주차)
# =============================================================================
# 목적: **plain Claude vs 이 하네스**를 같은 과제로 비교해, 하네스가 실제로 품질을
# 올리는지 증명한다. 개선이 증명 안 되는 role/fan-out/framework는 제거 근거가 된다.
# (리뷰 최종 판단: "이 비교에서 개선이 증명되지 않는 것은 제거하는 편이 맞다.")
#
# 각 과제는 **검증 가능한 acceptance-criteria**를 가진다(주관 점수 최소화). 실행은
# benchmark.py 로 두 arm(plain/harness)의 결과를 rubric으로 채점·비교한다.
# 카테고리: code-bugfix · code-feature · refactor · docs · design · decision/analysis.
# =============================================================================
golden-tasks:
version: 1
categories: [code-bugfix, code-feature, refactor, docs, design, decision]
tasks:
- id: GT-01
category: code-bugfix
difficulty: low
prompt: "paginate.py 의 off-by-one 버그로 각 페이지 마지막 항목이 빠진다. 원인을 규명하고 최소 변경으로 수정하라. test_paginate.py 가 통과해야 한다."
# 자기완결 실행 픽스처(benchmark.py run 이 임시 복사본에서 arm 을 실행 후 verify 로 채점).
fixture: fixtures/GT-01
verify: "python3 -m pytest -q"
expected-changed-files: [paginate.py] # unnecessary-change-lines 채점 기준
acceptance-criteria:
- "수정 후 test_paginate.py 통과(green)"
- "기존 테스트 회귀 없음"
- "변경은 최소(무관한 리팩터 없음 — paginate.py 만 변경)"
artifacts: [fix-diff]
- id: GT-02
category: code-bugfix
difficulty: med
prompt: "간헐 실패(flaky) 테스트의 원인(시간 의존/경쟁)을 규명하고 결정적으로 만든다."
acceptance-criteria:
- "근본 원인을 재현 근거로 규명(추측 아님)"
- "100회 반복에서 결정적으로 통과"
- "타임아웃 늘리기 같은 은폐책 아님"
artifacts: [root-cause-note, fix-diff]
- id: GT-03
category: code-feature
difficulty: med
prompt: "기존 REST 엔드포인트에 커서 기반 페이지네이션을 추가한다(계약 명세 포함)."
acceptance-criteria:
- "API 계약(요청/응답/에러) 문서화"
- "단위+통합 테스트 통과"
- "기존 오프셋 방식과 하위호환 유지"
- "수용기준별 검증 근거 제시"
artifacts: [api-contract, code-diff, tests]
- id: GT-04
category: code-feature
difficulty: high
prompt: "멱등키(idempotency-key) 기반 중복요청 방지를 결제 생성 경로에 도입한다."
acceptance-criteria:
- "동시/재시도 시 정확히 1회 처리(경쟁 테스트로 증명)"
- "키 저장소 TTL·충돌 처리 명시"
- "위협모델(재생공격) 검토"
artifacts: [design-note, code-diff, race-test, threat-note]
- id: GT-05
category: refactor
difficulty: med
prompt: "600줄짜리 God 모듈을 책임 단위로 분리하되 동작을 바꾸지 않는다."
acceptance-criteria:
- "전 테스트 그대로 통과(행위 불변)"
- "공개 인터페이스 유지 또는 명시적 마이그레이션"
- "각 단위가 단일 책임"
artifacts: [refactor-diff, boundary-note]
- id: GT-06
category: refactor
difficulty: low
prompt: "중복된 검증 로직 3곳을 하나의 재사용 함수로 합친다."
acceptance-criteria:
- "동작 동일(테스트 통과)"
- "호출부 3곳 모두 갱신"
- "과도한 추상화 없음"
artifacts: [refactor-diff]
- id: GT-07
category: docs
difficulty: low
prompt: "신규 개발자용 로컬 실행 가이드를 작성한다(Diátaxis: tutorial)."
acceptance-criteria:
- "명령을 그대로 따라 실행 가능(검증됨)"
- "선행조건·예상결과 명시"
- "한 번에 이해 가능(작업기억 과부하 없음)"
artifacts: [tutorial-md]
- id: GT-08
category: docs
difficulty: med
prompt: "공개 API의 레퍼런스 문서를 실제 시그니처와 일치하게 작성한다."
acceptance-criteria:
- "모든 파라미터/반환/에러 문서화"
- "코드와 불일치 0"
- "예제가 실제 실행 가능"
artifacts: [reference-md]
- id: GT-09
category: design
difficulty: med
prompt: "대시보드 카드 컴포넌트를 디자인 시스템 토큰만으로 만든다(상태 포함)."
acceptance-criteria:
- "하드코딩 색 0(토큰만 소비)"
- "loading/empty/error/overflow 상태 처리"
- "WCAG 대비 통과 + 포커스 가시성"
- "preview_ui 게이트 통과"
artifacts: [component-code, preview-png]
- id: GT-10
category: design
difficulty: high
prompt: "기존 스택을 discovery해 reuse/adapt/create를 판단하고 화면 1개를 조립한다."
acceptance-criteria:
- "기존 stack/tokens/components 조사 근거 제시"
- "reuse/adapt/create 판단에 근거"
- "기존 컨벤션 위반 없음"
- "preview_ui 게이트 통과"
artifacts: [discovery-note, screen-code, preview-png]
- id: GT-11
category: decision
difficulty: high
prompt: "관측성 스택(자체구축 vs SaaS)을 근거로 하나 고른다(옵션≥2, 근거접지)."
acceptance-criteria:
- "옵션 2개 이상을 근거로 발산(ground)"
- "비용/운영/리스크 트레이드오프 명시"
- "confidence가 근거등급에서 파생(자기채점 금지)"
- "반대의견(dissent) 보존"
artifacts: [option-set, decision-packet]
- id: GT-12
category: decision
difficulty: med
prompt: "모호한 기능 요청을 수용기준이 있는 PRD로 정리한다."
acceptance-criteria:
- "사용자문제·성공지표 명시"
- "수용기준이 검증가능(모호어 없음)"
- "비목표(non-goals) 명시"
artifacts: [prd-md]
- id: GT-R2
category: code-bugfix
difficulty: low
prompt: "stats.py 의 median() 이 짝수 길이 입력에서 두 중앙값의 평균이 아니라 아래쪽 값을 돌려주는 버그가 있다. 최소 변경으로 수정하라. test_stats.py 가 통과해야 한다."
fixture: fixtures/GT-R2
verify: "python3 -m pytest -q"
expected-changed-files: [stats.py]
acceptance-criteria:
- "수정 후 test_stats.py 통과(green)"
- "변경은 최소(stats.py 만 변경)"
artifacts: [fix-diff]
# 채점은 benchmark-rubric.yaml. 각 과제를 두 arm(plain/harness)으로 실행 후 채점.
# fixture+verify 가 있는 과제는 benchmark.py run 이 실제 실행·자동 채점한다(나머지는 수동 record).
scoring: benchmark/benchmark-rubric.yaml
+4
View File
@@ -0,0 +1,4 @@
{"at": "2026-07-11T03:22:55Z", "task": "GT-01", "arm": "plain", "scores": {"first-pass-acceptance": 1.0, "tests-pass-rate": 1.0, "unnecessary-change-lines": 0}, "note": "auto(run)", "workdir": "/tmp/bench_GT-01_plain_3wlrjv5s"}
{"at": "2026-07-11T03:23:32Z", "task": "GT-01", "arm": "harness", "scores": {"first-pass-acceptance": 1.0, "tests-pass-rate": 1.0, "unnecessary-change-lines": 0}, "note": "auto(run)", "workdir": "/tmp/bench_GT-01_harness_ihgea7yk"}
{"at": "2026-07-11T03:23:59Z", "task": "GT-R2", "arm": "plain", "scores": {"first-pass-acceptance": 1.0, "tests-pass-rate": 1.0, "unnecessary-change-lines": 0}, "note": "auto(run)", "workdir": "/tmp/bench_GT-R2_plain_2ye_9sg8"}
{"at": "2026-07-11T03:24:21Z", "task": "GT-R2", "arm": "harness", "scores": {"first-pass-acceptance": 1.0, "tests-pass-rate": 1.0, "unnecessary-change-lines": 0}, "note": "auto(run)", "workdir": "/tmp/bench_GT-R2_harness_8w8sq2t9"}