@walwal-harness/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/templates/AGENTS.md.template +52 -0
- package/assets/templates/HARNESS.md +159 -0
- package/assets/templates/config.json +108 -0
- package/assets/templates/progress.txt.template +15 -0
- package/bin/init.js +281 -0
- package/gotchas/README.md +37 -0
- package/gotchas/evaluator-functional.md +5 -0
- package/gotchas/evaluator-visual.md +5 -0
- package/gotchas/generator-backend.md +5 -0
- package/gotchas/generator-frontend.md +5 -0
- package/gotchas/planner.md +5 -0
- package/package.json +35 -0
- package/scripts/init-agents-md.sh +327 -0
- package/scripts/scan-project.sh +269 -0
- package/skills/dispatcher/SKILL.md +53 -0
- package/skills/dispatcher/references/gotcha-flow.md +52 -0
- package/skills/dispatcher/references/initialization.md +53 -0
- package/skills/dispatcher/references/pipeline-definitions.md +76 -0
- package/skills/evaluator-functional/SKILL.md +58 -0
- package/skills/evaluator-functional/references/ia-compliance.md +37 -0
- package/skills/evaluator-functional/references/playwright-tools.md +43 -0
- package/skills/evaluator-functional/references/scoring-rubric.md +52 -0
- package/skills/evaluator-visual/SKILL.md +41 -0
- package/skills/evaluator-visual/references/responsive-checklist.md +44 -0
- package/skills/evaluator-visual/references/scoring-rubric.md +59 -0
- package/skills/generator-backend/SKILL.md +43 -0
- package/skills/generator-backend/references/nestjs-msa-patterns.md +69 -0
- package/skills/generator-backend/references/sprint-contract-be.md +32 -0
- package/skills/generator-frontend/SKILL.md +49 -0
- package/skills/generator-frontend/references/anti-slop-rules.md +21 -0
- package/skills/generator-frontend/references/component-patterns.md +52 -0
- package/skills/planner/SKILL.md +48 -0
- package/skills/planner/references/api-contract-schema.md +34 -0
- package/skills/planner/references/ia-map-guide.md +31 -0
- package/skills/planner/references/plan-template.md +51 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-dispatcher
|
|
3
|
+
description: "AI 하네스 파이프라인 선택 및 Gotcha 관리. 사용자 요청을 분석하여 FULLSTACK/FE-ONLY/BE-ONLY 파이프라인을 결정하고, 실수 지적 시 해당 에이전트의 gotchas에 기록한다. 트리거: '하네스 엔지니어링 시작', '하네스 시작', 'harness start'"
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dispatcher — Pipeline Selector + Gotcha Manager
|
|
8
|
+
|
|
9
|
+
## 1. Request Classification (최우선)
|
|
10
|
+
|
|
11
|
+
사용자 입력을 먼저 분류합니다:
|
|
12
|
+
|
|
13
|
+
- **실수 지적** ("아니", "잘못", "그렇게 하면 안 돼", "X로 해야지") → **Gotcha Flow**
|
|
14
|
+
- **기능 요청** ("만들어", "추가", "시작", PRD, OpenAPI) → **Pipeline Flow**
|
|
15
|
+
- **혼합** → Gotcha 먼저 기록 → Pipeline 이어서
|
|
16
|
+
|
|
17
|
+
## 2. Gotcha Flow
|
|
18
|
+
|
|
19
|
+
실수 지적 감지 시 → [Gotcha 상세 가이드](references/gotcha-flow.md)
|
|
20
|
+
|
|
21
|
+
핵심:
|
|
22
|
+
1. 교정 시그널 감지 (HIGH/MEDIUM만 기록)
|
|
23
|
+
2. 도메인 분석 → 대상 에이전트 판별
|
|
24
|
+
3. `.harness/gotchas/[agent].md`에 항목 추가 (중복 시 Occurrences 증가)
|
|
25
|
+
4. 사용자에게 기록 확인
|
|
26
|
+
|
|
27
|
+
## 3. Initialization Check (Phase 0)
|
|
28
|
+
|
|
29
|
+
파이프라인 선택 전 초기화 상태 확인:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
.harness/ 없음 → bash scripts/scan-project.sh . && bash scripts/init-agents-md.sh .
|
|
33
|
+
AGENTS.md 없음 → 위와 동일
|
|
34
|
+
AGENTS.md 비하네스 → 기존 백업 + 리빌드
|
|
35
|
+
정상 → Pipeline Selection 진행
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
상세 → [초기화 가이드](references/initialization.md)
|
|
39
|
+
|
|
40
|
+
## 4. Pipeline Selection
|
|
41
|
+
|
|
42
|
+
| 시그널 | 파이프라인 |
|
|
43
|
+
|--------|-----------|
|
|
44
|
+
| OpenAPI/Swagger + FE 요청 | **FE-ONLY**: Planner(light) → Gen-FE → Eval-Func → Eval-Visual |
|
|
45
|
+
| 기존 서버 + BE 추가 | **BE-ONLY**: Planner → Gen-BE → Eval-Func(API-only) |
|
|
46
|
+
| 신규 PRD / 제품 설명 | **FULLSTACK**: Planner → Gen-BE → Gen-FE → Eval-Func → Eval-Visual |
|
|
47
|
+
| 불명확 | 3개 질문으로 확정 |
|
|
48
|
+
|
|
49
|
+
상세 → [파이프라인 정의](references/pipeline-definitions.md)
|
|
50
|
+
|
|
51
|
+
## 5. Output
|
|
52
|
+
|
|
53
|
+
`.harness/actions/pipeline.json` 생성 → 사용자 확인 → 다음 에이전트 실행
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Gotcha Flow — 상세 가이드
|
|
2
|
+
|
|
3
|
+
## 교정 시그널 감지
|
|
4
|
+
|
|
5
|
+
| 시그널 패턴 | 예시 | 확신도 |
|
|
6
|
+
|------------|------|--------|
|
|
7
|
+
| 명시적 부정 | "아니", "틀렸어", "no" | HIGH |
|
|
8
|
+
| 행동 교정 | "그렇게 하면 안 돼", "X 하지 마" | HIGH |
|
|
9
|
+
| 올바른 방법 제시 | "X는 Y로 해야 해" | HIGH |
|
|
10
|
+
| 반복 불만 | "왜 또 이래", "또 같은 실수" | HIGH |
|
|
11
|
+
| 암시적 교정 | "그게 아니라", "다시 해봐" | MEDIUM |
|
|
12
|
+
| 질문형 | "이게 맞아?" | LOW (확인 후 판단) |
|
|
13
|
+
|
|
14
|
+
**HIGH/MEDIUM만 Gotcha로 기록.**
|
|
15
|
+
|
|
16
|
+
## 대상 에이전트 판별
|
|
17
|
+
|
|
18
|
+
| 도메인 키워드 | 대상 |
|
|
19
|
+
|-------------|------|
|
|
20
|
+
| API, 엔드포인트, DB, 스키마, NestJS, Gateway, 서비스 | `generator-backend` |
|
|
21
|
+
| 컴포넌트, UI, 스타일, 반응형, React, CSS, 상태 | `generator-frontend` |
|
|
22
|
+
| 테스트, 검증, 통과, 기준, 채점, PASS/FAIL | `evaluator-functional` |
|
|
23
|
+
| 디자인, 접근성, 색상, 레이아웃, 반응형 심사 | `evaluator-visual` |
|
|
24
|
+
| 설계, 아키텍처, 기획, 기능 목록, IA, 서비스 분할 | `planner` |
|
|
25
|
+
| 불명확 | 사용자에게 질문 |
|
|
26
|
+
|
|
27
|
+
## Gotcha 항목 형식
|
|
28
|
+
|
|
29
|
+
`.harness/gotchas/[agent-name].md`에 추가:
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
### [G-NNN] 간결한 제목
|
|
33
|
+
- **Date**: 2026-04-07
|
|
34
|
+
- **Trigger**: "사용자 원문 요약"
|
|
35
|
+
- **Wrong**: 에이전트가 했던 잘못된 행동
|
|
36
|
+
- **Right**: 사용자가 지시한 올바른 행동
|
|
37
|
+
- **Why**: 왜 잘못인지 근거
|
|
38
|
+
- **Scope**: 항상 / 특정 조건에서만
|
|
39
|
+
- **Occurrences**: 1
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 중복 처리
|
|
43
|
+
|
|
44
|
+
1. 기존 gotchas 파일 읽기
|
|
45
|
+
2. 동일/유사 항목 존재 → `Occurrences` 증가 + 날짜 업데이트
|
|
46
|
+
3. 신규 → 다음 G-NNN 번호로 추가
|
|
47
|
+
|
|
48
|
+
## 관리 규칙
|
|
49
|
+
|
|
50
|
+
- Dispatcher만 gotchas 파일 쓰기 가능
|
|
51
|
+
- 해결된 항목: `[RESOLVED]` 태그 (삭제하지 않음)
|
|
52
|
+
- 20개 초과 시 가장 오래된 RESOLVED부터 정리
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Initialization Guide — Phase 0
|
|
2
|
+
|
|
3
|
+
## Phase 0a: 전체 초기화 (빈 프로젝트 / 하네스 미설치)
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bash scripts/scan-project.sh .
|
|
7
|
+
bash scripts/init-agents-md.sh .
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Phase 0b: AGENTS.md 없음 (하네스는 있으나 문서 누락)
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bash scripts/scan-project.sh .
|
|
14
|
+
bash scripts/init-agents-md.sh .
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Phase 0c: 기존 CLAUDE.md 보존 + 리빌드 (브라운필드)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. 스캔 — 기존 CLAUDE.md 내용을 scan-result.json에 보존
|
|
21
|
+
bash scripts/scan-project.sh .
|
|
22
|
+
|
|
23
|
+
# 2. 리빌드 — 기존 규칙을 "Preserved Rules" 섹션으로 이관
|
|
24
|
+
# 원본은 .harness/archive/pre-harness-backup/ 에 백업
|
|
25
|
+
bash scripts/init-agents-md.sh .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Phase 0 이후 사용자 확인
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
AGENTS.md가 생성/리빌드되었습니다.
|
|
32
|
+
|
|
33
|
+
스캔 결과:
|
|
34
|
+
- 프로젝트 타입: [fullstack / backend-only / frontend-only / empty]
|
|
35
|
+
- 감지된 스택: [BE] / [FE] / [DB]
|
|
36
|
+
- 미분류 경로: [N]개 ([?] 태그)
|
|
37
|
+
- 기존 규칙 이관: [Y/N]
|
|
38
|
+
|
|
39
|
+
[?] 태그 경로를 확인해 주세요. 확인 후 요청사항을 말씀해 주시면 파이프라인을 선택합니다.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## scan-project.sh 감지 항목
|
|
43
|
+
|
|
44
|
+
| 항목 | 감지 방법 |
|
|
45
|
+
|------|----------|
|
|
46
|
+
| NestJS | nest-cli.json |
|
|
47
|
+
| FastAPI | requirements.txt + "fastapi" |
|
|
48
|
+
| Next.js | next.config.* |
|
|
49
|
+
| React/Vite | vite.config.* |
|
|
50
|
+
| 모노레포 | turbo.json, nx.json, pnpm-workspace.yaml |
|
|
51
|
+
| DB | package.json 내 typeorm/prisma/mongoose |
|
|
52
|
+
| OpenAPI | openapi.json/yaml, swagger.json/yaml |
|
|
53
|
+
| Git | .git/ 존재, 커밋 수, 브랜치 |
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Pipeline Definitions
|
|
2
|
+
|
|
3
|
+
## FE-ONLY
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
trigger: 외부 API 존재 + FE 작업 요청
|
|
7
|
+
agents:
|
|
8
|
+
- planner (light):
|
|
9
|
+
skip: MSA 서비스 설계, BE 기능 목록
|
|
10
|
+
do: OpenAPI → api-contract.json 변환, FE 컴포넌트 설계, feature-list (layer: frontend만)
|
|
11
|
+
- generator-frontend
|
|
12
|
+
- evaluator-functional
|
|
13
|
+
- evaluator-visual
|
|
14
|
+
skip:
|
|
15
|
+
- generator-backend
|
|
16
|
+
notes:
|
|
17
|
+
- api-contract.json은 OpenAPI에서 파생 (Planner가 변환)
|
|
18
|
+
- Eval-Func의 API Health Check는 외부 서버 대상
|
|
19
|
+
- AGENTS.md IA-MAP에 BE 경로 없음 (외부 서버)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## BE-ONLY
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
trigger: 기존 서버 + BE 기능 추가 요청
|
|
26
|
+
agents:
|
|
27
|
+
- planner:
|
|
28
|
+
skip: FE 컴포넌트 설계, 비주얼 요구사항
|
|
29
|
+
do: 기존 코드 분석, 신규 API 설계, api-contract.json 확장
|
|
30
|
+
- generator-backend
|
|
31
|
+
- evaluator-functional:
|
|
32
|
+
mode: api-only
|
|
33
|
+
skip: browser 테스트
|
|
34
|
+
do: curl/httpie로 API 엔드포인트 직접 검증
|
|
35
|
+
skip:
|
|
36
|
+
- generator-frontend
|
|
37
|
+
- evaluator-visual
|
|
38
|
+
notes:
|
|
39
|
+
- Eval-Func는 Playwright 대신 CLI 기반 API 테스트
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## FULLSTACK
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
trigger: 신규 PRD / 제품 설명
|
|
46
|
+
agents:
|
|
47
|
+
- planner (full)
|
|
48
|
+
- generator-backend
|
|
49
|
+
- generator-frontend
|
|
50
|
+
- evaluator-functional
|
|
51
|
+
- evaluator-visual
|
|
52
|
+
skip: none
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## pipeline.json Output Format
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"decided_at": "ISO 8601",
|
|
60
|
+
"user_request_summary": "요약",
|
|
61
|
+
"detected_signals": ["시그널1", "시그널2"],
|
|
62
|
+
"pipeline": "FE-ONLY | BE-ONLY | FULLSTACK",
|
|
63
|
+
"agents_active": ["agent1", "agent2"],
|
|
64
|
+
"agents_skipped": ["agent3"],
|
|
65
|
+
"planner_mode": "light | full",
|
|
66
|
+
"evaluator_mode": "browser | api-only",
|
|
67
|
+
"api_source": { "type": "openapi | internal", "location": "URL or path" },
|
|
68
|
+
"notes": "추가 컨텍스트"
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Disambiguation (불명확 시 질문)
|
|
73
|
+
|
|
74
|
+
1. "백엔드 API가 이미 존재합니까? (OpenAPI/Swagger 문서 있음?)"
|
|
75
|
+
2. "프론트엔드 UI가 필요합니까?"
|
|
76
|
+
3. "신규 프로젝트입니까, 기존 프로젝트에 추가입니까?"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-evaluator-functional
|
|
3
|
+
description: "하네스 Functional Evaluator. Playwright MCP(browser_*)로 실행 중인 앱을 실제 사용자처럼 조작하며 E2E 기능을 검증한다. Step 0 IA 구조 검증(Gate) → Step 1-7 기능 테스트. 기준 미달 = FAIL."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Evaluator-Functional — Playwright MCP
|
|
8
|
+
|
|
9
|
+
## Critical Mindset
|
|
10
|
+
|
|
11
|
+
- **회의적 평가자**. Generator의 자체 평가를 신뢰하지 마세요.
|
|
12
|
+
- 문제 발견 후 "사소하다"고 자기 설득 금지.
|
|
13
|
+
- 코드 읽기는 평가가 아님 — **반드시 앱을 조작**.
|
|
14
|
+
- 기준 미달 = FAIL. 예외 없음.
|
|
15
|
+
|
|
16
|
+
## Startup
|
|
17
|
+
|
|
18
|
+
1. `AGENTS.md` 읽기 — IA-MAP
|
|
19
|
+
2. `.harness/gotchas/evaluator-functional.md` 읽기 — **과거 실수 반복 금지**
|
|
20
|
+
3. `actions/sprint-contract.md` — BE + FE 성공 기준 전체
|
|
21
|
+
4. `actions/feature-list.json` — 이번 스프린트 범위
|
|
22
|
+
5. `actions/api-contract.json` — 기대 API 동작
|
|
23
|
+
6. `progress.txt`
|
|
24
|
+
|
|
25
|
+
## Evaluation Steps
|
|
26
|
+
|
|
27
|
+
### Step 0: IA Structure Compliance (GATE)
|
|
28
|
+
|
|
29
|
+
AGENTS.md IA-MAP vs 실제 구조 대조. **미통과 시 이하 전체 SKIP, 즉시 FAIL.**
|
|
30
|
+
|
|
31
|
+
상세 → [IA 검증 가이드](references/ia-compliance.md)
|
|
32
|
+
|
|
33
|
+
### Step 1-7: 기능 테스트
|
|
34
|
+
|
|
35
|
+
1. Environment Verification (브라우저 로드, 콘솔 에러)
|
|
36
|
+
2. API Health Check (Gateway 직접 검증)
|
|
37
|
+
3. Regression Test (이전 기능 재확인)
|
|
38
|
+
4. Contract Criteria Verification (각 기준 순서대로)
|
|
39
|
+
5. API Contract Compliance (api-contract.json 대조)
|
|
40
|
+
6. Error Scenario Testing
|
|
41
|
+
7. Console Error Audit
|
|
42
|
+
|
|
43
|
+
Playwright 도구 → [도구 레퍼런스](references/playwright-tools.md)
|
|
44
|
+
채점 기준 → [스코어링 루브릭](references/scoring-rubric.md)
|
|
45
|
+
|
|
46
|
+
## Scoring
|
|
47
|
+
|
|
48
|
+
| 차원 | 가중치 | 하드 임계값 |
|
|
49
|
+
|------|--------|------------|
|
|
50
|
+
| Contract 충족률 | 40% | 80% |
|
|
51
|
+
| API 계약 준수 | 25% | 100% |
|
|
52
|
+
| 에러 내성 | 20% | 6/10 |
|
|
53
|
+
| 콘솔 청결 | 15% | JS에러 0개 |
|
|
54
|
+
|
|
55
|
+
## After Evaluation
|
|
56
|
+
|
|
57
|
+
- **PASS** → Evaluator-Visual 핸드오프
|
|
58
|
+
- **FAIL** → `failure_location` 기반 라우팅 (backend/frontend), max 3회
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# IA Structure Compliance — Step 0 (Gate)
|
|
2
|
+
|
|
3
|
+
## 검증 방법
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# 1. 실제 폴더 구조 확인
|
|
7
|
+
ls -R apps/ libs/ 2>/dev/null
|
|
8
|
+
|
|
9
|
+
# 2. git diff로 소유권 위반 검출
|
|
10
|
+
git log --name-only --pretty=format: HEAD~[sprint_commits].. | sort -u
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 검증 항목
|
|
14
|
+
|
|
15
|
+
| 검증 | 판정 | 예시 |
|
|
16
|
+
|------|------|------|
|
|
17
|
+
| IA-MAP 경로가 실제 존재하는가 | 누락 → FAIL | apps/service-a/ 미생성 |
|
|
18
|
+
| IA-MAP에 없는 경로가 생겼는가 | 미등록 → DRIFT 기록 | apps/service-c/ 무단 생성 |
|
|
19
|
+
| [BE] 소유를 FE가 수정했는가 | 침범 → FAIL | apps/gateway/ FE 수정 |
|
|
20
|
+
| [FE] 소유를 BE가 수정했는가 | 침범 → FAIL | apps/web/ BE 수정 |
|
|
21
|
+
| [META]/[HARNESS]를 Generator가 수정했는가 | 침범 → FAIL | AGENTS.md 수정 |
|
|
22
|
+
|
|
23
|
+
## 판정 규칙
|
|
24
|
+
|
|
25
|
+
- **경로 누락 / 소유권 침범** → 즉시 FAIL, Step 1 이하 SKIP
|
|
26
|
+
- **미등록 경로 (Drift)** → FAIL 아님, evaluation에 `## AGENTS.md Drift` 기록
|
|
27
|
+
|
|
28
|
+
## Output (evaluation-functional.md에 포함)
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
## Step 0: IA Structure Compliance
|
|
32
|
+
- Verdict: PASS / FAIL (GATE)
|
|
33
|
+
- IA-MAP paths checked: [N]개
|
|
34
|
+
- Missing paths: [목록 또는 "none"]
|
|
35
|
+
- Unregistered paths: [목록 또는 "none"]
|
|
36
|
+
- Ownership violations: [목록 또는 "none"]
|
|
37
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Playwright MCP Tools Reference
|
|
2
|
+
|
|
3
|
+
## 핵심 도구
|
|
4
|
+
|
|
5
|
+
| 도구 | 용도 | 주요 사용 Step |
|
|
6
|
+
|------|------|---------------|
|
|
7
|
+
| `browser_navigate` | URL 이동 | Step 1, 3, 4 |
|
|
8
|
+
| `browser_click` | 요소 클릭 | Step 3, 4 |
|
|
9
|
+
| `browser_fill` | 입력 필드 작성 | Step 4, 6 |
|
|
10
|
+
| `browser_select_option` | 드롭다운 선택 | Step 4 |
|
|
11
|
+
| `browser_press_key` | 키보드 (Enter, Escape, Tab) | Step 4, 6 |
|
|
12
|
+
| `browser_take_screenshot` | 스크린샷 (증거) | 모든 Step |
|
|
13
|
+
| `browser_snapshot` | 접근성 트리 (DOM 구조) | Step 1, 4 |
|
|
14
|
+
| `browser_console_messages` | 콘솔 에러 감지 | Step 1, 7 |
|
|
15
|
+
| `browser_network_requests` | API 호출 캡처 | Step 2, 4, 5 |
|
|
16
|
+
| `browser_wait` | 요소/상태 대기 | Step 4 |
|
|
17
|
+
| `browser_resize` | 뷰포트 크기 변경 | Step 4 |
|
|
18
|
+
| `browser_tabs` | 탭 목록 | Step 2 |
|
|
19
|
+
| `browser_handle_dialog` | alert/confirm 처리 | Step 6 |
|
|
20
|
+
| `browser_hover` | 호버 상태 | Step 4 |
|
|
21
|
+
| `browser_drag` | 드래그 앤 드롭 | Step 4 |
|
|
22
|
+
|
|
23
|
+
## 기준 검증 패턴
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
기준: "사용자가 아이템을 생성할 수 있다"
|
|
27
|
+
|
|
28
|
+
[Action]
|
|
29
|
+
1. browser_navigate → /items
|
|
30
|
+
2. browser_click → "새 아이템" 버튼
|
|
31
|
+
3. browser_fill → name 필드에 "Test"
|
|
32
|
+
4. browser_click → "저장"
|
|
33
|
+
5. browser_wait → 목록에 "Test" 표시
|
|
34
|
+
|
|
35
|
+
[Verify]
|
|
36
|
+
6. browser_take_screenshot → 결과 캡처
|
|
37
|
+
7. browser_network_requests → POST /api/v1/items 확인
|
|
38
|
+
8. browser_snapshot → DOM에 "Test" 존재 확인
|
|
39
|
+
|
|
40
|
+
[Verdict]
|
|
41
|
+
Result: PASS / FAIL
|
|
42
|
+
Evidence: [스크린샷, 네트워크, 스냅샷]
|
|
43
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Scoring Rubric — Functional Evaluation
|
|
2
|
+
|
|
3
|
+
## 차원별 채점
|
|
4
|
+
|
|
5
|
+
| 차원 | 가중치 | 하드 임계값 | 측정 방법 |
|
|
6
|
+
|------|--------|------------|----------|
|
|
7
|
+
| Contract 충족률 | 40% | 80% | 통과 기준 수 / 전체 기준 수 |
|
|
8
|
+
| API 계약 준수 | 25% | 100% | api-contract.json 불일치 = 즉시 FAIL |
|
|
9
|
+
| 에러 내성 | 20% | 6/10 | 에러 시나리오 처리 수준 |
|
|
10
|
+
| 콘솔 청결 | 15% | JS 에러 0개 | 콘솔 에러 개수 |
|
|
11
|
+
|
|
12
|
+
**어떤 차원이든 하드 임계값 미달 → 스프린트 FAIL**
|
|
13
|
+
|
|
14
|
+
## evaluation-functional.md 출력 형식
|
|
15
|
+
|
|
16
|
+
```markdown
|
|
17
|
+
# Functional Evaluation: Sprint [N]
|
|
18
|
+
|
|
19
|
+
## Date: [날짜]
|
|
20
|
+
## Verdict: PASS / FAIL
|
|
21
|
+
## Attempt: [N] / 3
|
|
22
|
+
|
|
23
|
+
## Step 0: IA Structure Compliance
|
|
24
|
+
- Verdict: PASS / FAIL (GATE)
|
|
25
|
+
|
|
26
|
+
## Regression Test
|
|
27
|
+
| Previous Feature | Status | Note |
|
|
28
|
+
|
|
29
|
+
## Contract Criteria Results
|
|
30
|
+
| # | Criterion | Result | Failure Location | Evidence |
|
|
31
|
+
|
|
32
|
+
## API Contract Compliance
|
|
33
|
+
| EP ID | Method + Path | Schema Match | Issues |
|
|
34
|
+
|
|
35
|
+
## Scores
|
|
36
|
+
| Dimension | Score | Threshold | Status |
|
|
37
|
+
|
|
38
|
+
## Failures Detail
|
|
39
|
+
### [#N] [기준명]
|
|
40
|
+
- **failure_location**: backend / frontend
|
|
41
|
+
- **Expected**: ...
|
|
42
|
+
- **Actual**: ...
|
|
43
|
+
- **Recommendation**: ...
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## failure_location 라우팅
|
|
47
|
+
|
|
48
|
+
| location | 재작업 대상 |
|
|
49
|
+
|----------|-----------|
|
|
50
|
+
| `backend` | Generator-Backend |
|
|
51
|
+
| `frontend` | Generator-Frontend |
|
|
52
|
+
| 혼합 | Backend 먼저 → Frontend |
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-evaluator-visual
|
|
3
|
+
description: "하네스 Visual Evaluator. Playwright MCP로 스크린샷, 반응형 검증, 접근성 트리 분석, AI슬롭 감지를 수행한다. Evaluator-Functional이 PASS한 후에만 실행. 기준 미달 = FAIL → Generator-Frontend 재작업."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Evaluator-Visual — Design & Accessibility
|
|
8
|
+
|
|
9
|
+
## Startup
|
|
10
|
+
|
|
11
|
+
1. `AGENTS.md` 읽기
|
|
12
|
+
2. `.harness/gotchas/evaluator-visual.md` 읽기 — **과거 실수 반복 금지**
|
|
13
|
+
3. `actions/evaluation-functional.md` — Verdict: PASS 확인
|
|
14
|
+
4. Frontend `http://localhost:5173` 실행 확인
|
|
15
|
+
|
|
16
|
+
## Evaluation Steps
|
|
17
|
+
|
|
18
|
+
1. **Full Page Capture** — 모든 라우트 Desktop 스크린샷
|
|
19
|
+
2. **Responsive Check** — 375px / 768px / 1280px 3 breakpoint
|
|
20
|
+
3. **Design Consistency** — 색상, 타이포, 간격, 모서리 통일성
|
|
21
|
+
4. **AI Slop Detection** — 감점 패턴 감지
|
|
22
|
+
5. **Accessibility** — 시맨틱 HTML, 키보드 네비게이션, 색상 대비
|
|
23
|
+
|
|
24
|
+
반응형 체크리스트 → [참조](references/responsive-checklist.md)
|
|
25
|
+
채점 기준 → [스코어링 루브릭](references/scoring-rubric.md)
|
|
26
|
+
|
|
27
|
+
## Scoring
|
|
28
|
+
|
|
29
|
+
| 차원 | 가중치 | 하드 임계값 |
|
|
30
|
+
|------|--------|------------|
|
|
31
|
+
| Design Consistency | 30% | 6/10 |
|
|
32
|
+
| Responsiveness | 25% | 7/10 |
|
|
33
|
+
| Accessibility | 25% | 6/10 |
|
|
34
|
+
| Originality | 20% | 5/10 |
|
|
35
|
+
|
|
36
|
+
**어떤 차원이든 하드 임계값 미달 → FAIL**
|
|
37
|
+
|
|
38
|
+
## After Evaluation
|
|
39
|
+
|
|
40
|
+
- **PASS** → progress.txt 업데이트, Archive 실행 요청
|
|
41
|
+
- **FAIL** → Generator-Frontend 재작업 (비주얼=항상 프론트), max 3회
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Responsive Checklist
|
|
2
|
+
|
|
3
|
+
## Breakpoints
|
|
4
|
+
|
|
5
|
+
| Breakpoint | Size | 검증 항목 |
|
|
6
|
+
|------------|------|----------|
|
|
7
|
+
| Mobile | 375x812 | 단일 컬럼, 터치 타겟 44px+, 햄버거 메뉴 |
|
|
8
|
+
| Tablet | 768x1024 | 적응형 레이아웃, 사이드바 토글 |
|
|
9
|
+
| Desktop | 1280x720 | 풀 레이아웃, 사이드바 상시 표시 |
|
|
10
|
+
|
|
11
|
+
## 검증 절차
|
|
12
|
+
|
|
13
|
+
각 breakpoint에서 모든 페이지:
|
|
14
|
+
```
|
|
15
|
+
1. browser_resize → 해당 크기
|
|
16
|
+
2. browser_take_screenshot → 캡처
|
|
17
|
+
3. browser_snapshot → 레이아웃 구조 확인
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 확인 항목
|
|
21
|
+
|
|
22
|
+
- [ ] 콘텐츠 잘림 / 오버플로우 없음
|
|
23
|
+
- [ ] 가로 스크롤 없음
|
|
24
|
+
- [ ] 텍스트 가독성 (mobile 최소 14px)
|
|
25
|
+
- [ ] 터치 타겟 크기 (mobile 44px+)
|
|
26
|
+
- [ ] 네비게이션 접근성
|
|
27
|
+
|
|
28
|
+
## 키보드 네비게이션
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
1. browser_press_key → Tab (반복)
|
|
32
|
+
2. 포커스 이동 순서 논리적인지 확인
|
|
33
|
+
3. browser_press_key → Enter (인터랙티브 요소 활성화)
|
|
34
|
+
4. browser_press_key → Escape (모달 닫기)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 접근성 트리 (browser_snapshot)
|
|
38
|
+
|
|
39
|
+
확인:
|
|
40
|
+
- 시맨틱: button, nav, main, header, footer, form
|
|
41
|
+
- heading 순서: h1 → h2 → h3 (건너뛰기 없음)
|
|
42
|
+
- 인터랙티브 요소에 접근 가능한 이름
|
|
43
|
+
- 이미지 alt 텍스트
|
|
44
|
+
- 폼 label 연결
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Scoring Rubric — Visual Evaluation
|
|
2
|
+
|
|
3
|
+
## 차원별 채점
|
|
4
|
+
|
|
5
|
+
| 차원 | 가중치 | 하드 임계값 |
|
|
6
|
+
|------|--------|------------|
|
|
7
|
+
| Design Consistency | 30% | 6/10 |
|
|
8
|
+
| Responsiveness | 25% | 7/10 |
|
|
9
|
+
| Accessibility | 25% | 6/10 |
|
|
10
|
+
| Originality | 20% | 5/10 |
|
|
11
|
+
|
|
12
|
+
**어떤 차원이든 하드 임계값 미달 → FAIL**
|
|
13
|
+
|
|
14
|
+
## AI Slop 감점표
|
|
15
|
+
|
|
16
|
+
| 패턴 | 감점 |
|
|
17
|
+
|------|------|
|
|
18
|
+
| 보라색/파란색 그라디언트 + 흰 카드 | -2 |
|
|
19
|
+
| 과도한 box-shadow 남발 | -1 |
|
|
20
|
+
| 기본 아이콘팩 무분별 사용 | -1 |
|
|
21
|
+
| "Welcome to [AppName]" 히어로 | -1 |
|
|
22
|
+
| 둥근 아바타 + 카드 그리드 | -1 |
|
|
23
|
+
| 전체 fade-in 애니메이션 | -1 |
|
|
24
|
+
| 과도한 보더/구분선 | -1 |
|
|
25
|
+
|
|
26
|
+
## evaluation-visual.md 출력 형식
|
|
27
|
+
|
|
28
|
+
```markdown
|
|
29
|
+
# Visual Evaluation: Sprint [N]
|
|
30
|
+
|
|
31
|
+
## Date / Verdict / Attempt
|
|
32
|
+
|
|
33
|
+
## Responsive Check
|
|
34
|
+
| Page | Mobile (375) | Tablet (768) | Desktop (1280) | Issues |
|
|
35
|
+
|
|
36
|
+
## Design Consistency
|
|
37
|
+
- Color Palette: [통일/혼재]
|
|
38
|
+
- Typography Scale: [일관/불일관]
|
|
39
|
+
- Spacing System: [체계적/비체계적]
|
|
40
|
+
- Border Radius: [통일/혼재]
|
|
41
|
+
|
|
42
|
+
## AI Slop Detection
|
|
43
|
+
| Pattern | Found | Deduction |
|
|
44
|
+
| **Total Deduction** | | **-X** |
|
|
45
|
+
|
|
46
|
+
## Accessibility
|
|
47
|
+
- Semantic HTML: PASS/FAIL
|
|
48
|
+
- Heading Order: PASS/FAIL
|
|
49
|
+
- Keyboard Navigation: PASS/FAIL
|
|
50
|
+
- Color Contrast: PASS/FAIL
|
|
51
|
+
- Form Labels: PASS/FAIL
|
|
52
|
+
|
|
53
|
+
## Scores
|
|
54
|
+
| Dimension | Score | Threshold | Status |
|
|
55
|
+
|
|
56
|
+
## Failures Detail
|
|
57
|
+
### [차원명]
|
|
58
|
+
- Issue / Screenshot / Recommendation
|
|
59
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-generator-backend
|
|
3
|
+
description: "하네스 Backend Generator. NestJS MSA 모노레포로 API Gateway, Microservices, DB 스키마를 구현한다. api-contract.json이 스펙이며, Sprint Contract의 Backend 섹션을 작성 후 구현한다."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Generator-Backend — NestJS MSA
|
|
8
|
+
|
|
9
|
+
## Startup
|
|
10
|
+
|
|
11
|
+
1. `AGENTS.md` 읽기 — IA-MAP, 권한 확인
|
|
12
|
+
2. `.harness/gotchas/generator-backend.md` 읽기 — **과거 실수 반복 금지**
|
|
13
|
+
3. `pwd` + `.harness/progress.txt` + `git log --oneline -20`
|
|
14
|
+
4. `.harness/actions/api-contract.json` 읽기 — **이것이 스펙**
|
|
15
|
+
5. `.harness/actions/feature-list.json` — `layer: "backend"` 필터
|
|
16
|
+
6. 통합 러너: `npm run dev`
|
|
17
|
+
7. Gateway 헬스체크: `curl http://localhost:3000/health`
|
|
18
|
+
|
|
19
|
+
## AGENTS.md — 읽기 전용
|
|
20
|
+
|
|
21
|
+
`[BE]` + `→ Generator-Backend` 소유 경로만 쓰기 가능. 구조 변경 필요 시 sprint-contract.md에 `## Change Request`.
|
|
22
|
+
|
|
23
|
+
## Sprint Workflow
|
|
24
|
+
|
|
25
|
+
1. **Sprint Contract BE 섹션 작성** — 엔드포인트, DB 변경, message patterns, 성공 기준
|
|
26
|
+
2. **구현** — Gateway 컨트롤러 + Microservice 핸들러 + Shared DTO
|
|
27
|
+
3. **Self-Verification** — Jest + curl 테스트
|
|
28
|
+
4. **Handoff** → Generator-Frontend
|
|
29
|
+
|
|
30
|
+
NestJS MSA 패턴 → [NestJS MSA 참조](references/nestjs-msa-patterns.md)
|
|
31
|
+
Sprint Contract 형식 → [Sprint Contract BE 템플릿](references/sprint-contract-be.md)
|
|
32
|
+
|
|
33
|
+
## 금지 사항
|
|
34
|
+
|
|
35
|
+
- api-contract.json에 없는 엔드포인트 추가
|
|
36
|
+
- Frontend(apps/web/) 코드 수정
|
|
37
|
+
- feature-list.json에서 `passes` 외 필드 수정
|
|
38
|
+
- 서비스 간 직접 DB 접근 (반드시 메시지 패턴)
|
|
39
|
+
- AGENTS.md 수정
|
|
40
|
+
|
|
41
|
+
## On Evaluator Feedback
|
|
42
|
+
|
|
43
|
+
`evaluation-functional.md` → `failure_location: "backend"` 필터 → 수정 → Jest 재실행 → 핸드오프
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# NestJS MSA Patterns
|
|
2
|
+
|
|
3
|
+
## 모노레포 구조
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
apps/
|
|
7
|
+
├── gateway/ # API Gateway (port 3000)
|
|
8
|
+
│ └── src/
|
|
9
|
+
│ ├── main.ts # bootstrap, CORS
|
|
10
|
+
│ ├── app.module.ts # ClientsModule 등록
|
|
11
|
+
│ ├── controllers/ # HTTP → MessagePattern 변환
|
|
12
|
+
│ └── guards/
|
|
13
|
+
├── service-[name]/ # Microservice (TCP)
|
|
14
|
+
│ └── src/
|
|
15
|
+
│ ├── main.ts # TCP bootstrap
|
|
16
|
+
│ ├── [name].module.ts
|
|
17
|
+
│ ├── [name].controller.ts # @MessagePattern 핸들러
|
|
18
|
+
│ ├── [name].service.ts
|
|
19
|
+
│ └── entities/
|
|
20
|
+
└── web/ # (Frontend — 별도 에이전트)
|
|
21
|
+
|
|
22
|
+
libs/
|
|
23
|
+
├── shared-dto/ # api-contract.json에서 파생
|
|
24
|
+
├── database/ # TypeORM/Prisma 설정
|
|
25
|
+
└── common/ # 필터, 인터셉터, 가드
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 통합 러너 (package.json)
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "concurrently \"npm run start:gateway\" \"npm run start:service-a\"",
|
|
34
|
+
"start:gateway": "nest start gateway --watch",
|
|
35
|
+
"start:service-a": "nest start service-a --watch"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Gateway ↔ Microservice 패턴
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// apps/gateway/src/controllers/items.controller.ts
|
|
44
|
+
@Controller('api/v1/items')
|
|
45
|
+
export class ItemsController {
|
|
46
|
+
constructor(@Inject('SERVICE_A') private readonly serviceA: ClientProxy) {}
|
|
47
|
+
|
|
48
|
+
@Post()
|
|
49
|
+
create(@Body() dto: CreateItemDto) {
|
|
50
|
+
return this.serviceA.send({ cmd: 'create_item' }, dto);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// apps/service-a/src/items.controller.ts
|
|
55
|
+
@Controller()
|
|
56
|
+
export class ItemsController {
|
|
57
|
+
@MessagePattern({ cmd: 'create_item' })
|
|
58
|
+
create(dto: CreateItemDto) {
|
|
59
|
+
return this.service.create(dto);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 규칙
|
|
65
|
+
|
|
66
|
+
- Gateway = 라우팅 + 검증만, 비즈니스 로직은 서비스에서
|
|
67
|
+
- 서비스 간 통신: `ClientProxy.send()` (요청-응답)
|
|
68
|
+
- CORS: Gateway에서 `localhost:5173` 허용
|
|
69
|
+
- 각 서비스 독립 기동 가능해야 함
|