dev.to

164 disposable computers, one judging afternoon, and a question nobody had time to ask

일회용 컴퓨터 164대와 해커톤 심사 — 아무도 물을 시간이 없던 질문

해커톤 출품작 164개의 저장소를 Fly.io Sprites의 일회용 Linux 머신에서 격리 실행해 빌드 여부를 확인한 도구와 결과를 소개합니다. 113개가 빌드에 성공했고, 저자는 점수 대신 객관적인 실행 단계와 실패 상태를 심사자에게 제공하자고 제안합니다.

AI 요약

해커톤 심사는 루브릭과 심사위원 배정, 점수 조정 절차를 갖춰 공정성을 높여 왔습니다. 하지만 심사 시간이 짧아 대부분의 출품작은 실제로 빌드되는지 확인하지 못한 채 README와 시연을 기준으로 평가합니다. 저자는 시연이 입증하는 건 참가자 노트북에서 작동한다는 사실뿐이라며, “빌드되는가?”라는 질문을 심사 과정에 넣어야 한다고 말합니다.

심사 현장에서는 확인하기 어려웠던 빌드

보통 48시간 해커톤에는 40~80개 팀이 참가하고, 심사위원은 테이블을 돌며 팀마다 4~5분씩 발표와 시연을 봅니다. 그 시간에 저장소를 복제하고 의존성을 설치한 다음 빌드까지 확인하기는 어렵습니다. 심사위원들이 의심이 들거나 수상권에 든 프로젝트 몇 개만 검증하는 것도 이 시간 제약 때문입니다. 나머지 프로젝트는 팀이 주장하는 기능을 기준으로 평가합니다.

이 형식에서는 혁신성, 발표, 사용자 경험, 후원사 기술 활용 같은 항목을 루브릭에 넣기 쉬운 반면, 60개 팀의 빌드 성공 여부를 정직하게 확인할 방법은 없었습니다. 일부 생태계에서는 스마트 계약을 컴파일하지만, 프로젝트 전체를 빌드하는 경우는 드뭅니다. 출처가 불분명한 설치 스크립트를 심사자의 컴퓨터에서 실행하면 파일이나 키, 브라우저 세션에 접근할 위험도 있습니다.

점수 대신 사실을 기록하는 도구

저자는 Fly.io Sprites를 사용해 제출된 저장소마다 새 Linux 머신을 만들고, 저장소 복제부터 의존성 설치, 컴파일, 테스트 실행까지 자동화했습니다. 머신은 API 호출로 몇 초 안에 준비되며 사용한 시간만큼 과금되고, 작업이 끝나면 버릴 수 있습니다. 실행 명령은 npm run judge -- --input submissions.csv --executor sprites --concurrency 4입니다.

도구는 프로젝트에 점수를 매기지 않습니다. 대신 저장소에 접근할 수 없음, 의미 있는 코드가 없음, 필요한 도구 체인을 구하지 못해 평가할 수 없음, 설치 실패, 빌드 실패, 빌드할 대상 없음, 테스트 없음, 테스트 실패, 테스트 통과로 상태를 구분합니다. 도구 체인 문제처럼 실행 환경의 한계로 생긴 실패는 프로젝트 결함과 분리합니다. 심사자는 주관적 점수에 대한 논쟁 대신 컴파일러가 특정 줄에서 오류 코드 2를 반환했다는 사실을 확인할 수 있습니다.

각 제출은 새 머신에서 실행합니다. 설치 스크립트가 전역 패키지를 바꾸거나 파일을 수정해도 다음 프로젝트 결과에 영향을 주지 않습니다. 실패한 머신은 오류가 난 시점의 상태로 저장해 참가자가 열어볼 수 있게 하고, 통과한 머신은 삭제합니다. 대시보드에는 팀 이름이 아니라 해시로 식별한 빌드가 표시됩니다.

164개 제출에서 확인한 결과

저자는 한 해커톤의 제출작 164개를 한 번에 네 개씩 실행했습니다. 전체 작업에는 약 55분이 걸렸고 프로젝트당 중앙값은 58초였습니다. 첫 시도에서 잘못된 결과가 나와 다시 실행한 경우까지 포함한 사용료는 1달러를 조금 넘었습니다.

