know-thy-build 0.5.0 → 0.7.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.
@@ -35,62 +35,81 @@ This document is what makes "done" concrete. Without it, "done" is an opinion.
35
35
 
36
36
  ---
37
37
 
38
+ ## Before You Begin
39
+
40
+ ### 0. Worktree detection
41
+
42
+ Check if you're working in the correct worktree:
43
+
44
+ ```bash
45
+ REPO=$(basename $(git rev-parse --show-toplevel))
46
+ BRANCH=$(git branch --show-current)
47
+ ```
48
+
49
+ **If the branch starts with `feature/`:** You're in the worktree. Proceed.
50
+ **If the branch is `main` or `master`:**
51
+ - Check if `../${REPO}-wt` exists
52
+ - If yes: "You should be working in the worktree at `../${REPO}-wt`. Switch there before proceeding."
53
+ - If no: "No worktree found. Run `/know-thy-build:feature` first to create the feature spec and worktree."
54
+
55
+ ---
56
+
38
57
  ## How You Operate
39
58
 
40
59
  ### Behavioral Testing Axes (NOT Character Personas)
41
60
 
42
- **WARNING: "GPT/Claude에게 페르소나를 프롬프트로 주고 QA 시켜라" 접근은 거의 확실히 실패한다.** (τ-bench, CMU 2026: LLM 시뮬레이터는 지나치게 협조적이고 문체가 균일하며, 에이전트 성공률을 인간 기준선보다 부풀린다.)
61
+ **WARNING: "Prompt an LLM with a persona and have it QA" almost certainly fails.** (τ-bench, CMU 2026: LLM simulators are overly cooperative, stylistically uniform, and inflate agent success rates above human baselines.)
43
62
 
44
- 캐릭터 기반 페르소나("까다로운 유저처럼 행동해") 대신, **직교 행동축(orthogonal behavioral axes)**으로 테스트를 정의한다. (PersonaTester, FSE 2026: 9 조합이 실제 크라우드소싱 테스트 트레이스의 95.4%를 커버)
63
+ Instead of character-based personas ("act like a picky user"), define tests using **orthogonal behavioral axes**. (PersonaTester, FSE 2026: 9 combinations cover 95.4% of real crowdsourced test traces)
45
64
 
46
- #### 1: Testing Mindset (테스팅 마인드셋)
65
+ #### Axis 1: Testing Mindset
47
66
 
48
- | | 행동 | 단위 지시 |
67
+ | Value | Behavior | Turn-Level Instruction |
49
68
  |---|------|------------|
50
- | **Sequential** | 정해진 흐름대로 순서대로 진행 | "화면에 보이는 순서대로 모든 필드를 채워라" |
51
- | **Divergent** | 엉뚱한 순서로, 건너뛰며 진행 | "마지막 필드부터 채워라. 중간 필드는 비워라. 제출을 먼저 눌러라" |
69
+ | **Sequential** | Follow the intended flow in order | "Fill every field in the order they appear on screen" |
70
+ | **Divergent** | Skip around, use unexpected order | "Start from the last field. Leave middle fields empty. Hit submit first" |
52
71
 
53
- #### 2: Exploration Strategy (탐색 전략)
72
+ #### Axis 2: Exploration Strategy
54
73
 
55
- | | 행동 | 단위 지시 |
74
+ | Value | Behavior | Turn-Level Instruction |
56
75
  |---|------|------------|
57
- | **Click-through** | 보이는 모든 것을 클릭 | "버튼, 링크, 아이콘을 보이는 대로 전부 클릭해라. 순서 무관" |
58
- | **Input-focused** | 입력 필드에 집중, 다양한 투입 | "모든 입력 필드에 경계값을 넣어라: 값, 1자, 10000자, 특수문자, 이모지" |
59
- | **Core-feature** | 핵심 기능만 집중적으로 반복 | "핵심 액션을 10 반복해라. 매번 미세하게 다른 입력으로" |
76
+ | **Click-through** | Click everything visible | "Click every button, link, and icon you see. Order doesn't matter" |
77
+ | **Input-focused** | Focus on input fields, try diverse values | "Enter boundary values in every input: empty, 1 char, 10000 chars, special chars, emoji" |
78
+ | **Core-feature** | Repeat the core action intensively | "Repeat the core action 10 times. Use slightly different input each time" |
60
79
 
61
- #### 3: Interaction Habit (인터랙션 습관)
80
+ #### Axis 3: Interaction Habit
62
81
 
63
- | | 행동 | 단위 지시 |
82
+ | Value | Behavior | Turn-Level Instruction |
64
83
  |---|------|------------|
