바이트 단위로 동일한 로그는 그 자체로 시험 도구다
같은 시나리오가 바이트까지 같은 CSV를 만들면, diff가 곧 회귀 시험 장치가 된다 — 프레임워크 없이.
NOKTRA SIL Runtime은 소박하게 들리지만 소박하지 않은 약속을 합니다: 같은 시나리오를 두 번 돌리면, 두 로그 파일이 동일하다. 비슷한 게 아니라, 오차 내에서 같은 것도 아니라 — 바이트 단위로. 모든 플랫폼에서 LF 줄바꿈, BOM 없는 UTF-8, 불변 숫자 포매팅, 그리고 파일 안에 벽시계 타임스탬프를 쓰지 않음.
마지막 항목이 핵심입니다. 로그 안의 타임스탬프는 두 로그를 비교하고 싶어지는 날까지는 무해합니다. 그날이 오면 모든 줄이 달라져 있고, 비교에는 파서와 허용 오차와 회의가 필요해집니다. 타임스탬프를 빼면 비교는 머신에서 가장 오래된 도구로 환원됩니다: diff. 출력이 비어 있거나, 발견이 있거나.
이로써 재현성은 철학적 입장이 아니라 일상의 계기가 됩니다. 적분기를 리팩터링했다? 골든 시나리오를 돌리고 보관된 로그와 diff. 컴파일러 플래그를 바꿨다? diff. 프레임워크를 올렸다? diff. 누구나 돌릴 수 있고, 몇 초면 되고, 그 판정에는 반론이 불가능합니다 — 리뷰에서 중요한 건 바로 그 속성입니다.
여기 도달하는 데는 실제 설계 결정들이 들고, 이름을 불러줄 가치가 있습니다. 시뮬레이션 시간은 언제나 스텝 인덱스 × dt이며 누적이 아니라서, 1kHz로 10,000사이클이면 부동소수점 표류 없이 정확히 10.0초에 떨어집니다. 벽시계 페이싱은 사이클이 '언제' 도는지만 정하고 '무엇을' 계산하는지는 결코 건드리지 않아서, 눈으로 보는 페이싱 런과 CI용 고속 런이 같은 숫자를 냅니다. 표시용 버퍼는 결정론 경로 바깥에 살아서, UI 샘플 하나가 떨어져도 결과가 바뀔 수 없습니다. 컴파일된 C 모델조차 FP 축약을 끄고 빌드합니다 — 융합 곱셈-덧셈은 더 정확하고, 다르게 틀리기 때문입니다.
시뮬레이션을 넘어서는 일반 교훈이 있습니다. 결과를 파일로 쓰는 모든 도구는 — 리포트, 내보내기, 생성 코드 — 자기 출력이 diff 가능한지를 조용히 선택하고 있습니다. 타임스탬프, 맵 순회 순서, 로케일 포매팅, 부동소수점 출력: 하나하나가 diff 가능성을 보존하거나 소모하는 작은 결정입니다. 대부분의 소프트웨어는 눈치채지 못한 채 소모합니다.
오프라인이라는 조건이 고리를 닫습니다. 폐쇄망 벤치에는 런을 대신 비교해 줄 대시보드 서비스가 없습니다. 파일이 있고, diff가 있습니다. 그 방을 위해 설계된 도구라면, 그 둘로 충분하게 만들어야 합니다.