Implement Commit Skill
implementation-plan.toml의 커밋을 기계적인 TDD 파이프라인으로 실행합니다.
사용 시점
docs/features/NNNN-name/implementation-plan.toml에 구현 계획이 존재할 때- 코드 작성을 시작할 준비가 되었을 때
오케스트레이터의 역할
당신은 기계적인 오케스트레이터입니다. 드라이버(ic-driver.py)가 상태 전이를 처리합니다.
당신은 다음만 수행합니다:
- 드라이버 명령 호출
- 스폰 동작 실행
- 결과 보고
문제가 발생하지 않는 한 관련 파일을 읽지 않아야 합니다. 토큰을 아끼고 ic-driver를 신뢰하세요.
설정
import json
from pydantic import BaseModel
from typing import Literal
# 경로
feature_dir = "docs/features/NNNN-feature"
plan_path = f"{feature_dir}/implementation-plan.toml"
state_dir = ".ic"
driver = "skills/implement-commit/ic-driver.py"
workspace = "." # 계획 메타 정보로부터
# 응답 모델
class PhaseResult(BaseModel):
status: Literal["ok", "problems"]
files_created: list[str] = []
files_modified: list[str] = []
notes: str | None = None
class GateDiscovery(BaseModel):
designer_gate: str
test_gate: str
class FormatterDiscovery(BaseModel):
fmt_cmd: str
lint_cmd: str
class StyleResult(BaseModel):
status: Literal["accept", "violations"]
violations: list[str] = []
class ArbiterResult(BaseModel):
proceed: bool
reasoning: str
# 스폰용 에이전트 파일
agents = {
"designer": "skills/implement-commit/agents/designer.md",
"tester": "skills/implement-commit/agents/tester.md",
"implementor": "skills/implement-commit/agents/implementor.md",
"arbiter": "skills/implement-commit/agents/arbiter.md",
}
style_guides = {
"designer": "docs/style/rust-design.md",
"tester": "docs/style/rust-test.md",
"implementor": "docs/style/rust-impl.md",
}
메인 루프
각 커밋에 대해 (의존성 순서대로):
commit_id = 1 # 의존성 분석 결과
state_path = f"{state_dir}/commit-{commit_id}.json"
# 초기화
bash(f"python {driver} init --plan {plan_path} --commit {commit_id} --state {state_path}", on_error="raise")
# 드라이브 루프
while True:
try:
output = bash(f"python {driver} next --state {state_path}", on_error="raise")
except BashError as e:
# 드라이버가 LLM 도움 필요 - 아래 '에스컬레이션 처리' 참조
handle_escalation(e, state_path)
continue
action = json.loads(output)
if action["action"] == "done":
break
if action["action"] == "spawn":
result = execute_spawn(action)
bash(
f"python {driver} report --state {state_path} --result '{json.dumps(result)}'",
on_error="raise"
)
스폰 실행
def execute_spawn(action: dict) -> dict:
phase = action.get("phase")
# 컨텍스트 파일 결정
context_files = [f"{feature_dir}/design.md"]
if phase and phase in agents:
context_files.append(agents[phase])
if phase in style_guides:
context_files.append(style_guides[phase])
# 응답 모델 결정
if action.get("response_schema") == "GateDiscovery":
model = GateDiscovery
elif action.get("response_schema") == "FormatterDiscovery":
model = FormatterDiscovery
elif action.get("style_review"):
model = StyleResult
elif action.get("arbiter"):
model = ArbiterResult
else:
model = PhaseResult
# 스폰 실행
result = spawn(
prompt=action["prompt"],
context_files=context_files,
response_model=model,
read_only=action.get("style_review") or action.get("scope_review"),
isolate_to=Cwd(workspace) if not action.get("style_review") else None,
)
result_dict = result.parsed.model_dump()
# 드라이버 상태 머신을 위한 액션 플래그 유지
if action.get("arbiter"):
result_dict["arbiter"] = True
return result_dict
에스컬레이션 처리
드라이버가 종료 코드 1로 종료되면 LLM 도움이 필요합니다:
def handle_escalation(e: BashError, state_path: str):
# stderr에서 에스컬레이션 정보 파싱
escalation = json.loads(e.stderr)
error = escalation["error"]
# LLM 개입 - 문제 이해 및 수정
# 이 부분에서 THINK(생각)하세요. 드라이버가 제어권을 넘겼습니다.
if "gate failed" in error.lower():
# 코드 오류 또는 게이트 설정 오류 가능성
# 수정 에이전트 스폰 또는 게이트 조정
spawn(
prompt=f"게이트 실패 수정: {error}",
context_files=[...],
isolate_to=Cwd(workspace),
)
elif "arbiter rejected" in error.lower():
# 스타일 문제가 너무 심각함
agent_feedback(f"스타일 검토 실패: {error}")
elif "scope violations" in error.lower():
# 범위를 벗어난 변경
agent_feedback(f"범위 위반: {error}")
else:
agent_feedback(f"알 수 없는 에스컬레이션: {error}")
# 수정 후 재개
bash(f"python {driver} resume --state {state_path}", on_error="raise")
드라이버 명령어
| 명령어 | 목적 |
|---|---|
init | 커밋을 위한 상태 파일 생성 |
next | 다음 동작(스폰) 가져오기 또는 게이트/배시 직접 실행 |
report | 스폰 결과 보고, 상태 전이 |
resume | LLM 개입 후 계속 진행 |
status | 현재 상태 표시 (디버깅) |
상태 머신
EXPLORE_GATES -> EXPLORE_FORMATTERS ->
DESIGNER_PHASE -> DESIGNER_GATE -> DESIGNER_STYLE ->
TESTER_PHASE -> TESTER_GATE -> TESTER_STYLE ->
IMPLEMENTOR_PHASE -> IMPLEMENTOR_GATE -> IMPLEMENTOR_STYLE ->
SCOPE_REVIEW -> FORMAT -> COMMIT -> DONE
- 게이트 실패 시 해당 단계 최대 2회 재시도 후 에스컬레이션
- 스타일 위반 시 최대 3회 루프 후 중재자 호출
- 드라이버가 게이트/포맷/커밋을 직접 실행 (LLM 오버헤드 없음)
- 스폰만 오케스트레이터 동작 필요
파일 구조
skills/implement-commit/
├── SKILL.md # 이 파일
├── ic-driver.py # 상태 머신 드라이버
└── agents/
├── designer.md # 타입과 시그니처 생성
├── tester.md # 테스트 작성
├── implementor.md # 로직 구현
└── arbiter.md # 스타일 검토 진행/실패 결정
리뷰어는 별도 스킬 사용: review-scope, review-style.