65
- | **Short-valid** | 최소한의 유효 입력 | "필수 필드만 최소 글자로 채우고 즉시 제출" |
66
- | **Long-boundary** | 길고 경계를 테스트하는 입력 | "모든 필드를 허용 최대 길이 + 1로 채워라" |
67
- | **Invalid** | 무효한 입력 | "숫자 필드에 한글, 이메일 필드에 URL, 날짜 필드에 'yesterday'" |
84
+ | **Short-valid** | Minimal valid input | "Fill only required fields with minimum characters and submit immediately" |
85
+ | **Long-boundary** | Long, boundary-testing input | "Fill every field to max allowed length + 1" |
86
+ | **Invalid** | Invalid input | "Put a URL in the email field, letters in the number field, 'yesterday' in the date field" |
68
87
 
69
- #### 4: Cooperation Level (비협조 수준) — NCUser, ICLR 2026
88
+ #### Axis 4: Cooperation Level — NCUser, ICLR 2026
70
89
 
71
- | | 행동 | 단위 지시 |
90
+ | Value | Behavior | Turn-Level Instruction |
72
91
  |---|------|------------|
73
- | **Cooperative** | 시스템이 원하는 대로 행동 | 기본. Happy path 테스트용 |
74
- | **Impatient** | 기다리지 않음 | "3초 안에 반응 없으면 새로고침. 로딩 다른 버튼 클릭" |
75
- | **Incomplete** | 정보를 번에 주지 않음 | "필수 3 필드 1개만 채우고 제출. 오류 1 채우고 다시 제출" |
76
- | **Impossible** | 시스템이 없는 것을 요구 | "존재하지 않는 리소스 접근. 삭제된 항목 편집 시도. 권한 없는 작업 실행" |
77
- | **Off-track** | 의도된 흐름에서 이탈 | "결제 도중 설정 변경. 입력 다른 탭으로 이동 후 복귀" |
92
+ | **Cooperative** | Behave as the system expects | Default. For happy path testing |
93
+ | **Impatient** | Refuse to wait | "Refresh if no response within 3 seconds. Click other buttons while loading" |
94
+ | **Incomplete** | Provide information incrementally | "Fill only 1 of 3 required fields and submit. After the error, fill 1 more and submit again" |
95
+ | **Impossible** | Request what the system cannot do | "Access a nonexistent resource. Try editing a deleted item. Attempt an unauthorized action" |
96
+ | **Off-track** | Deviate from the intended flow | "Change settings mid-checkout. Switch to another tab mid-input, then return" |
78
97
 
79
- #### 조합 = 테스트 프로필
98
+ #### Axis Combinations = Test Profiles
80
99
 
81
- 9-15 조합이 pairwise coverage 만족한다. 모든 축의 모든 조합을 테스트할 필요는 없다**가장 위험한 조합을 우선 선택**한다.
100
+ 9-15 combinations satisfy pairwise coverage. You do NOT need to test every possible combination **prioritize the riskiest combinations first**.
82
101
 
83
- 예시 프로필:
102
+ Example profiles:
84
103
 
85
- | # | Mindset | Strategy | Habit | Cooperation | 의미 |
104
+ | # | Mindset | Strategy | Habit | Cooperation | Meaning |
86
105
  |---|---------|----------|-------|-------------|------|
87
106
  | P1 | Sequential | Core-feature | Short-valid | Cooperative | Happy path baseline |
88
- | P2 | Divergent | Input-focused | Invalid | Impatient | 가장 파괴적 조합 |
89
- | P3 | Sequential | Click-through | Long-boundary | Incomplete | 성실하지만 실수 많은 유저 |
90
- | P4 | Divergent | Core-feature | Short-valid | Off-track | 산만한 파워유저 |
91
- | P5 | Sequential | Input-focused | Invalid | Impossible | 시스템 한계 탐색 |
107
+ | P2 | Divergent | Input-focused | Invalid | Impatient | Most destructive combination |
108
+ | P3 | Sequential | Click-through | Long-boundary | Incomplete | Diligent but error-prone user |
109
+ | P4 | Divergent | Core-feature | Short-valid | Off-track | Distracted power user |
110
+ | P5 | Sequential | Input-focused | Invalid | Impossible | System limit exploration |
92
111
 
93
- **핵심: 캐릭터를 연기하지 말고, 조합의 단위 지시를 따라라.** "성급한 유저처럼 행동해" 아니라 "3초 안에 반응 없으면 새로고침하고, 로딩 다른 버튼을 클릭하라."
112
+ **Key: Do NOT role-play a character follow the axis combination's turn-level instructions.** Not "act like an impatient user" but "refresh if no response within 3 seconds, and click other buttons while loading."
94
113
 
95
114
  ### Evidence-Based Verification
96
115
 
@@ -107,20 +126,20 @@ A test without evidence is not a test — it's an opinion.
107
126
 
108
127
  ### Failure State Injection
109
128
 
110
- (VISTA, 2026: UI-only 테스트 대비 실패 상태 주입 고유 실패 42% 추가 발견)
129
+ (VISTA, 2026: Failure state injection finds 42% more unique failures compared to UI-only testing)
111
130
 
112
- 유저 행동만 시뮬레이션하는 것은 절반의 테스트다. **시스템 실패 상태를 주입**해야 한다:
131
+ Simulating user behavior alone is only half the test. You must also **inject system-side failure states**:
113
132
 
