전체 검색

글, 태그와 카테고리를 검색하고 바로 이동해요

백엔드 개발자가 프론트 화면을 고치기 시작했다 — AI 개발 하네스

"작업해줘" 한 마디면 지라 수집부터 구현·검증까지. 규칙을 기계에 옮겨놨더니 기여자가 프론트 개발자일 필요가 없어졌어요. 사람이 매번 하던 설명 워크플로우를 하네스에 녹인 이야기예요.

2026. 08. 05. 18:22:339분 읽기프로젝트/데이터 플랫폼
#하네스
조회 16

백엔드 개발자가 올린 프론트엔드 PR이 머지됐어요.

놀라운 건 그게 아니에요. 그 PR이 올라오기까지, 프론트엔드 팀 누구도 그에게 아무것도 설명해주지 않았다는 겁니다. 기여 모델이 뭔지, 라우트가 어떻게 조립되는지, 컨벤션이 몇 층인지. 아무것도요.

그가 한 일은 한 마디였어요. "TICKET-731 작업해줘."

얼마 전까지 저는 이 블로그에 "하네스가 뭔지 잘 모른다"고 고백했던 사람이에요. 안 찾아봤다고, 우선순위의 문제라고요. 그 말은 지금도 유효한데 — 결국 하네스를 알게 된 건 검색이 아니라 필요 때문이었습니다. 만들어야 할 일이 생겼거든요.

(그 글에서 "내부가 궁금해지는 날이 오면 그때 파도 늦지 않다"고 했는데, 그날이 진짜 왔습니다. 파는 정도가 아니라 만들었어요.)

병목은 코드가 아니라 설명이었어요

저희 팀 사정은 이 시리즈를 읽으신 분이라면 아실 거예요. 제품 6종에 고객사 8곳, 프론트엔드는 2명. 티켓은 늘 프론트 앞에 줄을 섭니다.

처음엔 사람을 늘리면 풀리는 문제라고 생각했어요. 그런데 화면 하나를 붙이는 데 필요한 지식을 목록으로 적어보고 생각이 바뀌었습니다.

알아야 하는 것왜 필요한가
기여(Contribution) 모델화면은 중앙 파일이 아니라 패키지의 기여로 등록되니까
활성화 키와 프래그먼트어느 시점에 어떤 코드가 로드되는지 여기서 결정되니까
컨벤션 4개 층네이밍부터 레이어 방향까지, 어기면 빌드가 막히니까
라우트 조립라우트는 작성이 아니라 합성이니까
게이트 규칙 50여 개뭐가 금지인지 모르면 왜 실패했는지도 모르니까

신규 입사자도 이 목록 앞에서 몇 주를 씁니다. 옆 팀 백엔드 개발자가 "화면 하나만 붙이고 싶은데요"라고 왔을 때, 이걸 다 가르칠 수는 없어요.

그리고 더 큰 비용이 따로 있었습니다. 티켓이 올 때마다 반복되는 일이요.

지라 티켓이 생기면, 누군가 그걸 읽습니다. 에픽을 거슬러 올라가고, 댓글을 뒤지고, 피그마를 열고, 스웨거를 확인하고 — 그걸 요약해서 작업할 사람에게 설명해줘요. 티켓 하나에 30분씩. 티켓은 매주 옵니다.

구현이 아니라 이 설명 워크플로우가 진짜 병목이었어요. 사람이 하는 일 중 가장 기계적인데, 가장 사람에게 묶여 있었죠.

전제 — 규칙이 이미 기계였다는 것

이 시리즈 앞의 세 편이 전부 이 이야기의 복선이었습니다. 컨벤션은 실패하는 빌드로 존재하고, 화면 불변은 해시가 증명하고, 브라우저가 뭘 받아가는지는 CI가 지켜봐요.

규칙을 전부 기계로 옮기고 나니, 예상 못 한 결론이 하나 따라왔어요.

구현하는 손이 누구인지가 중요하지 않게 된 겁니다.

리뷰어의 기억이 규칙을 지키는 코드베이스에서는 낯선 기여자가 위험해요. 하지만 규칙 위반이 빌드 실패로 돌아오는 코드베이스에서는, 초보든 백엔드 개발자든 AI든 — 어기면 막히니까요. 사람 리뷰는 설계를 보면 되고요.

