@tuzi-ince/hi-loop 0.4.0 → 0.4.1

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 CHANGED
@@ -174,7 +174,9 @@ CI·배포 설정, 빌드·러너 설정, 환경 변수. "테스트는 통과했
174
174
  사람이 놓치지 않게 한다.
175
175
 
176
176
  **(b) 조건부 검사 — 바뀐 파일에 따라 게이트를 켠다.** 무거운 검사(e2e 등)를 매 회차 돌리는
177
- 대신, 특정 경로가 바뀐 회차에만 돌린다.
177
+ 대신, 특정 경로에 변경이 있을 때만 돌린다. `--when` 은 `git status`(HEAD 대비 워킹트리 변경)로
178
+ 매칭한다 — 즉 "그 경로를 건드린 그 회차만"이 아니라 **커밋 전 변경분에 그 경로가 있는 한 이후
179
+ 회차마다** 검사가 돈다(2회차에 e2e 가 사라지지 않게 하려는 의도).
178
180
 
179
181
  ```bash
180
182
  hi-loop run --goal "..." \
@@ -188,6 +190,22 @@ hi-loop run --goal "..." \
188
190
  - `--when` 글롭에 안 맞은 검사는 **건너뜀으로 기록**된다 — 안 돌린 것이 통과처럼 보이지 않게
189
191
  Gaps에 남는다.
190
192
 
193
+ **MCP 에서도 같은 걸 쓴다 — "UI 변경 회차에만 e2e"를 엔진이 강제한다.** `hiloop_run` 이 `checks`
194
+ 인자를 받는다(CLI `--check/--when` 의 MCP 노출):
195
+
196
+ ```json
197
+ "checks": [
198
+ { "cmd": "npm test" },
199
+ { "cmd": "npx playwright test", "when": "src/**/*.tsx" }
200
+ ]
201
+ ```
202
+
203
+ - e2e 를 "스킬이 사람에게 기억해서 실행"(제안)이 아니라 **엔진이 결정론적으로 강제**(메커니즘)하는 길이다.
204
+ UI 파일이 바뀐 회차마다 엔진이 e2e 를 돌리고 통과해야 pass 로 인정한다 — 조용히 빠지지 않는다.
205
+ - e2e 는 **셸 명령**이어야 한다. 엔진은 Playwright **MCP 도구**를 부를 수 없으므로, MCP 만 있는
206
+ 프로젝트는 `flow` 스킬이 루프 통과 후 MCP 로 돌린다(폴백). 셸 e2e 명령도 없으면 스킵.
207
+ - `flow` 스킬이 UI 작업을 감지하면 사용자에게 물은 뒤 이 `checks` 를 자동 구성해 `hiloop_run` 에 넘긴다.
208
+
191
209
  **diff만 리뷰하고 싶다면** — 지금 워킹트리 변경분을 정확성·보안·YAGNI 축으로 심판:
192
210
 
193
211
  ```bash
@@ -275,7 +293,7 @@ hi-loop run --goal "..." --start-from BUILD --stop-after CODE_REVIEW
275
293
 
276
294
  | 사용자가 이렇게 말하면 | LLM이 하는 일 |
277
295
  |---|---|
278
- | `/hi-loop 로그인 폼 만들어줘` (슬래시 스킬) | hi-loop 스킬 기동 → `hiloop_run(full=true)` 실행 |
296
+ | `/hi-loop:flow 로그인 폼 만들어줘` (슬래시 스킬) | `flow` 스킬 기동 → `hiloop_run(full=true)` 실행 (bare `/hi-loop` 은 명령이지 이 스킬이 아님) |
279
297
  | "hiloop_run 도구로 결제 버그 고쳐줘" | 지목된 MCP 도구를 로드해 바로 호출 |
280
298
  | 터미널에서 `hi-loop run --goal "..." --full` | 엔진을 CLI로 직접 구동(LLM 개입 없음) |
281
299
 
package/docs/DESIGN.md CHANGED
@@ -571,7 +571,7 @@ try/catch 로 감싼다. **텔레그램 장애로 빌드가 죽는 것은 설계
571
571
 
572
572
  | 항목 | 상태 | 근거 |
573
573
  |---|---|---|