114
- | 주입 유형 | 방법 | 목적 |
133
+ | Injection Type | Method | Purpose |
115
134
  |----------|------|------|
116
- | Network failure | 브라우저 DevTools throttle / 서버 중단 | 네트워크 끊김 UI 반응 |
117
- | Slow response | 인위적 지연 주입 | 타임아웃 처리, 로딩 상태 |
118
- | Resource deletion | DB/파일에서 직접 삭제 UI 접근 | 404/orphan 처리 |
119
- | Session expiry | 쿠키/토큰 삭제 액션 시도 | 인증 만료 처리 |
120
- | Concurrent mutation | 다른 세션에서 데이터 변경 원래 세션에서 저장 | 충돌 처리 |
121
- | Server error | 서버 프로세스 임시 중단 | 500 에러 UI 반응 |
135
+ | Network failure | Browser DevTools throttle / kill server | UI response when network drops |
136
+ | Slow response | Inject artificial delay | Timeout handling, loading states |
137
+ | Resource deletion | Delete directly from DB/file, then access via UI | 404/orphan handling |
138
+ | Session expiry | Delete cookies/tokens, then attempt action | Auth expiry handling |
139
+ | Concurrent mutation | Change data in another session, then save in original session | Conflict handling |
140
+ | Server error | Temporarily stop server process | UI response on 500 error |
122
141
 
123
- 모든 주입 유형이 모든 기능에 적용되지는 않는다. REVIEW 모드에서 해당 기능에 적용 가능한 주입 유형을 선택하고, TEST 모드에서 실제 주입한다.
142
+ Not every injection type applies to every feature. Select applicable injection types during REVIEW mode, and actually inject them during TEST mode.
124
143
 
125
144
  ---
126
145
 
@@ -183,17 +202,245 @@ Identify start/stop/health/seed/reset commands. **Ask the user if unclear.**
183
202
 
184
203
  **Actually run the commands and verify they work.** Record what succeeds and what fails.
185
204
 
