제출 명령의 잘못된 인수 막기
자동 제출 명령에 인수를 잘못 붙였을 때 빈 입력이 실제 실패 로그로 남는 문제를 다뤄요. 인수 검증을 가장 앞단에 두고 종료 코드 64로 끊어, 환경 로드·게이트 실행·로그 기록 전에 멈추는 설계와 테스트 기준을 설명해요.
2026-10-03 기준으로 자동 제출 명령은 인수가 하나라도 있으면 종료 코드 64와 사용법만 반환하고, 환경 로드·제출 게이트·제출 로그 기록보다 먼저 종료하도록 고쳤어요. 이 순서가 중요한 이유는 도움말처럼 무해한 호출도 빈 표준 입력으로 흘러가면 실제 제출 실패처럼 보이는 기록을 남길 수 있기 때문이에요.
증상과 실패 경로
자동화용 명령은 보통 표준 입력에서 JSON 같은 제출 데이터를 읽어요. 사용자가 습관적으로 도움말 인수를 붙이거나 호출 측이 인수를 넘기면, 명령이 인수를 무시한 채 입력 처리로 진입할 수 있어요.
이번 작업 기록에서는 도움말 인수가 붙은 호출이 빈 입력을 만나 JSON 해석 오류로 끝났어요. 실제 전송은 일어나지 않았고 실패 시 안전하게 멈췄어요.
하지만 제출 로그에는 가드레일 실패가 남았어요. 운영자가 로그만 보면 콘텐츠나 게이트가 실패했다고 오해하기 쉬운 상태예요.
문제는 JSON 해석 오류 자체가 아니에요. 잘못된 호출 형식과 실제 제출 데이터 오류가 같은 관측 지점, 즉 제출 로그에서 만난다는 점이 문제예요. 자동화에서는 실패를 막는 것만큼 실패 원인을 분리하는 일이 중요해요.
| 호출 상태 | 기존에 보일 수 있던 결과 | 바꾼 뒤 결과 | 로그 기록 |
|---|---|---|---|
| 인수 없음 + 유효한 입력 | 제출 흐름 진행 | 제출 흐름 진행 | 제출 결과에 따라 기록 |
| 인수 있음 | 빈 입력 해석까지 진행할 수 있음 | 사용법을 출력하고 종료 | 기록하지 않음 |
| 인수 없음 + 빈 입력 | 입력 오류로 중단 | 입력 오류로 중단 | 실제 제출 경로의 오류로 구분 |
표의 기준일은 2026-10-03이에요. 작업 기록에는 도움말 인수 호출이 종료 코드 64를 반환하고 제출 로그를 만들지 않았다고 남아 있어요.
종료 코드 64는 명령 사용법 오류를 나타내는 관례적 값으로, 실행 실패와 별도로 취급하는 편이 좋아요. GNU Bash 매뉴얼은 명령 실행과 종료 상태의 기본 동작을 확인할 때 참고할 수 있어요.
부작용보다 앞선 인수 검증
제출 명령에는 입력 읽기 외에도 환경을 준비하고, 검증 게이트를 호출하고, 결과를 기록하는 단계가 붙어요. 인수 검증이 이 단계들 뒤에 있으면 잘못된 호출도 일부 부작용을 만든 뒤에야 실패해요.
특히 로그는 진단을 위한 데이터이면서 다음 자동화의 판단 근거가 되기도 해요. 단순한 사용법 오류가 제출 실패로 축적되면 실패율과 재시도 판단이 오염돼요.
실패를 숨기자는 뜻이 아니에요. 호출자가 고칠 수 있는 사용법 오류를 제출 실패 원장에 섞지 말자는 뜻이에요.
여기서 유용한 경계는 두 가지예요. 인수는 명령 인터페이스 계약으로 즉시 검사하고, 표준 입력은 인수가 없다는 것이 확인된 뒤에만 제출 데이터로 해석해요. 두 경계를 분리하면 도움말 호출과 빈 JSON, 실제 게이트 거절이 서로 다른 실패로 남아요.
고친 방법과 적용 범위
수정은 복잡하지 않지만 위치가 핵심이에요. 명령이 시작되자마자 인수 개수를 검사하고, 하나라도 있으면 표준 오류로 사용법을 출력한 뒤 64로 끝내요. 그 뒤에만 환경 준비와 입력 해석을 허용해요.
if arguments_present; then
print_usage_to_stderr
exit 64
fi
read_submission_from_stdin
이 패턴의 장점은 실패 경로가 짧다는 데 있어요. 인수가 있다는 사실만으로 종료하므로 환경 변수 로드 여부나 네트워크 상태, JSON 문법에 따라 사용법 오류의 결과가 달라지지 않아요. 작업 기록에서는 이 검사를 환경 로드, 게이트 실행, 제출 로그 쓰기보다 앞에 배치했어요.
반대로 인수를 허용해야 하는 명령이라면 무조건 64로 막으면 안 돼요. 허용할 옵션과 위치 인수를 명시적으로 파싱하고 문서·테스트·호출부를 함께 바꿔야 해요. 이번 경우에는 호출하는 쪽이 인수를 전달하지 않는 것을 확인한 뒤, 인수 전체를 오류로 삼는 좁은 계약을 택했어요.
회귀를 막는 테스트 기준
이 문제는 도움말 호출이 실패했다는 사실만 확인하면 다시 생길 수 있어요. 테스트는 종료 코드, 표준 오류, 부작용 세 가지를 함께 확인해야 해요.
- 잘못된 인수 호출이 종료 코드 64를 반환하는지 확인해요.
- 표준 오류에 사용법이 있는지 확인해요.
- 제출 로그가 새로 생기지 않았는지 확인해요.
- 인수 검사를 제거한 변형에서는 이 테스트가 실패하는지 확인해요.
작업 기록에는 이 시나리오를 포함한 검증에서 Bash 구문 검사와 Node 테스트 285건이 통과했다고 적혀 있어요.
다만 이 수치는 해당 변경 시점의 테스트 결과일 뿐, 다른 환경이나 이후 변경에서도 같은 동작을 보장하는 성능 수치는 아니에요.
자동 제출 명령에서 좋은 실패는 조용한 실패가 아니에요. 사용자가 바로 고칠 수 있는 오류는 제출 처리에 닿기 전에 분명히 알려 주고, 실제 제출만 제출 로그에 남기는 실패예요. 인수 검증을 맨 앞에 두면 오류 메시지 하나를 다듬는 것만이 아니라 운영 기록이 무엇을 뜻하는지까지 지킬 수 있어요.
관련 글
자동화 레인 편입 전 확인할 것
새 자동화 레인은 한 번의 그림자 통과만으로 즉시 정식 흐름에 넣으면 안 돼요. 실행 순서, 미편입 상태의 종료 방식, 관측 지표를 분리해 두면 일정 변경이 기존 작업을 멈추게 하는 문제를 줄일 수 있어요.
자동 저작 전 Git 사본 동기화
자동 저작이 오래된 규칙을 읽지 않게 하려면 모델 호출보다 먼저 작업 사본을 원격 기준으로 fast-forward해야 해요. 갱신 불가 상태를 실패로 끝내는 이유와 분기된 사본을 안전하게 막는 테스트 기준을 다뤄요.
TOON과 JSON, 균일 레코드 실측
2026-10-06 기준 균일한 hikes 레코드 1,000개 실험에서 toon-format의 UTF-8 출력 중앙값은 27562 bytes, 공백 없는 JSON은 65643 bytes였어요. 다만 직렬화 중앙값은 TOON 8.619585ms, JSON 0.967026ms로 갈렸고, 크기와 생성 시간을 한 지표로 바꾸지 않아야 해요.
공개 자료를 바탕으로 AI가 쓰고, 발행 전에 수치와 주장을 원문과 대조합니다.