Implement a task with TDD (enforced when a test runner exists). Gate: tests pass + stack build check. Runs automatically right after spec. 트리거: "구현해", "이 태스크".
Scanned 9/19/2026
Install to Claude Code
npx -y skills add snwlee/Nereus --skill build --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Build?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/snwlee-build)More formats (shields.io, HTML) on the badges page.
---
name: build
description: Implement a task with TDD (enforced when a test runner exists). Gate: tests pass + stack build check. Runs automatically right after spec. 트리거: "구현해", "이 태스크".
---
# build
nereus:common 규칙을 따른다. 담당 에이전트: 스택에 따라 backend / frontend / app. 두 스택 이상이면 태스크별로 나눈다.
## 1. TDD 가능 환경 판별
`nereus` 훅 라이브러리의 `detectTestRunner`와 같은 기준이다.
- Flutter: `pubspec.yaml`에 `flutter_test` 또는 `test` → `flutter test`
- Spring: `gradlew`/`build.gradle*` → `./gradlew test`, `pom.xml` → `mvn test`
- Node: `package.json` test 스크립트, 또는 vitest/jest 설정 파일
러너가 있으면 **TDD 강제**. 없으면 사용자에게 딱 한 번 묻는다: "테스트 환경이 없습니다. 세팅할까요?" 승인하면 `references/<stack>.md`의 세팅을 적용한다. 거절하면 TDD 없이 진행하고 handoff.md 테스트 상태에 "테스트 없음(사용자 선택)"을 적는다.
## 2. 태스크 루프
tasks 파일에서 첫 미완료 태스크를 고른다. 태스크마다:
1. **RED**: 완료 조건을 테스트로 옮긴다. 실행해서 **실패를 확인**한다. 실패 출력 첫 줄을 기록한다. 실패하지 않으면 테스트가 잘못된 것이다.
> **Iron Law — NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.**
> 실패하는 테스트 없이 프로덕션 코드를 쓰지 않는다.
2. **GREEN**: 테스트를 통과시키는 최소 구현. 처음 쓰는 API는 Context7로 확인.
**무엇을 만들지는 `references/laziness-ladder.md` 의 사다리로 정한다** — 버티는 첫 단에서 멈춘다.
사다리는 해답을 줄이는 것이지 문제를 읽는 것을 줄이지 않는다. 충돌하면 TDD 게이트가 이긴다.
3. **REFACTOR**: 중복 제거, 이름 정리. 테스트 다시 실행.
4. tasks 체크박스를 채우고 handoff.md의 "완료"와 "다음"을 갱신한다.
`tdd.enforce: "block"` 이면 PreToolUse 가 구현 파일 편집을 **실제로 차단한다**(경고가 아니다).
| 상태 | 구현 파일 편집 |
|---|---|
| RED — 마지막 테스트 실행 실패 | 허용 (지금이 구현 단계) |
| GREEN + 대응 테스트 있음 | 허용 (REFACTOR) |
| GREEN + 대응 테스트 없음 | **차단** — 실패 테스트를 먼저 쓴다 |
| 테스트를 한 번도 안 돌림 | **차단** — RED 를 가정할 수 없다 |
테스트 파일 편집은 언제나 허용된다. 차단되면 정공법은 실패하는 테스트를 쓰고 `run-tests.mjs` 로 돌리는 것이다. 정당한 예외라면 사유를 적어 `.nereus/tdd-override` 를 만든다 — **다음 편집 1회만** 통과하고 파일은 소비된다. 급하면 `tdd.enforce` 를 `"warn"` 으로 낮춘다. 우회했으면 handoff.md Rulings 에 이유를 남긴다.
`tdd.enforce` 가 `"warn"`(기본)이면 PostToolUse 의 `tdd-guard` 훅이 사후 경고만 낸다. 경고를 무시하고 넘어가지 않는다.
설정·마이그레이션·생성 파일(`tdd.exclude`)은 테스트 대상이 아니다.
테스트 실행은 래퍼로 한다. 결과가 작업트리 해시와 함께 `.nereus/evidence.json`에 기록되어 finish 게이트가 "테스트가 진짜 돌았고 그 뒤 코드가 안 바뀌었는지"를 확인한다.
```bash
node "${CLAUDE_PLUGIN_ROOT}/skills/build/scripts/run-tests.mjs" # 러너 자동 감지
node "${CLAUDE_PLUGIN_ROOT}/skills/build/scripts/run-tests.mjs" --cmd "./gradlew test --tests '*Foo*'"
```
코드를 한 줄이라도 더 고쳤으면 evidence는 STALE이 된다. 마지막 편집 뒤에 반드시 한 번 더 돌린다.
## 3. 막혔을 때 — nereus:debug 를 부른다
버그·실패 테스트·예상과 다른 동작을 만나면 **`nereus:debug` 스킬을 부른다**. 여기서 요약하지 않는다 — 절차가 그 스킬에 있다.
철칙만 옮겨 적으면: **근본 원인 조사 없이 수정하지 않는다.** 같은 태스크에서 가설 3개가 연속으로 틀리면 멈추고 구조를 의심한다(`ooo unstuck` → 사용자에게 재설계 여부). 실패한 접근은 전부 handoff.md MUST NOT 에 남긴다.
## 4. 게이트
- 전체 테스트 실행 → 전부 통과. 출력을 인용한다.
- 스택별 빌드·정적 검사를 한 번 더 돌린다(`flutter analyze`, `./gradlew build`, `npm run build`, `tsc --noEmit`, 또는 `node --check`).
`ooo qa` 는 **아티팩트 하나**(파일이나 텍스트)를 판정하는 도구다 — `ooo qa <파일>` 형태로만 쓰고, 저장소 전체 게이트로 쓰지 않는다(`--json` 같은 플래그는 없다).
- 디자인 표면(스타일시트·디자인 토큰·시각 마크업)을 만졌으면 `nereus:design` 의 렌더 라운드를 돌린다. 스크린샷을 확보해 Gemini 비평을 받고 `--files` 로 커버한다. 건너뛰면 finish 게이트가 차단한다.
```bash
node "${CLAUDE_PLUGIN_ROOT}/skills/design/scripts/design-feedback.mjs" status # 무엇이 미이행인지 먼저 확인
```
- `[flow]` 태스크가 포함됐으면 `nereus:e2e`를 먼저 실행한 뒤 `nereus:review`로 넘어간다. 아니면 바로 review.
## 5. 비용 티어 (출처: oh-my-openagent category + superpowers tiering)
| 작업 등급 | 예 | 티어 |
|---|---|---|
| 기계적 (mechanical) | 포맷·린트·재테스트·단순 수정 | 가장 낮은 가용 티어 |
| 통합 (integration) | 다파일 기능 구현·리뷰 반영 | 표준 티어 |
| 설계·최종판단 (design/final) | 아키텍처 결정·R4–5 escalate·breaker 판정 | 가장 높은 티어 |
fix 4라운드 이후는 무조건 한 티어 위로 올린다 (고친 주체가 자기 문제를 못 본다).
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!