
mustfail는 코딩 에이전트가 바꾼 소스 파일을 기준 커밋으로 되돌리고, 에이전트가 작성한 테스트는 그대로 둔 채 검사를 다시 실행하는 도구다. 되돌린 뒤에도 검사가 통과하면 해당 작업을 테스트가 확인하지 못한 것으로 보고한다. Python 3.8 이상과 git이 필요하며 런타임 의존성은 없다. 프로젝트 저장소
도구는 먼저 변경 사항이 있는 상태에서 모든 검사를 실행하는 긍정 대조군을 확인한다. 이어 변경된 소스 파일을 기준 커밋으로 되돌리고 테스트는 유지한 채 부정 대조군을 실행한다. 새 함수의 가져오기가 실패한 경우처럼 단순히 로드 단계에서 발생한 오류는 약한 신호로 분류해 기본적으로 탐지로 계산하지 않는다. 대조군이 탐지되지 않았을 때만 소스 파일을 하나씩 되돌려 어떤 파일을 테스트가 다루지 못하는지 표시한다. 검사 명령과 CI 설정에서 실패 종료 코드가 무시되는 패턴도 별도로 검색한다.
기본 설정에서는 검사 하나라도 유효한 실패를 감지하면 충분하다. 모든 검사가 모든 소스 파일 변경을 다뤄야 한다면 require.control_detects를 "all"로 설정할 수 있고, 로드 단계의 오류도 실패로 취급하려면 해당 검사에서 on_weak_signal을 "fail"로 지정할 수 있다. 실행 시간은 테스트 스위트의 약 두 배로 예상되므로, 테스트가 10분 걸린다면 작업 종료 시점이 아니라 푸시 전이나 CI에서 실행하라고 안내한다.
설치와 주요 명령은 다음과 같다.
pipx install mustfail # or: pip install mustfail
설치 없이 복제본에서 실행할 수도 있다.
git clone https://github.com/greenlitbooks/mustfail
PYTHONPATH=mustfail/src python3 -m mustfail --help
기본 설정 파일을 만들고, 설정된 게이트를 점검하거나 실행하는 명령은 다음과 같다. scan은 실행 없이 정적 검사만 하며, selftest는 테스트 자료 모음과 매니페스트를 대조한다.
mustfail init # writes a starter mustfail.json
mustfail doctor # is the gate wired, and would it fire?
mustfail run # positive control, negative control, verdict
mustfail scan # static scan only, milliseconds, no execution
mustfail selftest # run the corpus and check it against its manifest
최소 설정은 소스 경로와 검사 명령, 기대 종료 코드, 되돌림 대조군을 지정한다.
{
"version": 1,
"source": ["src/**"],
"checks": [
{ "id": "unit", "run": "npm test", "must_exit": 0, "control": "revert-source" }
]
}
종료 코드는 0이 정상, 1은 내부 오류, 2는 지정한 검사 실패, 3은 검사는 통과했지만 대조군을 감지하지 못한 경우, 4는 차단 대상인 실패 무시 패턴이 발견된 경우, 5는 설정 오류를 뜻한다.
mustfail에는 각각 테스트가 스텁에 맞춰 작성된 경우, 단언이 없는 테스트, 목(mock)이 실제 단위 코드를 가리는 경우, 파이프가 종료 코드를 삼키는 경우 등을 재현하는 사례 저장소가 포함된다. 저장소 설명에 따르면 7개 사례가 매니페스트의 예상 결과와 일치했다. 정직한 수정과 테스트가 통과하는 사례도 포함해, 유효한 작업을 막는 오탐을 중요하게 다룬다. 실제 실행에서 측정한 탐지율은 아직 제시하지 않는다고 밝힌다.
한계도 있다. 파일 전체를 되돌리는 방식은 거칠어 순수 리팩터링은 탐지되지 않은 것으로 보일 수 있고, 실패 분류는 문자열 일치, 정적 검사는 파서가 아닌 정규식에 의존한다. 파일을 편집할 수 있는 에이전트가 설정도 수정할 수 있다. 한계 문서와 관련 도구 문서를 확인한 뒤 활용해야 한다.
Claude Code에서는 mustfail hook 명령으로 .claude/settings.json에 붙여 넣을 블록을 출력한다. Stop 훅은 대조군을 감지하지 못하면 구체적인 이유를 제시하며 턴을 막고, 같은 응답을 반복한 뒤에는 세션이 갇히지 않도록 작동을 멈춘다. 도구는 에이전트 대화를 읽지 않고 git, 파일 시스템, 종료 코드만 사용하므로 Codex, Cursor, 푸시 전 훅, CI, 사람이 실행하는 환경에서도 사용할 수 있다고 설명한다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요