From 240849f5eff5d543bbd9ee6adf799affca444b21 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Tue, 11 Aug 2026 00:35:35 +0900 Subject: [PATCH 1/5] fix: pre-existing bash 3.2 and Python syntax bugs found during testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scripts/validate-agents.sh used `declare -A`, which crashes on bash 3.2 (the default /bin/bash on every stock macOS install, despite the repo's own "Platform: macOS" badge). Replaced with a portable space-delimited set so the script actually runs on macOS. - tools/claude-pipeline.py `list` used a backslash-escaped quote inside an f-string nested in another f-string — a SyntaxError on every Python version, so `claude-pipeline list`/`--help` never worked at all. Hoisted the value into a local variable instead. - Added __pycache__/*.pyc to .gitignore (generated while testing tools/). Found while verifying the autonomy/lessons/MCP-guide changes in this branch. --- .gitignore | 4 ++++ scripts/validate-agents.sh | 10 +++++----- tools/claude-pipeline.py | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 2f1b38e..991e00e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,7 @@ desktop.ini # Rust build artifacts rust/target/ + +# Python build artifacts +__pycache__/ +*.pyc diff --git a/scripts/validate-agents.sh b/scripts/validate-agents.sh index 96c8e22..f4c6358 100644 --- a/scripts/validate-agents.sh +++ b/scripts/validate-agents.sh @@ -29,7 +29,7 @@ if [ ! -d "$AGENTS_DIR" ]; then exit 1 fi -declare -A SEEN_NUMS +SEEN_NUMS=" " # space-delimited set; avoids `declare -A` for bash 3.2 (stock macOS) compatibility for f in "$AGENTS_DIR"/[0-9][0-9]-*.md; do [ -f "$f" ] || { warn "No agent files found in $AGENTS_DIR"; break; } @@ -38,10 +38,10 @@ for f in "$AGENTS_DIR"/[0-9][0-9]-*.md; do num="${base:0:2}" # Duplicate number check - if [ "${SEEN_NUMS[$num]+x}" ]; then - fail "Duplicate agent number: $num (${SEEN_NUMS[$num]} and $base)" - fi - SEEN_NUMS[$num]="$base" + case "$SEEN_NUMS" in + *" $num "*) fail "Duplicate agent number: $num ($base)" ;; + *) SEEN_NUMS="$SEEN_NUMS$num " ;; + esac # Non-empty if [ ! -s "$f" ]; then diff --git a/tools/claude-pipeline.py b/tools/claude-pipeline.py index 739776b..39ab9bd 100644 --- a/tools/claude-pipeline.py +++ b/tools/claude-pipeline.py @@ -241,7 +241,8 @@ def cmd_list(): d = json.loads(f.read_text(encoding="utf-8")) marker = green(" ◀ active") if f.stem == active_name else "" stage_count = len(d.get("stages", [])) - print(f" {d['name']}{marker} {dim(f'{stage_count} stages · created {d[\"created\"][:10]}')}") + created = d.get("created", "")[:10] + print(f" {d['name']}{marker} {dim(f'{stage_count} stages · created {created}')}") except Exception: print(f" {f.stem} {red('(corrupted)')}") From 5478e81739e9c673f163e97b65af21075db71e9f Mon Sep 17 00:00:00 2001 From: BcKmini Date: Tue, 11 Aug 2026 00:36:08 +0900 Subject: [PATCH 2/5] feat: add autonomy level (L0-L4) framework to harness design Harness type (tight/loose/adaptive) controls output constraint; autonomy level is a separate axis for how much human checking a task needs before or after the AI acts. Adds the 5-level model (L0 human-only .. L4 fully autonomous, L2 draft+review as the common default) from the AI Agent autonomy article this branch is based on. - autonomy: field added to all 11 agent frontmatters, assigned per role - claude-harness.py: new required check (autonomy declared), `autonomy` subcommand printing the L0-L4 table, templates updated - harness-designer (09): new design step + Autonomy Level output field - docs/HARNESS-GUIDE.md(.ko): new Autonomy Levels section - README Agent Roster table: new Autonomy column - /harness command + cheatsheets: autonomy validate check + prompts Closes #26 --- .claude/commands/harness.md | 9 +++++++++ agents/00-orchestrator.md | 1 + agents/01-planner.md | 1 + agents/02-implementer.md | 1 + agents/03-reviewer.md | 1 + agents/04-tester.md | 1 + agents/05-security-auditor.md | 1 + agents/06-performance-optimizer.md | 1 + agents/07-database-expert.md | 1 + agents/08-documenter.md | 1 + agents/09-harness-designer.md | 20 ++++++++++++++++++-- agents/10-pipeline-orchestrator.md | 1 + docs/AGENT-CHEATSHEET.ko.md | 18 +++++++++++++++++- docs/AGENT-CHEATSHEET.md | 18 +++++++++++++++++- docs/HARNESS-GUIDE.ko.md | 30 +++++++++++++++++++++++++++++- docs/HARNESS-GUIDE.md | 28 ++++++++++++++++++++++++++++ tools/claude-harness.py | 27 +++++++++++++++++++++++++++ 17 files changed, 155 insertions(+), 5 deletions(-) diff --git a/.claude/commands/harness.md b/.claude/commands/harness.md index 828a357..f2a7a1a 100644 --- a/.claude/commands/harness.md +++ b/.claude/commands/harness.md @@ -8,6 +8,7 @@ Design an AI harness for automating a specific workflow. /harness design /harness validate /harness types +/harness autonomy ``` --- @@ -59,6 +60,7 @@ Reviews an existing agent `.md` file and checks: - [ ] Output format is constrained - [ ] Forbidden actions are listed - [ ] Tools are minimal (only what's needed) +- [ ] Autonomy level (L0-L4) is declared - [ ] Human oversight point is defined --- @@ -69,5 +71,12 @@ Prints a quick reference of all three harness types with examples and trade-offs --- +## /harness autonomy + +Prints the L0-L4 autonomy level reference (`claude-harness autonomy`) — how much human +checking a task needs, independent of harness type. See `docs/HARNESS-GUIDE.md#autonomy-levels-l0-l4`. + +--- + *Powered by `harness-designer` (agent 09) — see `agents/09-harness-designer.md`* *Inspired by: Musinsa Tech Blog — AI Specialist + Harness-controlled Pipeline* diff --git a/agents/00-orchestrator.md b/agents/00-orchestrator.md index 58b1175..079819c 100644 --- a/agents/00-orchestrator.md +++ b/agents/00-orchestrator.md @@ -2,6 +2,7 @@ name: orchestrator description: "Master coordinator for all tasks. Analyzes complex requests and delegates to specialist agents. Auto-invoked for 'add feature', 'improve code', 'find bug', etc. | 모든 작업의 시작점. 복잡한 요청을 분석해 전문 에이전트에게 위임하는 총괄 지휘자. '새 기능 만들어줘', '이 코드 개선해줘', '버그 잡아줘' 등 큰 작업에 자동 호출됨." model: claude-opus-4-5 +autonomy: L2 # drafts a delegation plan; human reviews before irreversible sub-agent actions tools: Read, Glob, Grep, Task, TodoWrite --- diff --git a/agents/01-planner.md b/agents/01-planner.md index 4c9e962..2f4ec9d 100644 --- a/agents/01-planner.md +++ b/agents/01-planner.md @@ -2,6 +2,7 @@ name: planner description: "Architecture & design expert. Analysis only — no code changes. Called for 'design this', 'plan the architecture', or by orchestrator at design phase. | 구현 전 설계·전략 수립 전문가. 코드 변경 없이 분석만 수행. '어떻게 만들지 설계해줘', '아키텍처 잡아줘' 또는 orchestrator가 설계 단계에서 호출." model: claude-opus-4-5 +autonomy: L1 # proposes a design; human decides whether to proceed tools: Read, Grep, Glob permissionMode: default --- diff --git a/agents/02-implementer.md b/agents/02-implementer.md index 0b8251f..1287525 100644 --- a/agents/02-implementer.md +++ b/agents/02-implementer.md @@ -2,6 +2,7 @@ name: implementer description: "Writes and edits code. Takes planner's design and implements it. Called for 'write code', 'add feature', 'fix bug'. | 실제 코드 작성·수정 전담. planner의 설계를 받아 구현. '코드 작성해줘', '기능 추가해줘', '버그 수정해줘' 시 호출." model: claude-sonnet-4-5 +autonomy: L2 # writes code; human reviews via reviewer/PR before merge tools: Read, Write, Edit, Bash, Glob, Grep, TodoRead, TodoWrite --- diff --git a/agents/03-reviewer.md b/agents/03-reviewer.md index a28089b..7a39f63 100644 --- a/agents/03-reviewer.md +++ b/agents/03-reviewer.md @@ -2,6 +2,7 @@ name: reviewer description: "Code reviewer. Called immediately after code changes. Reviews from 4 angles: bugs, security, quality, performance. Read-only — never modifies code. | 코드 수정 후 즉시 호출. 버그·보안·품질·성능 4가지 관점 리뷰. 절대 코드 수정 안 함. PR 전, 구현 완료 후 자동 호출." model: claude-sonnet-4-5 +autonomy: L1 # read-only findings; human decides what to act on tools: Read, Grep, Glob permissionMode: default memory: user diff --git a/agents/04-tester.md b/agents/04-tester.md index 72342f2..19e64be 100644 --- a/agents/04-tester.md +++ b/agents/04-tester.md @@ -2,6 +2,7 @@ name: tester description: "Writes and runs unit, integration, and E2E tests. Called after reviewer approval. Triggered by 'write tests', 'increase coverage'. | 유닛·통합·E2E 테스트 작성 및 실행 전담. reviewer 승인 후 호출. '테스트 작성해줘', '테스트 커버리지 높여줘' 시 호출." model: claude-sonnet-4-5 +autonomy: L2 # writes/runs tests; human reviews results before merge tools: Read, Write, Edit, Bash, Glob, Grep --- diff --git a/agents/05-security-auditor.md b/agents/05-security-auditor.md index 9001d81..d8a9d1b 100644 --- a/agents/05-security-auditor.md +++ b/agents/05-security-auditor.md @@ -2,6 +2,7 @@ name: security-auditor description: "Security vulnerability specialist. Called before PRs or when 'security review' is requested. OWASP Top 10 audit. Read-only. | 보안 취약점 전문 감사. PR 전 또는 '보안 검토해줘' 시 호출. OWASP Top 10 기준 검토. 읽기 전용." model: claude-opus-4-5 +autonomy: L1 # read-only audit; human judges risk and remediation tools: Read, Grep, Glob, Bash permissionMode: default --- diff --git a/agents/06-performance-optimizer.md b/agents/06-performance-optimizer.md index f899c11..cc95694 100644 --- a/agents/06-performance-optimizer.md +++ b/agents/06-performance-optimizer.md @@ -2,6 +2,7 @@ name: performance-optimizer description: "Performance bottleneck analyst and optimizer. Called for 'slow', 'optimize', 'improve performance'. Analyzes and provides concrete fix directions. | 성능 병목 분석 및 최적화 전문가. '느려', '성능 개선', '최적화' 키워드 시 호출. 분석 후 구체적 수정 방향 제시." model: claude-sonnet-4-5 +autonomy: L2 # applies optimizations; human reviews before merge tools: Read, Grep, Glob, Bash, Edit, Write --- diff --git a/agents/07-database-expert.md b/agents/07-database-expert.md index 75809c5..bb97b0a 100644 --- a/agents/07-database-expert.md +++ b/agents/07-database-expert.md @@ -2,6 +2,7 @@ name: database-expert description: "DB schema design, query optimization, and migration expert. Called for DB work, schema changes, query tuning. | DB 스키마 설계·쿼리 최적화·마이그레이션 전문가. DB 관련 작업, 스키마 변경, 쿼리 튜닝 시 호출." model: claude-sonnet-4-5 +autonomy: L2 # drafts schema/migrations; human approves before applying (irreversible on prod data) tools: Read, Write, Edit, Bash, Grep, Glob --- diff --git a/agents/08-documenter.md b/agents/08-documenter.md index b766613..0258c08 100644 --- a/agents/08-documenter.md +++ b/agents/08-documenter.md @@ -2,6 +2,7 @@ name: documenter description: "README, API docs, and inline comment writer. Called for 'document this', 'update README', 'write API docs'. Does NOT modify code logic. | README·API 문서·인라인 주석 작성 전담. '문서화해줘', 'README 업데이트', 'API 문서 만들어줘' 시 호출. 코드 수정 안 함." model: claude-haiku-4-5 +autonomy: L3 # applies doc edits directly; human spot-checks after (low blast radius) tools: Read, Write, Edit, Grep, Glob --- diff --git a/agents/09-harness-designer.md b/agents/09-harness-designer.md index 32744d1..103e2a2 100644 --- a/agents/09-harness-designer.md +++ b/agents/09-harness-designer.md @@ -2,6 +2,7 @@ name: harness-designer description: "AI harness architect. Designs tight/loose/adaptive harnesses for specialist AI agents. Called for 'design an AI pipeline', 'build a specialist agent', 'automate this workflow with AI'. | AI 하네스 설계 전문가. 특정 문제에 최적화된 타이트·느슨·적응형 하네스를 설계. 'AI 파이프라인 설계해줘', '스페셜리스트 에이전트 만들어줘', 'AI로 이 업무 자동화해줘' 시 호출." model: claude-opus-4-5 +autonomy: L1 # proposes a harness design; human implements and approves tools: Read, Grep, Glob permissionMode: default --- @@ -87,9 +88,21 @@ Verdict: PASS | WARNING | MISMATCH | ERROR Default behavior: warn (not block), unless high-stakes ``` -### Step 5: Human Oversight Points (사람의 개입 지점) +### Step 5: Autonomy Level (자율성 수준) +Pick the level the task needs — not the highest one available: ``` -- What decisions does the AI make autonomously? +L0 Human does everything — AI not involved +L1 AI proposes, human executes +L2 AI drafts, human reviews ← most common in practice +L3 AI executes, human checks after the fact +L4 Fully autonomous +``` +Full autonomy is a stretch goal, not a default. Choose the level that matches the task's +blast radius today; raise it later once the harness has a track record. + +### Step 6: Human Oversight Points (사람의 개입 지점) +``` +- What decisions does the AI make autonomously? (bounded by the autonomy level above) - What requires human approval before proceeding? - What is NEVER automated (final merge, production apply, etc.)? ``` @@ -104,6 +117,9 @@ Default behavior: warn (not block), unless high-stakes ### Harness Type [Tight / Loose / Adaptive] — reason +### Autonomy Level +[L0-L4] — reason + ### Specialist Agents Required | Agent | Persona | Input | Output | Forbidden | |-------|---------|-------|--------|-----------| diff --git a/agents/10-pipeline-orchestrator.md b/agents/10-pipeline-orchestrator.md index 8c12fe4..49f4a68 100644 --- a/agents/10-pipeline-orchestrator.md +++ b/agents/10-pipeline-orchestrator.md @@ -2,6 +2,7 @@ name: pipeline-orchestrator description: "Multi-stage AI pipeline manager. Executes harness-designed pipelines with context isolation, parallel agents, and review loops. Called for 'run the pipeline', 'execute this automated workflow', 'run all stages'. | 다단계 AI 파이프라인 실행 관리자. 컨텍스트 격리, 병렬 에이전트, 리뷰 루프를 포함한 하네스 기반 파이프라인 실행. '파이프라인 실행해줘', '자동화 워크플로우 돌려줘', '모든 단계 실행해줘' 시 호출." model: claude-opus-4-5 +autonomy: L2 # executes pipeline stages; quality gates + human oversight points per stage tools: Read, Glob, Grep, Task, TodoWrite, TodoRead --- diff --git a/docs/AGENT-CHEATSHEET.ko.md b/docs/AGENT-CHEATSHEET.ko.md index a8ed43a..0999499 100644 --- a/docs/AGENT-CHEATSHEET.ko.md +++ b/docs/AGENT-CHEATSHEET.ko.md @@ -131,6 +131,17 @@ Produce a run report at the end. claude-harness check-all # agents/ 폴더 전체 검증 ``` +### 하네스 설계 전에 자율성 레벨부터 정하기 +```bash +claude-harness autonomy # L0-L4 참조표 출력 +``` +``` +Have harness-designer design a harness for [작업]. +자율성 레벨(L0-L4)을 명시적으로 정하고 근거를 밝혀줘 — +작업의 영향 범위가 명확히 낮은 감독으로도 충분하지 않다면 +기본값은 L2(AI 초안, 사람 리뷰)로 해줘. +``` + ### 파이프라인 추적 워크플로우 ```bash claude-pipeline init my-workflow @@ -197,6 +208,8 @@ claude --agent reviewer "re-check src/auth after implementer changes" | `/harness validate` | 에이전트 하네스 검증 | `/harness validate agents/03-reviewer.md` | | `/pipeline run` | 다단계 파이프라인 실행 | `/pipeline run 분석 및 패치 생성` | | `/pipeline status` | 파이프라인 실행 현황 | `/pipeline status` | +| `/lessons add` | 실패 원인과 해결법 기록 | `/lessons add` | +| `/lessons context` | 특정 주제의 과거 실패 회상 | `/lessons context --tag db` | --- @@ -211,6 +224,7 @@ claude --agent reviewer "re-check src/auth after implementer changes" | 환경 헬스체크 | `claude-tools env` | | 미완료 작업으로 재개 | `claude-remind \| claude` | | 전체 세션 복원 | `claude-handoff load \| claude` | +| 이 영역의 과거 실패 회상 | `claude-lessons context --tag X \| claude` | | 특정 파일만 참조 | `@src/auth/login.ts 이 파일 리뷰해줘` | --- @@ -220,10 +234,12 @@ claude --agent reviewer "re-check src/auth after implementer changes" ```bash # 세션 종료 claude-handoff save --note "OAuth 완료, 다음: 이메일 인증" +claude-lessons add # 오늘 실패했다가 고친 게 있을 때만 -# 세션 시작 (하나 또는 둘 다 사용) +# 세션 시작 (필요한 것 선택) claude-remind | claude # 미완료 TODO 항목 확인 claude-handoff load | claude # 전체 git 컨텍스트 복원 +claude-lessons context | claude # 이 영역을 다시 건드리기 전 과거 실패 회상 ``` --- diff --git a/docs/AGENT-CHEATSHEET.md b/docs/AGENT-CHEATSHEET.md index fd828b1..0273bf7 100644 --- a/docs/AGENT-CHEATSHEET.md +++ b/docs/AGENT-CHEATSHEET.md @@ -131,6 +131,17 @@ Early exit if: no new findings or no improvement vs. previous round. claude-harness check-all # validate all agents in agents/ ``` +### Pick an Autonomy Level Before Designing a Harness +```bash +claude-harness autonomy # print the L0-L4 reference table +``` +``` +Have harness-designer design a harness for [task]. +State the autonomy level (L0-L4) explicitly and justify it — +default to L2 (AI drafts, human reviews) unless the task's +blast radius clearly justifies less oversight. +``` + ### Pipeline Tracking Workflow ```bash claude-pipeline init my-workflow @@ -197,6 +208,8 @@ claude --agent reviewer "re-check src/auth after implementer changes" | `/harness validate` | Validate agent harness | `/harness validate agents/03-reviewer.md` | | `/pipeline run` | Run a multi-stage pipeline | `/pipeline run analyze and patch slow queries` | | `/pipeline status` | Show pipeline run status | `/pipeline status` | +| `/lessons add` | Record why something failed and the fix | `/lessons add` | +| `/lessons context` | Recall past failures for a topic | `/lessons context --tag db` | --- @@ -211,6 +224,7 @@ claude --agent reviewer "re-check src/auth after implementer changes" | Environment health check | `claude-tools env` | | Resume with pending tasks | `claude-remind \| claude` | | Full session restore | `claude-handoff load \| claude` | +| Recall past failures for this area | `claude-lessons context --tag X \| claude` | | Reference a specific file | `@src/auth/login.ts review this file` | --- @@ -220,10 +234,12 @@ claude --agent reviewer "re-check src/auth after implementer changes" ```bash # End of session claude-handoff save --note "OAuth done, next: email verification" +claude-lessons add # only if something failed and got fixed today -# Start of next session (pick one or both) +# Start of next session (pick what's relevant) claude-remind | claude # see pending TODO items claude-handoff load | claude # full git context restore +claude-lessons context | claude # recall past failures before touching this area again ``` --- diff --git a/docs/HARNESS-GUIDE.ko.md b/docs/HARNESS-GUIDE.ko.md index a143191..e2233b6 100644 --- a/docs/HARNESS-GUIDE.ko.md +++ b/docs/HARNESS-GUIDE.ko.md @@ -1,6 +1,6 @@ [← README로 돌아가기](../README.md) -**English** · **[한국어](HARNESS-GUIDE.ko.md)** +**[English](HARNESS-GUIDE.md)** · **한국어** # AI 하네스 설계 가이드 @@ -79,6 +79,31 @@ AI 기반 워크플로우에서 엔지니어의 역할: --- +## 자율성 레벨 (L0-L4) + +하네스 유형(타이트/느슨/적응형)은 *출력*이 얼마나 제약되는지를 결정합니다. 자율성 레벨은 별개의 축입니다 — 작업 전후로 *사람의 확인*이 얼마나 필요한지를 나타냅니다. 타이트 하네스라도 모든 출력에 승인이 필요할 수 있습니다. + +> *참고: "AI Agent 시대, 나는 AI를 어떻게 써야 할까?" (velog.io/@mi_nini)의 5단계 자율성 모델* + +| 레벨 | 누가 무엇을 하는가 | 이 프로젝트의 예시 | +|---|---|---| +| **L0** | 사람이 전부 담당 — AI 미개입 | 최종 머지, 프로덕션 배포 | +| **L1** | AI 제안, 사람 실행 | `planner`, `reviewer`, `security-auditor`, `harness-designer` — 읽기 전용, 출력은 참고용 | +| **L2** | AI 초안, 사람 리뷰 — **실무에서 가장 일반적** | `orchestrator`, `implementer`, `tester`, `performance-optimizer`, `database-expert`, `pipeline-orchestrator` | +| **L3** | AI 실행, 사후 확인 | `documenter` — 영향 범위가 작고 코드 로직은 건드리지 않음 | +| **L4** | 완전 자율 | 이 프로젝트에서 기본값으로 사용하지 않음 — 시작점이 아니라 장기 목표 | + +**원칙:** 모델이 낼 수 있는 최고 레벨이 아니라 *작업*에 맞는 레벨을 선택하세요. 하네스는 가정이 아니라 실적을 쌓으며 더 높은 자율성을 얻습니다. + +에이전트 frontmatter에 명시: +```yaml +autonomy: L2 # AI 초안, 사람 리뷰 +``` + +`claude-harness check-all` / `claude-harness validate`는 자율성 레벨을 선언하지 않은 에이전트를 실패 처리합니다. `claude-harness autonomy`로 이 표를 커맨드라인에 출력할 수 있습니다. + +--- + ## 컨텍스트 격리: Context Rot 방지 긴 파이프라인에서 축적된 컨텍스트는 "Context Rot"을 유발합니다 — 초기 오류가 후속 단계를 오염시킵니다. @@ -233,6 +258,9 @@ claude-harness validate agents/09-harness-designer.md # 타이트 하네스 템플릿 생성 claude-harness template tight my-specialist > agents/11-my-specialist.md +# L0-L4 자율성 레벨 참조표 출력 +claude-harness autonomy + # 파이프라인 실행 추적 claude-pipeline init my-workflow claude-pipeline stage "분석" start diff --git a/docs/HARNESS-GUIDE.md b/docs/HARNESS-GUIDE.md index 92dcd6b..7e0d3d8 100644 --- a/docs/HARNESS-GUIDE.md +++ b/docs/HARNESS-GUIDE.md @@ -79,6 +79,31 @@ Characteristics: --- +## Autonomy Levels (L0-L4) + +Harness type (tight/loose/adaptive) controls how constrained the *output* is. Autonomy level is a separate axis: how much *human checking* the task needs before or after the AI acts. A tight harness can still require approval on every single output. + +> *Inspired by the 5-level autonomy model in: "AI Agent 시대, 나는 AI를 어떻게 써야 할까?" (velog.io/@mi_nini)* + +| Level | Who does what | Example in this project | +|---|---|---| +| **L0** | Human does everything — AI not involved | Final merge, production deploy | +| **L1** | AI proposes, human executes | `planner`, `reviewer`, `security-auditor`, `harness-designer` — read-only, output is advisory | +| **L2** | AI drafts, human reviews — **most common in practice** | `orchestrator`, `implementer`, `tester`, `performance-optimizer`, `database-expert`, `pipeline-orchestrator` | +| **L3** | AI executes, human checks after the fact | `documenter` — low blast radius, doesn't touch code logic | +| **L4** | Fully autonomous | Not used by default in this project — a stretch goal, not a starting point | + +**Rule of thumb:** pick the level the *task* needs today, not the highest one the model is capable of. A harness earns a higher autonomy level over time by building a track record, not by assumption. + +Declare it in the agent's frontmatter: +```yaml +autonomy: L2 # AI drafts, human reviews +``` + +`claude-harness check-all` / `claude-harness validate` fail an agent that doesn't declare one. Run `claude-harness autonomy` to print this table on the command line. + +--- + ## Context Isolation: Preventing Context Rot In long pipelines, accumulated context causes "Context Rot" — early errors contaminate later stages. @@ -233,6 +258,9 @@ claude-harness validate agents/09-harness-designer.md # Generate a tight harness template claude-harness template tight my-specialist > agents/11-my-specialist.md +# Print the L0-L4 autonomy level reference +claude-harness autonomy + # Track pipeline execution claude-pipeline init my-workflow claude-pipeline stage "analysis" start diff --git a/tools/claude-harness.py b/tools/claude-harness.py index 26bd67b..5463d4e 100644 --- a/tools/claude-harness.py +++ b/tools/claude-harness.py @@ -45,8 +45,17 @@ def dim(s): ("forbidden_listed", "Forbidden actions are listed", r"(never|do not|must not|forbidden|절대)", True), ("tools_minimal", "Tools list is minimal", r"^tools:", True), ("language_support", "Bilingual language support", r"(Language:|language:|Korean|한국어)", True), + ("autonomy_declared", "Autonomy level (L0-L4) is declared", r"^autonomy:\s*L[0-4]", True), ] +AUTONOMY_LEVELS = { + "L0": "Human does everything — AI not involved", + "L1": "AI proposes, human executes", + "L2": "AI drafts, human reviews (most common)", + "L3": "AI executes, human checks after the fact", + "L4": "Fully autonomous", +} + def parse_frontmatter(content): """Extract YAML frontmatter from a markdown file.""" @@ -141,6 +150,7 @@ def check_all_agents(): name: {name} description: "[EN description] | [KO 설명]" model: claude-sonnet-4-5 +autonomy: L2 # [why this level fits — see: claude-harness autonomy] tools: Read, Grep, Glob permissionMode: default --- @@ -176,6 +186,7 @@ def check_all_agents(): name: {name} description: "[EN description] | [KO 설명]" model: claude-opus-4-5 +autonomy: L1 # [why this level fits — see: claude-harness autonomy] tools: Read, Write, Edit, Bash, Glob, Grep --- @@ -201,6 +212,7 @@ def check_all_agents(): name: {name} description: "[EN description] | [KO 설명]" model: claude-opus-4-5 +autonomy: L2 # [why this level fits — see: claude-harness autonomy] tools: Read, Glob, Grep, Task, TodoWrite --- @@ -240,6 +252,17 @@ def print_template(harness_type, name="my-agent"): print(TEMPLATES[harness_type].format(name=name, title=title)) +def print_autonomy_levels(): + print(bold("Autonomy Levels (L0-L4)")) + print(dim("=" * 50)) + for level, desc in AUTONOMY_LEVELS.items(): + print(f" {bold(level)} {desc}") + print() + print(dim("Declare one per agent with an `autonomy:` frontmatter field.")) + print(dim("Pick the level the TASK needs, not the highest one available —")) + print(dim("L2 (draft + human review) is the most common in practice.")) + + def usage(): print(f"""{bold('claude-harness')} v{VERSION} — AI harness design helper @@ -247,11 +270,13 @@ def usage(): validate Validate a single agent file check-all Check all agents in agents/ template tight|loose|adaptive Print a harness template + autonomy Print the L0-L4 autonomy level reference {bold('Examples:')} claude-harness validate agents/03-reviewer.md claude-harness check-all claude-harness template tight > agents/11-my-specialist.md + claude-harness autonomy """) @@ -274,6 +299,8 @@ def main(): harness_type = args[1] if len(args) > 1 else "tight" agent_name = args[2] if len(args) > 2 else "my-specialist" print_template(harness_type, agent_name) + elif cmd == "autonomy": + print_autonomy_levels() else: print(red(f"Unknown command: {cmd}")) usage() From b3c324d677d6ff76175e34fbe5c3743f1b168e70 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Tue, 11 Aug 2026 00:36:30 +0900 Subject: [PATCH 3/5] feat: add claude-lessons failure/lessons-learned tool claude-handoff captures session state; nothing in this project recorded WHY something failed and HOW it was fixed, so the next session (or agent) had no way to avoid repeating a past mistake. Unlike handoffs, lessons accumulate indefinitely and are searchable by tag/keyword rather than pruned by age. claude-lessons add # symptom / root cause / fix / tags claude-lessons list # recent, optionally filtered by tag claude-lessons search Q # keyword search claude-lessons context # pipeable into claude for session-start context Stdlib-only, mirrors tools/claude-handoff.py conventions. Wired into Makefile install-tools/status/test-python and install.sh's TOOLS array. Closes #27 --- .claude/commands/lessons.md | 52 ++++++ Makefile | 7 +- install.sh | 2 +- tools/claude-lessons.py | 306 ++++++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 .claude/commands/lessons.md create mode 100755 tools/claude-lessons.py diff --git a/.claude/commands/lessons.md b/.claude/commands/lessons.md new file mode 100644 index 0000000..8c50d56 --- /dev/null +++ b/.claude/commands/lessons.md @@ -0,0 +1,52 @@ +# /lessons — Failure / Lessons-Learned Log + +Record why something failed and how it was fixed, so the next session doesn't repeat it. Complements `/handoff` (session state) and `/remind` (pending tasks) — `/lessons` is for accumulated knowledge, not session snapshots. + +## Usage + +``` +/lessons add # record a new lesson (prompts for missing fields) +/lessons list # recent lessons +/lessons list --tag db # filter by tag +/lessons search QUERY # keyword search +/lessons show # most recent lesson (or --id ID) +/lessons context # print matching lessons, pipeable into claude +``` + +## Recording a lesson + +```bash +claude-lessons add \ + --title "Migration timed out" \ + --tags db,migration \ + --symptom "ALTER TABLE locked prod for 4min" \ + --cause "no lock_timeout set" \ + --fix "added SET lock_timeout='2s' before DDL" +``` + +Any field left out is prompted for interactively. + +## Recalling lessons at session start + +```bash +claude-lessons context | claude # last 5 lessons, any tag +claude-lessons context --tag db | claude # only db-tagged lessons +``` + +## Typical workflow + +```bash +# During/after debugging a tricky failure +claude-lessons add + +# Start of a new session touching the same area +claude-lessons context --tag db | claude +``` + +## Tool + +Runs `python tools/claude-lessons.py` (or `claude-lessons` if installed globally). + +Install: `make install-tools` + +Unlike `claude-handoff`, lessons are **not** pruned automatically — they're meant to accumulate as long-term project memory. diff --git a/Makefile b/Makefile index 1189301..b182c58 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ install-commands: ## Install slash commands to ~/.claude/commands/ install-tools: ## Install Python tools to ~/.local/bin/ @mkdir -p $(BIN_TARGET) - @for tool in snippet claude-handoff claude-cost claude-review-diff claude-remind claude-harness claude-pipeline; do \ + @for tool in snippet claude-handoff claude-cost claude-review-diff claude-remind claude-harness claude-pipeline claude-lessons; do \ src="$(TOOLS_DIR)/$$tool.py"; \ dst="$(BIN_TARGET)/$$tool"; \ if [ -f "$$src" ]; then \ @@ -96,6 +96,9 @@ test-python: ## Smoke-test Python tools @echo "Testing claude-pipeline..." @$(PYTHON) $(TOOLS_DIR)/claude-pipeline.py --help > /dev/null \ && echo " ✓ pipeline --help" || echo " ✗ pipeline" + @echo "Testing claude-lessons..." + @$(PYTHON) $(TOOLS_DIR)/claude-lessons.py --help > /dev/null \ + && echo " ✓ lessons --help" || echo " ✗ lessons" test-agents: ## Verify agent files exist and are non-empty @ok=0; fail=0; \ @@ -143,7 +146,7 @@ status: ## Show git + agent + tool install status @ls $(AGENTS_TARGET)/*.md 2>/dev/null | wc -l | xargs -I{} echo " {} agents in $(AGENTS_TARGET)" @echo "" @echo "=== Tools in PATH ===" - @for t in snippet claude-handoff claude-cost claude-review-diff claude-remind claude-harness claude-pipeline claude-tools; do \ + @for t in snippet claude-handoff claude-cost claude-review-diff claude-remind claude-harness claude-pipeline claude-lessons claude-tools; do \ command -v $$t >/dev/null 2>&1 \ && echo " ✓ $$t" \ || echo " ✗ $$t (not installed)"; \ diff --git a/install.sh b/install.sh index 13d3365..f758506 100644 --- a/install.sh +++ b/install.sh @@ -310,7 +310,7 @@ ok "${count} slash commands → ${CLAUDE_HOME}/commands/" if need_cmd python3; then mkdir -p "$BIN_DIR" - TOOLS=(snippet claude-handoff claude-cost claude-review-diff claude-remind claude-harness claude-pipeline) + TOOLS=(snippet claude-handoff claude-cost claude-review-diff claude-remind claude-harness claude-pipeline claude-lessons) for tool in "${TOOLS[@]}"; do src="${REPO_DIR}/tools/${tool}.py" [ -f "$src" ] || continue diff --git a/tools/claude-lessons.py b/tools/claude-lessons.py new file mode 100755 index 0000000..a6d4b6f --- /dev/null +++ b/tools/claude-lessons.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 +""" +claude-lessons v1.0 -- Failure / lessons-learned log for Claude Code + +Handoffs capture session state; lessons capture WHY something failed and +HOW it was fixed, so the next session (or the next agent) doesn't repeat +the same mistake. Unlike handoffs, lessons are meant to accumulate +indefinitely and be searched by tag or keyword. + +Homepage: https://github.com/BcKmini/claude-code-use +""" + +VERSION = "1.0.0" + +import argparse +import os +import sys +from datetime import datetime +from pathlib import Path + +LESSONS_DIR = Path.home() / ".claude" / "lessons" + +# --------------------------------------------------------------------------- +# Color support +# --------------------------------------------------------------------------- + +def _enable_win_vt() -> None: + if sys.platform != "win32": + return + try: + import ctypes + k = ctypes.windll.kernel32 + k.SetConsoleMode(k.GetStdHandle(-11), 7) + except Exception: + pass + + +_enable_win_vt() +_COLOR = sys.stdout.isatty() and not os.environ.get("NO_COLOR") + + +def _c(code: str, text: str) -> str: + return f"\033[{code}m{text}\033[0m" if _COLOR else text + + +def green(s): return _c("32", s) +def yellow(s): return _c("33", s) +def cyan(s): return _c("36", s) +def red(s): return _c("31", s) +def bold(s): return _c("1", s) +def dim(s): return _c("2", s) + + +# --------------------------------------------------------------------------- +# Storage +# --------------------------------------------------------------------------- + +def _lesson_id() -> str: + """Timestamp-based ID, disambiguated on collision so rapid adds never overwrite.""" + base = datetime.now().strftime("%Y%m%d-%H%M%S") + if not _lesson_path(base).exists(): + return base + n = 2 + while _lesson_path(f"{base}-{n}").exists(): + n += 1 + return f"{base}-{n}" + + +def _lesson_path(lid: str) -> Path: + return LESSONS_DIR / f"{lid}.md" + + +def _prompt(label: str) -> str: + sys.stdout.write(f"{label}: ") + sys.stdout.flush() + return sys.stdin.readline().strip() + + +def _build_lesson_doc(title, tags, symptom, cause, fix) -> str: + ts = datetime.now().strftime("%Y-%m-%d %H:%M") + lines = [ + f"# Lesson — {ts}", + "", + f"**Title:** {title}", + f"**Tags:** {tags or '(none)'}", + "", + "## Symptom", + symptom or "(not recorded)", + "", + "## Root Cause", + cause or "(not recorded)", + "", + "## Fix", + fix or "(not recorded)", + "", + ] + return "\n".join(lines) + + +def _parse_lesson(path: Path) -> dict: + content = path.read_text(encoding="utf-8") + title = "" + tags = "" + for line in content.splitlines(): + if line.startswith("**Title:**"): + title = line.replace("**Title:**", "").strip() + elif line.startswith("**Tags:**"): + tags = line.replace("**Tags:**", "").strip() + return {"id": path.stem, "path": path, "title": title, "tags": tags, "content": content} + + +def _list_lessons() -> list: + if not LESSONS_DIR.exists(): + return [] + files = sorted(LESSONS_DIR.glob("*.md"), reverse=True) + items = [] + for f in files: + try: + items.append(_parse_lesson(f)) + except Exception: + pass + return items + + +# --------------------------------------------------------------------------- +# Commands +# --------------------------------------------------------------------------- + +def cmd_add(args): + LESSONS_DIR.mkdir(parents=True, exist_ok=True) + + title = args.title or _prompt("Title (what went wrong, one line)") + if not title: + print(red("[!] Title is required."), file=sys.stderr) + sys.exit(2) + + tags = args.tags or _prompt("Tags (comma-separated, optional)") + symptom = args.symptom or _prompt("Symptom (what you observed)") + cause = args.cause or _prompt("Root cause (why it happened)") + fix = args.fix or _prompt("Fix (how it was resolved)") + + doc = _build_lesson_doc(title, tags, symptom, cause, fix) + lid = _lesson_id() + path = _lesson_path(lid) + path.write_text(doc, encoding="utf-8") + + print(green(f"[OK] Lesson saved: {lid}")) + print(dim(f" {path}")) + + +def cmd_list(args): + items = _list_lessons() + if args.tag: + needle = args.tag.lower() + items = [i for i in items if needle in i["tags"].lower()] + + if not items: + print(yellow("No lessons recorded yet.")) + print(dim(" Run: claude-lessons add")) + return + + n = args.limit or 20 + items = items[:n] + + print(f"\n {bold('id'):<22} {bold('tags'):<24} {bold('title')}") + print(" " + dim("-" * 90)) + for item in items: + print(f" {cyan(item['id']):<{22+9}} " + f"{dim(item['tags'] or '-'):<{24+9}} " + f"{item['title']}") + print(f"\n {dim(str(len(items)) + ' lesson(s)')}\n") + + +def cmd_show(args): + items = _list_lessons() + if not items: + print(yellow("No lessons recorded yet.")) + return + + if args.id: + matches = [i for i in items if i["id"] == args.id] + if not matches: + print(red(f"[!] Lesson '{args.id}' not found."), file=sys.stderr) + sys.exit(1) + item = matches[0] + else: + item = items[0] + + print(item["content"]) + + +def cmd_search(args): + items = _list_lessons() + needle = args.query.lower() + matches = [i for i in items if needle in i["content"].lower()] + + if not matches: + print(yellow(f"No lessons matching '{args.query}'.")) + return + + print(f"\n {bold('id'):<22} {bold('tags'):<24} {bold('title')}") + print(" " + dim("-" * 90)) + for item in matches: + print(f" {cyan(item['id']):<{22+9}} " + f"{dim(item['tags'] or '-'):<{24+9}} " + f"{item['title']}") + print(f"\n {dim(str(len(matches)) + ' match(es)')}\n") + + +def cmd_context(args): + items = _list_lessons() + if args.tag: + needle = args.tag.lower() + items = [i for i in items if needle in i["tags"].lower()] + + n = args.limit or 5 + items = items[:n] + + if not items: + if sys.stdout.isatty(): + print(dim("No lessons recorded yet. Run: claude-lessons add"), file=sys.stderr) + return + + print("# Lessons Learned — Context") + print() + print("Before proceeding, note the following past failures and their fixes") + print("so you don't repeat them:") + print() + for item in items: + print(f"---\n{item['content']}") + + if sys.stdout.isatty(): + print(dim("\n-- Tip: pipe to claude: claude-lessons context | claude"), + file=sys.stderr) + + +def cmd_version(args): + print(f"claude-lessons {bold(VERSION)}") + + +# --------------------------------------------------------------------------- +# Argument parser +# --------------------------------------------------------------------------- + +def _build_parser() -> argparse.ArgumentParser: + p = argparse.ArgumentParser( + prog="claude-lessons", + description="Failure / lessons-learned log for Claude Code", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +examples: + claude-lessons add --title "Migration timed out" --tags db,migration \\ + --symptom "ALTER TABLE locked prod for 4min" \\ + --cause "no lock_timeout set" \\ + --fix "added SET lock_timeout='2s' before DDL" + claude-lessons list --tag db + claude-lessons search "lock_timeout" + claude-lessons context | claude +""", + ) + p.add_argument("--version", action="version", version=f"claude-lessons {VERSION}") + + sub = p.add_subparsers(dest="command", metavar="") + sub.required = True + + s = sub.add_parser("add", help="Record a new lesson (what failed, why, how it was fixed)") + s.add_argument("--title", "-t", help="Short title — what went wrong") + s.add_argument("--tags", help="Comma-separated tags") + s.add_argument("--symptom", help="What you observed") + s.add_argument("--cause", help="Root cause") + s.add_argument("--fix", help="How it was resolved") + s.set_defaults(func=cmd_add) + + s = sub.add_parser("list", help="List recorded lessons") + s.add_argument("--limit", "-n", type=int, default=20, help="Max entries to show (default: 20)") + s.add_argument("--tag", help="Filter by tag substring") + s.set_defaults(func=cmd_list) + + s = sub.add_parser("show", help="Show full lesson content") + s.add_argument("--id", help="Lesson ID (default: most recent)") + s.set_defaults(func=cmd_show) + + s = sub.add_parser("search", help="Search lessons by keyword") + s.add_argument("query", help="Keyword to search for") + s.set_defaults(func=cmd_search) + + s = sub.add_parser("context", + help="Print matching lessons (pipe to claude for session-start context)") + s.add_argument("--limit", "-n", type=int, default=5, help="Max lessons to include (default: 5)") + s.add_argument("--tag", help="Only include lessons matching this tag") + s.set_defaults(func=cmd_context) + + s = sub.add_parser("version", help="Print version") + s.set_defaults(func=cmd_version) + + return p + + +def main() -> None: + parser = _build_parser() + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + main() From e996a68ba0e652ee75cb3f99ff4c98b036e98393 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Tue, 11 Aug 2026 00:37:34 +0900 Subject: [PATCH 4/5] feat: add MCP server guide with a working claude-lessons example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents when to convert a CLI tool into an MCP server (Claude calls it mid-conversation) vs. keeping it a slash command or manual pipe (human stays in control of when it runs) — including a guideline against wrapping mutating/write actions as auto-callable MCP tools, tied to the autonomy levels added earlier in this branch. examples/mcp-lessons-server.py wraps tools/claude-lessons.py (add_lesson, search_lessons, recent_lessons) via the `mcp` Python SDK's FastMCP API. Lives under examples/, not tools/, since tools/ must stay dependency-free per docs/CONTRIBUTING.md — documented there as the one exception. Verified end-to-end against a real `mcp` install: `pip install mcp` now pulls a 2.x release that reworked/moved FastMCP, so the guide and example both pin `mcp>=1.2,<2`, confirmed working with 1.29.0. Closes #28 --- docs/CONTRIBUTING.ko.md | 4 ++ docs/CONTRIBUTING.md | 4 ++ docs/INTEGRATION.ko.md | 2 + docs/INTEGRATION.md | 2 + docs/MCP-GUIDE.ko.md | 97 ++++++++++++++++++++++++++++++++++ docs/MCP-GUIDE.md | 97 ++++++++++++++++++++++++++++++++++ examples/mcp-lessons-server.py | 76 ++++++++++++++++++++++++++ 7 files changed, 282 insertions(+) create mode 100644 docs/MCP-GUIDE.ko.md create mode 100644 docs/MCP-GUIDE.md create mode 100755 examples/mcp-lessons-server.py diff --git a/docs/CONTRIBUTING.ko.md b/docs/CONTRIBUTING.ko.md index 37d1865..1b0bf89 100644 --- a/docs/CONTRIBUTING.ko.md +++ b/docs/CONTRIBUTING.ko.md @@ -97,6 +97,10 @@ python tools/snippet.py run my-snippet --dry-run - `NO_COLOR` 환경변수 반드시 준수 - 종료 코드: `0` 성공, `1` 찾을 수 없음/이미 존재, `2` 사용법 오류 +"외부 의존성 없음" 규칙의 유일한 예외는 `examples/`입니다 — MCP 서버처럼 서드파티 패키지가 +정말로 필요한 실행 가능한 연동 예제를 위한 디렉토리입니다. 그런 예제는 `tools/`에 넣지 말고, +의존성을 예제의 docstring과 (관련 있다면) `docs/MCP-GUIDE.md`에 명확히 밝히세요. + ### Rust (claude-tools) - `cargo check` 에러 없어야 함 - `cargo clippy` 경고 최소화 diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 1d0471f..59d50b3 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -97,6 +97,10 @@ python tools/snippet.py run my-snippet --dry-run - `NO_COLOR` environment variable must be respected - Exit codes: `0` success, `1` not found / exists, `2` usage error +`examples/` is the one exception to "no external dependencies" — it's for runnable integration +examples (e.g. an MCP server) that legitimately need a third-party package. Keep those out of +`tools/`; state the dependency clearly in the example's docstring and in `docs/MCP-GUIDE.md` if relevant. + ### Rust (claude-tools) - `cargo check` must pass with no errors - Minimize `cargo clippy` warnings diff --git a/docs/INTEGRATION.ko.md b/docs/INTEGRATION.ko.md index 486057a..bd2bbb4 100644 --- a/docs/INTEGRATION.ko.md +++ b/docs/INTEGRATION.ko.md @@ -99,6 +99,8 @@ docker run -d --restart always \ docker compose run rag-ingest # 코드베이스 인덱싱 ``` +> 이 레포 자체의 도구(예: `claude-lessons`)를 수동 파이프 대신 MCP 서버로 만드는 것은 별개의, 더 작은 규모의 패턴입니다 — [MCP-GUIDE.ko.md](MCP-GUIDE.ko.md) 참고. + ### 4. 이벤트 라우팅 비교 | 기능 | Claude Code | claw-code | diff --git a/docs/INTEGRATION.md b/docs/INTEGRATION.md index c9e3e97..b8adee5 100644 --- a/docs/INTEGRATION.md +++ b/docs/INTEGRATION.md @@ -99,6 +99,8 @@ docker run -d --restart always \ docker compose run rag-ingest # index your codebase ``` +> Turning one of *this* repo's own tools (e.g. `claude-lessons`) into an MCP server instead of a manual pipe is a separate, smaller-scale pattern — see [MCP-GUIDE.md](MCP-GUIDE.md). + ### 4. Event Routing Comparison | Feature | Claude Code | claw-code | diff --git a/docs/MCP-GUIDE.ko.md b/docs/MCP-GUIDE.ko.md new file mode 100644 index 0000000..37ca5db --- /dev/null +++ b/docs/MCP-GUIDE.ko.md @@ -0,0 +1,97 @@ +[← README로 돌아가기](../README.md) + +**[English](MCP-GUIDE.md)** · **한국어** + +# MCP 서버 가이드 + +이 프로젝트의 모든 도구(`snippet`, `claude-handoff`, `claude-cost`, `claude-lessons` 등)는 직접 실행하고 대개 `claude`에 파이프하는 CLI입니다. **MCP 서버**는 이 수동 단계를 없앱니다 — 같은 기능을 Claude가 대화 중간에 직접 호출할 수 있는 도구로 노출시켜서, 사람이 명령어를 실행하고 출력을 붙여넣을 필요가 없게 만듭니다. + +--- + +## 슬래시 커맨드 vs 수동 파이프 vs MCP — 언제 무엇을 쓸까 + +| | 사람이 실행 | Claude가 호출 | 적합한 상황 | +|---|---|---|---| +| **슬래시 커맨드** (`/lessons add`) | 예, Claude Code 안에서 | 아니오 | *언제* 실행할지 사람이 결정 — 명시적인 1회성 행동 | +| **수동 파이프** (`claude-lessons context \| claude`) | 예, 셸에서 | 아니오 | *새* 세션에 컨텍스트를 주입할 때 (아직 컨텍스트가 없음) | +| **MCP 서버** | 아니오 | 예, 대화 중간에 | Claude가 *언제* 필요한지 스스로 판단해야 하는, 이미 진행 중인 작업 안에서의 반복 조회 | + +**경험칙:** 같은 CLI 명령을 여러 번 실행해서 결과를 Claude에 붙여넣고 있다면 MCP 서버 후보입니다. 반면 의도적인 체크포인트 행동(핸드오프 저장, 교훈 기록)이라면 슬래시 커맨드가 "누가 통제하는지"를 더 정직하게 드러냅니다 — 사람의 체크포인트를 자동화로 없애지 마세요 ([자율성 레벨](HARNESS-GUIDE.ko.md#자율성-레벨-l0-l4) 참고). + +이 프로젝트에서 가장 명확한 후보는 `claude-lessons`입니다: 과거 실패를 회상하는 것은, 사람이 먼저 기억해서 실행해야 하는 게 아니라 Claude가 위험한 영역을 건드리기 직전에 스스로 트리거해야 하는 전형적인 조회 작업입니다. + +--- + +## MCP 서버의 최소 구조 + +[Python MCP SDK](https://modelcontextprotocol.io)는 데코레이터 기반 서버(`FastMCP`)를 제공합니다 — 함수를 정의하고 데코레이터를 붙이면, docstring이 모델이 보는 도구 설명이 됩니다: + +```python +from mcp.server.fastmcp import FastMCP + +mcp = FastMCP("my-server") + +@mcp.tool() +def my_tool(arg: str) -> str: + """모델이 이 도구를 언제 호출할지 판단하는 데 쓰는 한 줄 설명.""" + return do_something(arg) + +if __name__ == "__main__": + mcp.run(transport="stdio") +``` + +구조는 이게 전부입니다: `FastMCP` 인스턴스 하나, 기능마다 `@mcp.tool()` 함수 하나, Claude Code와 로컬로 연동할 때는 `stdio` 트랜스포트. + +> **버전 주의:** 현재 `pip install mcp`는 이 API를 크게 바꾼 **2.x** 버전을 설치합니다 (`FastMCP` 위치/이름 변경). 이 가이드와 [`examples/mcp-lessons-server.py`](../examples/mcp-lessons-server.py)는 안정적으로 자리잡은 **1.x** 라인을 대상으로 합니다 — 2.x 마이그레이션 가이드를 읽지 않았다면 `pip install "mcp>=1.2,<2"`로 버전을 고정하세요. + +--- + +## 실전 예제: MCP 서버로 만든 `claude-lessons` + +[`examples/mcp-lessons-server.py`](../examples/mcp-lessons-server.py)는 `tools/claude-lessons.py`를 감싸서 3개의 도구를 노출합니다: + +- `add_lesson(title, symptom, cause, fix, tags)` +- `search_lessons(query)` +- `recent_lessons(limit, tag)` — 실패 이력이 있는 영역을 건드리기 전에 자동으로 호출할 가치가 가장 큰 도구 + +파일명에 하이픈이 있어 일반적인 `import`가 안 되는 `tools/claude-lessons.py`를 파일 경로로 로드해서, 교훈 파일 형식을 다시 구현하지 않고 저장 함수를 그대로 재사용합니다 — 그래서 CLI와 MCP 서버가 교훈이 어디에 저장되고 어떤 형식인지에 대해 항상 일치합니다. + +`tools/`가 아니라 `examples/`에 둔 이유는, `docs/CONTRIBUTING.md`가 `tools/` 아래 모든 것을 의존성 없는(stdlib only) 상태로 유지하도록 요구하는데 `mcp` 패키지는 외부 의존성이기 때문입니다. + +### 실행해보기 + +```bash +pip install "mcp>=1.2,<2" +python3 examples/mcp-lessons-server.py # stdio 서버 시작, 클라이언트 대기 +``` + +### Claude Code에 등록 + +```bash +claude mcp add lessons -- python3 /path/to/examples/mcp-lessons-server.py +``` + +등록하면 `claude-lessons context | claude` 없이도, 실패 이력이 있는 영역을 작업하려 할 때 Claude가 `recent_lessons`를 직접 호출할 수 있습니다. + +--- + +## 이 프로젝트의 다른 도구에 적용하기 + +같은 패턴은 사람이 파이프하는 대신 Claude가 직접 조회해야 하는 도구라면 어디든 적용됩니다: + +| 도구 | MCP로 감쌀 가치가 있는가? | 이유 | +|---|---|---| +| `claude-lessons` | 예 (위 참고) | 반복적인 조회, 특히 읽기 경로는 위험도 낮음 | +| `claude-remind` | 경우에 따라 | 작업 시작 시 Claude가 호출하면 유용하지만 `/remind`로도 충분 | +| `claude-cost` | 읽기 전용 부분만 | 지출 조회는 괜찮지만 `set-budget`은 수동/슬래시 커맨드로 유지 | +| `claude-handoff save` | 아니오 | 핸드오프 저장은 의도적인 사람의 체크포인트 — 슬래시 커맨드 유지 | +| `claude-pipeline` | 아니오 | 단계 전환은 자동 트리거가 아니라 명시적이고 리뷰 가능해야 함 | + +판단이 애매하면 **쓰기/변경 행동은 MCP 도구로 감싸지 않는 쪽을 기본값**으로 하세요 — 대화 중간에 조용히 호출될 수 있는 에이전트는, 사람이 명시적으로 입력하는 슬래시 커맨드보다 더 높은 자율성 레벨입니다 ([자율성 레벨](HARNESS-GUIDE.ko.md#자율성-레벨-l0-l4) 참고). + +--- + +*참고:* +- *[`examples/mcp-lessons-server.py`](../examples/mcp-lessons-server.py) — 실행 가능한 예제* +- *[`tools/claude-lessons.py`](../tools/claude-lessons.py) — 이 서버가 감싸는 CLI* +- *[HARNESS-GUIDE.ko.md](HARNESS-GUIDE.ko.md) — 자율성 레벨과 하네스 설계* diff --git a/docs/MCP-GUIDE.md b/docs/MCP-GUIDE.md new file mode 100644 index 0000000..3fd0fd4 --- /dev/null +++ b/docs/MCP-GUIDE.md @@ -0,0 +1,97 @@ +[← Back to README](../README.md) + +**[한국어](MCP-GUIDE.ko.md)** · **English** + +# MCP Server Guide + +Every tool in this project (`snippet`, `claude-handoff`, `claude-cost`, `claude-lessons`, …) is a CLI you run manually and, usually, pipe into `claude`. An **MCP server** removes that manual step: it exposes the same functionality as tools Claude can call directly, in the middle of a conversation, without you running a command and pasting the output back in. + +--- + +## Slash command vs. manual pipe vs. MCP — when to use which + +| | You run it | Claude calls it | Best for | +|---|---|---|---| +| **Slash command** (`/lessons add`) | Yes, inside Claude Code | No | You decide *when* it runs — explicit, one-off actions | +| **Manual pipe** (`claude-lessons context \| claude`) | Yes, in your shell | No | Feeding output into a *fresh* session (context does not exist yet) | +| **MCP server** | No | Yes, mid-conversation | Claude should decide *when* it needs this — recurring lookups inside a task it's already running | + +**Rule of thumb:** if you find yourself running the same CLI command and pasting its output into Claude more than a couple of times per session, that's a candidate for an MCP server. If it's a deliberate checkpoint action (save a handoff, log a lesson), a slash command is more honest about who's in control — don't automate away human checkpoints (see [Autonomy Levels](HARNESS-GUIDE.md#autonomy-levels-l0-l4)). + +`claude-lessons` is the clearest candidate in this project: recalling past failures is exactly the kind of lookup Claude should trigger itself when it's about to touch a risky area, not something a human should have to remember to run first. + +--- + +## Minimal anatomy of an MCP server + +The [Python MCP SDK](https://modelcontextprotocol.io) gives you a decorator-based server (`FastMCP`) — define a function, decorate it, the docstring becomes the tool description the model sees: + +```python +from mcp.server.fastmcp import FastMCP + +mcp = FastMCP("my-server") + +@mcp.tool() +def my_tool(arg: str) -> str: + """One line the model reads to decide when to call this.""" + return do_something(arg) + +if __name__ == "__main__": + mcp.run(transport="stdio") +``` + +That's the whole shape: a `FastMCP` instance, one `@mcp.tool()` function per capability, `stdio` transport for local use with Claude Code. + +> **Version note:** `pip install mcp` currently installs a **2.x** release that reworked this API (`FastMCP` moved/renamed). This guide and [`examples/mcp-lessons-server.py`](../examples/mcp-lessons-server.py) target the well-established **1.x** line — pin `pip install "mcp>=1.2,<2"` unless you've read the 2.x migration guide. + +--- + +## Worked example: `claude-lessons` as an MCP server + +[`examples/mcp-lessons-server.py`](../examples/mcp-lessons-server.py) wraps `tools/claude-lessons.py` and exposes three tools: + +- `add_lesson(title, symptom, cause, fix, tags)` +- `search_lessons(query)` +- `recent_lessons(limit, tag)` — the one worth calling automatically, before touching an area with a known failure history + +It loads `tools/claude-lessons.py` by file path (its filename has a hyphen, so it can't be `import`ed directly) and reuses its storage functions rather than re-implementing the lesson file format — so the CLI and the MCP server always agree on where lessons live and what they look like. + +It lives in `examples/`, not `tools/`, because `docs/CONTRIBUTING.md` requires everything under `tools/` to stay dependency-free (stdlib only), and the `mcp` package is an external dependency. + +### Try it + +```bash +pip install "mcp>=1.2,<2" +python3 examples/mcp-lessons-server.py # starts a stdio server, waits for a client +``` + +### Register it with Claude Code + +```bash +claude mcp add lessons -- python3 /path/to/examples/mcp-lessons-server.py +``` + +Once registered, Claude can call `recent_lessons` itself when it's about to work in an area with recorded failures — no `claude-lessons context | claude` needed. + +--- + +## Applying this to other tools in this project + +The same pattern works for any tool here that Claude should query rather than a human piping in: + +| Tool | Worth wrapping as MCP? | Why / why not | +|---|---|---| +| `claude-lessons` | Yes (see above) | Recurring lookup, low-stakes, read path especially | +| `claude-remind` | Maybe | Useful as a tool Claude calls at task start; still fine as `/remind` | +| `claude-cost` | Maybe, read-only tools only | Letting Claude read spend is fine; keep `set-budget` a manual/slash action | +| `claude-handoff save` | No | Saving a handoff is a deliberate human checkpoint — keep it a slash command | +| `claude-pipeline` | No | Stage transitions should stay explicit and reviewable, not auto-triggered | + +When in doubt, default to **not** wrapping a write/mutating action as an MCP tool — an agent that can silently call it mid-conversation is a higher autonomy level (see [Autonomy Levels](HARNESS-GUIDE.md#autonomy-levels-l0-l4)) than a slash command the human explicitly types. + +--- + +*See also:* +- *[`examples/mcp-lessons-server.py`](../examples/mcp-lessons-server.py) — the runnable example* +- *[`tools/claude-lessons.py`](../tools/claude-lessons.py) — the CLI it wraps* +- *[HARNESS-GUIDE.md](HARNESS-GUIDE.md) — autonomy levels and harness design* diff --git a/examples/mcp-lessons-server.py b/examples/mcp-lessons-server.py new file mode 100755 index 0000000..c2cec3e --- /dev/null +++ b/examples/mcp-lessons-server.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +""" +mcp-lessons-server.py — Example MCP server exposing claude-lessons as MCP tools. + +Wraps tools/claude-lessons.py (see ../docs/MCP-GUIDE.md) so Claude Code can call +add_lesson / search_lessons / recent_lessons directly, instead of a human running +the CLI and pasting output back in. + +This lives in examples/, not tools/, because it needs the optional `mcp` package. +Everything under tools/ must stay stdlib-only (see docs/CONTRIBUTING.md). + +Setup: + pip install "mcp>=1.2,<2" + # `mcp` 2.x is a breaking rewrite (FastMCP moved/renamed) — pin <2 for this API. + +Register with Claude Code: + claude mcp add lessons -- python3 /path/to/examples/mcp-lessons-server.py + +Quick manual check (starts a stdio server, waits for a client — Ctrl+C to stop): + python3 examples/mcp-lessons-server.py +""" + +import importlib.util +from pathlib import Path + +from mcp.server.fastmcp import FastMCP + +# tools/claude-lessons.py has a hyphen in its filename, so it can't be +# `import`ed normally — load it by path and reuse its storage functions +# directly instead of re-implementing the lesson file format here. +_TOOL_PATH = Path(__file__).resolve().parent.parent / "tools" / "claude-lessons.py" +_spec = importlib.util.spec_from_file_location("claude_lessons", _TOOL_PATH) +claude_lessons = importlib.util.module_from_spec(_spec) +_spec.loader.exec_module(claude_lessons) + +mcp = FastMCP("claude-lessons") + + +@mcp.tool() +def add_lesson(title: str, symptom: str, cause: str, fix: str, tags: str = "") -> str: + """Record a lesson: what failed, why it happened, and how it was fixed.""" + claude_lessons.LESSONS_DIR.mkdir(parents=True, exist_ok=True) + doc = claude_lessons._build_lesson_doc(title, tags, symptom, cause, fix) + lid = claude_lessons._lesson_id() + claude_lessons._lesson_path(lid).write_text(doc, encoding="utf-8") + return f"Saved lesson {lid}" + + +@mcp.tool() +def search_lessons(query: str) -> str: + """Search past lessons by keyword. Returns matches, most recent first.""" + items = claude_lessons._list_lessons() + matches = [i for i in items if query.lower() in i["content"].lower()] + if not matches: + return f"No lessons matching '{query}'." + return "\n---\n".join(i["content"] for i in matches[:10]) + + +@mcp.tool() +def recent_lessons(limit: int = 5, tag: str = "") -> str: + """Get the most recent lessons, optionally filtered by tag. + + Call this before starting work in an unfamiliar area, so past failures + and their fixes are in context before you repeat them. + """ + items = claude_lessons._list_lessons() + if tag: + items = [i for i in items if tag.lower() in i["tags"].lower()] + items = items[:limit] + if not items: + return "No lessons recorded yet." + return "\n---\n".join(i["content"] for i in items) + + +if __name__ == "__main__": + mcp.run(transport="stdio") From f614a3a1319d7a1f26e3900702690c2def911b67 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Tue, 11 Aug 2026 00:37:48 +0900 Subject: [PATCH 5/5] docs: sync README.md/.ko.md for autonomy levels, claude-lessons, MCP guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Agent Roster: new Autonomy column + explanation - Tools: 7 -> 8, new Tool 8 (claude-lessons) section, /lessons row, repo layout tree, context-cost-tips row - Nav bars + repo layout: MCP-GUIDE.md(.ko) link - README.ko.md also gets the harness/pipeline Tool 6/7 detail sections and full 11-agent repo layout it was missing — it had fallen out of sync with README.md (only the slash-command table and top badges had been updated when those tools were added), which this branch's changes would otherwise have made worse --- README.ko.md | 149 ++++++++++++++++++++++++++++++++++++++++++--------- README.md | 79 ++++++++++++++++++++------- 2 files changed, 186 insertions(+), 42 deletions(-) diff --git a/README.ko.md b/README.ko.md index 904c1bc..5e4cd28 100644 --- a/README.ko.md +++ b/README.ko.md @@ -4,7 +4,7 @@ # Claude Code 멀티 에이전트 시스템 -**Claude Code를 위한 11개의 전문 에이전트 + 7개의 생산성 도구** +**Claude Code를 위한 11개의 전문 에이전트 + 8개의 생산성 도구** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE) [![Python 3.8+](https://img.shields.io/badge/Python-3.8%2B-blue?style=flat-square&logo=python&logoColor=white)](https://www.python.org) @@ -12,10 +12,10 @@ [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey?style=flat-square)](https://github.com/BcKmini/Claudecode-Agent) [![Claude Code](https://img.shields.io/badge/Claude_Code-Compatible-blueviolet?style=flat-square&logo=anthropic)](https://claude.ai/code) [![Agents](https://img.shields.io/badge/Agents-11-green?style=flat-square)](#에이전트-구성) -[![Tools](https://img.shields.io/badge/Tools-7-informational?style=flat-square)](#도구) +[![Tools](https://img.shields.io/badge/Tools-8-informational?style=flat-square)](#도구) [![Bilingual](https://img.shields.io/badge/Lang-EN%20%7C%20KO-orange?style=flat-square)](#) -**[English README](README.md)** · **[환경 세팅](docs/SETUP.ko.md)** · **[치트시트](docs/AGENT-CHEATSHEET.ko.md)** · **[하네스 가이드](docs/HARNESS-GUIDE.ko.md)** · **[연동 가이드](docs/INTEGRATION.ko.md)** · **[기여 가이드](docs/CONTRIBUTING.ko.md)** +**[English README](README.md)** · **[환경 세팅](docs/SETUP.ko.md)** · **[치트시트](docs/AGENT-CHEATSHEET.ko.md)** · **[하네스 가이드](docs/HARNESS-GUIDE.ko.md)** · **[MCP 가이드](docs/MCP-GUIDE.ko.md)** · **[연동 가이드](docs/INTEGRATION.ko.md)** · **[기여 가이드](docs/CONTRIBUTING.ko.md)** @@ -33,6 +33,7 @@ 6. **`claude-remind`** — 세션 시작 시 TODO 미완료 항목을 자동으로 표시 7. **`claude-harness`** — 에이전트 하네스 정의를 검증하고 템플릿을 생성 8. **`claude-pipeline`** — 다단계 파이프라인 실행을 추적하고 보고서 생성 +9. **`claude-lessons`** — 무엇이 왜 실패했고 어떻게 고쳤는지 기록하고, 세션을 넘나들며 검색 모든 도구는 Python CLI와 Claude Code 슬래시 커맨드로 제공됩니다. 핵심 도구는 단일 **Rust 바이너리**(`claude-tools`)로도 제공됩니다. @@ -146,31 +147,33 @@ claude ## 에이전트 구성 -| # | 에이전트 | 모델 | 역할 | -|---|---------|------|------| -| 00 | **orchestrator** | Opus | 작업 분해 및 서브 에이전트 위임 총괄 | -| 01 | **planner** | Opus | 아키텍처·설계 결정 — 읽기 전용 | -| 02 | **implementer** | Sonnet | 실제 코드 작성·수정 | -| 03 | **reviewer** | Sonnet | 버그·보안·품질·성능 리뷰 — 읽기 전용 | -| 04 | **tester** | Sonnet | 유닛·통합·E2E 테스트 작성 | -| 05 | **security-auditor** | Opus | OWASP Top 10 기준 보안 감사 — 읽기 전용 | -| 06 | **performance-optimizer** | Sonnet | 성능 병목 분석 및 최적화 | -| 07 | **database-expert** | Sonnet | DB 스키마 설계·쿼리·마이그레이션 | -| 08 | **documenter** | Haiku | README·API 문서·인라인 주석 작성 | -| 09 | **harness-designer** | Opus | 타이트·느슨·적응형 AI 하네스 설계 | -| 10 | **pipeline-orchestrator** | Opus | 컨텍스트 격리 기반 다단계 파이프라인 실행 관리 | +| # | 에이전트 | 모델 | 자율성 | 역할 | +|---|---------|------|:---:|------| +| 00 | **orchestrator** | Opus | L2 | 작업 분해 및 서브 에이전트 위임 총괄 | +| 01 | **planner** | Opus | L1 | 아키텍처·설계 결정 — 읽기 전용 | +| 02 | **implementer** | Sonnet | L2 | 실제 코드 작성·수정 | +| 03 | **reviewer** | Sonnet | L1 | 버그·보안·품질·성능 리뷰 — 읽기 전용 | +| 04 | **tester** | Sonnet | L2 | 유닛·통합·E2E 테스트 작성 | +| 05 | **security-auditor** | Opus | L1 | OWASP Top 10 기준 보안 감사 — 읽기 전용 | +| 06 | **performance-optimizer** | Sonnet | L2 | 성능 병목 분석 및 최적화 | +| 07 | **database-expert** | Sonnet | L2 | DB 스키마 설계·쿼리·마이그레이션 | +| 08 | **documenter** | Haiku | L3 | README·API 문서·인라인 주석 작성 | +| 09 | **harness-designer** | Opus | L1 | 타이트·느슨·적응형 AI 하네스 설계 | +| 10 | **pipeline-orchestrator** | Opus | L2 | 컨텍스트 격리 기반 다단계 파이프라인 실행 관리 | > **모든 에이전트가 이중 언어를 지원합니다** — 사용자 언어를 감지해 한국어 또는 영어로 응답합니다. > 각 에이전트는 자기 역할에 관련된 컨텍스트만 가집니다. 병렬 실행(planner + security-auditor 동시)으로 작업 시간도 단축됩니다. +> **자율성**(L0 = 사람이 전부 담당 → L4 = 완전 자율)은 하네스 유형과 별개의 축입니다 — 출력이 얼마나 제약되는지가 아니라, 얼마나 사람이 확인해야 하는지를 나타냅니다. 자세한 내용은 [자율성 레벨](docs/HARNESS-GUIDE.ko.md#자율성-레벨-l0-l4) 참고. + > 바로 쓸 수 있는 프롬프트 24개 이상 → [AGENT-CHEATSHEET.ko.md](docs/AGENT-CHEATSHEET.ko.md) --- ## 도구 -Claude Code가 기본으로 제공하지 않는 기능을 채우는 7가지 도구. +Claude Code가 기본으로 제공하지 않는 기능을 채우는 8가지 도구. ### 슬래시 커맨드 한눈에 보기 @@ -183,6 +186,7 @@ Claude Code가 기본으로 제공하지 않는 기능을 채우는 7가지 도 | `/pipeline` | 다단계 AI 파이프라인 실행 및 추적 | | `/review-diff` | git diff 기반 코드 리뷰 프롬프트 | | `/remind` | 세션 시작 시 TODO 미완료 항목 표시 | +| `/lessons` | 실패 원인과 해결법 기록 및 회상 | --- @@ -305,6 +309,90 @@ claude-handoff load | claude # 전체 컨텍스트 복원 --- +### 도구 6 — `claude-harness` — 하네스 검증기 & 템플릿 생성기 + +에이전트 하네스 정의를 검증하고 커맨드라인에서 하네스 템플릿을 생성합니다. + +```bash +claude-harness check-all # agents/ 전체 에이전트 검증 +claude-harness validate agents/09-harness-designer.md # 단일 에이전트 검증 +claude-harness template tight my-specialist # 타이트 하네스 템플릿 출력 +claude-harness template adaptive my-orchestrator # 적응형 하네스 템플릿 출력 +claude-harness autonomy # L0-L4 자율성 레벨 참조표 출력 +``` + +``` +/harness design 슬로우 쿼리 탐지 및 패치 자동화 +/harness validate agents/03-reviewer.md +/harness types +/harness autonomy +``` + +**에이전트별 검사 항목:** +- 역할이 명확히 스코프되어 있는가 +- 출력 형식이 제약되어 있는가 +- 금지 행동이 명시되어 있는가 +- 도구 목록이 최소한인가 +- 자율성 레벨(L0-L4)이 선언되어 있는가 +- 이중 언어 지원이 있는가 + +--- + +### 도구 7 — `claude-pipeline` — 파이프라인 추적기 & 리포터 + +다단계 AI 파이프라인 실행을 추적하고, 단계별 결과를 기록하고, 마크다운 실행 보고서를 생성합니다. + +```bash +claude-pipeline init slow-query-fix # 파이프라인 생성 및 활성화 +claude-pipeline stage "detection" start +claude-pipeline stage "detection" pass --note "슬로우 쿼리 3개 발견" +claude-pipeline stage "patch-gen" start +claude-pipeline stage "patch-gen" warn --note "1개 쿼리는 안전한 수정 불가" +claude-pipeline status # 실시간 상태 표시 +claude-pipeline report # 마크다운 실행 보고서 +claude-pipeline list # 저장된 모든 파이프라인 +``` + +``` +/pipeline run 슬로우 쿼리 분석 및 리뷰 루프 포함 패치 생성 +/pipeline status +/pipeline stages +``` + +--- + +### 도구 8 — `claude-lessons` — 실패/교훈 기록 + +무엇이 왜 실패했고 어떻게 고쳤는지 기록해서, 다음 세션(또는 다른 에이전트)이 같은 실수를 반복하지 않게 합니다. 세션 단위로 정리되는 `claude-handoff`와 달리, 교훈은 무기한 누적되며 태그·키워드로 검색할 수 있습니다. + +```bash +claude-lessons add --title "마이그레이션 타임아웃" --tags db,migration \ + --symptom "ALTER TABLE이 프로덕션을 4분간 잠금" \ + --cause "lock_timeout 미설정" \ + --fix "DDL 전에 SET lock_timeout='2s' 추가" +claude-lessons list --tag db +claude-lessons search lock_timeout +claude-lessons context | claude # 최근 교훈을 새 세션에 파이프 +``` + +``` +/lessons add +/lessons list --tag db +/lessons context +``` + +**전형적인 워크플로우:** + +```bash +# 까다로운 실패를 디버깅한 직후 +claude-lessons add + +# 같은 영역을 다시 건드리는 세션 시작 시 +claude-lessons context --tag db | claude +``` + +--- + ### Rust 바이너리 — `claude-tools` 모든 도구를 의존성 없는 단일 바이너리로 컴파일 — Python 불필요. @@ -356,8 +444,9 @@ make clean # 빌드 아티팩트 제거 ## 저장소 구조 ``` -Claudecode-Agent/ +claude-code-use/ ├── Makefile ← 빌드 / 설치 / 테스트 / 정리 +├── install.sh ← 원라인 설치 스크립트 ├── setup-agents.ps1 ← Windows 빠른 설치 ├── setup-agents.sh ← macOS / Linux 빠른 설치 │ @@ -365,28 +454,37 @@ Claudecode-Agent/ │ ├── 00-orchestrator.md · 01-planner.md · 02-implementer.md │ ├── 03-reviewer.md · 04-tester.md · 05-security-auditor.md │ ├── 06-performance-optimizer.md · 07-database-expert.md -│ └── 08-documenter.md +│ ├── 08-documenter.md +│ ├── 09-harness-designer.md ← 하네스 설계 에이전트 +│ └── 10-pipeline-orchestrator.md ← 파이프라인 관리 에이전트 │ ├── .claude/commands/ ← 슬래시 커맨드 → ~/.claude/commands/ │ ├── snippet.md · handoff.md · cost.md -│ ├── review-diff.md ← 신규 -│ └── remind.md ← 신규 +│ ├── review-diff.md · remind.md +│ ├── harness.md · pipeline.md +│ └── lessons.md ← 신규 /lessons │ ├── snippets/defaults.json ← 기본 프롬프트 템플릿 20개 │ ├── tools/ │ ├── snippet.py · claude-handoff.py · claude-cost.py -│ ├── claude-review-diff.py ← 신규 -│ ├── claude-remind.py ← 신규 +│ ├── claude-review-diff.py · claude-remind.py +│ ├── claude-harness.py · claude-pipeline.py +│ ├── claude-lessons.py ← 신규 실패/교훈 기록 │ ├── install-tools.ps1 · install-tools.sh │ ├── rust/claude-tools/src/ │ ├── main.rs · snippet.rs · handoff.rs · cost.rs -│ ├── watch.rs · env.rs (신규) · colors.rs +│ ├── watch.rs · env.rs · colors.rs +│ +├── examples/ +│ └── mcp-lessons-server.py ← 신규 MCP 서버 예제 │ └── docs/ ├── SETUP.md / SETUP.ko.md ├── AGENT-CHEATSHEET.md / .ko.md + ├── HARNESS-GUIDE.md / .ko.md + ├── MCP-GUIDE.md / .ko.md ← 신규 ├── INTEGRATION.md / .ko.md ├── CONTRIBUTING.md / .ko.md └── CLAUDE.md / .ko.md @@ -405,6 +503,7 @@ Claudecode-Agent/ | 환경 상태 확인 | `claude-tools env` | | 미완료 작업으로 재개 | `claude-remind \| claude` | | 전체 세션 복원 | `claude-handoff load \| claude` | +| 이 영역의 과거 실패 회상 | `claude-lessons context --tag X \| claude` | --- @@ -443,6 +542,8 @@ winget install GnuWin32.Make |------|--------|---------| | 환경 세팅 가이드 | [SETUP.ko.md](docs/SETUP.ko.md) | [SETUP.md](docs/SETUP.md) | | 에이전트 치트시트 | [AGENT-CHEATSHEET.ko.md](docs/AGENT-CHEATSHEET.ko.md) | [AGENT-CHEATSHEET.md](docs/AGENT-CHEATSHEET.md) | +| 하네스 설계 가이드 | [HARNESS-GUIDE.ko.md](docs/HARNESS-GUIDE.ko.md) | [HARNESS-GUIDE.md](docs/HARNESS-GUIDE.md) | +| MCP 서버 가이드 | [MCP-GUIDE.ko.md](docs/MCP-GUIDE.ko.md) | [MCP-GUIDE.md](docs/MCP-GUIDE.md) | | 통합 가이드 | [INTEGRATION.ko.md](docs/INTEGRATION.ko.md) | [INTEGRATION.md](docs/INTEGRATION.md) | | 기여 가이드 | [CONTRIBUTING.ko.md](docs/CONTRIBUTING.ko.md) | [CONTRIBUTING.md](docs/CONTRIBUTING.md) | | 코딩 가이드라인 | [CLAUDE.ko.md](docs/CLAUDE.ko.md) | [CLAUDE.md](docs/CLAUDE.md) | diff --git a/README.md b/README.md index e07787e..0ffff80 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # Claude Code Multi-Agent System -**11 specialized AI agents + 7 productivity tools — all for Claude Code** +**11 specialized AI agents + 8 productivity tools — all for Claude Code** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE) [![Python 3.8+](https://img.shields.io/badge/Python-3.8%2B-blue?style=flat-square&logo=python&logoColor=white)](https://www.python.org) @@ -12,10 +12,10 @@ [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey?style=flat-square)](https://github.com/BcKmini/Claudecode-Agent) [![Claude Code](https://img.shields.io/badge/Claude_Code-Compatible-blueviolet?style=flat-square&logo=anthropic)](https://claude.ai/code) [![Agents](https://img.shields.io/badge/Agents-11-green?style=flat-square)](#agent-roster) -[![Tools](https://img.shields.io/badge/Tools-7-informational?style=flat-square)](#tools) +[![Tools](https://img.shields.io/badge/Tools-8-informational?style=flat-square)](#tools) [![Bilingual](https://img.shields.io/badge/Lang-EN%20%7C%20KO-orange?style=flat-square)](#) -**[한국어 README](README.ko.md)** · **[Setup Guide](docs/SETUP.md)** · **[Cheatsheet](docs/AGENT-CHEATSHEET.md)** · **[Harness Guide](docs/HARNESS-GUIDE.md)** · **[Integration](docs/INTEGRATION.md)** · **[Contributing](docs/CONTRIBUTING.md)** +**[한국어 README](README.ko.md)** · **[Setup Guide](docs/SETUP.md)** · **[Cheatsheet](docs/AGENT-CHEATSHEET.md)** · **[Harness Guide](docs/HARNESS-GUIDE.md)** · **[MCP Guide](docs/MCP-GUIDE.md)** · **[Integration](docs/INTEGRATION.md)** · **[Contributing](docs/CONTRIBUTING.md)** @@ -33,6 +33,7 @@ A drop-in enhancement for **Claude Code** that gives you: 6. **`claude-remind`** — surface incomplete TODO items at session start 7. **`claude-harness`** — validate and generate AI harness definitions for specialist agents 8. **`claude-pipeline`** — track multi-stage pipeline execution with quality gates and run reports +9. **`claude-lessons`** — record why something failed and how it was fixed, searchable across sessions All tools ship as Python CLIs and as Claude Code slash commands. The core tools also ship as a single compiled **Rust binary** (`claude-tools`). @@ -151,31 +152,33 @@ claude ## Agent Roster -| # | Agent | Model | Job | -|---|-------|-------|-----| -| 00 | **orchestrator** | Opus | Breaks down requests and delegates to sub-agents | -| 01 | **planner** | Opus | Architecture & design decisions — read-only | -| 02 | **implementer** | Sonnet | Writes and edits code | -| 03 | **reviewer** | Sonnet | Bug, security, quality, performance review — read-only | -| 04 | **tester** | Sonnet | Unit, integration, E2E test authoring | -| 05 | **security-auditor** | Opus | OWASP Top 10 audit — read-only | -| 06 | **performance-optimizer** | Sonnet | Bottleneck analysis and optimization | -| 07 | **database-expert** | Sonnet | Schema design, queries, migrations | -| 08 | **documenter** | Haiku | README, API docs, inline comments | -| 09 | **harness-designer** | Opus | Designs tight/loose/adaptive AI harnesses for automation | -| 10 | **pipeline-orchestrator** | Opus | Manages multi-stage pipelines with context isolation | +| # | Agent | Model | Autonomy | Job | +|---|-------|-------|:--------:|-----| +| 00 | **orchestrator** | Opus | L2 | Breaks down requests and delegates to sub-agents | +| 01 | **planner** | Opus | L1 | Architecture & design decisions — read-only | +| 02 | **implementer** | Sonnet | L2 | Writes and edits code | +| 03 | **reviewer** | Sonnet | L1 | Bug, security, quality, performance review — read-only | +| 04 | **tester** | Sonnet | L2 | Unit, integration, E2E test authoring | +| 05 | **security-auditor** | Opus | L1 | OWASP Top 10 audit — read-only | +| 06 | **performance-optimizer** | Sonnet | L2 | Bottleneck analysis and optimization | +| 07 | **database-expert** | Sonnet | L2 | Schema design, queries, migrations | +| 08 | **documenter** | Haiku | L3 | README, API docs, inline comments | +| 09 | **harness-designer** | Opus | L1 | Designs tight/loose/adaptive AI harnesses for automation | +| 10 | **pipeline-orchestrator** | Opus | L2 | Manages multi-stage pipelines with context isolation | > **All agents are bilingual** — they detect the user's language and respond in English or Korean (한국어). > Each agent carries only the context relevant to its role. Parallel execution (planner + security-auditor simultaneously) cuts wall-clock time. +> **Autonomy** (L0 = human does everything → L4 = fully autonomous) is a separate axis from harness type — it says how much human checking a task needs, not how constrained the output is. See [Autonomy Levels](docs/HARNESS-GUIDE.md#autonomy-levels-l0-l4). + > See [AGENT-CHEATSHEET.md](docs/AGENT-CHEATSHEET.md) for 24+ ready-to-use prompts. --- ## Tools -Five productivity tools that fill the gaps Claude Code doesn't cover out of the box. +Eight productivity tools that fill the gaps Claude Code doesn't cover out of the box. ### Slash commands overview @@ -188,6 +191,7 @@ Five productivity tools that fill the gaps Claude Code doesn't cover out of the | `/remind` | Surface pending TODO items at session start | | `/harness` | Design and validate AI harness definitions | | `/pipeline` | Run and track multi-stage AI pipelines | +| `/lessons` | Record and recall why past tasks failed and how they were fixed | --- @@ -359,6 +363,38 @@ claude-pipeline list # all saved pipelines --- +### Tool 8 — `claude-lessons` — Failure / Lessons-Learned Log + +Record why something failed and how it was fixed, so the next session (or agent) doesn't repeat it. Unlike `claude-handoff` (session-scoped, prunable), lessons accumulate indefinitely and are searchable by tag or keyword. + +```bash +claude-lessons add --title "Migration timed out" --tags db,migration \ + --symptom "ALTER TABLE locked prod for 4min" \ + --cause "no lock_timeout set" \ + --fix "added SET lock_timeout='2s' before DDL" +claude-lessons list --tag db +claude-lessons search lock_timeout +claude-lessons context | claude # pipe recent lessons into a new session +``` + +``` +/lessons add +/lessons list --tag db +/lessons context +``` + +**Typical workflow:** + +```bash +# During/after debugging a tricky failure +claude-lessons add + +# Start of a new session touching the same area +claude-lessons context --tag db | claude +``` + +--- + ### Rust binary — `claude-tools` All tools compiled into one zero-dependency binary — no Python required. @@ -435,7 +471,8 @@ Claudecode-Agent/ │ ├── review-diff.md │ ├── remind.md │ ├── harness.md ← NEW /harness -│ └── pipeline.md ← NEW /pipeline +│ ├── pipeline.md ← NEW /pipeline +│ └── lessons.md ← NEW /lessons │ ├── snippets/ │ └── defaults.json ← 20 built-in prompt templates @@ -448,6 +485,7 @@ Claudecode-Agent/ │ ├── claude-remind.py │ ├── claude-harness.py ← NEW harness validator + template gen │ ├── claude-pipeline.py ← NEW pipeline tracker + reporter +│ ├── claude-lessons.py ← NEW failure/lessons-learned log │ ├── install-tools.ps1 ← Windows tool installer │ └── install-tools.sh ← macOS/Linux tool installer │ @@ -460,10 +498,14 @@ Claudecode-Agent/ │ ├── env.rs ← NEW environment health check │ └── colors.rs │ +├── examples/ +│ └── mcp-lessons-server.py ← NEW MCP server example +│ └── docs/ ├── SETUP.md / SETUP.ko.md ├── AGENT-CHEATSHEET.md / .ko.md ├── HARNESS-GUIDE.md / .ko.md ← NEW harness design guide + ├── MCP-GUIDE.md / .ko.md ← NEW MCP server guide ├── INTEGRATION.md / .ko.md ├── CONTRIBUTING.md / .ko.md └── CLAUDE.md / .ko.md @@ -482,6 +524,7 @@ Claudecode-Agent/ | Check environment | `claude-tools env` | | Resume with pending tasks | `claude-remind \| claude` | | Full session restore | `claude-handoff load \| claude` | +| Recall past failures for this area | `claude-lessons context --tag X \| claude` | ---