OmniRoute
41,856★ 게이트웨이를 안 쓴 이유는 성능이 아니다. 이 도구의 1티어가 내 구독 계정을 위장해 태워 보내는 구조라서다.
설계에서 배울 게 일곱 가지 있었고, 일곱 가지 다 안 쓰기로 했습니다. OmniRoute는 AI 프로바이더 291개를 로컬 엔드포인트 하나로 묶어 주는 게이트웨이입니다. 별 41,856개, npm 월 다운로드 21만. 그런데 이 게이트웨이가 요청을 제일 먼저 태워 보내는 1티어가 제 Claude Code·Codex 구독 계정이고, 그걸 태우는 방법이 TLS 지문 위장과 클라이언트 이름 난독화입니다. 레포 자신이 「계정 영구 정지」를 예외가 아니라 상시 운영 상태로 모델링해 두고 밴 감지 UI를 제품 기능으로 팔고 있었습니다.
무엇을 하는 물건인가
로컬에 뜨는 OpenAI 호환 프록시입니다. npm i -g omniroute 로 깔면 localhost:20128/v1 이 열리고, IDE와 CLI는 그 주소 하나만 바라봅니다. 뒤에서 라우터가 프로바이더를 고르고, 앞이 실패하면 다음 칸으로 내려갑니다. 파는 것은 세 가지입니다 — 4티어 자동 폴백 · 12엔진 토큰 압축 · 3계층 복원력.
규모는 실물입니다. 카탈로그만 채운 레포가 아닙니다.
| 구성 | 실측 |
|---|---|
| 소스 | 전체 11,091 파일 중 .ts 7,133 · .tsx 1,023 |
| 테스트 | 4,240 파일 — unit 3,991 / integration 124 / e2e 42 |
| 문서 | 1,460 파일. 다만 그중 1,215가 43개 언어 번역본이라 원문은 약 245개 |
| 배포 | npm 전역 · Docker · Electron · Termux · PWA |
| 기계 인터페이스 | MCP 104 tool / 31 scope · A2A · REST · 웹훅 · CLI 80+ 명령 |
npm 월 다운로드 21만 1,769건, 6개월에 288 버전. 유령 레포가 아니라 실제로 도는 물건입니다.
대표 기법 — 여기는 진짜 잘 만들었다
실패를 한 덩어리로 안 봅니다. 같은 “에러”를 세 단위로 쪼갭니다. L1 서킷브레이커는 프로바이더 전체를 끊고(408·5xx 에만 발동, 60/30/15초 뒤 절반만 열어 탐침), L2 쿨다운은 키 하나만 재웁니다(기저 5초에 지수 백오프, 429는 Retry-After 준수), L3 락아웃은 모델 하나만 잠급니다. 한 군데 터졌을 때 무엇이 죽은 것인지를 층으로 구분합니다.
그리고 재시도하면 안 되는 실패를 따로 둡니다. 문서 원문이 이렇습니다 — “terminal state(banned·expired·credits exhausted)는 운영자를 위한 것이지 쿨다운 대상이 아니다.” 되살아날 수 없는 실패를 재시도 큐에 넣지 않고 사람에게 올립니다.
나머지 다섯은 이렇습니다. changelog 파편 — PR마다 changelog.d/<이슈번호>-<슬러그>.md 를 새로 하나 만들고 릴리스 때 합칩니다. 같은 파일을 여럿이 안 고치니 병합 충돌이 구조적으로 0입니다. 야간 CI 다섯 종 — 변이 테스트·속성 기반·OpenAPI 스키마 퍼징·복원력·LLM 보안. 숫자에 산정 방법을 붙이는 규율 — 헤드라인 옆에 중복 제거 방식과 재감사 주기와 “숫자는 양방향으로 움직인다” 를 같이 적습니다. 스킬 45개로 도구 자신을 감싸기. 보존 엔진 — 압축 엔진 12개 앞에 코드·URL·JSON을 바이트 단위로 지키는 층을 따로 둡니다.
깨본 결과 — 간판 숫자 셋이 전부 안 버텼다
「평균 89.2% 토큰 절감」은 곱셈 한 줄입니다. 산식이 1 − (1−0.80) × (1−0.46) 인데, 이건 두 압축기가 서로 다른 잉여를 먹는다는 가정 위에서만 참입니다. 실제로 앞 엔진은 툴 출력의 구조적 반복을, 뒤 엔진은 산문의 어휘 잉여를 줄입니다 — 겹칩니다. 레포에 그 독립성을 잰 데이터가 없습니다.
「291 프로바이더 · 테스트 25,000+」는 산술적으로 성립하지 않습니다. 테스트 파일을 직접 세면 왕복 검증에 해당하는 건 e2e 42 · integration 124 뿐입니다. 291개를 실제로 왕복해 본 테스트는 존재할 수 없습니다. 대부분은 카탈로그 항목이지 검증된 경로가 아닙니다.
「기여자 500+」는 전수 페이징으로 368명이었습니다. API 상한은 500이니 상한에 막힌 것도 아닙니다. 게다가 커밋 6,225건 중 3,822건(61%)이 한 사람이고 2위가 216건입니다. 기여자 10위에 Antigravity Assistant(45커밋)가 있고 주간 최대 572커밋(하루 80건)이 찍힙니다 — 커밋 상당수가 AI 생성으로 봐야 합니다.
그래서 왜 전부 기각했나
차단 사유는 성능이 아니라 구조입니다. 네 가지가 겹쳤습니다.
- 구독 계정 우회가 1티어입니다. 클라이언트 이름의 첫 글자 뒤에 제로폭 결합자(U+200D)를 끼워 넣습니다. 문서가 밝힌 목적이 “상류 필터가 grep 하지 못하도록” 입니다. 별도 모듈은 Firefox TLS 지문을 그대로 흉내 내고, 또 다른 모듈은 요청을 “공식 CLI 트래픽과 구별 불가능하게” 재구성합니다. 같은 문서 서두에는 「ToS 위반용이 아니다」라고 적혀 있습니다 — 부인 문구와 코드가 하는 일이 어긋납니다.
- 밴을 상수로 취급합니다. 상류 응답에서
suspended·deactivated신호를 잡아 그 연결을 영구 차단 상태로 내리는 기능이 있고, 대시보드에 설정 카드까지 있습니다. 밴 감지가 제품 기능이라는 건 밴이 예외가 아니라는 뜻입니다. - 루트 CA를 OS 신뢰 저장소에 심습니다. 로컬 HTTPS 복호화 모듈이 60여 파일. 기본 비활성이고 레포도 위험하다고 경고하지만, 개인 판단으로 할 일이 아니라 보안 승인 사안입니다.
- 안전장치 둘이 모두 조용히 실패합니다. 개인정보 마스킹은 “fail-open이며 예외는 절대 트래픽을 막지 않는다” — 마스커가 터지면 원문이 그대로 나갑니다. 감사 로그는 “실패하면 조용히 삼킨다” — 결손을 알 수 없는 로그는 근거로 쓸 수 없습니다.
그리고 수확 기법 7종까지 같이 기각했습니다. 이게 이 페이지에서 제일 값을 치른 판단입니다. 3계층 실패 격리도 terminal state 분리도 제 야간 QA 루프에 그대로 맞는 설계였는데, 좋은 설계 조각을 뽑아 오는 일 자체가 이 레포를 계속 열어 보게 만든다는 게 문제였습니다. 조각을 가져오려면 원본을 계속 참조해야 하고, 참조하다 보면 “이 정도는 개인 PC에서” 로 미끄러집니다. 경계는 조각 단위가 아니라 레포 단위로 긋는 게 맞았습니다.
판정
| 항목 | 판정 |
|---|---|
| 도구 도입 | 차단. 재론 불필요 |
| 설계 수확 7종 | 전량 기각. 조각만 빼 오는 것도 안 함 |
| 재제안 | 금지. 이 문서를 근거로 다시 제안하지 않는다 |
| 다시 여는 조건 | 제가 명시적으로 이 레포를 다시 꺼낼 때만 |
공정하게 덧붙이면, 이 레포는 위험한 일을 하면서 그 위험을 문서로 드러내 놓는 쪽입니다. 보안 문서만 15편이고 반출 정책·에러 살균·공급망·사고 대응이 전부 따로 있습니다. 숨기는 쪽보다 낫습니다. 다만 드러내 놓았다는 사실이 도입 가능하다는 뜻은 아닙니다 — 위험을 알고 있다는 것과 위험이 사라지는 것은 다른 일입니다.
건강도에서 하나만 더. 커밋 61%가 한 사람, npm 메인테이너 한 명 — 버스 팩터 1입니다. 6개월에 288 버전이면 이틀에 1.5회 릴리스이고, 회귀 위험이 구조적으로 높습니다. 별 41,856개는 이 둘을 가려 주지 않습니다.