@walwal-harness/cli 2.0.1 → 2.3.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.
Files changed (29) hide show
  1. package/assets/templates/config.json +41 -1
  2. package/bin/init.js +65 -3
  3. package/package.json +5 -2
  4. package/scripts/harness-next.sh +36 -1
  5. package/scripts/harness-user-prompt-submit.sh +106 -0
  6. package/scripts/lib/harness-render-progress.sh +15 -1
  7. package/scripts/scan-project.sh +24 -2
  8. package/skills/brainstorming/SKILL.md +200 -0
  9. package/skills/brainstorming/references/attribution.md +109 -0
  10. package/skills/brainstorming/references/spec-document-reviewer-prompt.md +49 -0
  11. package/skills/brainstorming/references/visual-companion.md +287 -0
  12. package/skills/brainstorming/scripts/frame-template.html +214 -0
  13. package/skills/brainstorming/scripts/helper.js +88 -0
  14. package/skills/brainstorming/scripts/server.cjs +354 -0
  15. package/skills/brainstorming/scripts/start-server.sh +148 -0
  16. package/skills/brainstorming/scripts/stop-server.sh +56 -0
  17. package/skills/dispatcher/SKILL.md +114 -2
  18. package/skills/dispatcher/references/pipeline-definitions.md +53 -5
  19. package/skills/evaluator-functional-flutter/SKILL.md +198 -0
  20. package/skills/evaluator-functional-flutter/references/ia-compliance.md +77 -0
  21. package/skills/evaluator-functional-flutter/references/scoring-rubric.md +132 -0
  22. package/skills/evaluator-functional-flutter/references/static-check-rules.md +99 -0
  23. package/skills/generator-frontend-flutter/SKILL.md +138 -0
  24. package/skills/generator-frontend-flutter/references/anti-patterns.md +288 -0
  25. package/skills/generator-frontend-flutter/references/api-layer-pattern.md +233 -0
  26. package/skills/generator-frontend-flutter/references/i18n-pattern.md +102 -0
  27. package/skills/generator-frontend-flutter/references/riverpod-pattern.md +199 -0
  28. package/skills/planner/SKILL.md +23 -1
  29. package/skills/planner/references/fe-stack-detection.md +131 -0
@@ -16,13 +16,31 @@ disable-model-invocation: false
16
16
  1. progress.json 업데이트:
17
17
  - `agent_status` → `"completed"`
18
18
  - `completed_agents`에 `"dispatcher"` 추가
