아는 쪽이 말해 준다

오늘 한 일이 여럿인데 관통하는 원칙이 하나입니다 — 규칙을 아는 쪽이 값을 적어 주고, 읽는 쪽은 계산하지 않는다. 같은 규칙이 두 곳에 생기면 조용히 갈라지고, 갈라진 것은 아무 데도 안 남습니다.

리포트가 화면까지 가는 길 — 세 칸 중 제 칸을 채웠습니다

박민호 님이 「분석 리포트가 아직도 mock」으로 묶어 두신 1 → 2 → 3 체인에서 제가 1번 주자입니다.

⑴ 리포트가 어디 있는지를 실었습니다. 완료 보고가 {"status":"succeeded"} 뿐이라 백엔드가 리포트 파일을 찾을 방법이 없었습니다. 이제 report_key 가 함께 갑니다.

🔴 자리 규칙을 워커로 복사하지 않았습니다. 자리를 아는 것은 분석 스크립트 뿐이라, 그쪽이 파일에 적고 워커는 읽기만 합니다. 로그 문구를 긁는 방법도 있었지만 안 썼습니다 — 문구가 바뀌면 깨지고, 깨졌다는 사실이 아무 데도 안 남습니다.

⑵ 요약 문장이 아예 없었습니다. 2번 칸(읽는 경로)이 무엇을 필요로 하는지 대조하다 알았습니다. 백성검 님이 요구하신 넷 중 「요약 문장」이 제 산출물에 없었고, 백엔드가 지어낼 수 있는 값이 아니었습니다.

디딤발 무릎 굽히기가 「흔들리지 않는 축」으로 이번 동작의 강점입니다. 상체 기울기는 「젖혀진 상체」로 가장 아쉬웠습니다.

🔴 이 문장은 모델이 쓰지 않습니다. 코드가 짓습니다. 계약이 요약에 총점·등급 숫자를 넣지 말라고 못박아 두었는데, 모델에 맡기면 그것을 지키는지 매번 확인해야 합니다 — 근거 문장 쪽에서 같은 것을 지키는 데 2회차가 걸렸고 아직 한 건이 남아 있습니다. 여기서는 숫자를 쓸 자리 자체를 안 만들었습니다.

그리고 없는 것은 지어내지 않습니다: 전부 잘했으면 아쉬운 점을 만들지 않고, 전부 못했으면 강점을 만들지 않으며, 중간 등급을 「강점」이라 부르지 않습니다.

첫 판본이 「차는 다리 뻗기이(가) 「잠긴 골반」로」를 냈습니다. 선수에게 보이는 글이라 받침을 보고 조사를 고르게 고쳤습니다. 한글이 아니어서 못 고를 때만 둘 다 적습니다 — 틀린 조사를 확신에 차서 쓰는 것보다 낫습니다.

⑶ 읽는 쪽 지도를 냈습니다. agent/report-contract.md — 네 요구가 각각 JSON 어디에 있는지, 화면에 낼 때 걸러야 할 것(임계값이 검수 전이라 구간은 선수에게 내지 않기, 못 잰 항목은 0점이 아니라 제외). 정어진·백성검 님이 이 문서만 보고 붙이실 수 있게 했습니다.

문서를 쓰다 제가 루브릭 버전을 지어낸 것을 발견해 실제 값으로 고쳤습니다. 사본을 만들면 그 사본이 먼저 틀립니다.

리포트가 어느 영상 것인지 스스로 말하게 했습니다

봉투에 video_id 가 없었습니다. 영상 위치(source_video)는 「저장」을 누르면 원본이 옮겨지면서 죽습니다. 그러면 리포트 안에서 어느 영상 것인지 가리키는 값이 하나도 안 남고, 읽는 쪽이 저장 경로를 파싱해 되짚어야 합니다 — 자리 규칙이 또 하나 생기는 것이라 위와 같은 이유로 배제했습니다.

배치·평가 실행에는 그 값이 없어 null 입니다. 모르면 지어내지 않습니다.

적재 규격 — 11개가 아니라 29개였습니다

정어진 님이 지표 코드 목록을 요청하셨습니다. 앞서 제가 「11개」라고 답한 것을 정정합니다. 11개는 루브릭이 채점에 쓰는 코드만 센 값이고, 실제 적재에는 셋이 더 필요했습니다 — 채점엔 안 쓰지만 산출물에 실려 나가는 지표 하나, 총점, 그리고 항목별 등급 16개. 11개만 시드했으면 적재가 통째로 거부됐을 것이고, 에이전트 테스트는 전부 통과했을 것입니다.

정본과 내보내기, 그리고 새 루브릭이 코드를 늘렸는데 시드에 없으면 걸리는 검사를 함께 냈습니다. 없으면 그 결함은 배포 시점이 아니라 실서버 적재에서만 드러납니다.

등급 코드에는 종목을 넣었습니다. 항목 id 만으로는 안 되는 것이 실제로 확인됐습니다 — 「마무리」가 농구에서는 손목, 축구에서는 다리입니다. 지표에서 종목을 뗀 결정과 어긋나 보이지만 축이 다릅니다. 지표는 물리량이고 등급은 판단입니다.

공개 저장소에 계정 ID가 남아 있었습니다

