GitHub Actions를 사용하여 CI에서 AI 코딩 하네스 성숙도 측정하기
요약
GitHub Actions를 활용하여 AI 코딩 에이전트의 환경(Harness) 성숙도를 측정하고 CI 파이프라인에 통합하는 방법을 설명합니다. Harness Score를 통해 에이전트의 설정 상태를 L0~L4 레벨로 정량화하여 코드 품질을 관리할 수 있습니다.
핵심 포인트
- Harness Score를 통해 AI 에이전트 환경의 성숙도를 6가지 차원으로 측정 가능
- LLM 호출이나 네트워크 사용 없이 결정론적인 점수 산출 가능
- GitHub Actions에 통합하여 성숙도 저하 시 PR을 실패 처리하는 CI 게이트 구축
- Cursor, Claude Code, Copilot 등 다양한 AI 도구의 설정 상태 스캔 지원
두 팀이 동일한 모델과 동일한 프롬프트(prompt)를 사용하더라도 완전히 다른 결과를 얻을 수 있습니다.
그 차이는 종종 모델 때문이 아닙니다. 그것은 바로 하네스(harness), 즉 에이전트(agent)를 둘러싸고 있는 가이드, 규칙, 기술, 훅(hooks), 테스트, 그리고 CI 피드백입니다.
대부분의 저장소(repository)는 이러한 하네스를 천천히 구축합니다. 하지만 그 중 거의 어느 곳도 이를 **측정(measure)**하지 않습니다. 더 나쁜 점은, 풀 리퀘스트(pull request)가 조용히 hooks.json을 삭제하거나 CI 게이트(gate)를 제거할 수 있으며, 에이전트가 값비싼 실수를 저지르기 전까지는 아무도 이를 알아차리지 못한다는 것입니다.
이 튜토리얼에서는 Harness Score를 사용하여 GitHub Actions 파이프라인에 결정론적인(deterministic) 성숙도 점수를 도입하는 방법을 보여줍니다. 이를 통해 AI 지원 저장소도 테스트나 린트(lint)에서 기대하는 것과 동일한 방식의 래칫(ratchet) 효과를 얻을 수 있습니다.
"AI 하네스 성숙도"의 의미
Harness Score는 Cursor, Claude Code, Windsurf, Cline, Continue, Codex, Copilot과 같은 도구 전반에 걸쳐 파일 시스템 증거를 스캔합니다. 결과로 다음을 반환합니다:
- **L0 (Unharnessed)**에서 **L4 (Self-correcting)**까지의 성숙도 레벨
- 6가지 차원에 걸친 점수 (최대 108점)
- 다음에 수정해야 할 항목의 순위 목록
| 레벨 | 이름 | 대략적인 의미 |
|---|---|---|
| L0 | Unharnessed | 에이전트가 매 세션마다 프로젝트를 다시 발견함 |
| ... |
중요한 제약 사항 (설계 의도):
- 스캔 중 LLM 호출 없음
- 스캔 중 네트워크 사용 없음
- 동일한 커밋 ⇒ 동일한 점수
이러한 특성 덕분에 CI 게이트를 설정할 때 해당 수치를 안전하게 사용할 수 있습니다.
먼저 로컬에서 시도해 보세요:
npx harness-score@1.5.1
왜 이것을 GitHub Actions에 넣어야 하는가
로컬 스캔도 유용하지만, CI는 계약(contract)입니다.
파이프라인에 Action을 추가하면 다음과 같은 작업을 할 수 있습니다:
- 최소 성숙도 레벨 미만으로 떨어지는 PR 실패 처리
- 차원별 분석이 포함된 작업 요약(job summary) 표시
- 베이스 브랜치 대비 점수 변화량(delta)을 포함한 고정형 PR 댓글(sticky PR comment) 게시
- 성숙도가 변경될 때 업데이트되는 README 배지(badge) 발행
공식 Action: Harness Score on the GitHub Marketplace
튜토리얼: CI에 Harness Score 추가하기
1) 워크플로우(workflow) 생성
.github/workflows/harness.yml 파일을 추가합니다:
name: Harness maturity
on:
...
Commit, push를 수행한 후 Actions 탭을 엽니다. 다음과 같은 작업 요약(job summary)과 함께 차원별(per-dimension) 테이블이 표시됩니다:
Harness Score: L2 · Guided (65% maturity)
팁: 더 강력한 공급망 위생(supply-chain hygiene)을 위해, Action을
@v1대신 전체 커밋 SHA로 고정(pin)하세요.
2) 기준점(baseline)을 파악한 후 게이팅(gating) 시작하기
저장소의 현재 위치를 파악했다면, 하한선(floor)을 높이세요.
예시: main 브랜치와 PR에 대해 최소 L3 · Sensing을 요구하도록 설정:
- uses: paladini/harness-score@v1
with:
min-level: '3'
...
성숙도가 L3 미만으로 떨어지면 작업(job)이 실패하며, 복구에 필요한 격차(gaps)(예: 누락된 센서 또는 CI 커버리지)를 출력합니다.
실제 도입 단계:
- 1주 차:
min-level: '0'(관찰) - 2주 차:
min-level을 현재 수준으로 설정 (퇴보(regressions) 방지) - 이후: 가이드(guides), 센서(sensors), 훅(hooks)을 추가함에 따라 한 번에 한 단계씩 상향
3) 고정 PR 댓글 추가 (선택 사항, 강력 권장)
pull_request 이벤트 발생 시, 이 Action은 PR의 head를 base 브랜치와 비교하여 하나의 고정된 댓글(sticky comment)을 업데이트할 수 있습니다:
on:
pull_request:
...
pull-requests: write 권한이 필요합니다. Action이 이 권한을 대신 부여할 수는 없습니다.
댓글에는 레벨 변화(예: L2 → L3), 점수 차이(deltas), 그리고 새로 통과하거나 새로 실패한 체크 항목들이 표시됩니다. 이를 통해 하네스 퇴보(harness regressions)를 Checks 탭의 빨간색 X 표시뿐만 아니라 리뷰 과정에서도 시각적으로 확인할 수 있습니다.
4) README에 배지(badge) 게시하기
Action은 실행될 때마다 harness-badge.svg를 작성할 수 있습니다. 일반적인 패턴은 이를 badges 브랜치에 커밋하거나(또는 정적 자산을 호스팅하는 곳에 업로드), 다음과 같이 임베드하는 것입니다:
<img alt="Harness Score" src="https://raw.githubusercontent.com/<you>/<repo>/badges/harness-badge.svg" height="20">
자동 업데이트를 원하지 않는다면 문서 사이트에서 제공하는 정적 레벨 배지를 사용할 수도 있습니다.
더 많은 배지 레시피: Show your maturity
유용한 Action 입력값 (Useful Action inputs)
| 입력값 (Input) | 기본값 (Default) | 기능 (What it does) |
|---|---|---|
min-level | 0 | 성숙도 (maturity)가 이 레벨(0–4)보다 낮을 경우 실패 처리 |
| ... |
이후 단계에서 사용할 수 있는 출력값 (Outputs): level, level-name, percent.
선택 사항: 리포지토리 설정 (Optional: repository config)
팀 정책(범위(scopes), 프리셋(presets), 체크별 규칙(per-check rules))이 필요한 경우, 리포지토리 루트에 .harness-score.json을 추가하세요.
예시: 사용자 범위 오버레이(user-scope overlays)를 통한 로컬 진단은 허용하면서, 리포지토리 (repository) 성숙도에 따라 CI 게이트(CI gated)를 유지하는 경우:
{
"scopes": {
"user": true,
...
커스터마이징은 투명하게 이루어집니다. 제외된 체크 항목은 획득한 점수와 가용 점수 모두에서 제거됩니다 (무료 크레딧 없음). 또한, 노출된 자격 증명(exposed credentials)에 대한 보안 체크는 비활성화할 수 없습니다.
이 도구가 주장하지 않는 것 (What this does not claim)
높은 점수는 신뢰할 수 있는 에이전트(agent) 작업을 위한 **인프라스트럭처 (infrastructure)**가 존재함을 의미합니다:
- 컨텍스트 (context) 및 규칙 (rules)
- 기술/명령어 (skills/commands)
- 훅/가드레일 (hooks/guardrails)
- 센서 (sensors) (테스트/린트/타입)
- CI 피드백 (CI feedback)
- 위생/안전 (hygiene/safety)
이것이 귀하의 테스트가 훌륭하다거나, 규칙이 정확하다거나, 모든 런타임 경로(runtime path)가 약속된 하네스(harness)를 준수한다는 것을 의미하지는 않습니다. 이러한 정직함은 의도된 것입니다. 결정론적 스캐너(deterministic scanners)가 분위기(vibes)를 판단하는 척해서는 안 되기 때문입니다.
전체 스타터 워크플로우 (Full starter workflow)
게이트(gate) + PR 댓글(PR comment) + 배지(badge) + 리포트(report)가 포함된 복사-붙여넣기 버전:
name: Harness maturity
on:
...
시도해보고, 점진적으로 개선하세요 (Try it, then ratchet)
- 로컬에서
npx harness-score@1.5.1을 실행합니다. min-level: '0'과 함께 워크플로우를 추가합니다.- 조용한 퇴보(silent regressions)를 방지하기 위해
min-level을 현재 레벨로 설정합니다. - 리포트에서 제공하는 순위별 수정 목록(ranked fix list)을 통해 L3/L4를 향해 올라갑니다.
링크:
이것을 리포지토리(repo)에 추가한 후, 여러분의 시작 단계(L0–L4)와 가장 놀라웠던 첫 번째 체크 항목을 댓글로 남겨주세요. 그러한 보고서들은 성숙도 모델(maturity model)을 더욱 견고하게 만드는 가장 좋은 방법입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기