186
- ### Step 2: Verify access methods and tools
205
+ ### Step 2: Product Type Classification & Interaction Strategy
206
+
207
+ **This is the most critical step in SETUP.** To test like a real user, QA must first determine what the product IS and which tools can interact with it.
208
+
209
+ #### 2a. Product type detection
210
+
211
+ Read `docs/PROJECT.md` (Output/Form section) and `docs/TECHNICAL.md` (Stack section). Scan the codebase:
212
+
213
+ ```bash
214
+ # Web indicators
215
+ ls src/**/*.html src/**/*.tsx src/**/*.vue src/**/*.svelte 2>/dev/null | head -5
216
+ grep -r "express\|fastify\|next\|nuxt\|remix\|flask\|django\|rails" package.json pyproject.toml Gemfile 2>/dev/null
217
+
218
+ # CLI indicators
219
+ grep -r '"bin"' package.json 2>/dev/null
220
+ ls src/cli* bin/* 2>/dev/null
187
221
 
188
- Determine how QA will interact with the product and **verify each method works**:
222
+ # API-only indicators
223
+ grep -r "swagger\|openapi\|graphql\|grpc" . --include="*.json" --include="*.yaml" 2>/dev/null | head -5
189
224
 
190
- | Entry Point | Method | Address | Tool | Verified |
191
- |-------------|--------|---------|------|----------|
192
- | Web UI | Browser | {{URL}} | claude-in-chrome | ✅/❌ |
193
- | CLI | Terminal | {{command}} | Bash | ✅/❌ |
194
- | API | HTTP | {{URL}} | Bash (curl) | ✅/❌ |
225
+ # Mobile indicators
226
+ ls android/ ios/ *.xcodeproj *.xcworkspace 2>/dev/null
227
+ grep -r "react-native\|expo\|flutter\|capacitor\|ionic" package.json pubspec.yaml 2>/dev/null
195
228
 
196
- For browser-based testing, verify: navigate, read content, click elements, capture screenshots, read console logs.
229
+ # Desktop indicators
230
+ grep -r "electron\|tauri\|wails" package.json Cargo.toml 2>/dev/null
231
+
232
+ # Library indicators
233
+ grep -r '"main"\|"exports"\|"types"' package.json 2>/dev/null
234
+ ls src/index.ts src/lib.rs src/__init__.py 2>/dev/null
235
+
236
+ # Game indicators
237
+ grep -r "phaser\|pixi\|three\|unity\|godot\|canvas\|webgl" package.json 2>/dev/null
238
+ ```
239
+
240
+ Classify and announce:
241
+
242
+ ```
243
+ 📋 **Product type detected: {{type}}**
244
+
245
+ Primary: {{Web App | CLI | API | Mobile App | Desktop App | Library | Game | Hybrid}}
246
+ Secondary entry points: {{list any additional interfaces}}
247
+ ```
248
+
249
+ #### 2b. Interaction strategy — "how does QA become a real user?"
250
+
251
+ **For each product type, QA MUST determine what tools can replicate real user actions, and build an Interaction Playbook.**
252
+
253
+ If QA cannot interact with the product as a real user, it MUST stop and tell the user what it needs.
254
+
255
+ ---
256
+
257
+ **🌐 Web App / Web Game**
258
+
259
+ **Primary tool: Playwright MCP** (built into Claude Code, 40+ tools)
260
+
261
+ | Real User Action | MCP Tool | Usage |
262
+ |---|---|---|
263
+ | Visit page | `browser_navigate` | URL |
264
+ | Read screen | `browser_snapshot` | Accessibility tree capture (assigns ref) |
265
+ | Click | `browser_click` | by `ref` |
266
+ | Type text | `browser_type` / `browser_fill_form` | ref + text |
267
+ | Drag and drop | `browser_drag` + `browser_drop` | source ref → target ref |
268
+ | Scroll | `browser_mouse_wheel` | direction + amount |
269
+ | Go back | `browser_navigate_back` | — |
270
+ | Keyboard actions | `browser_press_key` | Tab, Enter, Escape, shortcuts |
271
+ | Upload file | `browser_file_upload` | ref + file path |
272
+ | Handle alert/confirm | `browser_handle_dialog` | accept/dismiss |
273
+ | Select dropdown | `browser_select_option` | ref + value |
274
+ | Hover | `browser_hover` | ref |
275
+ | Change viewport | `browser_resize` | width × height |
276
+ | Manage tabs | `browser_tabs` | create, switch, close |
277
+
278
+ **Advanced interactions (vision mode):**
279
+ | Action | Tool | Implementation |
280
+ |---|---|---|
281
+ | Long press | `browser_mouse_down` → wait → `browser_mouse_up` | coordinate-based |
282
+ | Pinch zoom | `browser_evaluate` | inject touch events via JS |
283
+ | Swipe | `browser_mouse_move_xy` sequence | start→end coordinates |
284
+ | Double click | `browser_evaluate` | `el.dispatchEvent(new MouseEvent('dblclick'))` |
285
+ | Rapid repeated clicks | `browser_click` called N times | same ref |
286
+
287
+ **Evidence collection:**
288
+ | Evidence | Tool | When to Collect |
289
+ |---|---|---|
290
+ | Screenshot | `browser_take_screenshot` | Every assertion point — BEFORE and AFTER the action |
291
+ | Console errors | `browser_console_messages` | End of every test case |
292
+ | Network requests | `browser_network_requests` | API call verification |
293
+ | Session video | `browser_start_video` / `browser_stop_video` | Complex multi-step flows |
294
+ | Performance trace | `browser_start_tracing` / `browser_stop_tracing` | Performance-sensitive tests |
295
+
296
+ **Failure simulation:**
297
+ | Scenario | Implementation |
298
+ |---|---|
299
+ | Network offline | `browser_network_request` to intercept → return failure |
300
+ | Slow network | Network mocking with delay injection |
301
+ | Session expiry | `browser_evaluate` to clear cookies/localStorage, then act |
302
+ | Server error | Mock API response to return 500 |
303
+
304
+ ---
305
+
306
+ **⌨️ CLI Tool**
307
+
308
+ **Primary tool: Bash**
309
+
310
+ | Real User Action | Implementation |
311
+ |---|---|
312
+ | Run command | Execute directly via `bash` tool |
313
+ | Interactive input | `echo "input" \| command` or expect script |
314
+ | Pipeline | `command1 \| command2` |
315
+ | Ctrl+C interrupt | `timeout N command`, then check state |
316
+ | Wrong arguments | Empty args, nonexistent file, invalid option |
317
+ | Large input | Pipe large stdin |
318
+ | Permission denied | Write to read-only file |
319
+ | Concurrent execution | Run same command twice simultaneously |
320
+
321
+ **Evidence collection:**
322
+ | Evidence | Method |
323
+ |---|---|
324
+ | stdout/stderr | Capture command output |
325
+ | Exit code | `echo $?` |
326
+ | File changes | `diff`, `ls -la` before/after |
327
+ | Process state | `ps`, `lsof` |
328
+
329
+ ---
330
+
331
+ **🔌 API (REST / GraphQL / gRPC)**
332
+
333
+ **Primary tool: Bash (curl/httpie)**
334
+
335
+ | Real User Action | Implementation |
336
+ |---|---|
337
+ | Send request | `curl -X METHOD url -d 'body'` |
338
+ | Authentication | Obtain token → include in header |
339
+ | Bad request | Malformed JSON, missing fields, wrong types |
340
+ | Concurrent requests | `parallel curl` or background execution |
341
+ | Large payload | Request body exceeding limits |
342
+ | Rate limiting | Rapid sequential requests |
343
+
344
+ **Evidence:** HTTP status code, response body, response time (`curl -w "%{time_total}"`), headers
345
+
346
+ ---
347
+
348
+ **📱 Mobile App (React Native / Flutter / Native)**
349
+
350
+ **Primary tool: Limited — relies on emulator + CLI tools**
351
+
352
+ ```bash
353
+ # iOS Simulator
354
+ xcrun simctl list devices 2>/dev/null
355
+ # Android Emulator
356
+ adb devices 2>/dev/null
357
+ # Expo
358
+ npx expo start 2>/dev/null
359
+ # Flutter
360
+ flutter devices 2>/dev/null
361
+ ```
362
+
363
+ | Capability | Tool |
364
+ |---|---|
365
+ | Launch emulator | `xcrun simctl boot` / `emulator -avd` |
366
+ | Install/run app | `adb install` / `xcrun simctl install` |
367
+ | Screenshot | `adb exec-out screencap` / `xcrun simctl io screenshot` |
368
+ | Text input | `adb shell input text` |
369
+ | Tap/swipe | `adb shell input tap x y` / `adb shell input swipe` |
370
+ | Deep link | `adb shell am start -d "scheme://path"` |
371
+ | Network control | `adb shell svc wifi disable` |
372
+
373
+ **⚠️ Limitation:** Claude Code cannot directly see emulator screens. Screenshots must be captured and analyzed as images.
374
+
375
+ **When a limitation exists, state it explicitly:**
376
+ > "The following mobile test scenarios cannot be automated:"
377
+ > - Multi-touch gestures (precise pinch zoom, rotation)
378
+ > - Sensor input (accelerometer, GPS movement simulation)
379
+ > - Behavior on push notification receipt
380
+ >
381
+ > "These items are generated as manual test checklist entries."
382
+
383
+ ---
384
+
385
+ **📚 Library / SDK**
386
+
387
+ **Primary tool: Code execution (Bash + test runner)**
388
+
389
+ | Real User Action | Implementation |
390
+ |---|---|
391
+ | Call API | Write test code + execute |
392
+ | Incorrect usage | Type mismatch, null argument, wrong call order |
393
+ | Concurrent usage | Promise.all / multi-thread test |
394
+ | Memory/performance | Large-volume call loop + memory measurement |
395
+
396
+ **Evidence:** Test execution output, error messages, performance metrics
397
+
398
+ ---
399
+
400
+ **🖥️ Desktop App (Electron / Tauri)**
401
+
402
+ Web-based → **Playwright MCP** works (Playwright natively supports Electron).
403
+ Native → **OS automation tools** required — state limitations explicitly.
404
+
405
+ ---
406
+
407
+ #### 2c. Build the Interaction Playbook
408
+
409
+ Based on the analysis above, write an **Interaction Playbook** for this project in QA.md:
410
+
411
+ ```markdown
412
+ ## Interaction Playbook
413
+
414
+ ### Product Type: {{type}}
415
+ ### Primary Testing Tool: {{tool}}
416
+
417
+ ### Available Interactions
418
+ | User Action | Tool / Method | Automatable |
419
+ |---|---|---|
420
+ | {{action}} | {{tool + method}} | ✅ / ⚠️ partial / ❌ manual |
421
+
422
+ ### Unavailable Interactions (manual testing required)
423
+ | User Action | Reason | Manual Checklist Item |
424
+ |---|---|---|
425
+ | {{action}} | {{why not automatable}} | [ ] {{checklist item}} |
426
+
427
+ ### Evidence Collection Strategy
428
+ | Evidence Type | Collection Tool | When to Collect |
429
+ |---|---|---|
430
+ | {{evidence type}} | {{tool}} | {{when}} |
431
+
432
+ ### Failure Injection Strategy
433
+ | Failure Type | Injection Method | Automatable |
434
+ |---|---|---|
435
+ | {{failure}} | {{method}} | ✅ / ❌ |
436
+ ```
437
+
438
+ **Interaction Playbook principles:**
439
+ - **Automate everything automatable.** "Running test code" is not automation. "Clicking a button in the browser and verifying the result" is automation.
440
+ - **Explicitly list everything NOT automatable.** Convert to manual test checklist entries in QA.md.
441
+ - **Ask the user when a tool is missing.** "This test requires {{tool}}. Would you like to install it?"
442
+
443
+ **⚠️ Core principle: QA does NOT run test code — QA reproduces what a real user does with the product.** Every test case starts with "what does the user do" and is implemented with "which tool replicates that action."
197
444
 
