산출물 관리 편 · 에이전트 하네스 시리 즈 중 하나입니다.
⚠ 먼저 밝혀둡니다. 이 글은 엑셀 만들기 요령이 아닙니다. 22,019건 파이프라인의 최종 산출물이 파일 하나로 수렴해야 했던 이유, 낡은 지시가 파일명이 다른 두 번째 정본을 만들 뻔했던 순간, 그리고 실행 환경 차이로 반쪽짜리 파일이 정본 자리를 차지하는 것을 막은 장치의 기록입니다. 수치는 파일 실물과 당일 재현 출력에서 왔습니다.
1. 시작은 "정본이 두 개면 정본이 없는 것"이었습니다
수집·분류가 끝난 22,019건은 결국 사람이 열어 보는 파일 하나로 나갑니다. 이 파일이 정본입니다 — 회의에서 인용되고, 다른 작업의 입력이 되고, "그 표에 있던 숫자"의 출처가 됩니다. 그런데 인수인계 과정에 함정이 있었습니다. 앞선 지시문에는 산출물 파일명이 특정 날짜로 적혀 있었고, 실제 최신 빌드는 그 다음 날짜였습니다. 지시문을 문자 그대로 따르면 낡은 파일명으로 두 번째 파일을 만들게 되는 상황이었습니다.
같은 내용이라도 파일이 둘이면 사고는 시간문제입니다. 한쪽만 갱신되고, 누군가는 낡은 쪽을 인용하고, 두 파일의 숫자가 어긋난 날 "어느 쪽이 맞느냐"는 조사가 시작됩니다. 정본이 두 개라는 것은 정본이 없다는 뜻입니다.
2. 그래서 이번에 정한 질문 하나
"어느 파일명이 맞나"가 아니었습니다. 질문은 이것이었습니다. 지시와 실물이 어긋날 때 무엇이 이기는가. 파일명은 지시의 흔적이고 빌드 날짜는 실물의 사실입니다. 실물이 이겨야 합니다 — 그래서 낡은 파일명 지시를 무효로 선언하고, 정본은 최신 빌드 하나뿐이며 둘로 만들지 마라를 인수 문서에 명문화했습니다.
3. 사용한 개념과 도구 — 파일 하나에 실린 세 겹
밖에서 보면 이 산출물에 들어오는 것은 수집·분류를 마친 데이터 파일들이고, 나가는 것은 시트 여섯 장짜리 통합 문서 한 개입니다. 그 한 개 안에 세 겹이 실립니다 — 데이터(글·댓글 전량), 집계(공간별·태그별·작성자별), 그리고 안내 시트(각 열의 신뢰 등급과 읽는 법).
빌드 데이터 파일들 → 단일 빌드 스크립트 → 통합 문서 1개 → 파일이 하나인가
가드 실행 환경 → 라이브러리 존재 검사 → 없으면 즉시 중단 → 반쪽 파일이 없는가
안내 열 신뢰 등급 → 안내 시트에 명문 → 파일 안에 동봉 → 등급이 실렸는가4. 실제로 만든 것 — 기능 세 개와, 그 기능이 막는 실패
① 산출물을 파일 한 개로 강제했다 — 두 파일이 서로 정본 행세하는 것을 막는다
빌드 스크립트의 출력 파일명은 하나로 고정돼 있고, 인수 문서에는 "낡은 파일명 지시는 무효, 정본은 이것 하나, 둘로 만들지 마라"가 명시됐습니다. 부분 산출물 (시트별 임시 파일)을 남기지 않고 통합 문서만 남깁니다. 누가 언제 열어도 후보가 하나면 "어느 쪽이 맞느냐"는 질문 자체가 생기지 않습니다.
② 실행기 차이를 시작 시점의 가드로 진단하게 했다 — 반쪽 파일이 정본을 덮는 것을 막는다
같은 기계에 파이썬 실행기가 둘 있었고, 한쪽에만 엑셀 라이브러리가 설치돼 있었습니다. 잘못된 실행기로 빌드하면 도중에 죽는데, 최악의 경우는 죽는 것이 아니라 덜 만들어진 파일이 정본 이름으로 남는 것입니다. 그래서 스크립트 시작 지점에 라이브러리 존재 검사를 넣어, 없으면 어느 실행기로 다시 돌리라는 진단 문구를 내고 파일을 건드리기 전에 중단하게 했습니다. 당일 재현에서 잘못된 실행기는 시작 즉시 실패했고 정본은 무사했습니다.
③ 신뢰 등급을 파일 안 안내 시트에 실었다 — 표가 맥락 없이 돌아다니며 과신되는 것을 막는다
이 데이터에는 등급 차가 있습니다 — 유형 분류는 독립 실행 일치율이 높아 믿을 만하고, 주제 분류는 일치율이 낮아 참고값입니다. 이 경고를 바깥 문서에 적으면 파일만 복사돼 돌아다니는 순간 경고가 떨어져 나갑니다. 그래서 안내 시트를 문서의 첫 장으로 넣어 각 열의 신뢰 등급, 관측 시점, 확인 방법을 파일 안에 동봉했습니다. 표를 열면 경고가 먼저 보입니다.
5. 지금까지 관찰된 결과 (실측 · 명령을 같이 적습니다)
정본 실물의 계측입니다. 크기·수정 시각은 파일 속성 조회(Get-ChildItem)로, 행 수는 원천 데이터 파일의 줄 수(wc -l 상당)로 확인했습니다.
마지막 두 줄이 이 글의 알맹이입니다. 잘못된 실행기는 파일을 건드리기 전에 죽었고, 낡은 지시의 파일명으로 만들어진 파일은 존재하지 않습니다. 사고가 안 난 것이 아니라, 사고가 나는 두 길목이 막혀 있었던 것입니다.
6. 따라 해보고 싶으시면 — 가장 작은 형태부터
파이프라인의 최종 산출물을 넘길 때의 최소 형태는 이렇습니다.
- 정본 파일명을 하나로 고정하고, 문서에 "이것 하나뿐, 둘로 만들지 마라"를 명문으로 적으십시오. 지시와 실물이 어긋나면 실물이 이깁니다.
- 빌드 스크립트 시작 지점에 의존물 존재 검사를 넣으십시오. 도중에 죽는 것과 시작 전에 진단 문구를 내고 멈추는 것은 복구 비용이 다릅니다.
- 데이터의 신뢰 등급·관측 시점·확인 방법을 파일 안에 동봉 하십시오. 바깥 문서의 경고는 파일이 복사되는 순간 떨어져 나갑니다.
7. 판정은 네 가지로 나누십시오 (두 가지로는 부족합니다)
산출물을 "있다/없다"로만 보면, 덜 만들어진 파일과 낡은 파일이 정본 칸에 들어갑니다.
PASS 정본 1개 · 원천 계수와 일치 · 안내 시트 동봉 (현 정본이 여기)
PASS_WITH_NOTE 값은 실렸으나 참고 등급 — 주제 열이 여기 (안내 시트에 명문)
HOLD 지시와 실물이 어긋남 — 만들기 보류·실물 기준 확인 (낡은 파일명 지시가 여기)
FAIL 빌드가 도중에 죽어 반쪽 파일이 남음 (가드가 막는 대상)8. 한계와 대가 (얻은 것 옆에 잃은 것)
파일 하나로 좁힌 대신 분명히 잃은 것이 있습니다.
42.7MB짜리 단일 파일은 무겁습니다. 열람에 시간이 걸리고, 일부만 필요한 사람도 전체를 받아야 합니다. 용도별로 쪼갠 가벼운 파일들이 편의로는 나은데, 그 편의가 정확히 "정본이 여러 개"라는 위험의 다른 이름이라 버렸습니다. 쪼갠 파일이 필요하면 정본에서 그때그때 뽑는 것으로 하고, 뽑은 파일은 정본이 아니라고 못 박았습니다.
시트 여섯 장의 행 단위 전수 대조는 미실행입니다. 원천 계수와 행 수가 일치하는 것까지 확인했고, 셀 값의 전수 대조는 표본 검사로 갈음했습니다. "행 수가 맞다"와 "모든 셀이 맞다"는 다른 명제이고, 이 글은 앞의 것까지만 주장합니다.
그리고 안내 시트는 읽는 사람이 열어야 작동합니다. 첫 장에 두었지만 바로 데이터 시트로 건너뛰는 사람에게는 경고가 닿지 않습니다. 등급을 각 열 머리에도 줄여 적었지만, 파일 형식의 한계 안에서의 타협이지 완전한 방어는 아닙니다.
9. 결론 — 가져가실 규칙 세 개
첫째, 정본이 두 개면 정본이 없는 것입니다. 편의를 위한 사본, 낡은 지시가 시킨 다른 이름의 파일 — 어느 쪽이든 두 번째 파일이 생기는 순간 "어느 쪽이 맞느냐"의 비용이 미래로 적립됩니다.
둘째, 지시와 실물이 어긋나면 실물이 이깁니다. 문서에 적힌 파일명은 쓰인 날의 사실이고, 디스크의 빌드는 지금의 사실입니다. 낡은 지시를 따르는 성실함이 사고를 만듭니다 — 어긋남을 발견하면 지시를 갱신하는 것까지가 작업입니다.
셋째, 경고는 데이터와 같은 파일에 실으십시오. 신뢰 등급, 관측 시점, 확인 방법이 파일 밖에 있으면 파일의 복사 한 번에 분리 됩니다. 표가 어디로 돌아다니든 경고가 따라다니게 하는 방법은 동봉뿐입니다.
10. 참고
정본을 하나로 강제하는 것은 문서 관리의 단일 진실 원천(single source of truth) 원칙을 산출물 파일에 적용한 것이고, 시작 시점의 의존물 검사는 실행 전 조건 검증(precondition check)의 흔한 형태입니다. 열 신뢰 등급을 산출물에 동봉하는 것은 이 시리즈의 분류 편에서 정한 "유형은 신뢰, 주제는 참고값" 판정을 파일 안까지 배달하는 마지막 구간입니다.