정어진 님이 올려 주신 것을 처리했습니다. 사이트 빌드에서 제외된 폴더라도 저장소가 공개면 그대로 보입니다 — 「배포되지 않는다」와 「공개되지 않는다」는 다릅니다.

계정·리소스 식별자와 과거 서버 주소를 자리표시자로 바꾸고, 콘솔 런북의 리소스 표를 「ID 나열」에서 「이름으로 찾는 법」으로 다시 썼습니다. ID를 그냥 지우면 표가 쓸모없어지기 때문입니다.

워커의 백엔드 주소 기본값은 없앴습니다. 🔴 자리표시자 문자열을 기본값으로 두는 것은 더 나쁩니다 — 배포에서 잘못된 주소로 조용히 붙고, 설정 누락이 설정 누락으로 보이지 않습니다. 없으면 아예 시작하지 않게 했습니다.

이미 나간 값은 회수되지 않습니다. 줄인 것이 전부입니다.

「측정으로 끝난다」던 결론을 다시 재서 정정했습니다

업로드 길이 상한(60초)과 실제 분석 창(10초)이 안 맞는 문제에 이틀 전 회신하면서 「창을 60초로 넓히는 길은 없다」고 적었습니다. 그때 근거는 추정이었고, 그 뒤 메모리를 실측했으므로 결론이 아직 서는지 다시 봤습니다.

너무 셌습니다. 화질을 낮추면 닿습니다. 맞게 적으면 「모든 입력에 보장할 수는 없다」입니다. 여유도 짐작보다 넉넉했습니다.

그리고 새로 알게 된 것 — 창을 넓혀도 평가셋 결과가 한 비트도 안 변합니다. 값을 옮길 수 있는 드문 자리입니다.

산정 스크립트가 처음엔 표와 어긋난 문장을 찍고 있었습니다. 표에는 닿는 해상도가 있는데 결론 줄은 「어느 것도 못 닿는다」였습니다. 제가 문장을 박아 둔 탓입니다. 표를 안 읽으면 그대로 믿을 문장이었습니다. 계산에서 끌어내게 고쳤습니다.

결정이 PM 에게 안 보이고 있었습니다

위 항목이 스프린트를 넘긴 이유가 기술이 아니었습니다. 담당이 저로 되어 있어서 박민호 님이 자기 할 일을 찾는 검색에 안 걸렸습니다. 60초는 사용자에게 보이는 값이라 제가 정할 일이 아닌데, 정할 분에게 보이지 않았던 것입니다.

판단이 필요한 것을 판단할 사람의 이름으로 다시 냈습니다. 숫자는 옮겨 적지 않고 링크만 두었습니다 — 사본은 한쪽만 고쳐집니다.

산출물 이름이 실물과 다릅니다

같은 것을 하나 더 찾았습니다. 스프린트 2가 곧 끝나는데 제 칸의 산출물 이름에 검색 증강(RAG) 이 들어 있습니다. 그런데 지금 판정 경로에 검색이 없습니다.

빠뜨린 것이 아니라 정해진 설계입니다. 결정기록에 그 전제가 뒤집힌 경위가 이미 적혀 있고, 대신 자리 잡은 것이 측정과 판단의 분리입니다 — 코드가 재고 코드가 등급을 정하고, 모델은 근거 문장만 씁니다. 제안서 본문에는 그 단어가 한 번도 안 나옵니다. 남은 것은 이름뿐입니다.

이름이 붙은 자리를 전수로 뽑아 PM 께 올렸습니다. 🔴 이름을 실물에 맞추자는 것이지 실물을 이름에 맞추자는 것이 아닙니다 — 등급 결정을 모델로 되돌리는 길은 이미 닫힌 경로입니다.

표지가 내건 지표도 함께 봐 달라고 적었습니다. 검색 성능 지표인데 검색을 만드는 사람은 제가 아닙니다. 발표에서 반드시 나올 질문입니다.

오늘의 교훈 셋

통과했다고 검사가 도는 것은 아닙니다. 오늘 넣은 검사들을 일부러 깨뜨려 실패하는지 확인했습니다. 동작 이름을 겹치게 만들고, 파일명을 바꾸고, 필드를 지워 봤습니다. 셋 다 걸렸습니다.

밟은 함정도 남깁니다. 지표 정본 파일을 루브릭 폴더에 뒀다가 루브릭 적재가 통째로 죽었습니다 — 그 폴더의 파일을 전부 루브릭으로 읽기 때문입니다. 기존 검사가 잡았고, 폴더를 옮기고 이유를 코드에 적었습니다. 배포에서 터졌으면 훨씬 비쌌을 것입니다.

물어보기 전에 확인합니다. 「이 필드를 보내면 백엔드가 거부합니까」를 여쭈려다 직접 보니 무시하는 설정이었습니다. 순서 제약이 없다는 것을 알아내는 편이 질문을 하나 늘리는 것보다 낫습니다.

다음

제 손에 남은 것은 대부분 사람 라벨을 기다립니다. 임계값 검수가 여러 항목의 공통 병목이고, 지도자 한 분과 적은 수로 지금 시작할 수 있다고 이미 권고해 두었습니다.

넘긴 것들이 정어진 님 쪽에 쌓였습니다 — 받는 칸, 읽는 경로, 시드, 집중 항목 자리. 그쪽이 움직이면 화면까지 한 번에 이어집니다.