그렇다면 남는 문제는 둘이에요. 요구사항을 누가 수집하느냐. 그리고 AI에게 시키는 방법이 사람마다 달라서 결과가 복불복이라는 것. 이 둘을 묶어서 푸는 게 하네스입니다.

하네스 — "작업해줘" 한 마디의 해부

사용자 입장에서 하네스는 이렇게 생겼어요.

"TICKET-731 작업해줘"
   ↓
① 수집 — 지라 티켓·에픽·댓글, 피그마, 스웨거를 읽는다 (read-only)
② 정규화 — 읽은 것을 task record(JSON)에 요구사항·아키텍처 판정·질문으로 채운다
③ 구현 — 코드 분석 → 구현 → 게이트 통과까지
④ 검증 — 테스트·타입체크·게이트 결과를 record에 증거로 남긴다

─── 여기까지가 기본. 아래는 명시적으로 요청할 때만 ───
⑤ 커밋 / PR / 지라 완료 처리

사람이 매번 하던 "읽고 요약해서 설명해주기"가 ①과 ②로 들어갔습니다. 티켓을 읽는 사람이 따로 필요 없어요. 작업자는 티켓 번호만 알면 됩니다.

실행 범위는 사용자의 말로 정해져요. 옵션 플래그가 아니라, 사람이 원래 쓰는 문장으로요.

사용자가 하는 말하네스가 하는 일
"확인해줘"소스와 코드 분석만 하고 구현은 안 함
"작업해줘"수집 → 구현 → 검증까지
"지라 없이 작업해줘"대화에 티켓 번호가 있어도 지라를 안 봄
"커밋까지" / "PR까지"검증 성공 후에만 Git 단계 추가
"지라 완료까지"병합 증거 확인 후 티켓 종료 처리

이 표에서 제일 중요한 건 마지막 두 줄이에요. 커밋·PR·지라 상태 변경 같은 바깥에 흔적이 남는 일은 기본 범위에 없습니다. 명시적으로 말해야만 해요.

AI에게 일을 시킬 때 제일 무서운 건 실력이 아니라 월권이거든요. 시키지 않은 커밋, 물어보지 않은 티켓 코멘트. 그래서 권한의 계단을 사용자 언어에 박아놨습니다.

수집과 구현을 갈랐어요

내부는 두 덩어리로 나뉩니다. 수집을 담당하는 오케스트레이터와, 구현을 담당하는 구현 하네스요.

규칙은 하나예요. 구현 하네스는 지라·피그마·슬랙 커넥터에 의존하지 않는다.

구현부가 외부 시스템을 직접 물면, 지라가 느린 날 구현이 멈추고, 피그마 API가 바뀌면 구현 코드를 고쳐야 해요. 그래서 구현부는 정규화된 task record 하나만 입력으로 받습니다. 바깥세상이 어떻게 생겼는지 몰라요.

이 경계, 어디서 본 모양이죠. 플러그인이 DB를 모르고, 렌더러가 집계 위치를 모르는 것과 같은 원칙입니다. 하네스를 설계할 때도 결국 같은 손버릇이 나오더라고요.

태스크마스터를 닮은 티켓 — task record

하네스의 심장은 task record라는 JSON 문서 하나예요. 태스크마스터(Taskmaster) 같은 AI 작업 관리 도구를 써보신 분이라면 낯익은 모양일 겁니다. 그 형태를 레포 안에 내장한 셈이에요.

{
  "id": "TICKET-731",
  "input":          { "goal": "정산 요약 화면", "jiraKey": "...", "swaggerSources": ["..."] },
  "requirements":   { /* 지라·피그마에서 정규화한 요구사항 */ },
  "architecture":   { /* 어느 패키지가 소유하는가, 어떤 계약을 쓰는가 */ },
  "questions":      [ /* 소스가 침묵하는 지점 — 사람에게 물을 것 */ ],
  "implementation": { /* 단계별 진행 상태 */ },
  "verification":   { /* 게이트·테스트 통과 증거 */ },
  "decisions":      [ /* 버린 대안과 그 이유 */ ]
}

구조가 곧 프로세스예요. 위에서 아래로 채워지고, 앞 칸이 비면 뒤 칸을 못 채웁니다. 요구사항 없이 구현 못 하고, 검증 없이 완료 못 해요.