198
445
  ### Step 3: Define behavioral axes for this project
199
446
 
@@ -232,16 +479,16 @@ For each high-risk profile, generate **turn-level behavior instructions** — NO
232
479
  📋 **Profile P2 scenarios (Divergent + Input + Invalid + Impatient):**
233
480
 
234
481
  Turn-level instructions:
235
- 1. "3초 안에 반응 없으면 새로고침하라"
236
- 2. "숫자 필드에 한글을 입력하라"
237
- 3. "마지막 필드부터 채우고 필드는 비워라"
238
- 4. "제출 버튼을 3 연속 클릭하라"
239
- 5. "오류 메시지를 읽지 말고 같은 액션을 반복하라"
482
+ 1. "Refresh if no response within 3 seconds"
483
+ 2. "Enter non-Latin characters in the number field"
484
+ 3. "Fill from the last field first, leave the first field empty"
485
+ 4. "Click the submit button 3 times in rapid succession"
486
+ 5. "Do not read the error message — repeat the same action"
240
487
 
241
488
  Applicable scenarios:
242
- - 로그인 폼에서이메일에 URL 입력, 비밀번호 1자, 제출 3 클릭
243
- - 검색 기능에서특수문자 10000 입력, 결과 로딩 검색 시작
244
- - 설정 변경에서저장 다른 설정 탭으로 이동
489
+ - Login formenter a URL in the email field, 1-char password, click submit 3 times
490
+ - Search featureenter 10000 special characters, start a new search while results are loading
491
+ - Settings pageswitch to a different settings tab while saving
245
492
  ```
246
493
 
247
494
  Generate at minimum 20 turn-level instructions across all profiles. These grow with each QA run.
@@ -311,13 +558,33 @@ date: {{date}}
311
558
  - {{turn instruction}} — added: {{date}}
312
559
  - {{turn instruction}} — added: {{date}}
313
560
 
561
+ ## Interaction Playbook
562
+
563
+ ### Product Type: {{type}}
564
+ ### Primary Testing Tool: {{tool}}
565
+
566
+ ### Available Interactions
567
+ | User Action | Tool / Method | Automatable |
568
+ |---|---|---|
569
+ | {{action}} | {{tool + method}} | ✅ / ⚠️ partial / ❌ manual |
570
+
571
+ ### Unavailable Interactions (manual testing required)
572
+ | User Action | Reason | Manual Checklist Item |
573
+ |---|---|---|
574
+ | {{action}} | {{why}} | [ ] {{checklist item}} |
575
+
576
+ ### Evidence Collection Strategy
577
+ | Evidence Type | Collection Tool | When to Collect |
578
+ |---|---|---|
579
+ | {{type}} | {{tool}} | {{when}} |
580
+
314
581
  ### Failure State Injection Methods
315
582
 
316
- | Type | Method | Applicable When |
317
- |------|--------|----------------|
318
- | Network failure | {{how to simulate}} | {{which features}} |
319
- | Resource deletion | {{how to simulate}} | {{which features}} |
320
- | Session expiry | {{how to simulate}} | {{which features}} |
583
+ | Type | Method | Tool | Applicable When |
584
+ |------|--------|------|----------------|
585
+ | Network failure | {{how to simulate}} | {{tool}} | {{which features}} |
586
+ | Resource deletion | {{how to simulate}} | {{tool}} | {{which features}} |
587
+ | Session expiry | {{how to simulate}} | {{tool}} | {{which features}} |
321
588
 
322
589
  ### Discovered Patterns
323
590
 
@@ -340,14 +607,17 @@ date: {{date}}
340
607
  ```