19
- - `next_agent` → `"planner"`
19
+ - `next_agent` → **브레인스토밍 결정 트리에 따라 결정** ([섹션 6](#6-brainstormer-routing-decision) 참조)
20
+ - 신규/재플래닝 + 사용자가 브레인스토밍 선택 → `"brainstorming"`
21
+ - 신규/재플래닝 + 사용자가 건너뛰기 선택 → `"planner"`
22
+ - 특정 에이전트 직접 명령 → 해당 에이전트 (예: `"evaluator-functional"`)
23
+ - Gotcha 교정 후 재작업 → `failure.retry_target` (해당 에이전트)
20
24
  - `pipeline` → 선택된 파이프라인 (FULLSTACK/FE-ONLY/BE-ONLY)
21
- - `sprint.number` → `1`, `sprint.status` → `"in_progress"`
25
+ - `sprint.number` → `1`, `sprint.status` → `"in_progress"` (신규 파이프라인인 경우에만)
22
26
  2. `.harness/progress.log`에 요약 한 줄 추가
23
27
  3. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
24
28
  4. 출력: `"✓ Dispatcher 완료. bash scripts/harness-next.sh 실행하여 다음 단계 확인."`
25
29
 
30
+ ## Auto-Routing (UserPromptSubmit Hook)
31
+
32
+ walwal-harness v2.2.0+ 부터 **UserPromptSubmit 훅** 이 모든 사용자 프롬프트 앞에
33
+ `[walwal-harness] Auto-routing is ACTIVE` 안내를 자동 주입한다. 이 훅이 켜져 있으면
34
+ Claude 는 기본적으로 Dispatcher 경유로 분류/라우팅해야 한다.
35
+
36
+ - **활성 조건**: `.harness/config.json` 의 `behavior.auto_route_dispatcher == true`
37
+ - **per-message opt-out**: 사용자가 `harness skip`, `harness 없이`, `without harness`,
38
+ `just answer` 등을 말하면 그 메시지 한정으로 훅이 pass-through
39
+ - **전역 비활성**: `behavior.auto_route_dispatcher = false`
40
+
41
+ 훅이 주입하는 컨텍스트에는 `pipeline`, `current_agent`, `next_agent`, `sprint`,
42
+ `fe_stack` 현재값이 포함되므로 Dispatcher 는 별도 상태 조회 없이 판단 가능.
43
+
26
44
  ## 1. Request Classification (최우선)
27
45
 
28
46
  사용자 입력을 먼저 분류합니다:
@@ -30,6 +48,7 @@ disable-model-invocation: false
30
48
  - **실수 지적** ("아니", "잘못", "그렇게 하면 안 돼", "X로 해야지") → **Gotcha Flow**
31
49
  - **기능 요청** ("만들어", "추가", "시작", PRD, OpenAPI) → **Pipeline Flow**
32
50
  - **혼합** → Gotcha 먼저 기록 → Pipeline 이어서
51
+ - **메타/인사/Claude 자체 질문** → Dispatcher skip, 짧은 일반 응답 허용
33
52
 
34
53
  ## 2. Gotcha Flow
35
54
 
@@ -68,3 +87,96 @@ AGENTS.md 비하네스 → 기존 백업 + 리빌드
68
87
  ## 5. Output
69
88
 
70
89
  `.harness/actions/pipeline.json` 생성 → 사용자 확인 → Session Boundary Protocol On Complete 실행
90
+
91
+ ### fe_stack 필드 (FE 파이프라인에서 필수)
92
+
93
+ FE-ONLY 또는 FULLSTACK 선택 시, `pipeline.json`에 **`fe_stack`** 필드를 포함해야 한다:
94
+
95
+ - `scan-result.json.tech_stack.fe_stack` 값을 기본으로 사용 (`react` | `flutter`)
96
+ - 값이 없거나 불명확하면 Planner가 확정하도록 위임 (Dispatcher는 `"unknown"` 기록 + `notes` 에 메모)
97
+ - Flutter 선택 시 `agents_active`/`agents_skipped`에 치환된 에이전트명을 기록
98
+ - active: `generator-frontend-flutter`, `evaluator-functional-flutter`
99
+ - skipped: `generator-frontend`, `evaluator-functional`, `evaluator-visual`
100
+
101
+ ## 6. Brainstormer Routing Decision
102
+
103
+ **원칙**: Brainstormer 는 파이프라인의 고정 스텝이 **아니다**. Dispatcher 가 조건부로 삽입한다.
104
+
105
+ ### 6.1 결정 트리
106
+
107
+ Dispatcher 는 사용자 요청을 분류한 뒤 아래 순서로 판단:
108
+
109
+ ```
110
+ 1. Gotcha / 실수 지적인가?
111
+ → YES: gotcha 기록 → next_agent = failure.retry_target (해당 에이전트)
112
+ (브레인스토밍 없음)
113
+
114
+ 2. 특정 에이전트 직접 명령인가?
115
+ ("evaluator 다시 돌려", "generator-frontend 재작업", "planner plan.md 고쳐" 등)
116
+ → YES: next_agent = <대상 에이전트> (브레인스토밍 없음)
117
+
118
+ 3. Planner 가 동작해야 하는 케이스인가?
119
+ (신규 파이프라인 / 신규 PRD / 기존 plan.md 대폭 수정 / 신규 feature 대규모 추가)
120
+ → YES: 사용자에게 확인 질문 → 6.2 "브레인스토밍 확인 플로우"
121
+ → NO: 다른 에이전트로 라우팅 (generator 이어서 등)
122
+
123
+ 4. 그 외 (메타/인사/Claude 자체 질문) → Dispatcher skip
124
+ ```
125
+
126
+ ### 6.2 브레인스토밍 확인 플로우
127
+
128
+ Planner 를 호출해야 한다고 판단되면, **사용자에게 단 하나의 질문을 출력한 뒤 대기한다:**
129
+
130
+ ```
131
+ 이 요청은 Planner 가 처리할 신규/재플래닝 건으로 보입니다.
132
+ 러프한 요구사항을 먼저 구체화하는 Brainstormer 과정을 거칠까요?
133
+
134
+ (Y) 예 — Brainstormer 와 대화하며 요구사항을 fit 하게 만든 뒤 Planner
135
+ (N) 아니오 — 이미 PRD/OpenAPI 가 명확하므로 바로 Planner
136
+
137
+ 답변: Y / N
138
+ ```
139
+
140
+ 사용자 응답 처리:
141
+ - **Y (긍정)** — "네", "y", "yes", "필요해", "해줘" 등
142
+ → `next_agent = "brainstorming"`
143
+ - **N (부정)** — "아니오", "n", "no", "필요없어", "바로", "skip" 등
144
+ → `next_agent = "planner"`
145
+ - **불명확 / 무응답** — 한 번 더 "Y 또는 N 으로 답해주세요" 요청
146
+
147
+ ### 6.3 Skip 케이스 정리
148
+
149
+ 브레인스토밍이 **실행되지 않는** 경우 (Dispatcher 가 직접 다른 에이전트로 라우팅):
150
+
151
+ | 상황 | next_agent |
152
+ |------|-----------|
153
+ | "Eval, X 다시 검증해" | `evaluator-functional` (또는 `evaluator-visual`) |
154
+ | "Generator-FE, Y 버그 고쳐" | `generator-frontend` (또는 Flutter 변형) |
155
+ | "Generator-BE, API 재생성해" | `generator-backend` |
156
+ | Eval FAIL → retry | `failure.retry_target` |
157
+ | Gotcha 수정 | `failure.retry_target` 또는 현재 에이전트 |
158
+ | 기존 plan.md 소폭 수정 (Dispatcher 판단) | `planner` (직접) |
159
+ | 사용자가 "Brainstormer 없이" / "skip brainstorming" 명시 | `planner` (직접) |
160
+
161
+ ### 6.4 강제 호출 케이스
162
+
163
+ 사용자가 명시적으로 원하면 브레인스토밍은 언제든 재호출 가능:
164
+
165
+ - "Brainstormer 다시 돌려줘"
166
+ - "요구사항 다시 잡자"
167
+ - "plan 처음부터"
168
+
169
+ 이 경우 기존 `.harness/actions/brainstorm-spec.md` 는 Brainstormer 의 On Start 에서
170
+ `.harness/archive/brainstorm-spec-<timestamp>.md` 로 백업된다.
171
+
172
+ ## 7. Handoff 라우팅 (fe_stack 반영)
173
+
174
+ Dispatcher가 `next_agent` 를 세팅할 때 pipeline.json.fe_stack 을 참조해 치환:
175
+
176
+ | 원본 next_agent | fe_stack=react | fe_stack=flutter |
177
+ |-----------------|----------------|------------------|
178
+ | generator-frontend | generator-frontend | generator-frontend-flutter |
179
+ | evaluator-functional (FE 단계) | evaluator-functional | evaluator-functional-flutter |
180
+ | evaluator-visual | evaluator-visual | (skip → 다음 단계로 이동) |
181
+
182
+ **Brainstormer 는 fe_stack 치환 대상이 아니다** — 언어/스택 무관 공통 에이전트.
@@ -1,5 +1,52 @@
1
+ ---
2
+ docmeta:
3
+ id: pipeline-definitions
4
+ title: Pipeline Definitions
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-dispatcher
11
+ inputs:
12
+ - documentId: harness-dispatcher-skill
13
+ uri: ../SKILL.md
14
+ relation: output-from
15
+ sections:
16
+ - sourceRange:
17
+ startLine: 58
18
+ endLine: 70
19
+ targetRange:
20
+ startLine: 30
21
+ endLine: 95
22
+ tags:
23
+ - dispatcher
24
+ - pipeline
25
+ - fe-stack
26
+ - flutter
27
+ ---
28
+
1
29
  # Pipeline Definitions
2
30
 
31
+ > **FE Stack 차원**: 모든 FE 관련 파이프라인은 `fe_stack` 필드로 React/Flutter를 구분한다.
32
+ > Planner가 scan-result.json(`tech_stack.fe_stack`) 또는 사용자 질문으로 확정한다.
33
+
34
+ ## fe_stack 스위치 매트릭스
35
+
36
+ | fe_stack | FE Generator | FE Evaluator(Functional) | Evaluator-Visual |
37
+ |----------|--------------|--------------------------|------------------|
38
+ | `react` | `generator-frontend` | `evaluator-functional` (Playwright MCP) | `evaluator-visual` |
39
+ | `flutter`| `generator-frontend-flutter` | `evaluator-functional-flutter` (flutter analyze/test) | **SKIP** (브라우저 없음) |
40
+
41
+ Dispatcher는 `next_agent`를 설정할 때 다음 규칙으로 치환한다:
42
+
43
+ ```
44
+ if pipeline.json.fe_stack == "flutter":
45
+ "generator-frontend" → "generator-frontend-flutter"
46
+ "evaluator-functional" (FE 단계) → "evaluator-functional-flutter"
47
+ "evaluator-visual" → skip (agents_skipped로 이동)
48
+ ```
49
+
3
50
  ## FE-ONLY
4
51
 
5
52
  ```yaml
@@ -7,16 +54,17 @@ trigger: 외부 API 존재 + FE 작업 요청
7
54
  agents:
8
55
  - planner (light):
9
56
  skip: MSA 서비스 설계, BE 기능 목록
10
- do: OpenAPI → api-contract.json 변환, FE 컴포넌트 설계, feature-list (layer: frontend만)
11
- - generator-frontend
12
- - evaluator-functional
13
- - evaluator-visual
57
+ do: OpenAPI → api-contract.json 변환, FE 컴포넌트 설계, feature-list (layer: frontend만), fe_stack 확정
58
+ - generator-frontend OR generator-frontend-flutter # fe_stack에 따라
59
+ - evaluator-functional OR evaluator-functional-flutter
60
+ - evaluator-visual # fe_stack == "flutter" 이면 SKIP
14
61
  skip:
15
62
  - generator-backend
16
63
  notes:
17
64
  - api-contract.json은 OpenAPI에서 파생 (Planner가 변환)
18
- - Eval-Func의 API Health Check는 외부 서버 대상
65
+ - Eval-Func(React)의 API Health Check는 외부 서버 대상
19
66
  - AGENTS.md IA-MAP에 BE 경로 없음 (외부 서버)
67
+ - fe_stack=flutter 인 경우 evaluator-visual 생략
20
68
  ```
21
69
 
22
70
  ## BE-ONLY
@@ -0,0 +1,198 @@
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
+ > **주의**: Flutter 앱은 브라우저가 아니므로 Playwright MCP(`browser_*`)를 쓸 수 없다.
10
+ > 이 에이전트는 `flutter analyze`, `flutter test`, `dart format`, 정적 grep 검증, 생성 파일 일관성으로 평가한다.
11
+ > 실기기/시뮬레이터 UI 검증은 사람 QA 또는 별도 파이프라인으로 위임.
12
+
13
+ ## Session Boundary Protocol
14
+
15
+ ### On Start
16
+ 1. `.harness/progress.json` 읽기 — `next_agent`가 `"evaluator-functional-flutter"`인지 확인
17
+ 2. `.harness/actions/pipeline.json.fe_stack == "flutter"` 재확인 — 아니면 즉시 STOP + 불일치 보고
18
+ 3. progress.json 업데이트: `current_agent` → `"evaluator-functional-flutter"`, `agent_status` → `"running"`, `updated_at` 갱신
19
+
20
+ ### On Complete (PASS)
21
+ 1. progress.json 업데이트:
22
+ - `agent_status` → `"completed"`
23
+ - `completed_agents`에 `"evaluator-functional-flutter"` 추가
24
+ - `next_agent` → `"archive"` (fe_stack=flutter 이면 evaluator-visual 생략)
25
+ - `failure` 필드 초기화
26
+ 2. `feature-list.json`의 통과 feature `passes`에 `"evaluator-functional-flutter"` 추가
27
+ 3. `.harness/progress.log`에 PASS 요약 추가
28
+ 4. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
29
+ 5. 출력: `"✓ Evaluator-Functional-Flutter PASS. bash scripts/harness-next.sh 실행하여 다음 단계 확인."`
30
+
31
+ ### On Fail
32
+ 1. progress.json 업데이트:
33
+ - `agent_status` → `"failed"`
34
+ - `failure.agent` → `"evaluator-functional-flutter"`
35
+ - `failure.location` → `"frontend"` (Flutter 앱은 항상 FE 재작업)
36
+ - `failure.message` → 실패 요약 (1줄)
37
+ - `failure.retry_target` → `"generator-frontend-flutter"`
38
+ - `next_agent` → `"generator-frontend-flutter"`
39
+ - `sprint.retry_count` 증가
40
+ 2. `sprint.retry_count >= 10`이면 `agent_status` → `"blocked"`, 사용자 개입 요청
41
+ 3. `.harness/progress.log`에 FAIL 요약 추가
42
+ 4. **STOP.**
43
+ 5. 출력: `"✖ Evaluator-Functional-Flutter FAIL. bash scripts/harness-next.sh 실행하여 재작업 대상 확인."`
44
+
45
+ ## Critical Mindset
46
+
47
+ - **회의적 평가자**. Generator의 자체 평가를 신뢰하지 말고 직접 돌려라.
48
+ - `flutter analyze` 경고가 있으면 "사소하다"고 자기 설득 금지 — 기준 미달.
49
+ - 코드 읽기만으로 PASS 판정 금지 — **반드시 `flutter analyze` + `flutter test` 실행**.
50
+ - 기준 미달 = FAIL. 예외 없음.
51
+
52
+ ## Startup
53
+
54
+ 1. `AGENTS.md` 읽기 — IA-MAP (Flutter 경로 확인)
55
+ 2. `.harness/gotchas/evaluator-functional-flutter.md` (없으면 skip) — **과거 실수 반복 금지**
56
+ 3. `actions/sprint-contract.md` — FE 성공 기준
57
+ 4. `actions/feature-list.json` — 이번 스프린트 범위 (`layer: "frontend"` + `fe_stack: "flutter"`)
58
+ 5. `actions/api-contract.json` — 기대 API 계약 (Retrofit 매핑 대조용)
59
+ 6. `.harness/progress.json`
60
+ 7. **Generator의 anti-patterns.md 로드** — 정적 검증 rule 소스
61
+ → `skills/generator-frontend-flutter/references/anti-patterns.md`
62
+
63
+ ## Evaluation Steps
64
+
65
+ ### Step 0: IA Structure Compliance (GATE)
66
+
67
+ AGENTS.md IA-MAP vs 실제 구조 대조. **미통과 시 이하 전체 SKIP, 즉시 FAIL.**
68
+
69
+ 상세 → [IA 검증 가이드](references/ia-compliance.md)
70
+
71
+ ### Step 1: `flutter analyze` (정적 분석)
72
+
73
+ ```bash
74
+ # 프로젝트 루트 또는 integrated_data_layer 하위에서
75
+ flutter analyze --no-fatal-infos
76
+ ```
77
+
78
+ - **warning / error 1개 이상 → FAIL**
79
+ - info 수준은 허용 (하지만 evaluation 보고서에 카운트 기록)
80
+
81
+ ### Step 2: `flutter test` (단위/위젯 테스트)
82
+
83
+ ```bash
84
+ # integrated_data_layer 테스트
85
+ cd <integrated_data_layer 경로>
86
+ flutter test
87
+
88
+ # 앱 테스트 (존재 시)
89
+ cd <app 루트>
90
+ flutter test
91
+ ```
92
+
93
+ - **실패 1개 이상 → FAIL**
94
+ - 이번 스프린트에서 추가된 Request Body / Response에 `fromJson`/`toJson` 왕복 테스트 **존재 확인**
95
+ - 누락 시 → FAIL (Coverage gate)
96
+
97
+ ### Step 3: build_runner 일관성
98
+
99
+ ```bash
100
+ cd <integrated_data_layer 경로>
101
+ flutter pub run build_runner build --delete-conflicting-outputs
102
+ git diff --name-only
103
+ ```
104
+
105
+ - 재생성 후 `*.g.dart` diff 가 발생하면 → **FAIL** (Generator가 수동 편집 또는 재생성 누락)
106
+
107
+ ### Step 4: Anti-Pattern 정적 검증
108
+
109
+ `skills/generator-frontend-flutter/references/anti-patterns.md` 의 **"셀프 체크 스크립트"** 섹션을
110
+ 그대로 실행한다. 하나라도 결과가 있으면 → **FAIL**.
111
+
112
+ 상세 → [정적 검증 룰](references/static-check-rules.md)
113
+
114
+ ### Step 5: API Contract Compliance
115
+
116
+ `api-contract.json` 의 엔드포인트 vs `rest_api.dart` 의 Retrofit 어노테이션 대조:
117
+
118
+ - 계약에 있는 모든 엔드포인트가 `rest_api.dart` 에 존재하는가
119
+ - method, path, path param, body 타입이 일치하는가
120
+ - Response 타입이 계약 스키마와 구조적으로 일치하는가 (필드 존재 + nullable 여부)
121
+ - **불일치 1개 이상 → FAIL**
122
+
123
+ ### Step 6: Sprint Contract Criteria
124
+
125
+ `sprint-contract.md` 의 FE 성공 기준을 순서대로 검증:
126
+
127
+ - 새 페이지가 `xxx_page.dart` + `xxx_page_vm.dart` 쌍으로 존재하는가
128
+ - VM이 `NotifierProvider` 를 사용하는가
129
+ - i18n 키가 모든 arb 파일에 등록되었는가
130
+ - 기준별 PASS/FAIL 기록 → 충족률 계산
131
+
132
+ ## Scoring
133
+
134
+ | 차원 | 가중치 | 하드 임계값 | 측정 방법 |
135
+ |------|--------|------------|----------|
136
+ | Static Analysis | 25% | warning/error 0개 | `flutter analyze` |
137
+ | Test Pass Rate | 25% | 100% | `flutter test` |
138
+ | API Contract 준수 | 25% | 100% | rest_api.dart vs api-contract.json |
139
+ | Anti-Pattern 청결 | 15% | 위반 0건 | 정적 grep |
140
+ | Contract Criteria 충족률 | 10% | 80% | sprint-contract 기준 |
141
+
142
+ **어떤 차원이든 하드 임계값 미달 → 스프린트 FAIL**
143
+
144
+ 상세 채점 → [스코어링 루브릭](references/scoring-rubric.md)
145
+
146
+ ## evaluation-functional.md 출력
147
+
148
+ ```markdown
149
+ # Flutter Functional Evaluation: Sprint [N]
150
+
151
+ ## Date: [날짜]
152
+ ## Verdict: PASS / FAIL
153
+ ## Attempt: [N] / 10
154
+ ## Stack: flutter
155
+
156
+ ## Step 0: IA Structure Compliance
157
+ - Verdict: PASS / FAIL (GATE)
158
+
159
+ ## Step 1: Flutter Analyze
160
+ - errors: [N]
161
+ - warnings: [N]
162
+ - infos: [N]
163
+
164
+ ## Step 2: Flutter Test
165
+ - total: [N], passed: [N], failed: [N]
166
+ - missing_roundtrip_tests: [목록]
167
+
168
+ ## Step 3: build_runner 일관성
169
+ - drift: [none | 목록]
170
+
171
+ ## Step 4: Anti-Pattern
172
+ | Rule | Count | Files |
173
+ | dart:html | 0 | - |
174
+ | print() | 0 | - |
175
+ | Color(0x...) in 신규 | 0 | - |
176
+ | bridges/ 신규 | 0 | - |
177
+ | Text('한글') 신규 | 0 | - |
178
+
179
+ ## Step 5: API Contract Compliance
180
+ | EP ID | Method + Path | Dart Match | Issues |
181
+
182
+ ## Step 6: Contract Criteria Results
183
+ | # | Criterion | Result | Evidence |
184
+
185
+ ## Scores
186
+ | Dimension | Score | Threshold | Status |
187
+
188
+ ## Failures Detail
189
+ ### [#N] [기준/항목]
190
+ - **Expected**: ...
191
+ - **Actual**: ...
192
+ - **Recommendation**: ...
193
+ ```
194
+
195
+ ## After Evaluation
196
+
197
+ - **PASS** → Session Boundary Protocol On Complete (PASS) 실행
198
+ - **FAIL** → Session Boundary Protocol On Fail 실행 (retry_target = generator-frontend-flutter)
@@ -0,0 +1,77 @@
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
+ ```
@@ -0,0 +1,132 @@
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
+ ```