여기서 아낀 게 하나 더 있습니다. questions 칸이요. 소스를 다 읽고도 답이 없는 지점 — "이 버튼, 실패하면 어떻게 되나요?" — 만 모아서 사람에게 옵니다. 사람은 설명하는 대신 결정만 하면 돼요.

단계실패하면 어떻게 되나
수집구현을 시작하지 않음 — 빈 요구사항으로 달리지 않게
구현record에 진행 상태가 남아 다음 세션이 이어받음
검증실패 증거가 남고, 성공한 구현은 다시 실행하지 않음
보고·게시뒤 단계가 실패해도 앞 단계 결과는 보존

마지막 줄이 운영에서 제일 고마운 부분이에요. 각 단계가 독립 체크포인트라, 지라 보고가 실패했다고 성공한 구현을 다시 돌리는 일이 없습니다.

동시성도 record가 지켜요. 같은 task를 두 세션이 잡으면 lease가 충돌을 막습니다. 사람 둘이 같은 티켓을 잡는 사고를, 에이전트 둘이 재현하지 않도록요.

설치도 소프트웨어처럼 다룹니다

하네스에서 제가 제일 마음에 들어하는 부분은 사실 실행이 아니라 설치예요.

.harness/
  harness.lock.json     ← 스킬 버전·payload SHA·프로토콜을 고정
  payload/              ← 에이전트들이 공유하는 실행 규칙 원본
  task.schema.json      ← 티켓의 형태 그 자체
  state.local.json      ← 개인 상태 (Git 밖)

.claude/skills/  .agents/skills/   ← clone마다 설치되는 관리형 사본

실행 규칙이 lock 파일로 버전·해시가 고정돼요. 의존성을 잠그듯 워크플로우를 잠그는 겁니다. 그리고 같은 payload를 Codex와 Claude가 공유해요 — 도구를 갈아타도 일하는 방식은 그대로라는 걸, 이번엔 파일 하나로 보장하는 거죠.

설치 상태도 그냥 "됐다/안 됐다"가 아니라 상태 기계입니다.

상태
unconfigured설치 여부를 먼저 물어봄
ready질문 없이 바로 진행
update-requiredpayload가 낡음 — 갱신 후 새 세션
repair-required사용자 동의 후에만 복구
downgrade-blockedclone에 더 새 버전이 있으면 낮추지 않음
disabled이 clone에서는 다시 묻지 않음

downgrade-blocked 같은 상태가 있다는 게 이 설계의 성격을 보여줘요. 잘못 낮춰 깔리는 것까지 막습니다. 워크플로우를 소프트웨어로 취급하면, 워크플로우에도 버전 충돌이 있다는 걸 인정하게 되거든요.

AI가 남긴 코드의 "왜"를 지키기

AI가 구현하면 코드는 남는데 이유가 날아가기 쉬워요. 그래서 하네스에는 결정 기록 규칙이 같이 붙어 있습니다.

// TICKET-731: 스웨거에 응답 스키마가 아직 없어 임시 타입으로 대체
// 제거 조건: 정산 API v2 스키마가 공개되면 이 파일을 지우고 계약 타입을 쓴다

임시 구현에는 티켓 번호·이유·제거 조건이 반드시 붙어요. 여러 파일에 영향을 주는 결정은 별도 문서로 남기고, 필수 항목에 "버린 대안"이 들어갑니다. 완료된 구현에 "제안됨" 상태의 결정을 남기는 건 금지고요 — 결정 못 한 건 결정이 아니라 blocker로 보고해야 합니다.

아키텍처 예외를 주석으로 승인하는 것도 금지예요. 규칙을 바꾸고 싶으면 구현을 멈추고, 규칙 원본과 검사를 같이 바꿔야 합니다. 게이트를 우회하는 뒷문을 하네스가 직접 만들지 않도록요.

그래서 정말 되냐면

됩니다. 다만 정확히 말할게요.

백엔드 개발자가 프론트 화면을 붙이고, 신규 입사자가 첫 주에 티켓을 잡습니다. "이 티켓 요구사항이 뭐예요?"라고 묻는 슬랙 메시지가 눈에 띄게 줄었어요. 설명 워크플로우가 사람에게서 떨어져 나간 건 분명합니다.

