| name | harness-setup |
| description | AI Agent Harness Engineering infrastructure auto-provisioner. Detects project stack (Spring Boot, Vue, React, etc.) and generates project-scoped agents, hooks, settings, CLAUDE.md rules, runtime directories, and metrics infrastructure. Idempotent โ safely run on new or partially configured projects; only adds what's missing. Use this skill whenever: the user says 'harness setup', 'set up harness', 'configure harness', 'harness-setup', 'add harness to project', 'init harness', 'harness ์ค์ ', 'harness ๊ตฌ์ฑ', 'harness ์ด๊ธฐํ', 'harness ์ธํ
', 'new project harness', 'upgrade harness', 'check harness status', 'harness check'. Also trigger when user asks to add agents, hooks, or quality gates to a project even without explicitly saying 'harness'. |
/harness-setup โ Harness Engineering ์๋ ๊ตฌ์ฑ
ํ๋ก์ ํธ์ AI Agent Harness Engineering ์ธํ๋ผ๋ฅผ ์๋์ผ๋ก ๊ตฌ์ฑํ๋ค.
๊ธฐ์กด ๊ตฌ์ฑ์ด ์์ผ๋ฉด ๊ฐ์งํ์ฌ ๋ถ์กฑ๋ถ๋ง ๋ณด์ถฉํ๋ค. ๊ธฐ์กด ํ์ผ์ ๋ฎ์ด์ฐ์ง ์๋๋ค.
์ค๊ณ ๋ฌธ์: ~/.claude/docs/HARNESS-SETUP-SKILL-DESIGN.md
Scope
์ฌ์ฉ์์ ํ๋กฌํํธ์์ scope๋ฅผ ์ถ์ถํ๋ค:
| Scope | ๋์ |
|---|
| full (๊ธฐ๋ณธ) | ๊ฐ์ง โ Gap ๋ถ์ โ ๋ถ์กฑ๋ถ ์ ์ฒด ์์ฑ |
| check | ๊ฐ์ง โ ์ํ ๋ณด๊ณ ๋ง (๋ณ๊ฒฝ ์์) |
| upgrade | ๊ฐ์ง โ ์ต์ ํ์ค ๋๋น diff โ ์ฌ์ฉ์ ํ์ธ ํ ์์ |
scope๊ฐ ๋ช
์๋์ง ์์ผ๋ฉด full๋ก ๊ฐ์ฃผํ๋ค.
์์ฐ์ด ํ๋ผ๋ฏธํฐ
์ฌ์ฉ์๊ฐ ํจ๊ป ์ ๋ฌํ ์ ์๋ ์ ๋ณด. ๋ช
์๋์ง ์์ ํญ๋ชฉ์ Step 3 ์ธํฐ๋ทฐ์์ ์ง๋ฌธํ๋ค:
- mode: HARNESS_MODE ๊ฐ (
suggest / auto / off)
- prefix: ์์ด์ ํธ ์ด๋ฆ ์ ๋์ฌ (์:
myapp, cs, haback)
- stack: ๊ธฐ์ ์คํ (์๋ ๊ฐ์ง ๊ธฐ๋ณธ)
์ธํฐ๋ทฐ ์์น
์ด ์คํฌ์ ํ์ผ 20๊ฐ ์ด์์ ์์ฑ/์์ ํ๊ณ settings.local.json์ ๋ณ๊ฒฝํ๋ค. ๋ฐ๋ผ์ ์๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์กฐ์ฉํ ๋์ด๊ฐ์ง ์๋๋ค.
- ๋ค์ 3๊ฐ์ง๋ ๋ฐ๋์ ์ฌ์ฉ์์๊ฒ ํ์ธํ๋ค: mode, prefix, ์์ฑ ๊ณํ
- ์๋ ๊ฐ์งํ ๊ฐ์ ๋ณด์ฌ์ฃผ๊ณ ํ์ธ์ ๋ฐ๋๋ค (์กฐ์ฉํ ์ ์ฉ ๊ธ์ง)
- ์ง๋ฌธ์ Step 3์์ ํ ๋ฒ์ ๋ฌถ์ด ๋ฌผ์ด๋ณธ๋ค (drip-drip ๊ธ์ง)
scope=check๋ ์ฝ๊ธฐ ์ ์ฉ์ด๋ฏ๋ก ์ง๋ฌธ ์์
Step 0. git ํ์ธ
git rev-parse --show-toplevel 2>/dev/null
git์ด ์์ผ๋ฉด ๊ฒฝ๊ณ :
"โ ๏ธ git ๋ ํฌ๊ฐ ์๋๋๋ค. persist-checkpoint hook๊ณผ rollback ๊ธฐ๋ฅ์ด ์ ํ๋ฉ๋๋ค. ๊ณ์ ์งํํ ๊น์?"
์ฌ์ฉ์ ํ์ธ ํ ๊ณ์.
Step 1. ์คํ ๊ฐ์ง
์๋ ์์๋ก ๊ธฐ์ ์คํ์ ์๋ ๊ฐ์งํ๋ค:
- ์ฌ์ฉ์๊ฐ ๋ช
์ํ stack โ ๊ทธ๋๋ก ์ฌ์ฉ
- ํ์ผ ๊ธฐ๋ฐ ๊ฐ์ง:
| ํ์ผ | ์คํ | Tier |
|---|
build.gradle / build.gradle.kts | spring-boot | 1 (์ค์ ๊ฒ์ฆ) |
package.json + "vue" ์์กด์ฑ | vue | 1 (์ค์ ๊ฒ์ฆ) |
package.json + "react" ์์กด์ฑ | react | 1 (์ ์ฌ ๊ตฌ์กฐ) |
pom.xml | spring-boot-maven | 2 |
package.json + "next" | next | 2 |
package.json + "angular" | angular | 2 |
Cargo.toml | rust | 2 |
go.mod | go | 2 |
pyproject.toml / requirements.txt | python | 2 |
| ๊ธฐํ | unknown | 2 |
- ๊ฐ์ง ๋ถ๊ฐ โ ์ฌ์ฉ์์๊ฒ ์ง๋ฌธ
Tier 2 ์คํ์ ์ ๋ฌธ ์์ด์ ํธ ํ
ํ๋ฆฟ์ด ์๋ค. ์๋ด:
"์ด ์คํ({stack})์ ๊ธฐ๋ณธ ์์ด์ ํธ 3์ข
(explorer + security-reviewer + test-writer)์ผ๋ก ์์ํฉ๋๋ค.
ํ๋ก์ ํธ ์ด์ ํ ๋๋ฉ์ธ ์์ด์ ํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค."
Step 2. ๊ธฐ์กด Harness ์ํ ๊ฐ์ง
์๋ 7๊ฐ ํญ๋ชฉ์ ๊ฒ์ฌํ์ฌ ๊ฐ๊ฐ์ ์ํ๋ฅผ ๊ธฐ๋กํ๋ค:
| # | ํญ๋ชฉ | ํ์ธ ๋ฐฉ๋ฒ |
|---|
| D1 | .claude/settings.local.json | ํ์ผ ์กด์ฌ + HARNESS_MODE + hooks ์น์
|
| D2 | .claude/hooks/ (4์ข
) | harness-context-inject.sh, compile-check.sh, review-gate.sh, persist-checkpoint.sh |
| D3 | .claude/agents/ | ํ์ผ ๋ชฉ๋ก + ์ ๋์ฌ ํจํด |
| D4 | CLAUDE.md | "Harness" ํค์๋ ํฌํจ ์น์
์กด์ฌ ์ฌ๋ถ |
| D5 | .claude/runtime/ | ๋๋ ํ ๋ฆฌ + ํ์ ๊ตฌ์กฐ |
| D6 | .claude/runtime/harness-metrics/ | aggregate.py + scorecard.md |
| D7 | ๊ธ๋ก๋ฒ harness ์คํฌ | ~/.claude/skills/harness-*/SKILL.md ์กด์ฌ |
Step 3. ์ธํฐ๋ทฐ (๋ถ๊ธฐ)
scope=check
์ฝ๊ธฐ ์ ์ฉ. ๋ณด๊ณ ์ ์ถ๋ ฅ ํ ์ข
๋ฃ:
Harness Status: {project} ({stack}, {mode})
โ
settings โ
hooks(4/4) โ ๏ธ agents(4/7) โ rules โ
runtime โ
metrics
โ ๋ถ์กฑ: agents 3์ข
, rules
โ /harness-setup full ์คํ ์ ์๋ ๋ณด์ถฉ๋ฉ๋๋ค
์ถ๊ฐ ์ง๋ฌธ ์์ด ์ข
๋ฃ.
scope=full / upgrade โ ํตํฉ ์ธํฐ๋ทฐ
๊ฐ์ง ๊ฒฐ๊ณผ์ ์ ์์ ํ ๋ฒ์ ๋ณด์ฌ์ฃผ๊ณ ์ฌ์ฉ์ ํ์ธ์ ๋ฐ๋๋ค:
๐ ๊ฐ์ง ๊ฒฐ๊ณผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Project: {project_dir_name}
Stack: {detected_stack} ({gradle/maven/vite ๋ฑ})
Git: โ
(branch: {current_branch}) / โ
๊ธฐ์กด ๊ตฌ์ฑ: settings={Y/N}, hooks={N/4}, agents={N}๊ฐ ({prefix}-*)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ ๊ฒฐ์ ์ด ํ์ํ 3๊ฐ์ง ํญ๋ชฉ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1๏ธโฃ HARNESS_MODE (์ปค๋ฐ ์ฐจ๋จ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค)
โ suggest: Hook์ด ์ ์๋ง ํฉ๋๋ค (์ฐจ๋จ ์์) โ ์ด๊ธฐ ๋์
๊ถ์ฅ
โ auto: Hook์ด ๊ฐ์ ์ฃผ์
+ ํ์ง๊ฒ์ดํธ ๋ฏธํต๊ณผ ์ ์ปค๋ฐ ์ฐจ๋จ
โ off: Harness ๋นํ์ฑ
โ ์ด๋ค ๋ชจ๋๋ก ์ค์ ํ์๊ฒ ์ต๋๊น? (๊ธฐ๋ณธ: suggest)
2๏ธโฃ ์์ด์ ํธ ์ ๋์ฌ
๊ฐ์ง๋ ๊ฐ: "{auto_detected_prefix}"
(๊ทผ๊ฑฐ: {๊ธฐ์กด agents์์ ์ถ์ถ / ๋๋ ํ ๋ฆฌ๋ช
๊ธฐ๋ฐ})
โ ์ด ์ ๋์ฌ๊ฐ ๋ง์ต๋๊น? ๋ค๋ฅธ ์ด๋ฆ์ ์ฐ์๊ฒ ์ต๋๊น?
3๏ธโฃ ์์ฑํ ์์ด์ ํธ ๋ชฉ๋ก ({stack} ๊ธฐ์ค)
[ํต์ฌ 4์ข
, ๋ชจ๋ ์์ฑ ๊ถ์ฅ]
- {prefix}-explorer
- {prefix}-security-reviewer
- {prefix}-test-writer
- {prefix}-build-resolver
[๋๋ฉ์ธ ์์ด์ ํธ (๊ด๋ จ ์ฝ๋ ์กด์ฌ ์์๋ง ์์ฑ)]
- {prefix}-jpa-reviewer โ entity/ ๊ฐ์ง๋จ โ
- {prefix}-cqrs-refactorer โ service/ ๊ฐ์ง๋จ โ
- {prefix}-api-contract-reviewer โ controller/ ๊ฐ์ง๋จ โ
โ ์ ๋ถ ์์ฑํ ๊น์? ์ ์ธํ ์์ด์ ํธ๊ฐ ์์ต๋๊น?
์ฌ์ฉ์ ๋ต๋ณ ์์ ํ Step 4๋ก.
์ธํฐ๋ทฐ ์๋ต ์กฐ๊ฑด
์ฌ์ฉ์๊ฐ ํธ์ถ ์ ์ด๋ฏธ ๋ช
์ํ ๊ฒฝ์ฐ ํด๋น ์ง๋ฌธ๋ง ์๋ต:
- "auto ๋ชจ๋๋ก" ๋ช
์ โ 1๏ธโฃ ์ง๋ฌธ ์๋ต
- "์ ๋์ฌ myapp์ผ๋ก" ๋ช
์ โ 2๏ธโฃ ์ง๋ฌธ ์๋ต
- "์์ด์ ํธ๋ ํต์ฌ๋ง" ๋ช
์ โ 3๏ธโฃ ํต์ฌ 4์ข
๋ง ์ ํ
๋ชจ๋ ๊ฐ์ด ๋ช
์๋์ด ์์ด๋ ์ต์ข
"์งํํ ๊น์?" ํ์ธ์ Step 5์์ ๋ฐ๋์ ๋ฐ๋๋ค.
Step 4. ์ ๋์ฌ ํ์
์ธํฐ๋ทฐ ๋ต๋ณ์ ๋ฐ์ํ์ฌ ์ต์ข
์ ๋์ฌ ๊ฒฐ์ . ์ฌ์ฉ์๊ฐ ์ธํฐ๋ทฐ์์ ํ์ธํ์ผ๋ฏ๋ก ์ถ๊ฐ ์ง๋ฌธ ๋ถํ์.
์ ๋์ฌ ํ๋ณด ์ฐ์ ์์ (์ฌ์ฉ์ ๋ฏธ์ง์ ์):
- ๊ธฐ์กด
.claude/agents/ ํ์ผ๋ช
์์ ์ถ์ถ (์: haback-jpa-reviewer.md โ haback)
- ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ๋ช
๋ณํ (์:
app-ha-back โ haback, cs-front โ csfront, my-cool-app โ mycoolapp)
Step 5. ์ต์ข
์คํ ๊ณํ + ํ์ธ
๋ถ์กฑํ ์ปดํฌ๋ํธ ๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๊ณ ํ์ธ์ ๋ฐ๋๋ค:
๋ค์ ํ์ผ์ ์์ฑ/์์ ํฉ๋๋ค:
[์๋ก ์์ฑ]
.claude/hooks/harness-context-inject.sh
.claude/hooks/compile-check.sh
.claude/hooks/review-gate.sh
.claude/hooks/persist-checkpoint.sh
.claude/agents/{prefix}-explorer.md
.claude/agents/{prefix}-security-reviewer.md
.claude/agents/{prefix}-test-writer.md
.claude/agents/{prefix}-build-resolver.md
.claude/runtime/harness-metrics/aggregate.py
.claude/runtime/harness-metrics/aggregate.sh
.claude/runtime/harness-metrics/scorecard.md
[์์ ]
.claude/settings.local.json (HARNESS_MODE + hooks ์ถ๊ฐ)
CLAUDE.md (Harness Integration ์น์
์ถ๊ฐ)
[๊ฑด๋๋]
.claude/agents/existing-agent.md (์ด๋ฏธ ์์)
์งํํ ๊น์?
Step 6. ์คํ
6.1 settings.local.json
์์ ์ ๋ฐ๋์ .settings.local.json.bak ๋ฐฑ์
.
๊ธฐ์กด ํ์ผ์ด ์์ผ๋ฉด Read โ env.HARNESS_MODE ์ถ๊ฐ + hooks ์น์
์ถ๊ฐ.
permissions ์น์
์ ์ ๋ ๊ฑด๋๋ฆฌ์ง ์๋๋ค.
์์ผ๋ฉด ์๋ก ์์ฑ. JSON ๊ตฌ์กฐ:
{
"env": { "HARNESS_MODE": "{mode}" },
"hooks": {
"UserPromptSubmit": [{"hooks": [{"type": "command", "command": "bash .claude/hooks/harness-context-inject.sh", "statusMessage": "Harness context injection..."}]}],
"PostToolUse": [{"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "bash .claude/hooks/compile-check.sh", "statusMessage": "Harness compile check..."}]}],
"PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "bash .claude/hooks/review-gate.sh", "if": "Bash(git commit*)", "statusMessage": "Harness review gate..."}]}],
"Stop": [{"hooks": [{"type": "command", "command": "bash .claude/hooks/persist-checkpoint.sh", "statusMessage": "Harness checkpoint save..."}]}]
}
}
ํจ์ ์ฃผ์: hooks ํค๋ ์ด์ค ๋ฐฐ์ด โ [{ "hooks": [{ "type": "command", ... }] }]. ๋จ์ผ ๋ฐฐ์ด๋ก ์ฐ๋ฉด ๋์ํ์ง ์๋๋ค.
6.2 Hooks (4์ข
)
mkdir -p .claude/hooks ํ 4๊ฐ ์คํฌ๋ฆฝํธ ์์ฑ.
harness-context-inject.sh (๊ณตํต)
#!/usr/bin/env bash
HARNESS_MODE="${HARNESS_MODE:-suggest}"
[[ "$HARNESS_MODE" == "off" ]] && exit 0
PROMPT=$(cat)
if echo "$PROMPT" | grep -qi "/jira-plan\|jira-plan"; then
if [[ "$HARNESS_MODE" == "auto" ]]; then
cat <<'EOF'
INSTRUCTION: MANDATORY HARNESS SKILL ACTIVATION
/jira-plan์ด ๊ฐ์ง๋์์ต๋๋ค.
1. EVALUATE: /jira-plan์ ๋จผ์ ์คํํ์ฌ dev-guide.md๋ฅผ ์์ฑํฉ๋๋ค.
2. ACTIVATE: ์๋ฃ ํ Skill tool๋ก /harness-plan์ ๋ฐ๋์ ์คํํฉ๋๋ค.
3. IMPLEMENT: ๋ ์ฐ์ถ๋ฌผ์ด ๋ชจ๋ ์ค๋น๋ ํ์๋ง ๋ค์ ๋จ๊ณ๋ฅผ ์งํํฉ๋๋ค.
CRITICAL: /harness-plan์ ์คํํ์ง ์๊ณ ๋์ด๊ฐ๋ ๊ฒ์ WORTHLESS.
EOF
else
echo "RECOMMENDATION: /jira-plan ์๋ฃ ํ /harness-plan ์คํ์ ๊ถ์ฅํฉ๋๋ค."
fi
fi
if echo "$PROMPT" | grep -qi "/jira-execute\|jira-execute"; then
if [[ "$HARNESS_MODE" == "auto" ]]; then
cat <<'EOF'
INSTRUCTION: MANDATORY HARNESS REVIEW ACTIVATION
/jira-execute๊ฐ ๊ฐ์ง๋์์ต๋๋ค.
1. EVALUATE: Phase ๊ตฌํ์ ์๋ฃํฉ๋๋ค.
2. ACTIVATE: ์๋ฃ ํ Skill tool๋ก /harness-review๋ฅผ ๋ฐ๋์ ์คํํฉ๋๋ค.
3. IMPLEMENT: verdict=PASS์ผ ๋๋ง ๋ค์ Phase๋ก ์งํํฉ๋๋ค.
CRITICAL: /harness-review ์์ด ๋์ด๊ฐ๋ ๊ฒ์ WORTHLESS.
EOF
else
echo "RECOMMENDATION: Phase ์๋ฃ ํ /harness-review ์คํ์ ๊ถ์ฅํฉ๋๋ค."
fi
fi
exit 0
compile-check.sh (์คํ๋ณ)
์คํ์ ๋ฐ๋ผ ๋ด์ฉ์ด ๋ค๋ฅด๋ค. ์ด ํ์ผ๋ง ์คํ๋ณ๋ก ๋ค๋ฆ.
spring-boot: Entity ์์ ๊ฐ์ง โ ./gradlew compileJava -q. .java ํ์ผ ๋ณ๊ฒฝ ์ถ์ .
vue: .vue/.ts/.tsx ๋ณ๊ฒฝ ์ถ์ ๋ง (ํ์
์ฒดํฌ๋ ๋ฌด๊ฑฐ์ฐ๋ฏ๋ก ๋น๋ ์์๋ง).
react: vue์ ๋์ผ ํจํด.
tier2/unknown: ๋ณ๊ฒฝ ํ์ผ ์ถ์ ๋ง.
compile-check.sh ์์ฑ ์ Read tool๋ก references/agent-templates/{stack}.md๋ฅผ ์ฝ์ด ํด๋น ์คํ์ compile-check ํ
ํ๋ฆฟ ์น์
์ ์ฐธ์กฐํ๋ค. Tier 2/unknown ์คํ์ ์๋ generic ๋ฒ์ ์ฌ์ฉ:
#!/usr/bin/env bash
HARNESS_MODE="${HARNESS_MODE:-suggest}"
[[ "$HARNESS_MODE" == "off" ]] && exit 0
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | grep -oE '"file_path"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' 2>/dev/null || echo "")
if [[ -n "$FILE_PATH" ]]; then
mkdir -p .claude/runtime
echo "$FILE_PATH" >> .claude/runtime/changed-files.txt
sort -u .claude/runtime/changed-files.txt -o .claude/runtime/changed-files.txt
fi
exit 0
review-gate.sh (๊ณตํต)
#!/usr/bin/env bash
HARNESS_MODE="${HARNESS_MODE:-suggest}"
[[ "$HARNESS_MODE" == "off" ]] && exit 0
INPUT=$(cat)
CMD=$(echo "$INPUT" | grep -oE '"command"\s*:\s*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' 2>/dev/null || echo "")
if echo "$CMD" | grep -qi "git commit"; then
VERDICT_FILE=".claude/runtime/aggregate-verdict.md"
if [[ ! -f "$VERDICT_FILE" ]]; then
echo "[Harness] โ ๏ธ /harness-review๊ฐ ์คํ๋์ง ์์์ต๋๋ค." >&2
exit 0
fi
VERDICT=$(grep -oiE "(PASS|ITERATE|ESCALATE)" "$VERDICT_FILE" | head -1 || echo "UNKNOWN")
if echo "$VERDICT" | grep -qi "ITERATE\|ESCALATE"; then
echo "[Harness] ๐ด ํ์ง ๊ฒ์ดํธ ๋ฏธํต๊ณผ (verdict=$VERDICT)." >&2
[[ "$HARNESS_MODE" == "auto" ]] && exit 1
elif echo "$VERDICT" | grep -qi "PASS"; then
echo "[Harness] โ
ํ์ง ๊ฒ์ดํธ ํต๊ณผ." >&2
fi
fi
exit 0
persist-checkpoint.sh (๊ณตํต)
#!/usr/bin/env bash
HARNESS_MODE="${HARNESS_MODE:-suggest}"
[[ "$HARNESS_MODE" == "off" ]] && exit 0
cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
BRANCH=$(git branch --show-current 2>/dev/null || echo "")
ISSUE_KEY=$(echo "$BRANCH" | grep -oE "[A-Z]+-[0-9]+" || echo "")
[[ -z "$ISSUE_KEY" ]] && exit 0
mkdir -p .claude/runtime
cat > ".claude/runtime/checkpoint.md" << EOF
# Harness Checkpoint
- **Issue**: $ISSUE_KEY
- **Branch**: $BRANCH
- **Timestamp**: $(date -Iseconds)
- **Last Commit**: $(git log --oneline -1 2>/dev/null || echo "none")
## ๋ณต์: /harness-resume
EOF
echo "[Harness] ์ฒดํฌํฌ์ธํธ ์ ์ฅ๋จ" >&2
exit 0
6.3 Agents
ํต์ฌ ์์ด์ ํธ (๋ชจ๋ ์คํ, ๋ฐ๋์ ์์ฑ): {prefix}-explorer, {prefix}-security-reviewer, {prefix}-test-writer, {prefix}-build-resolver
๋๋ฉ์ธ ์์ด์ ํธ (Tier 1 ์คํ๋ง, ๊ด๋ จ ์ฝ๋ ์กด์ฌ ์):
- Read tool๋ก
references/agent-templates/{stack}.md๋ฅผ ์ฝ์ด ํด๋น ์คํ์ ์ ์ฒด ์์ด์ ํธ ๋ชฉ๋ก๊ณผ MD ํ
ํ๋ฆฟ์ ํ์ธํ๋ค.
- ๊ฐ ๋๋ฉ์ธ ์์ด์ ํธ์ "์กฐ๊ฑด"์ ํ์ธํ์ฌ ์ค์ ์ฝ๋๊ฐ ์์ ๋๋ง ์์ฑํ๋ค.
๋ชจ๋ ์์ด์ ํธ ๊ณตํต ๊ตฌ์กฐ:
---
name: {prefix}-{role}
description: "Use PROACTIVELY after {trigger}. {summary}. Provides analysis, never modifies code."
model: sonnet
tools: Read, Grep, Glob, Bash
---
# {prefix}-{role} โ {title}
## ์ญํ
...
## ํ๋
๋ฌธ์ (์ฒซ ํด์ Read)
- `CLAUDE.md`
{auto_detected_docs}
## ์ ๋ ๊ธ์ง
- ์ฝ๋ ์์ ๊ธ์ง (ํ๋จ+์ ์๋ง)
- ๊ฒฐ๊ณผ๋ stdout ๋ฐํ (์ง์ Write ๊ธ์ง)
## ํ๋จ ๊ธฐ์ค
...
## ์ถ๋ ฅ ํ์
| ID | ์์น | ์ฌ๊ฐ๋ | ์ค๋ช
| ์ ์ |
ํ๋
๋ฌธ์ ์๋ ์ฐ๊ฒฐ: ์์ด์ ํธ ์์ฑ ์ ํ๋ก์ ํธ ๋ด docs/, .claude/docs/๋ฅผ Glob์ผ๋ก ํ์ํ์ฌ ๊ด๋ จ .md ํ์ผ ๊ฒฝ๋ก๋ฅผ {auto_detected_docs}์ ์ฑ์ด๋ค. ํ์ผ์ด 10๊ฐ ์ด์์ด๋ฉด ๊ฐ์ฅ ๊ด๋ จ์ฑ ๋์ 3๊ฐ๋ง ์ ํ.
ํ๋ ์ด์คํ๋ ์นํ ํ์: ์์ด์ ํธ MD ์์ฑ ์ {prefix}, {auto_docs}, {auto_detected_docs} ๋ฑ ๋ชจ๋ ํ๋ ์ด์คํ๋๋ฅผ ์ค์ ๊ฐ์ผ๋ก ์นํํ๋ค. ์ค๊ดํธ ํ๋ ์ด์คํ๋๋ฅผ ๊ทธ๋๋ก ํ์ผ์ ๋จ๊ธฐ๋ฉด ์ ๋๋ค.
6.4 CLAUDE.md
๊ธฐ์กด CLAUDE.md๊ฐ ์์ผ๋ฉด ๋์ append. "Harness" ์น์
์ด ์ด๋ฏธ ์์ผ๋ฉด SKIP.
์ถ๊ฐํ ๋ด์ฉ:
## Harness Engineering Integration
### ์ด์ ๋ชจ๋
- `HARNESS_MODE`๋ `.claude/settings.local.json` ์ฐธ์กฐ
- `auto`: Hook์ด harness ๋จ๊ณ๋ฅผ ๊ฐ์ ์ฃผ์
+ ์ปค๋ฐ ๊ฒ์ดํธ ์ฐจ๋จ
- `suggest`: Hook์ด ์ ์๋ง
- `off`: Harness ๋นํ์ฑ
### ์ํฌํ๋ก ๊ท์น
- /jira-plan ์๋ฃ ํ /harness-plan ์คํ์ ์ ์ํ๋ผ
- /jira-execute ๊ฐ Phase ์๋ฃ ํ /harness-review๋ฅผ ์ ์ํ๋ผ
- /jira-commit ์ aggregate-verdict.md ํ์ธ์ ๊ถ์ฅํ๋ผ
### ์์ด์ ํธ ๋์คํจ์น
- ํ๋ก์ ํธ ์์ด์ ํธ({prefix}-*)๋ ๊ธ๋ก๋ฒ ์์ด์ ํธ๋ณด๋ค ์ฐ์
### ์ํฐํฉํธ ๊ฒฝ๋ก
- dev-guide: `docs/{ISSUE-KEY}-dev-guide.md`
- Sprint Contract: `.claude/runtime/sprint-contract/{ISSUE-KEY}.md`
- Verdict: `.claude/runtime/aggregate-verdict.md`
- State: `.claude/runtime/workflow-state.json`
6.5 Runtime ๋๋ ํ ๋ฆฌ
mkdir -p .claude/runtime/sprint-contract
mkdir -p .claude/runtime/agent-outputs
mkdir -p .claude/runtime/archive
mkdir -p .claude/runtime/harness-metrics
6.6 Metrics
Read tool๋ก references/metrics-templates/aggregate.py๋ฅผ ์ฝ์ด .claude/runtime/harness-metrics/aggregate.py์ ๋ณต์ฌ.
๊ฐ์ ๋ฐฉ์์ผ๋ก aggregate.sh์ scorecard.md ํ
ํ๋ฆฟ๋ ๋ณต์ฌ.
6.7 Manifest ๊ธฐ๋ก
{
"_generated_at": "<timestamp>",
"_generator": "/harness-setup {scope}",
"_stack": "{stack}",
"_prefix": "{prefix}",
"_mode": "{mode}",
"created_files": [...],
"modified_files": [...],
"skipped_files": [...]
}
Step 7. ๊ฒ์ฆ
| # | ํญ๋ชฉ | ๋ฐฉ๋ฒ |
|---|
| V1 | ์์ฑ ํ์ผ ์ ๋ถ ์กด์ฌ | ls ํ์ธ |
| V2 | settings.local.json ์ ํจ JSON | python -m json.tool |
| V3 | Hook ๋ฌธ๋ฒ | bash -n .claude/hooks/*.sh |
| V4 | HARNESS_MODE ์ ํจ๊ฐ | suggest/auto/off ์ค ํ๋ |
| V5 | Agent frontmatter | name, description, model ์กด์ฌ |
๊ฒ์ฆ ํต๊ณผ ํ ์ต์ข
๋ณด๊ณ :
โ
Harness Engineering ๊ตฌ์ฑ ์๋ฃ
Project: {project} ({stack})
Mode: {mode}
Agents: {count}์ข
({prefix}-*)
Hooks: 4/4
Metrics: aggregate.py + scorecard.md
๋ค์ ๋จ๊ณ: /harness-workflow {ISSUE-KEY} ๋ก ์ฒซ ์ค์ ์คํ
์๋ ค์ง ํจ์ (์์ฑ ์ ๋ฐ๋์ ํ์ธ)
| # | ํจ์ | ๋ฐฉ์ง |
|---|
| G1 | Hook JSON ์ด์ค ๋ฐฐ์ด | [{"hooks":[{...}]}] ๊ตฌ์กฐ ๋ฐ๋์ ์ค์ |
| G2 | Verdict ํ์ฑ markdown ๋์ถ | grep -oiE "(PASS|ITERATE|ESCALATE)" ์ฌ์ฉ |
| G3 | ์์ด์ ํธ ์ด๋ฆ ๋ถ์ผ์น | ์ ๋์ฌ ๊ฐ์ง ํ ๋ชจ๋ ๊ณณ์์ ์ผ๊ด ์ฌ์ฉ |
| G4 | Windows CRLF | .gitattributes์ *.sh text eol=lf ์ถ๊ฐ |
| G5 | settings ๋ฐฑ์
๋๋ฝ | ์์ ์ .bak ๋ฐฑ์
ํ์ |
| G6 | ํ๋
๋ฌธ์ 404 | ์์ด์ ํธ ์์ฑ ์ ํ์ผ ์กด์ฌ ํ์ธ |
Upgrade Scope ์ถ๊ฐ ๋์
/harness-setup upgrade ์ ๊ธฐ์กด ํ์ผ๋ ์์ ํ ์ ์๋ค:
| ์ฒดํฌ | ์ต์ ํ์ค | ๋์ |
|---|
| Hook: Forced Eval ํจํด | MANDATORY/CRITICAL/WORTHLESS ํค์๋ | ์๋ ์์ |
| Hook: verdict ํ์ฑ | grep -oiE ์ฌ์ฉ | ์๋ ์์ |
| Metrics ๋๋ฝ | aggregate.py + scorecard.md | ์์ผ๋ฉด ์์ฑ |
| Agent ๋ถ์กฑ | ์คํ ๊ธฐ๋ณธ ์ธํธ ๋๋น | ๋ถ์กฑ๋ถ๋ง ์ ์ (๊ธฐ์กด ์์ ์ ํจ) |
| CLAUDE.md ๊ฑฐ์ง ๊ฒฝ๋ก | ์กด์ฌํ์ง ์๋ ๋๋ ํ ๋ฆฌ ์ฐธ์กฐ | diff ๋ณด๊ณ |