341
608
 
342
609
  **SETUP is complete when:**
610
+ - [ ] Product type classified (Web / CLI / API / Mobile / Library / Desktop / Game)
343
611
  - [ ] Start command works — application runs
344
612
  - [ ] Health check confirms the application is responsive
345
- - [ ] At least one access method verified
613
+ - [ ] Interaction Playbook built every real user action mapped to a tool/method
614
+ - [ ] Unavailable interactions explicitly listed with manual checklist items
615
+ - [ ] Evidence collection strategy defined for this product type
346
616
  - [ ] Behavioral axes mapped to project persona
347
617
  - [ ] At least 5 test profiles defined (risk-ordered)
348
618
  - [ ] At least 20 turn-level scenarios generated
349
- - [ ] Failure state injection methods identified
350
- - [ ] `docs/QA.md` is written
619
+ - [ ] Failure state injection methods identified with specific tools
620
+ - [ ] `docs/QA.md` is written with Interaction Playbook section
351
621
 
352
622
  ---
353
623
 
@@ -460,26 +730,140 @@ Execute in this order:
460
730
  3. **Higher-risk profiles (P2, P3...)** — follow turn-level instructions exactly
461
731
  4. **Failure state injection** — actually inject failures and observe
462
732
 
463
- **For each test case:**
733
+ #### Execution by Product Type
734
+
735
+ **Read the Interaction Playbook in QA.md first.** All test execution follows the tools and methods defined in the Playbook.
736
+
737
+ **🌐 Web App — Playwright MCP execution pattern:**
738
+
739
+ Execute each test case following this pattern:
740
+
741
+ ```
742
+ 1. browser_navigate → target page
743
+ 2. browser_snapshot → read current state (acquire refs)
744
+ 3. browser_take_screenshot → capture BEFORE state as evidence
745
+ 4. [action] → browser_click / browser_type / browser_drag etc.
746
+ 5. browser_snapshot → read state after action
747
+ 6. browser_take_screenshot → capture AFTER state as evidence
748
+ 7. browser_console_messages → check for JS errors
749
+ ```
750
+
751
+ **Mandatory per test case:**
752
+ - `browser_take_screenshot` — minimum 2 times: BEFORE the key action and AFTER
753
+ - `browser_console_messages` — at test end, check for JS errors
754
+ - `browser_network_requests` — when API calls are involved, check for failures
755
+
756
+ **Evidence verdict pattern (mandatory for every test):**
757
+ ```
758
+ 📸 Evidence — Test #{{N}}: {{scenario name}}
759
+
760
+ BEFORE: [screenshot captured — {{describe what is visible}}]
761
+ ACTION: {{what was done — e.g. "clicked 'Save' button (ref e12)"}}
762
+ AFTER: [screenshot captured — {{describe what changed}}]
763
+
764
+ Console: {{clean / N errors found: [list]}}
765
+ Network: {{all 200 / failed: [list]}}
766
+
767
+ VERDICT: ✅ PASS — matches intent: "{{design intent or AC being verified}}"
768
+ ❌ FAIL — expected: {{expected}}, actual: {{actual}}
769
+ ⚠️ PARTIAL — {{what worked, what didn't}}
770
+ ```
771
+
772
+ **Every verdict MUST reference the specific acceptance criterion or design intent being verified.** A pass without a stated intent is not a pass — it is an unverified observation.
773
+
774
+ **Viewport testing (responsive):**
775
+ - Execute P1 happy path at default viewport first
776
+ - `browser_resize(390, 844)` (mobile) + re-execute same test
777
+ - `browser_resize(1024, 768)` (tablet) when applicable
778
+
779
+ **Exploratory testing (AI autonomous):**
780
+ - After all scripted test cases, run autonomous exploration
781
+ - "As {{persona_name}}, achieve {{feature's goal}}" → explore freely with Playwright MCP
782
+ - Do not constrain the path. The agent clicks, types, and navigates on its own.
783
+ - Record any discovered issues immediately in QA.md
784
+
785
+ **⌨️ CLI — Bash execution pattern:**
786
+
787
+ ```
788
+ 1. Run command → capture stdout/stderr
789
+ 2. Check exit code → echo $?
790
+ 3. Verify file/state changes → diff, ls -la before/after
791
+ 4. Assess whether error messages are useful to the user
792
+ ```
793
+
794
+ **Evidence verdict pattern:**
795
+ ```
796
+ 📋 Evidence — Test #{{N}}: {{scenario name}}
797
+
798
+ COMMAND: {{exact command run}}
799
+ STDOUT: {{first 20 lines or relevant excerpt}}
800
+ STDERR: {{if any}}
801
+ EXIT: {{code}}
802
+
803
+ STATE BEFORE: {{relevant state — file listing, DB row, etc.}}
804
+ STATE AFTER: {{relevant state}}
805
+
806
+ VERDICT: ✅ PASS / ❌ FAIL — expected: {{expected}}, actual: {{actual}}
807
+ ```
808
+
809
+ **⚠️ Even for CLI, test "like a user":**
810
+ - Enter commands with typos
811
+ - Run `--help` first and follow its guidance
812
+ - Try pipeline combinations
813
+ - Feed unexpected input (empty file, binary file, symlink)
814
+
815
+ **🔌 API — curl execution pattern:**
816
+
817
+ ```
818
+ 1. curl request → capture HTTP status + response body
819
+ 2. Measure response time → curl -w "%{time_total}"
820
+ 3. Bad requests → malformed body, missing auth, wrong Content-Type
821
+ 4. Concurrent requests → parallel PUT/DELETE to same resource
822
+ ```
823
+
824
+ **Evidence:** Full request + response (status, body, headers, time)
825
+
826
+ **📱 Mobile — emulator + screenshot pattern:**
827
+
828
+ ```
829
+ 1. Execute action via adb/xcrun
830
+ 2. Capture screenshot → analyze via Read tool
831
+ 3. Check errors via logcat / Console.app
832
+ 4. Non-automatable items → record in manual checklist
833
+ ```
834
+
835
+ **📚 Library — code execution pattern:**
836
+
837
+ ```
838
+ 1. Write test code → call API as a real user would
839
+ 2. Execute → verify result + error messages
840
+ 3. Copy-paste README examples verbatim → verify they actually work
841
+ 4. Induce type errors → verify error messages are clear and actionable
842
+ ```
843
+
844
+ ---
845
+
846
+ **For each test case (all product types):**
464
847
 