113개 프로젝트, 전체의 69%가 끝까지 빌드됐습니다. 33개는 의존성을 설치한 뒤 컴파일이나 빌드에 실패했고, 8개는 설치 단계에서 멈췄습니다. 9개는 설치는 됐지만 빌드할 대상이 없었으며, 저장소 한 곳은 첫 실행 때 접근됐지만 다음 날에는 사라졌습니다. 빌드 성공은 컴파일러가 코드를 받아들이고 빌드 스크립트가 종료 코드 0을 반환했다는 뜻입니다. 실제 기능이 작동하거나 README 설명과 일치한다는 보장은 아닙니다.

실패 사례에서 가장 흔한 유형은 스마트 계약은 컴파일되지만 이를 둘러싼 애플리케이션이 실패하는 경우였습니다. TypeScript 오류, 누락된 빌드 결과물, 해결되지 않는 패키지가 원인이 됐습니다. 다음으로는 모노레포의 패키지 하나가 실패해 전체 빌드를 막는 유형이 많았고, README와 다이어그램만 있는 저장소도 있었습니다. 저자는 이를 팀의 자질이 아니라 실패 유형으로 다뤘으며, 프로젝트 이름은 공개하지 않았습니다.

후원사 기술 확인과 도구의 한계

후원사 기술 활용 여부 가운데 저장소에 해당 플랫폼의 스마트 계약이 있는지, 시작 템플릿을 이름만 바꿔 썼는지, 플랫폼 고유 기능을 사용하는지, 계약이 컴파일되는지는 자동 확인 대상이 될 수 있습니다. 표본 164개 중 157개에 계약이 있었고, 그중 템플릿을 거의 그대로 사용한 사례는 하나였습니다. 계약이 선언한 컴파일러 버전으로 실행했을 때는 157개 중 114개가 컴파일됐습니다.

다만 기술을 의미 있게 활용했는지는 도구가 판단할 수 없습니다. 계약이 비공개 입력을 선언하고도 실제로 활용하지 않을 수 있습니다. 테스트 통과 결과도 주의해서 봐야 합니다. 많은 팀이 테스트가 포함된 시작 템플릿을 사용했기 때문에, 통과한 테스트가 팀이 새로 작성한 것인지 도구가 구분하지 못합니다. 그래서 저자는 테스트 통과율을 제시하지 않았습니다.

잘못된 결과를 바로잡은 과정

첫 버전은 저장소를 마지막으로 수정한 시점에 존재한 최신 컴파일러를 선택했습니다. 계약이 요구하는 언어 버전과 맞지 않아 정상적인 계약 42개가 실패로 분류됐습니다. 도구가 계약의 버전 선언을 읽고 해당 컴파일러를 설치하도록 고친 뒤 수치를 다시 계산했습니다. 이후에는 팀이 스크립트에 고정한 컴파일러 버전이 실행 환경에 없어 6개가 또 실패로 표시됐습니다. 이 문제도 해결한 뒤의 수치가 본문에 실린 결과입니다.

현재 버전의 컴파일러로 다시 빌드하면 정상적으로 작동한 계약 가운데 3분의 1은 더 이상 빌드되지 않았습니다. 빠르게 바뀌는 플랫폼에서는 현재 도구가 아니라 팀이 당시 사용한 도구로 작동 여부를 확인해야 한다는 점도 드러났습니다.

저자는 심사 전에 모든 제출작을 실행해 결과를 점수 대신 단계로 심사위원에게 제공하고, 실패한 팀에는 오류가 난 머신을 열어볼 수 있게 하자고 제안합니다. 빌드 여부를 루브릭에 추가하되, 독창성이나 난이도, 프로젝트의 완성도를 판단하는 일은 계속 심사위원이 맡아야 합니다. 다음 단계로는 빌드에 실패한 39개 프로젝트를 에이전트에 맡겨 수정하게 하고, 팀에 오류 원인을 전달할 계획입니다. 도구는 GitHub의 laurenelee/hackjudge에서 확인할 수 있습니다.

dev.to 반응

  • @jonmarkgo — 정말 멋집니다. 저는 코드베이스에서 후원사 API가 어떻게 구현됐는지 확인하는 비슷한 검증 작업을 해봤지만, 샌드박스에서 실제로 실행하지는 않았습니다.

원문: dev.to / 번역·요약: Trawling