UI 복잡 버전 234 RED→GREEN 완료(docs/UI_USECASES.md §A~§J): 라이브 테마 전환(DynamicResource 전환+ThemeResolver+HighContrast 테마, 재시작 없음), 디자인 토큰 체계·WCAG 대비 결함 5건 수정, 설정창 카테고리 내비/검색 재구성+AppConfig 40여 속성, 다운로드 관리자(속도/ETA/세그먼트맵/전체 일시정지-이어받기/CSV 내보내기/예약 게이트/중복 확인), 라이브러리·아카이브·작업공간·재생목록·즐겨찾기 편집 뷰, 접근성(자동화 속성 30여 개·커스텀 피어·docs/ACCESSIBILITY.md), 인터랙션(휠 클릭 새 탭·XButton 탐색·F12·영역 캡처·프로필 전환), 상태/알림(토스트·알림센터·온보딩·CrashReportDialog). 보강 테스트 35건+실창 E2E 4건(StaDispatcher 기반 — 프록시 설정이 기시작 핸들러를 건드리는 크래시 실결함 수정 포함) — 453/453 GREEN. 이전 미커밋 작업(CI 워크플로·Mdns·QueueHub·UpdateChecker·AGENTS/CLAUDE·빌드 스크립트) 일괄 포함
This commit is contained in:
parent
5a0ce730b2
commit
17f2f91152
88 changed files with 9463 additions and 1127 deletions
151
docs/HARNESS.md
Normal file
151
docs/HARNESS.md
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
# 개발 하네스 — 폐쇄루프 운영 지침
|
||||
|
||||
> 이 저장소에서 AI 코딩 에이전트가 **자율적으로, 그러나 검증 없이는 완료를 선언할 수 없게** 일하도록
|
||||
> 짜 놓은 장치들의 설계와 운영법. 사람과 에이전트 모두 이 문서를 읽는 대상이다.
|
||||
|
||||
## 왜 필요한가
|
||||
|
||||
에이전트의 가장 흔한 실패는 코드를 못 짜는 게 아니라 **"됐습니다"라고 말해버리는 것**이다.
|
||||
테스트가 깨진 채로, 실행해 보지도 않고, 문서는 옛날 상태인 채로 턴이 끝난다.
|
||||
|
||||
해법은 프롬프트로 더 강하게 부탁하는 게 아니라, **에이전트가 건너뛸 수 없는 결정적 층**을 두는 것이다.
|
||||
확률적인 판단(모델)과 결정적인 검사(훅)를 분리한다.
|
||||
|
||||
## 5계층 구조
|
||||
|
||||
| 계층 | 역할 | 이 저장소에서 |
|
||||
|---|---|---|
|
||||
| **① 하네스** | 에이전트가 사는 환경 | Claude Code + `.claude/settings.json` |
|
||||
| **② 루프 계약** | "완료"의 정의 | `AGENTS.md` §4 완료 기준 · `CLAUDE.md` |
|
||||
| **③ 상태층** | 세션이 끊겨도 남는 상태 | `docs/BACKLOG.md` 체크박스 · `docs/IMPLEMENTATION_AUDIT.md` · SessionStart 브리핑 |
|
||||
| **④ 체커** | 에이전트가 못 건너뛰는 검사 | **Stop 훅 → `dotnet test`** |
|
||||
| **⑤ 사람 관문** | 되돌릴 수 없는 일 앞의 확인 | 커밋·푸시·배포는 사용자 승인 (`/release` 스킬) |
|
||||
|
||||
핵심은 ④다. 나머지는 ④가 있어야 의미가 생긴다.
|
||||
|
||||
## 구성 요소
|
||||
|
||||
```
|
||||
AGENTS.md ← 도구 중립 작업 계약 (Codex/Cursor 등도 읽음)
|
||||
CLAUDE.md ← @AGENTS.md 임포트 + Claude Code 전용 지침
|
||||
.claude/
|
||||
settings.json ← 훅 등록 + 권한 (커밋됨, 팀 공유)
|
||||
hooks/
|
||||
session-brief.sh ← SessionStart: 저장소 상태를 컨텍스트에 주입 (상태층)
|
||||
verify-on-stop.sh ← Stop: 테스트 게이트 (체커)
|
||||
rules/ ← 경로별 자동 로드 규칙 (해당 파일을 열 때만 컨텍스트에 들어옴)
|
||||
desktop-wpf.md ← VideoDownloader.App/**, Browser/**
|
||||
engine-core.md ← Core/**, Server/**
|
||||
mobile-maui.md ← Mobile/**, Mobile.Core/**
|
||||
tests.md ← Tests/**
|
||||
skills/ ← 호출될 때만 로드되는 절차서
|
||||
tdd/SKILL.md ← /tdd RED→GREEN→증거
|
||||
verify/SKILL.md ← /verify 완료 기준 전수 점검
|
||||
release/SKILL.md ← /release 배포
|
||||
.verify-stamp ← 마지막 검증 성공 시점 (자동 생성, gitignore)
|
||||
```
|
||||
|
||||
### 왜 이렇게 나눴나
|
||||
|
||||
- **CLAUDE.md 는 짧게.** 매 세션 컨텍스트를 먹고, 길수록 지켜지지 않는다. 200줄 이내가 권장선이다.
|
||||
- **경로별 규칙은 `rules/` 로.** WPF 함정은 WPF 파일을 열 때만 필요하다. 항상 로드하면 낭비다.
|
||||
- **절차는 `skills/` 로.** 배포 순서 같은 건 배포할 때만 필요하다. 안 쓰면 토큰을 안 쓴다.
|
||||
- **강제는 훅으로.** CLAUDE.md 는 부탁이고 훅은 강제다. "반드시 X 해라"가 지켜지길 원하면 훅에 넣는다.
|
||||
|
||||
## 훅 동작
|
||||
|
||||
### SessionStart — 상태 브리핑
|
||||
|
||||
세션이 시작되면 브랜치·마지막 커밋·변경 파일·검증 상태·미완료 백로그를 컨텍스트에 넣는다.
|
||||
에이전트가 `git status` 를 따로 묻지 않고 현재 상황을 알고 시작한다.
|
||||
|
||||
### Stop — 테스트 게이트
|
||||
|
||||
턴을 끝내려 할 때:
|
||||
|
||||
1. `stop_hook_active` 가 `true` 면 즉시 통과 — **무한 루프 방지**.
|
||||
(Claude Code 는 Stop 훅이 8회 연속 차단하면 강제로 넘긴다. 가드가 없으면 그 8회를 다 태운다.)
|
||||
2. 소스(`.cs`/`.csproj`/`.xaml`/`.axaml`)의 최신 수정시각을 `.claude/.verify-stamp` 와 비교.
|
||||
같으면 즉시 통과 — 대화만 한 턴은 지연 0.
|
||||
3. 바뀌었으면 `dotnet test VideoDownloader.Tests` 실행 (증분 약 13초).
|
||||
4. 통과 → 스탬프 갱신 후 종료 허용. 실패 → **exit 2 로 종료 차단**, 실패 출력 60줄을 에이전트에게 전달.
|
||||
|
||||
즉 **테스트를 깨둔 채로 턴을 끝낼 수 없다.**
|
||||
|
||||
## 사용법
|
||||
|
||||
### 에이전트 (자율 동작)
|
||||
|
||||
특별히 할 일이 없다. 세션을 열면 브리핑이 들어오고, 계약(`AGENTS.md`)이 로드되고,
|
||||
파일을 열면 해당 영역 규칙이 붙고, 턴을 끝내면 테스트가 돈다.
|
||||
|
||||
기억할 것 세 가지:
|
||||
|
||||
1. 기능 작업은 `/tdd` 로 시작한다. 절차를 기억으로 재구성하지 않는다.
|
||||
2. 마무리 전에 `/verify` 로 완료 기준을 전수 점검한다.
|
||||
3. **Stop 훅이 막으면 우회하지 않는다.** 테스트를 지우거나 Skip 처리하는 것은 회귀를 숨기는 것이다.
|
||||
못 고치면 못 고친다고 보고한다.
|
||||
|
||||
### 사람
|
||||
|
||||
```powershell
|
||||
/hooks # 등록된 훅 확인
|
||||
/context # 어떤 지침 파일이 실제 로드됐는지 확인
|
||||
/memory # CLAUDE.md 등 열어서 편집
|
||||
```
|
||||
|
||||
**게이트를 잠깐 끄고 싶을 때** — 실험 중이라 테스트가 깨진 게 정상인 상황:
|
||||
|
||||
```jsonc
|
||||
// .claude/settings.local.json (gitignore 대상, 개인용)
|
||||
{ "disableAllHooks": true }
|
||||
```
|
||||
|
||||
작업이 끝나면 지운다. 켜 두는 게 기본이다.
|
||||
|
||||
**게이트가 느리다고 느껴지면** — 변경이 없으면 이미 스킵된다. 그래도 무거우면
|
||||
`verify-on-stop.sh` 의 `dotnet test` 를 `--filter` 로 좁히는 대신, 전체 실행 유지를 권한다.
|
||||
부분 검증은 회귀를 놓친다.
|
||||
|
||||
## 확장
|
||||
|
||||
### 새 경로 규칙 추가
|
||||
|
||||
`.claude/rules/<이름>.md` 에 프론트매터로 경로를 지정한다.
|
||||
|
||||
```markdown
|
||||
---
|
||||
paths:
|
||||
- "VideoDownloader.Avalonia/**"
|
||||
---
|
||||
# Avalonia 영역 규칙
|
||||
...
|
||||
```
|
||||
|
||||
해당 경로 파일을 열 때만 컨텍스트에 들어온다. 30줄 안쪽으로 유지한다.
|
||||
|
||||
### 새 절차 스킬 추가
|
||||
|
||||
`.claude/skills/<이름>/SKILL.md`. `description` 이 트리거를 결정하므로
|
||||
**언제 쓰는지**를 구체적으로 쓴다 — "코드 리뷰용"보다 "PR 올리기 전 변경 diff 를 검토할 때".
|
||||
|
||||
### 새 게이트 추가
|
||||
|
||||
무거운 검사(전체 빌드, 통합 테스트)는 `Stop` 에 붙인다. `PostToolUse` 에는 붙이지 않는다 —
|
||||
편집할 때마다 돌면 개발이 멈춘다. .NET 빌드는 특히 비싸다.
|
||||
|
||||
## 원칙
|
||||
|
||||
- **부탁은 CLAUDE.md, 강제는 훅.** 반드시 일어나야 하는 일을 프롬프트에 적어두고 기대하지 않는다.
|
||||
- **게이트는 우회 대상이 아니라 계약이다.** 막히면 원인을 고친다.
|
||||
- **완료 보고에는 실제 출력의 숫자를 인용한다.** 기억으로 쓴 "테스트 통과"는 근거가 아니다.
|
||||
- **되돌릴 수 없는 일 앞에는 사람을 둔다.** 커밋·푸시·배포는 자동화하지 않는다.
|
||||
|
||||
## 참고
|
||||
|
||||
- [Claude Code — 메모리와 CLAUDE.md](https://code.claude.com/docs/en/memory)
|
||||
- [Claude Code — 훅 레퍼런스](https://code.claude.com/docs/en/hooks)
|
||||
- [Claude Code — 스킬](https://code.claude.com/docs/en/skills)
|
||||
- [AGENTS.md 표준](https://agents.md) — 2025년 8월 공개 규격, 2025년 12월 Linux Foundation 산하
|
||||
Agentic AI Foundation 으로 이관. Claude Code 는 `AGENTS.md` 를 직접 읽지 않으므로
|
||||
`CLAUDE.md` 에서 `@AGENTS.md` 로 임포트하는 것이 공식 권장 방식이다.
|
||||
Loading…
Add table
Add a link
Reference in a new issue