465
848
  1. Set up precondition
466
- 2. Execute each step exactly as written
849
+ 2. Execute each step exactly as written — **use the tools defined in the Interaction Playbook**
467
850
  3. If the test case has a profile, **follow the profile's turn-level instructions** — don't improvise, don't be "kinder" than the instruction says
468
- 4. Capture evidence at every assertion point
851
+ 4. Capture evidence at every assertion point — **follow the Playbook's Evidence Collection Strategy**
469
852
  5. Record: ✅ PASS / ❌ FAIL / ⚠️ PARTIAL
470
853
 
471
854
  **For failure state injection test cases:**
472
855
 
473
856
  1. Start the normal flow (reach the target state)
474
- 2. **Inject the failure** (kill network, delete resource, expire session, etc.)
475
- 3. Observe how the UI/system responds
476
- 4. Capture evidence: screenshot + console + server log
477
- 5. Verify graceful handling (not crash, not silent failure)
857
+ 2. **Inject the failure** using the Playbook's Failure Injection Strategy
858
+ 3. Observe how the product responds
859
+ 4. Capture evidence: screenshot/output + console/log + server state
860
+ 5. Verify graceful handling (not crash, not silent failure, not data corruption)
478
861
 
479
862
  **If a new edge case is discovered during testing:**
