@walwal-harness/cli 4.0.0-alpha.2 → 4.0.0-alpha.20
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/README.md +226 -273
- package/assets/templates/config.json +1 -48
- package/assets/templates/gitignore-append.txt +1 -0
- package/bin/init.js +1 -0
- package/package.json +1 -1
- package/scripts/harness-dashboard-v4.sh +58 -81
- package/scripts/harness-next.sh +4 -15
- package/scripts/harness-prompts-v4.sh +106 -0
- package/scripts/harness-queue-manager.sh +59 -5
- package/scripts/harness-session-start.sh +18 -0
- package/scripts/harness-studio-v4.sh +69 -69
- package/scripts/harness-team-worker.sh +136 -123
- package/scripts/harness-user-prompt-submit.sh +31 -1
- package/skills/dispatcher/SKILL.md +7 -2
- package/skills/evaluator-functional-flutter/SKILL.md +0 -206
- package/skills/evaluator-functional-flutter/references/ia-compliance.md +0 -77
- package/skills/evaluator-functional-flutter/references/scoring-rubric.md +0 -132
- package/skills/evaluator-functional-flutter/references/static-check-rules.md +0 -99
- package/skills/generator-frontend-flutter/SKILL.md +0 -173
- package/skills/generator-frontend-flutter/references/anti-patterns.md +0 -320
- package/skills/generator-frontend-flutter/references/api-layer-pattern.md +0 -233
- package/skills/generator-frontend-flutter/references/flutter-web-pattern.md +0 -273
- package/skills/generator-frontend-flutter/references/i18n-pattern.md +0 -102
- package/skills/generator-frontend-flutter/references/riverpod-pattern.md +0 -199
|
@@ -25,8 +25,13 @@ disable-model-invocation: false
|
|
|
25
25
|
- `pipeline` → 선택된 파이프라인 (FULLSTACK/FE-ONLY/BE-ONLY)
|
|
26
26
|
- `sprint.number` → `1`, `sprint.status` → `"in_progress"` (신규 파이프라인인 경우에만)
|
|
27
27
|
2. `.harness/progress.log`에 요약 한 줄 추가
|
|
28
|
-
3. **
|
|
29
|
-
|
|
28
|
+
3. **v4 모드 감지**: `.harness/actions/feature-queue.json` 파일이 존재하는지 확인
|
|
29
|
+
- **존재**: v4 Parallel Agent Teams 활성 상태. 별도 안내 없이 즉시 STOP.
|
|
30
|
+
출력: `"✓ Dispatcher 완료. Agent Teams가 자율 실행 중입니다."`
|
|
31
|
+
- **미존재**: v3 Classic 모드.
|
|
32
|
+
출력: `"✓ Dispatcher 완료. bash scripts/harness-next.sh 실행하여 다음 단계 확인."`
|
|
33
|
+
4. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
|
|
34
|
+
- v4 모드에서는 `/harness-team 실행하시겠습니까?` 같은 **질문을 하지 않는다**. Teams는 이미 실행 중이거나 사용자가 별도로 시작한다.
|
|
30
35
|
|
|
31
36
|
## Auto-Routing (UserPromptSubmit Hook)
|
|
32
37
|
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: harness-evaluator-functional-flutter
|
|
3
|
-
description: "하네스 Flutter Functional Evaluator. Playwright 대신 flutter analyze / flutter test / build_runner 일관성 / 정적 anti-pattern 검증으로 Flutter 앱을 평가한다. Step 0 IA Gate → Step 1-6 정적/동적 검증. 기준 미달 = FAIL."
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Evaluator-Functional-Flutter — Dart/Flutter 정적·동적 검증
|
|
8
|
-
|
|
9
|
-
> **이 에이전트는 `fe_target = mobile` 또는 `desktop` 일 때만 사용된다.**
|
|
10
|
-
>
|
|
11
|
-
> Flutter Mobile/Desktop 앱은 브라우저가 아니므로 Playwright MCP(`browser_*`)를 쓸 수 없다.
|
|
12
|
-
> 이 에이전트는 `flutter analyze`, `flutter test`, `dart format`, 정적 grep 검증, 생성 파일
|
|
13
|
-
> 일관성으로 평가한다. 실기기/시뮬레이터 UI 검증은 사람 QA 또는 별도 파이프라인으로 위임.
|
|
14
|
-
>
|
|
15
|
-
> **`fe_target = web` 인 Flutter Web 프로젝트는 이 에이전트가 아니라 일반 `evaluator-functional`
|
|
16
|
-
> 과 `evaluator-visual` 이 Playwright 로 검증한다** (컴파일 결과가 HTML+JS+CSS 이므로).
|
|
17
|
-
> 이 경우 Generator-Frontend-Flutter 의 Self-Verification 단계에서 `flutter analyze` /
|
|
18
|
-
> `flutter test` / `flutter build web --release` 가 이미 통과했음이 전제된다.
|
|
19
|
-
|
|
20
|
-
## Session Boundary Protocol
|
|
21
|
-
|
|
22
|
-
### On Start
|
|
23
|
-
1. `.harness/progress.json` 읽기 — `next_agent`가 `"evaluator-functional-flutter"`인지 확인
|
|
24
|
-
2. `.harness/actions/pipeline.json.fe_stack == "flutter"` 재확인 — 아니면 즉시 STOP + 불일치 보고
|
|
25
|
-
3. progress.json 업데이트: `current_agent` → `"evaluator-functional-flutter"`, `agent_status` → `"running"`, `updated_at` 갱신
|
|
26
|
-
|
|
27
|
-
### On Complete (PASS)
|
|
28
|
-
1. progress.json 업데이트:
|
|
29
|
-
- `agent_status` → `"completed"`
|
|
30
|
-
- `completed_agents`에 `"evaluator-functional-flutter"` 추가
|
|
31
|
-
- `next_agent` → `"archive"` (fe_stack=flutter 이면 evaluator-visual 생략)
|
|
32
|
-
- `failure` 필드 초기화
|
|
33
|
-
2. `feature-list.json`의 통과 feature `passes`에 `"evaluator-functional-flutter"` 추가
|
|
34
|
-
3. `.harness/progress.log`에 PASS 요약 추가
|
|
35
|
-
4. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
|
|
36
|
-
5. 출력: `"✓ Evaluator-Functional-Flutter PASS. bash scripts/harness-next.sh 실행하여 다음 단계 확인."`
|
|
37
|
-
|
|
38
|
-
### On Fail
|
|
39
|
-
1. progress.json 업데이트:
|
|
40
|
-
- `agent_status` → `"failed"`
|
|
41
|
-
- `failure.agent` → `"evaluator-functional-flutter"`
|
|
42
|
-
- `failure.location` → `"frontend"` (Flutter 앱은 항상 FE 재작업)
|
|
43
|
-
- `failure.message` → 실패 요약 (1줄)
|
|
44
|
-
- `failure.retry_target` → `"generator-frontend-flutter"`
|
|
45
|
-
- `next_agent` → `"generator-frontend-flutter"`
|
|
46
|
-
- `sprint.retry_count` 증가
|
|
47
|
-
2. `sprint.retry_count >= 10`이면 `agent_status` → `"blocked"`, 사용자 개입 요청
|
|
48
|
-
3. `.harness/progress.log`에 FAIL 요약 추가
|
|
49
|
-
4. **STOP.**
|
|
50
|
-
5. 출력: `"✖ Evaluator-Functional-Flutter FAIL. bash scripts/harness-next.sh 실행하여 재작업 대상 확인."`
|
|
51
|
-
|
|
52
|
-
## Critical Mindset
|
|
53
|
-
|
|
54
|
-
- **회의적 평가자**. Generator의 자체 평가를 신뢰하지 말고 직접 돌려라.
|
|
55
|
-
- `flutter analyze` 경고가 있으면 "사소하다"고 자기 설득 금지 — 기준 미달.
|
|
56
|
-
- 코드 읽기만으로 PASS 판정 금지 — **반드시 `flutter analyze` + `flutter test` 실행**.
|
|
57
|
-
- 기준 미달 = FAIL. 예외 없음.
|
|
58
|
-
|
|
59
|
-
## Startup
|
|
60
|
-
|
|
61
|
-
1. `AGENTS.md` 읽기 — IA-MAP (Flutter 경로 확인)
|
|
62
|
-
2. `.harness/gotchas/evaluator-functional-flutter.md` (없으면 skip) — **과거 실수 반복 금지**
|
|
63
|
-
3. `.harness/memory.md` 읽기 — **프로젝트 공유 학습 규칙 적용**
|
|
64
|
-
4. `actions/sprint-contract.md` — FE 성공 기준
|
|
65
|
-
5. `actions/feature-list.json` — 이번 스프린트 범위 (`layer: "frontend"` + `fe_stack: "flutter"`)
|
|
66
|
-
6. `actions/api-contract.json` — 기대 API 계약 (Retrofit 매핑 대조용)
|
|
67
|
-
7. `.harness/progress.json`
|
|
68
|
-
8. **Generator의 anti-patterns.md 로드** — 정적 검증 rule 소스
|
|
69
|
-
→ `skills/generator-frontend-flutter/references/anti-patterns.md`
|
|
70
|
-
|
|
71
|
-
## Evaluation Steps
|
|
72
|
-
|
|
73
|
-
### Step 0: IA Structure Compliance (GATE)
|
|
74
|
-
|
|
75
|
-
AGENTS.md IA-MAP vs 실제 구조 대조. **미통과 시 이하 전체 SKIP, 즉시 FAIL.**
|
|
76
|
-
|
|
77
|
-
상세 → [IA 검증 가이드](references/ia-compliance.md)
|
|
78
|
-
|
|
79
|
-
### Step 1: `flutter analyze` (정적 분석)
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
# 프로젝트 루트 또는 integrated_data_layer 하위에서
|
|
83
|
-
flutter analyze --no-fatal-infos
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- **warning / error 1개 이상 → FAIL**
|
|
87
|
-
- info 수준은 허용 (하지만 evaluation 보고서에 카운트 기록)
|
|
88
|
-
|
|
89
|
-
### Step 2: `flutter test` (단위/위젯 테스트)
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
# integrated_data_layer 테스트
|
|
93
|
-
cd <integrated_data_layer 경로>
|
|
94
|
-
flutter test
|
|
95
|
-
|
|
96
|
-
# 앱 테스트 (존재 시)
|
|
97
|
-
cd <app 루트>
|
|
98
|
-
flutter test
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
- **실패 1개 이상 → FAIL**
|
|
102
|
-
- 이번 스프린트에서 추가된 Request Body / Response에 `fromJson`/`toJson` 왕복 테스트 **존재 확인**
|
|
103
|
-
- 누락 시 → FAIL (Coverage gate)
|
|
104
|
-
|
|
105
|
-
### Step 3: build_runner 일관성
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
cd <integrated_data_layer 경로>
|
|
109
|
-
flutter pub run build_runner build --delete-conflicting-outputs
|
|
110
|
-
git diff --name-only
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
- 재생성 후 `*.g.dart` diff 가 발생하면 → **FAIL** (Generator가 수동 편집 또는 재생성 누락)
|
|
114
|
-
|
|
115
|
-
### Step 4: Anti-Pattern 정적 검증
|
|
116
|
-
|
|
117
|
-
`skills/generator-frontend-flutter/references/anti-patterns.md` 의 **"셀프 체크 스크립트"** 섹션을
|
|
118
|
-
그대로 실행한다. 하나라도 결과가 있으면 → **FAIL**.
|
|
119
|
-
|
|
120
|
-
상세 → [정적 검증 룰](references/static-check-rules.md)
|
|
121
|
-
|
|
122
|
-
### Step 5: API Contract Compliance
|
|
123
|
-
|
|
124
|
-
`api-contract.json` 의 엔드포인트 vs `rest_api.dart` 의 Retrofit 어노테이션 대조:
|
|
125
|
-
|
|
126
|
-
- 계약에 있는 모든 엔드포인트가 `rest_api.dart` 에 존재하는가
|
|
127
|
-
- method, path, path param, body 타입이 일치하는가
|
|
128
|
-
- Response 타입이 계약 스키마와 구조적으로 일치하는가 (필드 존재 + nullable 여부)
|
|
129
|
-
- **불일치 1개 이상 → FAIL**
|
|
130
|
-
|
|
131
|
-
### Step 6: Sprint Contract Criteria
|
|
132
|
-
|
|
133
|
-
`sprint-contract.md` 의 FE 성공 기준을 순서대로 검증:
|
|
134
|
-
|
|
135
|
-
- 새 페이지가 `xxx_page.dart` + `xxx_page_vm.dart` 쌍으로 존재하는가
|
|
136
|
-
- VM이 `NotifierProvider` 를 사용하는가
|
|
137
|
-
- i18n 키가 모든 arb 파일에 등록되었는가
|
|
138
|
-
- 기준별 PASS/FAIL 기록 → 충족률 계산
|
|
139
|
-
|
|
140
|
-
## Scoring
|
|
141
|
-
|
|
142
|
-
| 차원 | 가중치 | 하드 임계값 | 측정 방법 |
|
|
143
|
-
|------|--------|------------|----------|
|
|
144
|
-
| Static Analysis | 25% | warning/error 0개 | `flutter analyze` |
|
|
145
|
-
| Test Pass Rate | 25% | 100% | `flutter test` |
|
|
146
|
-
| API Contract 준수 | 25% | 100% | rest_api.dart vs api-contract.json |
|
|
147
|
-
| Anti-Pattern 청결 | 15% | 위반 0건 | 정적 grep |
|
|
148
|
-
| Contract Criteria 충족률 | 10% | 80% | sprint-contract 기준 |
|
|
149
|
-
|
|
150
|
-
**어떤 차원이든 하드 임계값 미달 → 스프린트 FAIL**
|
|
151
|
-
|
|
152
|
-
상세 채점 → [스코어링 루브릭](references/scoring-rubric.md)
|
|
153
|
-
|
|
154
|
-
## evaluation-functional.md 출력
|
|
155
|
-
|
|
156
|
-
```markdown
|
|
157
|
-
# Flutter Functional Evaluation: Sprint [N]
|
|
158
|
-
|
|
159
|
-
## Date: [날짜]
|
|
160
|
-
## Verdict: PASS / FAIL
|
|
161
|
-
## Attempt: [N] / 10
|
|
162
|
-
## Stack: flutter
|
|
163
|
-
|
|
164
|
-
## Step 0: IA Structure Compliance
|
|
165
|
-
- Verdict: PASS / FAIL (GATE)
|
|
166
|
-
|
|
167
|
-
## Step 1: Flutter Analyze
|
|
168
|
-
- errors: [N]
|
|
169
|
-
- warnings: [N]
|
|
170
|
-
- infos: [N]
|
|
171
|
-
|
|
172
|
-
## Step 2: Flutter Test
|
|
173
|
-
- total: [N], passed: [N], failed: [N]
|
|
174
|
-
- missing_roundtrip_tests: [목록]
|
|
175
|
-
|
|
176
|
-
## Step 3: build_runner 일관성
|
|
177
|
-
- drift: [none | 목록]
|
|
178
|
-
|
|
179
|
-
## Step 4: Anti-Pattern
|
|
180
|
-
| Rule | Count | Files |
|
|
181
|
-
| dart:html | 0 | - |
|
|
182
|
-
| print() | 0 | - |
|
|
183
|
-
| Color(0x...) in 신규 | 0 | - |
|
|
184
|
-
| bridges/ 신규 | 0 | - |
|
|
185
|
-
| Text('한글') 신규 | 0 | - |
|
|
186
|
-
|
|
187
|
-
## Step 5: API Contract Compliance
|
|
188
|
-
| EP ID | Method + Path | Dart Match | Issues |
|
|
189
|
-
|
|
190
|
-
## Step 6: Contract Criteria Results
|
|
191
|
-
| # | Criterion | Result | Evidence |
|
|
192
|
-
|
|
193
|
-
## Scores
|
|
194
|
-
| Dimension | Score | Threshold | Status |
|
|
195
|
-
|
|
196
|
-
## Failures Detail
|
|
197
|
-
### [#N] [기준/항목]
|
|
198
|
-
- **Expected**: ...
|
|
199
|
-
- **Actual**: ...
|
|
200
|
-
- **Recommendation**: ...
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## After Evaluation
|
|
204
|
-
|
|
205
|
-
- **PASS** → Session Boundary Protocol On Complete (PASS) 실행
|
|
206
|
-
- **FAIL** → Session Boundary Protocol On Fail 실행 (retry_target = generator-frontend-flutter)
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docmeta:
|
|
3
|
-
id: ia-compliance
|
|
4
|
-
title: IA Structure Compliance — Step 0 (Gate) for Flutter
|
|
5
|
-
type: output
|
|
6
|
-
createdAt: 2026-04-09T00:00:00Z
|
|
7
|
-
updatedAt: 2026-04-09T00:00:00Z
|
|
8
|
-
source:
|
|
9
|
-
producer: agent
|
|
10
|
-
skillId: harness-evaluator-functional-flutter
|
|
11
|
-
inputs:
|
|
12
|
-
- documentId: evaluator-functional-ia-compliance
|
|
13
|
-
uri: ../../evaluator-functional/references/ia-compliance.md
|
|
14
|
-
relation: output-from
|
|
15
|
-
sections:
|
|
16
|
-
- sourceRange:
|
|
17
|
-
startLine: 1
|
|
18
|
-
endLine: 37
|
|
19
|
-
targetRange:
|
|
20
|
-
startLine: 32
|
|
21
|
-
endLine: 120
|
|
22
|
-
tags:
|
|
23
|
-
- evaluator
|
|
24
|
-
- flutter
|
|
25
|
-
- ia-compliance
|
|
26
|
-
- gate
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# IA Structure Compliance — Step 0 (Gate) for Flutter
|
|
30
|
-
|
|
31
|
-
## 검증 방법
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# 1. 실제 Flutter 구조 확인
|
|
35
|
-
ls -R lib/ integrated_data_layer/lib/ 2>/dev/null
|
|
36
|
-
|
|
37
|
-
# 2. git diff로 소유권 위반 검출 (이번 스프린트 범위)
|
|
38
|
-
git log --name-only --pretty=format: HEAD~[sprint_commits].. | sort -u
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## 검증 항목
|
|
42
|
-
|
|
43
|
-
| 검증 | 판정 | 예시 |
|
|
44
|
-
|------|------|------|
|
|
45
|
-
| IA-MAP 경로가 실제 존재하는가 | 누락 → FAIL | `lib/ui/pages/` 미생성 |
|
|
46
|
-
| IA-MAP에 없는 경로가 생겼는가 | 미등록 → DRIFT 기록 | `lib/services/` 무단 생성 |
|
|
47
|
-
| `[FE]` 소유를 BE가 수정했는가 | 침범 → FAIL | `lib/ui/` BE 수정 |
|
|
48
|
-
| `[META]`/`[HARNESS]` 침범 | 침범 → FAIL | `AGENTS.md` 수정 |
|
|
49
|
-
| `pubspec.yaml` 의존성 추가가 계약 범위 내인가 | 범위 이탈 → DRIFT 기록 | 승인 없는 의존성 추가 |
|
|
50
|
-
|
|
51
|
-
## Flutter 전용 추가 검증
|
|
52
|
-
|
|
53
|
-
| 검증 | 판정 |
|
|
54
|
-
|------|------|
|
|
55
|
-
| `integrated_data_layer/lib/2_data_sources/remote/` 내 파일이 프로젝트 컨벤션(`request/body/`, `response/`, `rest_api.dart`)을 지키는가 | 위반 → FAIL |
|
|
56
|
-
| `lib/ui/pages/` 내 새 페이지가 `xxx_page.dart` + `xxx_page_vm.dart` 쌍으로 존재하는가 | 파트너 누락 → FAIL |
|
|
57
|
-
| `bridges/` 하위에 신규 파일이 추가되었는가 | 추가 → FAIL (레거시 금지) |
|
|
58
|
-
| `lib/l10n/` 의 arb 파일 키 집합이 모든 언어에서 동일한가 | 불일치 → FAIL |
|
|
59
|
-
|
|
60
|
-
## 판정 규칙
|
|
61
|
-
|
|
62
|
-
- **경로 누락 / 소유권 침범 / 파트너 누락** → 즉시 FAIL, Step 1 이하 SKIP
|
|
63
|
-
- **미등록 경로 (Drift)** → FAIL 아님, evaluation에 `## AGENTS.md Drift` 기록
|
|
64
|
-
- **arb 키 불일치** → FAIL (i18n 원칙 위반)
|
|
65
|
-
|
|
66
|
-
## Output (evaluation-functional.md에 포함)
|
|
67
|
-
|
|
68
|
-
```markdown
|
|
69
|
-
## Step 0: IA Structure Compliance
|
|
70
|
-
- Verdict: PASS / FAIL (GATE)
|
|
71
|
-
- IA-MAP paths checked: [N]개
|
|
72
|
-
- Missing paths: [목록 또는 "none"]
|
|
73
|
-
- Unregistered paths: [목록 또는 "none"]
|
|
74
|
-
- Ownership violations: [목록 또는 "none"]
|
|
75
|
-
- Page/VM pair check: [N pages checked, N missing partners]
|
|
76
|
-
- arb key diff: [none | "app_ja.arb missing: cancel, confirm"]
|
|
77
|
-
```
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docmeta:
|
|
3
|
-
id: scoring-rubric
|
|
4
|
-
title: Flutter Functional Evaluation 스코어링 루브릭
|
|
5
|
-
type: output
|
|
6
|
-
createdAt: 2026-04-09T00:00:00Z
|
|
7
|
-
updatedAt: 2026-04-09T00:00:00Z
|
|
8
|
-
source:
|
|
9
|
-
producer: agent
|
|
10
|
-
skillId: harness-evaluator-functional-flutter
|
|
11
|
-
inputs:
|
|
12
|
-
- documentId: react-evaluator-scoring-rubric
|
|
13
|
-
uri: ../../evaluator-functional/references/scoring-rubric.md
|
|
14
|
-
relation: output-from
|
|
15
|
-
sections:
|
|
16
|
-
- sourceRange:
|
|
17
|
-
startLine: 1
|
|
18
|
-
endLine: 53
|
|
19
|
-
targetRange:
|
|
20
|
-
startLine: 32
|
|
21
|
-
endLine: 160
|
|
22
|
-
tags:
|
|
23
|
-
- evaluator
|
|
24
|
-
- flutter
|
|
25
|
-
- scoring
|
|
26
|
-
- rubric
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# Flutter Functional Evaluation 스코어링 루브릭
|
|
30
|
-
|
|
31
|
-
## 차원별 채점
|
|
32
|
-
|
|
33
|
-
| 차원 | 가중치 | 하드 임계값 | 측정 방법 |
|
|
34
|
-
|------|--------|------------|----------|
|
|
35
|
-
| Static Analysis | 25% | warning/error 0개 | `flutter analyze --no-fatal-infos` |
|
|
36
|
-
| Test Pass Rate | 25% | 100% | `flutter test` 모든 스위트 |
|
|
37
|
-
| API Contract 준수 | 25% | 100% | rest_api.dart vs api-contract.json 대조 — 불일치 즉시 FAIL |
|
|
38
|
-
| Anti-Pattern 청결 | 15% | 위반 0건 | static-check-rules.md 의 FL-01 ~ FL-08 |
|
|
39
|
-
| Contract Criteria 충족률 | 10% | 80% | sprint-contract.md FE 기준 통과 수 / 전체 |
|
|
40
|
-
|
|
41
|
-
**어떤 차원이든 하드 임계값 미달 → 스프린트 FAIL**
|
|
42
|
-
|
|
43
|
-
## 차원별 점수 계산
|
|
44
|
-
|
|
45
|
-
### Static Analysis (25점)
|
|
46
|
-
|
|
47
|
-
| 결과 | 점수 |
|
|
48
|
-
|------|------|
|
|
49
|
-
| error 0, warning 0 | 25 |
|
|
50
|
-
| error 0, warning 1~2 | 0 (하드 임계값 미달 → FAIL) |
|
|
51
|
-
| error 1+ | 0 (즉시 FAIL) |
|
|
52
|
-
|
|
53
|
-
info 수준은 점수에 반영하지 않지만 보고서에 카운트 기록.
|
|
54
|
-
|
|
55
|
-
### Test Pass Rate (25점)
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
score = 25 * (passed / total)
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
- `total == 0` (테스트 존재하지 않음) → **0점 + FAIL** (Coverage gate)
|
|
62
|
-
- `fromJson/toJson` 왕복 테스트 누락 (이번 스프린트 추가분) → **FAIL**
|
|
63
|
-
|
|
64
|
-
### API Contract 준수 (25점)
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
score = 25 * (matched_endpoints / total_endpoints)
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
불일치 허용 없음 — 1개라도 불일치면 즉시 FAIL (하드 임계값 100%).
|
|
71
|
-
|
|
72
|
-
매칭 체크:
|
|
73
|
-
- method (GET/POST/PUT/DELETE)
|
|
74
|
-
- path (변수명 포함)
|
|
75
|
-
- path param → `@Path(...)` 매핑
|
|
76
|
-
- body → `@Body() XxxBody`
|
|
77
|
-
- response 타입 → 계약 스키마의 code/data/errors 구조
|
|
78
|
-
|
|
79
|
-
### Anti-Pattern 청결 (15점)
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
score = 15 * (passed_rules / total_rules)
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
- 8개 룰 중 1개라도 FAIL → **0점 + 스프린트 FAIL**
|
|
86
|
-
- 위반 0건이면 15점
|
|
87
|
-
|
|
88
|
-
### Contract Criteria 충족률 (10점)
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
score = 10 * (passed_criteria / total_criteria)
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
- 80% 미달 → FAIL
|
|
95
|
-
- 개별 기준의 실패 사유를 "Failures Detail"에 기록
|
|
96
|
-
|
|
97
|
-
## Total
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
total = static_analysis + test_pass + api_contract + anti_pattern + contract_criteria
|
|
101
|
-
verdict = PASS (if all hard thresholds met AND total >= 80) else FAIL
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## failure_location 라우팅
|
|
105
|
-
|
|
106
|
-
Flutter 앱은 항상 FE 재작업이므로:
|
|
107
|
-
|
|
108
|
-
| location | 재작업 대상 |
|
|
109
|
-
|----------|-----------|
|
|
110
|
-
| `frontend` (기본) | `generator-frontend-flutter` |
|
|
111
|
-
|
|
112
|
-
예외: API Contract 불일치가 **서버 측 계약 오류**로 확인된 경우 → Planner에게 계약 수정 요청 필요.
|
|
113
|
-
이 경우 evaluation에 `## Change Request` 섹션 추가.
|
|
114
|
-
|
|
115
|
-
## evaluation-functional.md 헤더
|
|
116
|
-
|
|
117
|
-
```markdown
|
|
118
|
-
# Flutter Functional Evaluation: Sprint [N]
|
|
119
|
-
|
|
120
|
-
## Date: [YYYY-MM-DD]
|
|
121
|
-
## Verdict: PASS / FAIL
|
|
122
|
-
## Attempt: [N] / 10
|
|
123
|
-
## Stack: flutter
|
|
124
|
-
|
|
125
|
-
## Total Score: [N] / 100
|
|
126
|
-
| Dimension | Score | Threshold | Status |
|
|
127
|
-
| Static Analysis | X/25 | warning=0 | PASS/FAIL |
|
|
128
|
-
| Test Pass Rate | X/25 | 100% | PASS/FAIL |
|
|
129
|
-
| API Contract | X/25 | 100% | PASS/FAIL |
|
|
130
|
-
| Anti-Pattern | X/15 | 0 violations | PASS/FAIL |
|
|
131
|
-
| Contract Criteria | X/10 | 80% | PASS/FAIL |
|
|
132
|
-
```
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docmeta:
|
|
3
|
-
id: static-check-rules
|
|
4
|
-
title: Flutter 정적 검증 룰 (Anti-Pattern Gate)
|
|
5
|
-
type: output
|
|
6
|
-
createdAt: 2026-04-09T00:00:00Z
|
|
7
|
-
updatedAt: 2026-04-09T00:00:00Z
|
|
8
|
-
source:
|
|
9
|
-
producer: agent
|
|
10
|
-
skillId: harness-evaluator-functional-flutter
|
|
11
|
-
inputs:
|
|
12
|
-
- documentId: flutter-anti-patterns
|
|
13
|
-
uri: ../../generator-frontend-flutter/references/anti-patterns.md
|
|
14
|
-
relation: output-from
|
|
15
|
-
sections:
|
|
16
|
-
- sourceRange:
|
|
17
|
-
startLine: 1
|
|
18
|
-
endLine: 280
|
|
19
|
-
targetRange:
|
|
20
|
-
startLine: 32
|
|
21
|
-
endLine: 180
|
|
22
|
-
tags:
|
|
23
|
-
- evaluator
|
|
24
|
-
- flutter
|
|
25
|
-
- static-check
|
|
26
|
-
- anti-pattern
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# Flutter 정적 검증 룰
|
|
30
|
-
|
|
31
|
-
Generator의 `anti-patterns.md` 를 Source of Truth 로 삼아 정적 검증을 수행한다.
|
|
32
|
-
Generator가 신규 룰을 추가하면 Evaluator는 자동으로 그 룰을 따르게 된다 — **두 문서 간 drift 금지.**
|
|
33
|
-
|
|
34
|
-
## 실행 방법
|
|
35
|
-
|
|
36
|
-
**Evaluator는 반드시** `skills/generator-frontend-flutter/references/anti-patterns.md` 의
|
|
37
|
-
"셀프 체크 스크립트" 섹션을 **파일로 읽어서 그대로 실행**한다. 하네스의 단일 진실 원칙.
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# anti-patterns.md 에서 bash 블록만 추출해서 실행
|
|
41
|
-
awk '/^```bash$/,/^```$/' skills/generator-frontend-flutter/references/anti-patterns.md
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## 룰 요약 (Evaluator가 결과를 표로 정리)
|
|
45
|
-
|
|
46
|
-
| Rule ID | 설명 | 명령 | Fail 조건 |
|
|
47
|
-
|---------|------|------|----------|
|
|
48
|
-
| FL-01 | 웹 API 직접 참조 | `grep -rn "dart:html\|universal_html" lib/ integrated_data_layer/lib/` | 매치 1+ |
|
|
49
|
-
| FL-02 | print/console 남발 | `grep -rn "^\s*print(" lib/ integrated_data_layer/lib/` | 매치 1+ |
|
|
50
|
-
| FL-03 | 하드코딩 색상 (신규) | `git diff --name-only --diff-filter=A HEAD~N..HEAD \| grep '\.dart$' \| xargs grep -n "Color(0x"` | 매치 1+ (`ColorManager` 참조 제외) |
|
|
51
|
-
| FL-04 | StatefulWidget 직접 API 호출 | 수동 감사 — `_page.dart` 에 `dataLayer\|DataLayer` 호출이 있는데 짝 `_page_vm.dart` 없음 | 패턴 발견 |
|
|
52
|
-
| FL-05 | bridges/ 신규 참조 | `git diff HEAD~N..HEAD \| grep "^+.*bridges/"` | 매치 1+ |
|
|
53
|
-
| FL-06 | 하드코딩 한글 (신규 UI) | `git diff --name-only --diff-filter=AM HEAD~N..HEAD \| grep 'lib/ui/.*\.dart$' \| xargs grep -n "Text('[가-힣]"` | 매치 1+ |
|
|
54
|
-
| FL-07 | JsonSerializable includeIfNull 누락 | `grep -rn "@JsonSerializable" integrated_data_layer/lib/2_data_sources/remote/request/body/ \| grep -v "includeIfNull: false"` | 매치 1+ |
|
|
55
|
-
| FL-08 | API 키/시크릿 하드코딩 | `grep -rEn "(api[_-]?key\|secret\|token)\s*=\s*['\"][A-Za-z0-9]{16,}['\"]" lib/ integrated_data_layer/lib/` | 매치 1+ |
|
|
56
|
-
|
|
57
|
-
> `HEAD~N` 의 N은 sprint_commits 수 — `git log --format=%h HEAD~sprint_start..HEAD` 로 결정.
|
|
58
|
-
|
|
59
|
-
## FL-04 수동 감사 방법
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# 1. 신규/수정된 page 파일 목록
|
|
63
|
-
PAGES=$(git diff --name-only HEAD~N..HEAD | grep '_page\.dart$')
|
|
64
|
-
|
|
65
|
-
# 2. 각 page에서 API 호출 존재 여부
|
|
66
|
-
for p in $PAGES; do
|
|
67
|
-
if grep -q "dataLayer\|DataLayer" "$p"; then
|
|
68
|
-
vm="${p%_page.dart}_page_vm.dart"
|
|
69
|
-
if [ -f "$vm" ] && grep -q "dataLayer\|DataLayer" "$vm"; then
|
|
70
|
-
echo "OK (VM handles API): $p"
|
|
71
|
-
else
|
|
72
|
-
echo "FAIL (page calls API without VM): $p"
|
|
73
|
-
fi
|
|
74
|
-
fi
|
|
75
|
-
done
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
VM이 없고 페이지가 직접 호출하면 **FL-04 FAIL**.
|
|
79
|
-
|
|
80
|
-
## 결과 집계
|
|
81
|
-
|
|
82
|
-
```markdown
|
|
83
|
-
## Step 4: Anti-Pattern
|
|
84
|
-
|
|
85
|
-
| Rule | Status | Count | Files |
|
|
86
|
-
|------|--------|-------|-------|
|
|
87
|
-
| FL-01 dart:html | PASS/FAIL | 0 | - |
|
|
88
|
-
| FL-02 print | PASS/FAIL | 0 | - |
|
|
89
|
-
| FL-03 color hardcode | PASS/FAIL | 0 | - |
|
|
90
|
-
| FL-04 stateful API call | PASS/FAIL | 0 | - |
|
|
91
|
-
| FL-05 bridges/ new | PASS/FAIL | 0 | - |
|
|
92
|
-
| FL-06 ko hardcode | PASS/FAIL | 0 | - |
|
|
93
|
-
| FL-07 includeIfNull missing | PASS/FAIL | 0 | - |
|
|
94
|
-
| FL-08 secret hardcode | PASS/FAIL | 0 | - |
|
|
95
|
-
|
|
96
|
-
Overall: PASS / FAIL
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**어떤 룰이든 FAIL 1건 → Step 4 전체 FAIL → 스프린트 FAIL** (하드 임계값: 위반 0건).
|