
Level Up 개발자 — 문서를 정확히 고치는 것과, 문서가 틀렸을 때 알아차리는 것은 다른 문제였다.
공유 AI 스킬은 처음에는 문서처럼 보인다. 작업 절차를 마크다운에 적고, 필요한 참고 파일을 연결하면 끝날 것 같다. 하지만 여러 사람이 같은 스킬을 사용하기 시작하면 그 문서는 실제 작업의 입력이 된다. 틀린 속성 이름 하나가 업무 등록을 막고, 지워진 규칙 하나가 계속 질문을 만들어낸다.
공유 스킬을 운영하면서 같은 종류의 불일치를 반복해서 고쳤다. 처음에는 안내를 실제 스키마와 맞췄고, 이후에는 구조·버전·규칙 드리프트를 검사하도록 바꿨다. 이 과정에서 남은 결론은 사람이 읽는 규칙에도 실패 신호가 필요하다는 것이다. 다만 CI가 문장의 의미나 외부 서비스의 현재 상태까지 보장하는 것은 아니다.
첫 번째 문제는 작업 등록 안내에 적힌 값이 실제 업무 DB와 달랐다는 것이다. 상태 옵션이 존재하지 않았고, 특정 작업 유형에 연결한 템플릿도 다른 서식이었다. 안내대로 수행하면 등록이 실패하거나 잘못된 본문이 붙었다.
이때 수정의 기준은 다른 문서가 아니었다. 현재 스키마와 템플릿을 직접 조회해 이름·옵션·대응 관계를 대조했다. 동시에 설계 문서와 계획 문서에 복사된 같은 값을 지우고 하나의 reference를 가리키도록 바꿨다.
이전: 실제 스키마 → 안내 A / 설계 B / 계획 C에 값을 각각 복사
변경: 실제 스키마 → reference 한 곳 → 나머지 문서는 링크
여기서 ‘한 곳’은 저장소 안의 안내를 뜻한다. 외부 업무 DB가 원천이고 reference는 여전히 사본이다. 복사본의 수를 줄였다고 원천과의 시간 차이가 없어지는 것은 아니다.
바로 다음 날 날짜 속성 이름이 바뀌었다. 전날 맞춘 안내대로 요청하면 이제는 존재하지 않는 날짜 필드를 보내게 됐다. 오류에는 현재 편집 가능한 키가 함께 나왔고, 그 키와 라이브 스키마를 기준으로 안내를 다시 수정했다.
두 번째 수정에서는 reference뿐 아니라 스킬 본문의 같은 표기도 함께 바꿨다. 에이전트가 요약 본문만 읽느냐, 상세 reference까지 읽느냐에 따라 다른 행동을 하면 안 되기 때문이다.
이 두 변경이 보여준 것은 ‘이번 값만 정확히 쓰자’로 끝낼 수 없는 문제였다. 원천이 바뀌고, 사본이 늦게 따라가며, 요약과 상세도 따로 바뀔 수 있다. 실패했을 때 원천으로 되돌아가는 절차와 저장소 내부의 불일치를 드러내는 장치가 모두 필요했다.
애플리케이션 코드는 없는 모듈을 import하면 빌드가 깨질 수 있다. 반면 마크다운과 JSON 중심의 스킬 저장소는 훅 파일이 사라지거나 매니페스트 이름이 틀려도 저장소 자체는 조용하다. 설치한 사람의 세션에서야 문제가 드러난다.
그래서 CI에 세 종류의 검사를 넣었다.
| 검사 | 확인하는 계약 | 확인하지 않는 것 |
|---|---|---|
| 구조 | 설치 목록·디렉터리·매니페스트, 훅 파일·실행 권한, 메타데이터·reference 링크 | 지시문이 업무상 올바른지 |
| 버전 | 당시 플러그인 매니페스트들의 고정 버전 형식과 일치 | 새 파일이 실행 중 세션에 적용됐는지 |
| 규칙 드리프트 | 요약·상세에 지정 문구가 남아 있는지, reference가 검사 대상에 등록됐는지 | 문장의 의미가 같은지, 라이브 스키마가 바뀌었는지 |
PR이 열리거나 push가 발생할 때 스크립트를 실행하는 방식은 일반적인 GitHub Actions workflow로 연결할 수 있다. workflow와 job·step의 관계는 GitHub Actions 공식 문서에 설명돼 있다.
중요한 선택은 검사 대상을 ‘파일이 전부 옳은가’로 잡지 않은 것이다. 기계적으로 판정할 수 있는 계약부터 명시했다. 당시 변경에서 다섯 플러그인에 같은 초기 버전을 붙인 것은 그 시점의 배포 규칙이며, 모든 스킬 저장소가 같은 버전을 써야 한다는 일반 원칙은 아니다.
요약과 상세는 같은 규칙을 서로 다른 길이로 쓴다. 파일 전체를 비교하면 정상적인 요약도 항상 다르다고 나온다. 반대로 AI에게 ‘의미가 같은지’ 판정을 맡기면 작은 검사에 비해 비용과 불확실성이 커진다.
요약 파일, 상세 파일, 양쪽에 남아야 할 문구를 PAIRS에 선언했다. 경로와 문구를 단순화하면 검사 구조는 다음과 같다.
const pair = {
summary: 'skills/workflow/SKILL.md',
detail: 'skills/workflow/references/task-db.md',
invariants: ['작업기간', '담당자'],
};
for (const phrase of pair.invariants) {
const missing = [summaryText, detailText]
.filter((text) => !text.includes(phrase));
if (missing.length > 0) {
// 한쪽 수정 또는 규칙 폐기를 검토하도록 실패시킨다.
process.exitCode = 1;
}
}
검사에서는 한쪽에서만 문구가 사라진 경우와 양쪽 모두에서 사라진 경우를 구분해 오류를 출력한다. 규칙을 정말 폐기했다면 문서뿐 아니라 검사 목록에서도 제거해야 한다.
파일을 읽고 목록을 열거하는 것은 Node의 파일 시스템 API로 처리했다. 별도 검증 프레임워크를 만들기보다 작은 스크립트로 필요한 계약을 표현한 선택이다. 관련 API는 Node.js 파일 시스템 공식 문서에서 확인할 수 있다.
검사 목록을 사람이 관리하면 새 reference를 만들고 PAIRS에 등록하는 것을 잊을 수 있다. 그러면 CI가 초록색이어도 그 문서는 검사받지 않는다.
이를 막기 위해 plugins/*/skills/*/references/*.md 패턴에 맞는 문서를 찾아, 등록된 상세 파일 집합과 비교한다. 등록되지 않은 문서가 있으면 실패한다.
reference 문서 추가
↓
정해진 패턴으로 파일 열거
↓
PAIRS의 검사 대상에 포함됐는가?
├─ 아니오 → 실패: 요약·문구 계약을 먼저 등록
└─ 예 → 양쪽 문구 검사
이 장치가 검사 범위의 누락을 줄인다. 다만 이 glob은 정해진 깊이의 마크다운만 찾는다. 중첩 디렉터리나 다른 확장자까지 자동으로 보호하는 것은 아니다. 저장소 구조가 바뀌면 열거 범위도 함께 바꿔야 한다.
검사 도입 당시에는 정상 실행만 확인하지 않았다. 버전 불일치, 한쪽 문구 삭제, 훅 파일 삭제, 실행 권한 제거, 깨진 reference 링크처럼 의도적으로 계약을 깨는 경우도 검증했다. 구체적인 검증 항목과 결과는 아래 작업 PR에 남겼다.
특히 훅 경로 검사에서는 JSON 안의 이스케이프된 따옴표를 정규식이 처리하지 못해, 검사해야 할 경로를 찾지 못한 채 통과하는 문제가 있었다. 이를 수정한 뒤 실패 경로를 다시 확인했다는 기록도 남아 있다.
이 과정에서 검사 결과가 초록색이라는 사실보다, 무엇을 깨뜨렸을 때 빨간색이 되는지가 더 많은 것을 말해준다는 점을 배웠다. 정상 경로만 확인했다면 검사 대상 자체를 놓치는 문제를 발견하기 어려웠을 것이다.
includes 검사는 문구의 존재를 확인한다. 의미의 일치를 증명하지 않는다.
요약: “담당자를 반드시 지정한다.”
상세: “담당자를 지정하지 않는다.”
두 문장에 모두 ‘담당자’가 있으므로 이런 모순은 통과할 수 있다. 외부 DB에서 속성이 바뀌었는데 두 문서가 함께 낡은 경우도 이 검사로 알 수 없다.
그래서 역할을 나눠야 한다.
CI가 있으니 모든 규칙이 맞다는 결론이 아니라, 검사 가능한 조용한 실패 몇 가지를 눈에 보이게 바꿨다는 결론이다.
이 작업에서 가져갈 수 있는 것은 자동 검사 세 개만이 아니다. 문서를 고치는 단기 복구에서 출발해, 원천·사본·세션·검사 범위를 구분한 과정이다.
애플리케이션의 안전망으로 시각 회귀 비교 CLI를 다뤘다면, 이번에는 지시문 저장소의 안전망을 다뤘다. 둘 다 ‘문제가 없다고 추측’하는 대신, 어떤 변화가 생기면 실패 신호를 낼지 정의한다는 점에서 연결된다. 인증 정책의 경계와 대시보드 집계 계약에서도 같은 관점을 적용했다.
이번 작업은 스킬 내용을 더 많이 적는 것으로 끝나지 않았다. 반복되는 불일치를 원천과 사본의 문제로 나누고, 구조·버전·검사 누락을 자동으로 드러내는 장치를 남겼다. 아직 팀 생산성의 변화를 수치로 측정하지는 못했다. 그래도 어떤 실패를 탐지하고 어떤 판단은 사람에게 남겨야 하는지, 운영의 경계는 더 분명해졌다.
작업은 스키마 안내 수정 #13, 속성 변경 대응 #14, 자동 검사 도입 #23으로 나눠 진행했다. 각 PR에 변경 내용과 검증 기록을 남겼다. 저장소 링크는 접근 권한이 필요할 수 있다.