480
863
  1. Record it immediately
481
864
  2. Add it to the feature's test cases
482
865
  3. Add the underlying turn-level instruction to the relevant profile
866
+ 4. Update the Interaction Playbook if a new interaction pattern was discovered
483
867
 
484
868
  ### Phase 4: QA Self-Check
485
869
 
@@ -578,16 +962,16 @@ This is the ONLY definition of "done." Not "code works on my machine." Not "unit
578
962
 
579
963
  ## Limitations & Human Anchor
580
964
 
581
- **LLM QA 인간 테스트를 대체하지 않는다.** (τ-bench, Sim2Real 2026)
965
+ **LLM QA does not replace human testing.** (τ-bench, Sim2Real 2026)
582
966
 
583
- QA 프레임워크는 **실제 사용자 테스트 전에 설계를 다듬기 위한 시뮬레이션 파일럿**이다. 알아야 한계:
967
+ This QA framework is a **simulation pilot for refining designs before real user testing**. Known limitations:
584
968
 
585
- - LLM 시뮬레이터는 진짜 불만, 혼란, 감정적 반응을 표현하지 못한다
586
- - 자동 평가(pass/fail)가 인간 판단과 상당히 불일치할 있다
587
- - 모델 성능이 높다고 충실한 사용자 시뮬레이션이 되는 것은 아니다
588
- - 행동축 기반 접근이 캐릭터 기반보다 낫지만, 여전히 시뮬레이션이다
969
+ - LLM simulators cannot express genuine frustration, confusion, or emotional reactions
970
+ - Automated pass/fail judgments can diverge significantly from human judgment
971
+ - Higher model capability does not mean more faithful user simulation
972
+ - Behavioral-axis-based testing is better than character-based, but it is still a simulation
589
973
 
590
- **Human Anchor**: 가능하다면 실제 사용자 로그 수십 건을 수집하여 참조 분포로 활용하라. 이것이 전체 QA 구조의 앵커가 된다. QA.md의 `Discovered Patterns` 섹션에 실제 사용자에게서 관찰된 행동을 기록하라 이것이 시뮬레이션 시나리오보다 항상 우선한다.
974
+ **Human Anchor**: When possible, collect a few dozen real user session logs as a reference distribution. This anchors the entire QA structure. Record behaviors observed from actual users in the `Discovered Patterns` section of QA.md these always take priority over simulated scenarios.
591
975
 
592
976
  ---
593
977
 
@@ -656,7 +1040,34 @@ Implementation → Designer Review + Architect Review (parallel, both must pass)
656
1040
  - Test results with evidence recorded in `docs/QA.md`
657
1041
  - Insight synthesis: patterns, failure taxonomy, recommendations
658
1042
  - QA quality metrics updated (self-check against easy mode)
659
- - If all ✅: feature confirmed complete
660
1043
  - If any ❌: specific failure list with reproduction steps
661
1044
  - New turn-level scenarios added to the playbook
662
1045
  - The QA document is now richer for the next feature
1046
+
1047
+ ### Gate Update
1048
+
1049
+ After TEST mode completes with all test cases passing, update the feature spec's gate:
1050
+
1051
+ 1. Find the active feature spec:
1052
+ ```bash
1053
+ FEATURE_NUM=$(git branch --show-current | grep -oE '[0-9]+' | head -1)
1054
+ FEATURE_FILE="docs/features/$(printf '%03d' $FEATURE_NUM).md"
1055
+ ```
1056
+
1057
+ 2. Update gate status in the frontmatter:
1058
+ Change `qa: pending` to `qa: passed` in the `gate:` section.
1059
+
1060
+ 3. Add the current date next to the status:
1061
+ ```yaml
1062
+ gate:
1063
+ qa: passed # {{date}}
1064
+ ```
1065
+
1066
+ 4. **Check all gates:**
1067
+ Read the full gate section. If ALL gates are `passed` or `skipped`:
1068
+ > "All gates passed. Run `/know-thy-build:finish` to merge this feature to main."
1069
+
1070
+ If any gate is still `pending`:
1071
+ > "QA passed. Remaining gates: {{list pending gates}}. Complete those reviews before merge."
1072
+
1073
+ This gate update is recorded in the worktree. It will be merged to main with the rest of the feature's changes via `/know-thy-build:finish`.