ADR-0031: Future Rust Rewrite on Nabi Runtime¶
Umbra 는 향후 Go 에서 Rust 로 재작성하며, 런타임은 Pablo 가 개발 중인 Nabi(나비) 를 사용한다. 시점은 진욱이 Rust 실무 숙련도에 도달한 후로 결정한다. Go 스택은 이 재작성까지의 중간 단계이며 도메인 모델은 언어 무관 설계를 유지한다.
Status¶
Proposed (실행 시점 미정)
- Proposed at — 2026-04-13
- Proposed by — Pablo
- Decision pending — 실제 착수는 별도 승인 ADR 로
Context¶
Umbra 의 현재 스택 선택(Go, ADR-0001)은 세 요인의 산물이다.
- 진욱의 Rust 학습 곡선 — luxtra-bot 에서 페어 개발이 정체되어 프로젝트 폐기
- Pablo 의 언어 선호 — Rust 가 개인적 1순위이지만 팀 현실과 충돌
- MVP 출시 속도 — Go 의 페어 개발 가능성이 속도 확보
즉 Go 는 "지금 당장 가장 합리적인 타협" 이지만 장기 최적은 아니다. 장기 방향으로 Rust 를 고려하는 근거:
- Pablo 가 자체 Nabi 런타임 을 개발 중이며, Umbra 가 이 런타임의 첫 프로덕션 사용자가 되기에 적합
- Rust 의 타입 시스템과 zero-cost abstraction 이 결제/복구 같은 신뢰성 크리티컬 영역에 이상적
- 진욱이 Rust 숙련도를 쌓을 기회
이 ADR 은 재작성 자체의 결정이 아니라 "로드맵에 명시적으로 존재함" 을 기록 하는 것이 목적이다. Go 스택 선택이 "최종" 이 아니라 "의도적 중간 단계" 임을 팀과 미래 참여자에게 전달한다.
Decision¶
Umbra 를 Go → Rust 로 재작성하는 계획을 공식 로드맵에 포함한다.
Target runtime¶
Nabi — Pablo 가 개발 중인 Rust 런타임.
- Tokio/async-std 대안 포지션
- Umbra 의 요구사항 (Discord Gateway WebSocket, HTTP, DB, Temporal client, Redis) 을 모두 수용해야 함
- Nabi 성숙도가 Umbra 재작성의 prerequisite
Trigger conditions (재작성 착수 조건)¶
다음 조건이 모두 충족될 때 착수 ADR 작성:
- 진욱 Rust 숙련도 — 독립 구현 가능 수준 (기준: 단독으로 한 도메인 설계/구현 완료 경험)
- Nabi 성숙도 — Umbra 가 요구하는 인터페이스(Discord WS, PostgreSQL, Redis, Temporal) 가 stable
- Go 스택의 명확한 한계 또는 비용 — 유지보수 부담이나 성능 병목이 명확히 관측됨
- MVP 이후 안정기 진입 — 기능 개발이 정체기이거나 수익이 재작성 기간 리스크를 감당 가능
Guiding principles (재작성 준비)¶
지금부터 지키는 원칙이며 Go 개발에 영향을 준다.
- 도메인 모델 언어 무관 설계 — Hexagonal 의 Core (Recovery, Licensing, Billing)는 Go 특유 패턴에 종속되지 않음.
chan,errgroup,context.Context는 adapter 레이어에만 사용 - 도메인 이벤트 순수성 — 이벤트 payload 는 JSON 표현 가능한 구조로 제한 (Go interface, func 금지)
- SQL 재사용 — sqlc 쿼리는 PostgreSQL 표준이라 Rust 재작성 시 그대로 사용 가능
- OpenAPI spec 재사용 — 프론트엔드 계약(ADR-0030)은 언어 무관
- Temporal workflow — Temporal 은 Rust SDK 존재, 워크플로우 개념 자체는 이식 가능
- 테스트 케이스 재사용 — behavior 중심 테스트는 Rust 로 이식 가능 (구현 세부 테스트는 재작성 필요)
Scope of rewrite¶
재작성 시:
- 재작성 대상 —
apps/bot,apps/api,apps/worker,engine/*,platform/* - 유지 —
apps/web(React),db/schema/,docs/,docs/api/openapi.json - 재평가 — disgo → twilight-rs (Rust Discord lib), Echo → axum, sqlc → sqlx 등 도구 선택 전부
Incremental vs big-bang¶
incremental migration 을 원칙 으로 한다:
- Phase A: Supporting 도메인(Identity, Guild) 한 개를 Rust 로 재작성, gRPC 또는 공유 DB 로 공존
- Phase B: Core 도메인(Recovery 우선) 재작성
- Phase C: 모든 도메인 Rust 화 + Go 프로세스 제거
단, 인프라 교체 비용이 크면 big-bang 재평가.
Consequences¶
Positive¶
- 스택 선택의 의도와 방향성이 공식 기록됨
- 진욱의 Rust 학습에 공식 목표 제공
- 도메인 설계가 처음부터 언어 무관 원칙을 따름 → 재작성 비용 ↓
- Nabi 런타임에 프로덕션 검증 기회 제공
Negative¶
- Go 개발 시 "나중에 Rust 로 갈 건데" 태도가 단기 품질 저해할 위험
- Rust 재작성은 결제 SaaS 의 기능 개발을 중단 해야 할 가능성 → 수익 시점에 위험
- Nabi 의 개인 프로젝트 의존성 — Pablo 에게 장애가 생기면 블로커
- "언어 무관 원칙" 이 Go 의 자연스러운 관용구를 제약
Neutral¶
- Proposed 상태로 유지하면서 매 분기 재평가
- 재작성 착수 결정은 별도 ADR (이 ADR 의 후속)
Risk mitigation¶
Pre-rewrite risks¶
Go 개발 단계에서 지키는 것:
- 도메인 코어는 Go 관용구 최소화 (특히
context.Context는 adapter 에만) - 모든 외부 I/O 는 Port 경유 (Hexagonal, ADR-0019)
- 테스트는 behavior 중심
Rewrite risks¶
재작성 기간 동안 발생 가능한 리스크:
- 버그 재도입 — Go 에서 해결한 edge case 가 Rust 에서 다시 발생 → 테스트 케이스 이식 우선
- 프로덕션 중단 — big-bang 전환의 위험 → incremental migration 원칙
- 성능 회귀 — 이론적으로 Rust 가 빠르지만 실수로 더 느릴 수도 → 벤치마크 비교 의무화
- 일정 지연 — 재작성이 예상보다 오래 걸림 → Go 버전 동시 유지 (hybrid 기간)
Nabi dependency risks¶
Nabi 가 Umbra 의 요구를 충족 못 하면:
- Nabi 사용 포기, 표준 async runtime(Tokio) 로 대체
- 이 경우도 Rust 재작성 자체는 진행 가능
Timeline estimate (매우 느슨)¶
- Phase 0 (지금~) — Go 개발 지속, 도메인 설계 언어 무관 원칙 준수, 진욱 Rust 학습
- Phase 1 (수개월~1년) — MVP 출시, 운영 데이터 축적
- Phase 2 (1~2년) — 안정기 진입, Nabi 성숙도 평가
- Phase 3 (?) — 재작성 착수 ADR 작성 및 실행
구체적 날짜는 Trigger conditions 충족 기준으로 판단.
Alternatives considered¶
Alternative 1: Go 영구 유지¶
Pros
- 재작성 비용 0
- 운영 안정
Cons
- Pablo 의 장기 기술 비전과 불일치
- Nabi 의 프로덕션 사용처 필요성
- Rust 의 타입 시스템 이점을 영원히 포기
Why rejected (not really) — 완전히 거부되지 않음. Trigger 조건이 영원히 안 충족되면 결과적으로 이것이 됨.
Alternative 2: 지금 당장 Rust 재작성¶
Pros
- 스택 결정 명확
Cons
- 진욱 학습 곡선 반복 (luxtra-bot 폐기 원인 재발)
- MVP 지연
- Nabi 미성숙
Why rejected — 현실 조건 미충족.
Alternative 3: 언어 혼합 (도메인별 다른 언어)¶
Pros
- 각 도메인 최적 언어
Cons
- 운영 부담 ↑
- 팀 규모 대비 과함
Why rejected — 2인 팀에 부적합.
Compliance¶
- 이 ADR 의 원칙(도메인 모델 언어 무관 설계)은 현재 Go 개발에 즉시 적용
- 분기별 Trigger conditions 재평가 (팀 회의 또는 Pablo 판단)
- 착수 결정은 별도 ADR (ADR-0XXX: Initiate Rust Rewrite) 로 기록
- Nabi 가 Umbra 요구를 충족하는지 체크리스트는 Nabi repo 에 관리
Revisit triggers¶
- Trigger conditions 중 하나라도 충족되면 상세 재검토
- Rust 생태계의 Discord/결제 관련 라이브러리에 큰 변화 (Serenity/Poise, twilight-rs 성숙)
- Go 스택에서 해결 불가능한 기술적 장벽 발생
- Nabi 런타임 성숙도 주요 milestone 도달
References¶
- Nabi 런타임 프로젝트 (팀 내부, Pablo repo)
- twilight-rs — Rust Discord 라이브러리
- tokio — Rust async runtime (Nabi 대안)