574
- | 단위/수용 테스트 104개 | ✅ 통과 | `npm test` (네트워크·실제 LLM 없이) |
574
+ | 단위/수용 테스트 343개 | ✅ 통과 | `npm test` (네트워크·실제 LLM 없이) |
575
575
  | **설치본(tarball) 실행** | ✅ 실측 | `npm pack` → `npm install -g --prefix /tmp/lev-prefix ./tgz` → **심링크 bin 경유** 실행 및 전체 루프 E2E 통과. §4.5 버그를 잡아낸 경로 |
576
576
  | CLI 루프 E2E (가짜 에이전트) | ✅ 실측 | PLAN→실패→DO→통과→exit 0, 2회차 프롬프트에 실제 AssertionError 주입 확인 |
577
577
  | MCP 서버 (도구 왕복) | ✅ 실측 | stdio 로 initialize → tools/list(3종) → tools/call |
package/docs/SPEC.md CHANGED
@@ -222,7 +222,7 @@ runLoop({
222
222
  - FR-4.3 노출 도구:
223
223
  | tool | input | 동작 |
224
224
  |---|---|---|
225
- | `hiloop_run` | `goal`(필수), `testCommand?`, `maxLoops?`, `verifySpec?`, `spec?`, `reconcile?`, `cwd?` | 루프 실행 후 결과 텍스트 반환. `budgetUsd`·`stagnation`은 노출 안 함(CLI 전용) |
225
+ | `hiloop_run` | `goal`(필수), `testCommand?`, `maxLoops?`, `verifySpec?`, `spec?`, `reconcile?`, `reconcileSpec?`, `checks?`, `cwd?` | 루프 실행 후 결과 텍스트 반환. `budgetUsd`·`stagnation`은 노출 안 함(CLI 전용). `checks`=`[{cmd,when?}]` 조건부 검사(CLI `--check/--when` 의 MCP 노출) — UI 변경 회차에만 e2e 같은 게이트를 **엔진이 강제**한다 |
226
226
  | `hiloop_status` | `cwd?` | 현재 `.hi-loop/STATE.json` 요약 반환 |
227
227
  | `hiloop_reset` | `cwd?` | 상태 파일 삭제 |
228
228
  - FR-4.4 도구 오류는 예외를 던지지 않고 `isError: true` + 메시지로 반환한다.
package/docs/guide.md CHANGED
@@ -33,8 +33,9 @@ hi-loop run --goal "add 함수를 만들어라" --test "npm test" # 사람이
33
33
  | Git | 선택 (롤백/리뷰용) | `git --version` |
34
34
 
35
35
  > ⚠️ **`npm install -g handoff` 를 하지 마라.** 무스코프 `handoff` 는 이 프로젝트와
36
- > 무관한 **제3자의 redis lua 래퍼 패키지**(v0.1.3)다. 이 프로젝트의 이름은
37
- > **`@tuzi-ince/hi-loop`** 이며 아직 배포 전이다. 설치는 아래 §2 방법을 쓴다.
36
+ > 무관한 **제3자의 redis lua 래퍼 패키지**(v0.1.3)다. 이 프로젝트는 **스코프 이름
37
+ > `@tuzi-ince/hi-loop`** 으로 npm 레지스트리에 게시돼 있다(현재 0.4.0). 스코프를 반드시 붙여라.
38
+ > 최신 소스(0.4.1+)로 개발·검증하려면 아래 §2 의 로컬 설치를 쓴다.
38
39
 
39
40
  ---
40
41
 
@@ -45,9 +46,9 @@ hi-loop run --goal "add 함수를 만들어라" --test "npm test" # 사람이
45
46
  ```bash
46
47
  git clone <이 저장소> hi-loop && cd hi-loop
47
48
  npm install # @modelcontextprotocol/sdk, zod
48
- npm test # 104개 통과 확인
49
+ npm test # 전부 통과 확인
49
50
  npm link # 전역에 hi-loop / hi-loop-setup 심볼릭 링크
50
- hi-loop --version # 0.1.0
51
+ hi-loop --version # 0.4.1
51
52
  ```
52
53
 
53
54
  해제: `npm unlink -g @tuzi-ince/hi-loop`
@@ -62,10 +63,10 @@ npm install -g /absolute/path/to/hi-loop
62
63
 
63
64
  ```bash
64
65
  # 보내는 쪽
65
- npm pack # tuzi-ince-hi-loop-0.1.0.tgz 생성 (~26kB)
66
+ npm pack # tuzi-ince-hi-loop-0.4.1.tgz 생성 (~26kB)
66
67
 
67
68
  # 받는 쪽
68
- npm install -g ./tuzi-ince-hi-loop-0.1.0.tgz
69
+ npm install -g ./tuzi-ince-hi-loop-0.4.1.tgz
69
70
  ```
70
71
 
71
72
  ### 2-D. 설치 없이 직접 실행
@@ -259,7 +260,7 @@ hi-loop rollback --cwd . # 작업 대상 지정
259
260
 
260
261
  | 도구 | 인자 | 용도 |
261
262
  |---|---|---|
262
- | `hiloop_run` | `goal`(필수), `testCommand`, `maxLoops`, `verifySpec`, `full`, `ship`, `watch`, `stopAfter`, `spec`, `reconcile`, `reconcileSpec`, `cwd` | 자가 치유(+전과정) 루프 실행 |
263
+ | `hiloop_run` | `goal`(필수), `testCommand`, `maxLoops`, `verifySpec`, `full`, `ship`, `watch`, `stopAfter`, `spec`, `reconcile`, `reconcileSpec`, `checks`, `cwd` | 자가 치유(+전과정) 루프 실행 |
263
264
  | `hiloop_answer` | `choice`, `note`, `cwd` | 대기 중인 질문에 답하고 재개 가능 상태로 되돌림 |
264
265
  | `hiloop_status` | `cwd` | 진행 상태 조회 (장시간 루프를 들여다보는 창) |
265
266
  | `hiloop_rollback` | `to`, `cwd` | 체크포인트로 파일 복원 |
@@ -269,6 +270,18 @@ hi-loop rollback --cwd . # 작업 대상 지정
269
270
  > MCP `hiloop_run`은 CLI와 달리 `--budget-usd`·`--stagnation`을 노출하지 않는다.
270
271
  > 예산 상한이 필요하면 CLI(`hi-loop run`)를 쓴다. 정체 감지는 기본값(3회)으로 동작한다.
271
272
 
273
+ > **UI 변경 회차에만 e2e 를 엔진이 강제하기 (`checks`).** `checks: [{cmd, when?}]` 를 주면
274
+ > `testCommand` 대신 이 배열이 판정 기준이 되고, `when` 글롭에 맞는 파일이 바뀐 회차에만 그 검사를
275
+ > 돌린다. e2e 를 스킬의 자연어 지시(사람이 기억해서 실행)가 아니라 **엔진이 결정론적으로 강제**하는 길이다:
276
+ > ```json
277
+ > "checks": [
278
+ > { "cmd": "npm test" },
279
+ > { "cmd": "npx playwright test", "when": "src/**/*.tsx" }
280
+ > ]
281
+ > ```
282
+ > e2e 는 **셸 명령**이어야 한다(엔진은 Playwright MCP 도구를 부를 수 없다 — 그 경우는 스킬이 루프 후
283
+ > MCP 로 돌린다). `flow` 스킬이 UI 작업을 감지하면 이 `checks` 를 자동으로 구성해 넘긴다.
284
+
272
285
  > **cwd 기본값은 `CLAUDE_PROJECT_DIR || process.cwd()`.** MCP 는 호스트(클로드코드/커서)가 서버를
273
286
  > 띄우는 경로라, "어느 프로젝트인가"의 정답은 호스트가 주입하는 `CLAUDE_PROJECT_DIR` 다. 각 도구에
274
287
  > `cwd` 를 명시하면 그것이 최우선. (CLI 는 반대로 순수 `process.cwd()` — 터미널에서 cd 한 곳이 의도다.)
@@ -346,7 +359,7 @@ hi-loop 의 CHECK 단계는 **에이전트가 "다 됐다"고 말해도 믿지
346
359
  npm version patch --no-git-tag-version # 0.1.0 -> 0.1.1
347
360
 
348
361
  # ── CHECK 1: 소스에서 테스트
349
- npm test # 104
362
+ npm test # 343
350
363
 
351
364
  # ── CHECK 2: 아티팩트로 만든다 (레지스트리 안 건드림)
352
365
  npm pack # tuzi-ince-hi-loop-0.1.1.tgz
@@ -372,7 +385,7 @@ rm -rf /tmp/lev-prefix # 정리
372
385
 
373
386
  ### 이 루프가 실제로 잡아낸 버그
374
387
 
375
- 이 절차는 이론이 아니다. **소스에서는 104개 테스트가 다 통과하는데 설치본에서는
388
+ 이 절차는 이론이 아니다. **소스에서는 343개 테스트가 다 통과하는데 설치본에서는
376
389
  모든 명령이 아무 일도 안 하고 조용히 `exit 0` 으로 끝나는** 버그를 이 루프가 잡았다.
377
390
 
378
391
  원인: `bin/*.js` 의 "직접 실행인가?" 판정이
@@ -431,7 +444,7 @@ npm install -g @tuzi-ince/hi-loop # 명령 이름은 그대로 hi-loop / hi-l
431
444
 
432
445
  배포 전 체크리스트:
433
446
 
434
- - [ ] `npm test` 통과 (104개)
447
+ - [ ] `npm test` 통과 (343개)
435
448
  - [ ] **§7 의 실제 에이전트 스모크 테스트 통과** ← 아직 안 된 항목. **이게 통과하기 전엔 배포하지 마라**
436
449
  - [ ] `npm pack --dry-run` 으로 포함 파일 확인 (bin, src, docs, README)
437
450
  - [ ] `version` 갱신
@@ -468,11 +481,11 @@ cat .hi-loop/STATE.json | jq '{status, phase, iteration, sessionId, sessionSeria
468
481
 
469
482
  **실제로 실행해 확인함**
470
483
 
471
- - `npm test` 104개 통과
484
+ - `npm test` 전부 통과
472
485
  - `npm pack` → tarball 생성 (bin/src/docs/README 포함)
473
486
  - **`npm install -g --prefix /tmp/lev-prefix ./tarball` 로 진짜 설치 → 설치본 실행 확인**
474
487
  - `bin/hi-loop` 가 심링크로 생성됨을 `ls -l` 로 확인
475
- - **심링크 bin 경유** `hi-loop --version` → `0.1.0`, `run`(goal 없음) → exit 2
488
+ - **심링크 bin 경유** `hi-loop --version` → `0.4.1`, `run`(goal 없음) → exit 2
476
489
  - 설치본으로 전체 루프 E2E: PLAN→실패→DO→통과→exit 0
477
490
  - 설치본 `hi-loop-setup` → `.mcp.json` 이 설치 위치를 정확히 가리킴
478
491
  - `hi-loop-setup` 멱등, `--dry-run` 무기록
@@ -507,7 +520,8 @@ cat .hi-loop/STATE.json | jq '{status, phase, iteration, sessionId, sessionSeria
507
520
  - **MCP 모드에서 실제 에이전트 spawn** — 도구 왕복(initialize/tools/call)만 확인
508
521
  - 장시간(10회) 실제 루프
509
522
  - 텔레그램 실제 발송
510
- - 레지스트리 경유 설치(`npm install -g @tuzi-ince/hi-loop`) 배포 후에만 가능
523
+ - 레지스트리에는 **0.4.0** 게시돼 있다 — 이번 세션의 변경(0.4.1: `.hi-loop/` 상태·대문자 규약·
524
+ MCP `checks`)을 레지스트리로 받으려면 **0.4.1 재게시**가 필요하다. 그전까지 최신은 로컬 설치(§2)로만.
511
525
 
512
526
  **재현 절차**
513
527
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuzi-ince/hi-loop",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "CLI와 MCP 모드를 지원하는 초경량 자율형 자가 치유 엔진",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,6 +46,19 @@ user-invocable: true
46
46
  - `full: true` — 발굴·설계리뷰·코드리뷰를 포함한 전체 라이프사이클
47
47
  - `testCommand`: 프로젝트의 테스트 명령(기본 `npm test`)
48
48
  - 필요 시 `maxLoops`, `ship`, `watch`
49
+ - **UI 작업이면 e2e 를 엔진 게이트로 넣는다(권장 — LLM 기억에 의존하지 않는 결정론적 강제).**
50
+ goal 이 UI(화면·컴포넌트·라우팅·스타일)를 건드릴 것 같고 프로젝트에 **셸 e2e 명령**
51
+ (package.json `test:e2e` 스크립트, 또는 `playwright.config.*` → `npx playwright test`)이 있으면,
52
+ **먼저 사용자에게 e2e 게이트 여부를 묻고**, 켜기로 하면 `checks` 로 넘긴다:
53
+ ```json
54
+ "checks": [
55
+ { "cmd": "<기본 테스트, 예: npm test>" },
56
+ { "cmd": "<e2e 셸 명령>", "when": "<UI 글롭, 예: src/**/*.tsx>" }
57
+ ]
58
+ ```
59
+ → 엔진이 **UI 변경이 (커밋 전) 워킹트리에 있는 회차마다** e2e 를 돌리고, 통과해야 pass 로 인정한다(조용히 빠지지 않는다).
60
+ - 셸 e2e 명령이 없고 **Playwright MCP 만** 있으면 `checks` 를 쓰지 않는다(엔진은 MCP 도구를 못 부른다)
61
+ — 루프 통과 후 7단계에서 MCP 로 돌린다. **둘 다 없으면** e2e 는 스킵한다(도구를 임의 설치하지 않는다).
49
62
 
50
63
  5. **사용자 선택 처리.** 응답이 `⏸ 사용자의 선택이 필요합니다` 로 오면,
51
64
  그 질문을 **그대로 사용자에게 제시**하고 답을 받는다. 답을 `hiloop_answer`
@@ -54,27 +67,18 @@ user-invocable: true
54
67
  6. **결과 보고.** `✅ 통과` / `❌ 실패` 와 반복 횟수, 그리고 함께 온 Gaps(검증 한계)를
55
68
  사용자에게 전한다. false green(테스트만 초록이고 실제 미완)을 통과로 포장하지 않는다.
56
69
 
57
- 7. **UI 변경 e2e 게이트.** 문법·기능 테스트가 통과(✅)한 뒤, 이번 변경이
58
- **UI(프론트엔드 화면·컴포넌트·라우팅·스타일)** 건드렸는지 판단한다.
59
- - UI 변경이 **없으면** 단계를 건너뛴다(그대로 종료).
60
- - UI 변경이 **있으면** 사용자에게 **먼저 묻는다**: "UI 변경이 있었습니다. e2e 테스트를
61
- 진행할까요?" 임의로 실행하지 않는다.
62
-
63
- **e2e 실행 능력을 순서대로 탐지한다(강등 사다리).** e2e는 이미 통과한 루프의 *부가* 게이트다 —
64
- 없다고 루프를 실패로 만들지 않는다.
65
- 1. **Playwright MCP 도구가 세션에 있으면** 그걸로 실행한다(브라우저 구동·스크린샷 네이티브 지원).
66
- 2. 없지만 **프로젝트에 e2e 셋업이 있으면**(`@playwright/test` devDep + `test:e2e` 스크립트,
67
- 또는 `playwright.config.*`, 또는 `e2e` 스킬) 경로로 실행한다.
68
- 3. **둘 없으면** e2e 도구를 **임의로 설치하지 않는다** Playwright + 브라우저 바이너리는
69
- 수백 MB다. 사용자에게 상황을 알리고 선택지를 준다: (a) 설치 후 진행, (b) 이미 있는 다른
70
- 도구 사용, (c) 건너뛰기. 어느 쪽도 강요하지 않고, **이 게이트를 "스킵"으로 기록**한다.
71
-
72
- - e2e를 실제로 실행하기로 했으면 **결과 화면(스크린샷) 저장 여부도 사용자에게 묻는다**.
73
- 스크린샷은 **브라우저를 구동하는 도구(1·2)가 있을 때만** 가능하다 — 없으면 저장할 화면이
74
- 없음을 밝힌다.
75
- - 완료되면 **테스트 결과서와 스크린샷을 프로젝트의 test 폴더에 저장**한다
76
- (예: 리포트 `tests/e2e/report-<날짜시각>.md`, 스크린샷 `tests/e2e/screenshots/`).
77
- 날짜·시각은 실제 값으로 채운다. 저장 경로를 사용자에게 알린다.
70
+ 7. **e2e 후처리 (스크린샷·리포트, MCP 폴백).** 루프가 통과(✅)한 뒤, 4단계에서 정한 e2e 전략에 따라:
71
+ - **엔진 `checks` 로 돌린 경우**: e2e 는 이미 게이트로 통과했다(엔진이 강제). 결과 화면(스크린샷)
72
+ 저장이 필요하면 사용자에게 물어 저장한다. **여기서 다시 e2e 를 돌릴 필요는 없다.**
73
+ - **Playwright MCP 폴백 경우**(셸 e2e 명령이 없어 4단계에서 checks 못 건 경우): 사용자에게
74
+ "UI 변경이 있었습니다. 지금 Playwright MCP 로 e2e 를 돌릴까요?" 물어, 승인 시 MCP 로 실행한다.
75
+ - **스킵된 경우**(도구 없음): e2e 도구가 없어 스킵했음을 밝힌다 — 통과한 루프를 실패로 만들지 않는다.
76
+ - 실행한 경우 **결과서·스크린샷을 test 폴더에 저장**한다(예: 리포트 `tests/e2e/report-<날짜시각>.md`,
77
+ 스크린샷 `tests/e2e/screenshots/`). 날짜·시각은 실제 값으로 채우고 저장 경로를 알린다.
78
+ 스크린샷은 브라우저를 구동하는 도구(Playwright MCP/셸)가 있을 때만 가능하다.
79
+
80
+ > 이렇게 나누나: e2e "실행"은 결정론적 게이트라 **엔진(`checks`)**에 맡기는 최신 정설이다
81
+ > (프롬프트 지시는 "제안"이지 "강제"가 아니다). 엔진이 부르는 Playwright MCP LLM 이 후처리한다.
78
82
 
79
83
  8. **커밋 게이트 (git 워크플로).** 테스트가 통과(✅)하고 e2e 게이트까지 끝나면 `commitPolicy` 대로
80
84
  **로컬** 커밋한다. **push/PR 은 하지 않는다.** git 저장소가 아니면 건너뛴다.
package/src/mcp-server.js CHANGED
@@ -43,6 +43,7 @@ export const tools = {
43
43
  spec,
44
44
  reconcile,
45
45
  reconcileSpec,
46
+ checks,
46
47
  cwd = defaultCwd(),
47
48
  }) => {
48
49
  if (!goal) return fail('goal 은 필수입니다.');
@@ -62,6 +63,9 @@ export const tools = {
62
63
  specPath: spec || null,
63
64
  reconcile: reconcile === undefined ? null : Boolean(reconcile),
64
65
  reconcileSpec: reconcileSpec || null,
66
+ // 조건부 검사(--check/--when 의 MCP 노출): 주면 testCommand 대신 이 배열이 판정 기준이 된다.
67
+ // when 글롭에 맞는 파일이 바뀐 회차에만 그 검사를 돌린다(UI 변경 회차에만 e2e 등).
68
+ checks: Array.isArray(checks) && checks.length ? checks : null,
65
69
  cwd,
66
70
  logger: log,
67
71
  });
@@ -204,6 +208,15 @@ export async function startMcpServer({ version = '0.1.0' } = {}) {
204
208
  .string()
205
209
  .optional()
206
210
  .describe('정합 게이트가 대조할 표준 문서 경로(기본 docs/DESIGN.md). 예: docs/DESIGN.md. 지정하면 게이트가 켜진다.'),
211
+ checks: z
212
+ .array(z.object({ cmd: z.string(), when: z.string().optional() }))
213
+ .optional()
214
+ .describe(
215
+ '조건부 판정 검사. 주면 testCommand 대신 이 배열이 판정 기준이 된다(첫 항목에 기본 테스트를 넣을 것). ' +
216
+ 'when 글롭(예: "src/**/*.tsx")이 있으면 그 경로가 바뀐 회차에만 그 검사를 돌린다 — ' +
217
+ '"UI 를 고친 회차에만 e2e" 를 엔진이 강제하는 용도. e2e 는 셸 명령이어야 한다(예: {cmd:"npx playwright test", when:"src/**/*.tsx"}). ' +
218
+ 'short-circuit 하지 않아 유닛이 깨져도 e2e 결과를 같은 회차에 함께 본다.',
219
+ ),
207
220
  cwd: cwdSchema,
208
221
  },
209
222
  },