하지만 게이트가 모든 걸 잡아주는 건 아니에요.

기계가 잡는 것여전히 사람이 보는 것
컨벤션·레이어 위반이 화면이 제품으로서 말이 되는가
화면 불변·번들 예산이 요구사항 자체가 맞는 방향인가
요구사항 누락 질문 생성질문에 대한 답
버린 대안 기록 강제대안 중 무엇을 버릴지의 판단

리뷰가 사라진 게 아니라 이동했어요. "컨벤션 지켰나"를 보던 시간이 "설계가 맞나"를 보는 시간이 됐습니다. 그리고 그건 기계에 못 맡기는, 원래 사람이 했어야 하는 리뷰고요.

솔직한 한계도 하나. AI 구현 품질은 여전히 편차가 있습니다. 하네스는 바닥을 올려주는 장치지 천장을 올려주는 장치가 아니에요. 잘하는 사람이 쓰면 더 빨라지고, 처음 쓰는 사람이 써도 규칙은 안 깨지는 것 — 딱 거기까지가 하네스의 약속입니다.

다음 상상 — 게이트를 한 칸 더 왼쪽으로

여기서부터는 아직 만든 게 아니라 상상이에요. 그런데 요즘 이 생각을 자주 합니다.

지금 하네스는 개발 단계의 입구에 서 있어요. 티켓이 이미 존재한다는 전제죠. 그런데 현장에서 새는 물의 절반은 티켓이 만들어지기 전에 샙니다. 기획에서요.

기획에서 새는 것하네스가 할 수 있는 검사
버튼의 동작 정의 누락상태 완전성 심문 — 로딩·실패·빈·권한없음 상태가 다 있는가
데이터가 많은 화면의 용량 사고규모 심문 — 최대 행 수는? 최악 케이스는? 페이징은?
다른 기획과의 충돌스펙 충돌 검사 — 기존 문서·용어와 모순 탐지

기획자가 초안을 넣으면, 하네스가 이 체크리스트로 심문하는 거예요.

[기획 하네스 심문 — 상상]
Q. 이 목록의 최대 행 수는 얼마인가요? 미정이면 최악 케이스 기준으로 답해주세요.
Q. "저장" 버튼의 로딩·실패·권한없음 상태가 정의되지 않았어요.
Q. 이 화면의 "그룹"이라는 용어가 기존 스펙의 "조직"과 충돌해요.

질문에 답이 채워진 스펙만 개발 티켓이 될 수 있고, 그 정규화된 스펙이 그대로 개발 하네스의 input이 됩니다. 두 하네스가 파이프라인으로 이어지는 거죠. 지금은 "설명이 필요 없는 작업자"를 만들었는데, 그땐 애초에 설명이 필요 없는 티켓이 내려오는 거예요.

개발 리뷰에서 "이 경우엔 어떻게 되나요?"라고 묻던 것들이, 시니어 기획 리뷰가 하던 일이 — 검사가 되는 겁니다. 사람이라 비쌌고 안 규칙적이었을 뿐, 원래 있던 일이에요.

요즘 말로 하면 이게 AX라던데, 저는 그 단어보다 이렇게 부르고 싶어요. 게이트를 한 칸 왼쪽으로 미는 것. AI는 그걸 갑자기 싸게 만들어준 도구고요.


이 시리즈는 "규칙은 문서가 아니라 실패하는 빌드다"로 시작했어요. 세 편 내내 규칙을 기계로 옮겼고, 이번 편은 그 배당금 이야기였습니다.

규칙이 기계가 되면, 기여자가 사람일 필요도, 프론트엔드 개발자일 필요도 없어져요. 코드베이스를 지키는 건 기억이 아니라 게이트니까요. 하네스가 뭔지 몰랐던 제가 하네스를 만들게 된 이유— 결국 이 시리즈의 결론과 같은 문장이었습니다.

시리즈 이어읽기

규칙은 기계가 지킨다

4 / 4

이야기 나누기

반응을 남기고 새 글 소식을 받아보세요.

댓글0
서로를 존중하는 대화를 남겨주세요.

첫 댓글을 남겨 대화를 시작해보세요.

새 글 구독
새 글이 공개되면 이메일로 알려드려요.