기계가 읽는 인터페이스에서는 오류 메시지의 내용만큼 그 메시지가 들어간 자리가 중요하다. JSON 문법이 맞고 프로세스가 0으로 끝났다고 호스트가 받아주는 것은 아니다. 필드 이름과 페이로드 위치까지 맞아야 한다.
최근 검토한 세션 시작 훅에는 세 개의 경로가 있었다. 정상 성공, JSON 처리 도구 누락, 필요한 메타 스킬 누락이다. 예전 구현은 정상 경로에서는 호스트가 요구하는 외피를 내보냈지만, 두 오류 경로에서는 priority와 message 형태를 반환했다. 사람이 읽기에는 멀쩡한 안내였지만, 호스트가 찾는 hookSpecificOutput, hookEventName, additionalContext 자리는 없었다. 결과는 “유효한 JSON”으로 표현된 프로토콜 오류였다.
이런 결함은 정상 경로 중심의 시험을 쉽게 통과한다. 스크립트를 한 번 실행해 성공 출력만 보거나, 각 함수가 JSON을 만드는지만 검사하면 대개 녹색이 된다. 그러나 경계 밖의 호스트는 “문자열이 JSON인가”보다 “이 이벤트의 페이로드가 약속한 위치에 있는가”를 본다. 함수 단위에서는 통과한 오류 메시지가 통합 경계에서 사라지는 이유다.
해결 방법은 경로별 문구를 똑같이 맞추는 것이 아니다. 외피를 고정해야 한다. 정상, 입력 누락, 의존성 누락, 일부 기능 저하, fallback이 모두 같은 최상위 스키마를 반환해야 한다. 경로마다 바뀌어도 되는 것은 페이로드의 내용과 상태다. 이벤트 종류, 필수 필드, 페이로드 위치가 경로마다 바뀌면 호스트는 오류 설명을 읽는 대신 새 프로토콜을 추측해야 한다.
회귀 시험도 실제 경계에 맞춰야 한다. 각 분기를 실제 명령으로 통과시킨 뒤 stdout을 다시 파싱하고, 필수 event/type 필드와 페이로드 위치를 검증해야 한다. 종료 코드는 그 다음 검사 항목이다. 0은 프로세스가 자신의 일을 끝냈다는 뜻이지, 반환값이 상대방의 언어였다는 증거는 아니다.
스키마 검증은 훅을 설치하거나 활성화하는 허가와도 분리해야 한다. 출력 형식이 맞는지 확인하는 일은 자동 실행을 켜는 일과 다르다. 두 행위를 한 단계로 묶으면 형식 검증을 위해 실행 권한까지 넓히는 별도의 오류가 생긴다.
기계 판독용 인터페이스의 진짜 계약은 성공 화면에 있지 않다. 의존성이 없고 입력이 비었고 일부 기능만 남았을 때도 호스트가 같은 문법으로 읽을 수 있어야 한다. 정상 경로만 반듯하면 데모는 된다. 실패 경로까지 같은 문법을 지켜야 인터페이스가 된다.