TinyPilot: Month 42

Michael Lynch

TinyPilot: 42개월 차

한 줄 요약

어떻게 하면 더 많이 위임할 수 있을까?

하이라이트

  • 제품 의사결정과 문서를 더 잘 위임하는 방법을 고민했습니다.
  • Nix를 배운 경험과 Zig를 배운 경험을 비교했습니다.

목표 달성도 평가

매월 초에 달성하고 싶은 목표를 정합니다. 이번 달 목표에 대한 결과는 다음과 같습니다.

TinyPilot 라이선스 확인 기능 설계 완료

  • 결과: 설계 문서 작성을 마치고 리뷰를 완료했습니다.
  • 등급: A

이제 TinyPilot 고객이 최신 버전으로 업데이트하기 전에 유효한 라이선스를 보유하고 있는지 확인하는 방법에 대한 계획이 마련되었습니다. 타사 라이선스 관리 솔루션(현재는 Keygen을 고려 중입니다)을 선정하면 세부 사항을 채워야 하지만, 큰 틀은 잡았습니다.

신규 기기 제조 배치별 샘플 검수 프로세스 마련

  • 결과: 진행하지 못했습니다.
  • 등급: F

일정상 여유가 없었던 것이 부분적인 이유입니다. 협력사와 관련해 예상치 못한 문제들을 처리해야 했고, 그에 시간이 꽤 소요되었습니다.

또 다른 이유는 이 일이 꺼려져서 미루게 되었다는 점입니다. 제조 오류를 조기에 발견하려면 중요한 일이지만, 그동안 그다지 협조적이지 않았던 3PL(제3자 물류 업체)에 별도로 요청해야 하는 일이라 부담이 있었습니다.

TinyPilot 연말 세무 업무 처리

  • 결과: 모든 협력사로부터 W-9 양식을 취합했습니다.
  • 등급: A-

이제 이 업무는 완료되었고, 누가 W-9 양식을 제출해야 하는지 더 명확히 이해하게 되었습니다. 앞으로는 마감 직전에 허둥대지 않도록 할 수 있을 것 같습니다.

TinyPilot 통계

지표2023년 11월2023년 12월변동
순 방문자 수6,4006,700+300 (+5%)
판매 수익$84,055.05$75,198.00-$8,857.05 (-11%)
엔터프라이즈 구독$290.70$290.700
로열티$2,824.46$1,792.51-$1,031.95 (-37%)
총수익$87,170.21$77,281.21-$9,889.00 (-11%)
이익-$5,407.96-$59,117.41-$53,709.45 (-inf%)

수익은 11월보다 소폭 감소했지만, 매년 나타나는 계절적 추세입니다. 평소 월 수익 범위가 7만 5천~9만 달러 정도인데, 이번 달은 그 중 하위권에 속하지만 우려할 수준은 아닙니다.

이익이 크게 마이너스로 보이는 이유는 아직 현금 기준으로 장부를 정리하고 있기 때문입니다. 제3자 위탁 제조업체로 전환하면서 제조 비용을 선급으로 훨씬 많이 지출하고 있습니다. 4분기에 TinyPilot은 자재와 제조에 15만 달러를 지출했는데, 분기 기준으로 역대 최대 금액입니다. 매출원가(COGS) 기준으로 보면 12월 TinyPilot의 이익은 실제로 9천 달러(양수)였습니다.

다만 외부 제조 및 물류 업체로의 전환을 관리하는 데 집중하느라 마케팅을 소홀히 했습니다. 다행히 TinyPilot은 지난 몇 달간 마케팅에 큰 투자를 하지 않고도 성장했지만, 언제까지나 그렇게 되리라 기대할 수는 없습니다. 그래서 1월 목표 중 하나는 새로운 마케팅 채널을 모색하는 것입니다.

어려운 제품 의사결정을 위임할 수 있을까?

요즘 제 시간이 어디에 쓰이는지 돌아보면, 상당 부분이 소위 ‘어려운 제품 의사결정’에 할애되고 있음을 알 수 있습니다. TinyPilot에 어떤 기능이 필요한지, 거기에 얼마나 투자해야 하는지, 예상치 못한 문제가 생겼을 때 자원을 어떻게 재배치할지를 고민하는 시간입니다.

어려운 제품 의사결정을 TinyPilot 팀에 위임해 보려 했지만, 별다른 진전은 없었습니다.

기능 하나를 만드는 데 드는 비용과 그 기능이 사용자를 얼마나 만족시킬지를 보여주는 차트를 만들어, 팀에게 “이 선 위에 있는 것만 하자”고 말할 수 있다면 얼마나 좋을까요.

고객 만족도와 개발 비용의 관계를 곡선으로 정의한 뒤, 팀에게 그 곡선 위에 머물라고 조언할 수 있다면 좋겠습니다.

하지만 새로운 기능에 얼마나 투자할지를 결정할 때는 그 외에도 고려해야 할 요소가 훨씬 많습니다. 예를 들면:

  • 이 기능이 필요 없는 사용자에게 혼란이나 복잡함을 초래하지는 않을까?
  • 이 기능을 장기적으로 유지보수하는 데 드는 부담은 얼마나 될까?
  • 이 기능이 고객 지원 팀에 어떤 영향을 미칠까?

설령 이런 다차원 차트를 만들 수 있다 해도, 모든 변수를 유의미하게 추정하기는 어렵습니다. 한 사람은 어떤 기능의 수혜자가 전체 사용자의 5%라고 생각할 수 있고, 다른 동료는 15%라고 추정할 수도 있습니다. 그 변수 하나만으로도 기능의 가치는 3배가 달라집니다. 모든 변수를 합치면 두 사람이 산출한 투자 수익률 추정치는 100배까지 벌어질 수 있습니다.

거창하게 들릴지 모르지만, 최종 결정을 내리는 사람은 ‘제품 비전’을 갖추고 있어야 합니다. 고객과 개발 팀, 지원 팀 모두와 연결되어 있어야 합니다. 그리고 TinyPilot에서 그 위치에 있는 사람은 저뿐입니다.

한 가지 가능한 해결책은 프로덕트 매니저를 채용해 상위 전략을 구체적인 계획으로 만들고 팀과 함께 실행하도록 하는 것입니다. 하지만 이는 관리하고 팀 커뮤니케이션에 포함시켜야 할 인원이 한 명 더 는다는 뜻이라 그다지 현실적이지 않습니다. 현재 저는 6명을 관리하고 있는데, 이 정도가 제가 효과적으로 관리할 수 있는 상한선이라고 느껴집니다.

다른 가능성은 기존 팀원에게 프로덕트 매니저 역할을 맡기는 것이지만, 이 역시 현실성이 떨어집니다. 아침에 우편물을 가져오는 일처럼 단순히 업무 하나를 추가하는 수준이 아니라, 거의 모든 고객 및 팀 내 상호작용에 참여해야 하므로 주당 10~20시간의 추가 업무가 됩니다. 설령 그렇게 한다 해도, 누군가를 제대로 된 제품 의사결정을 내릴 수준까지 교육할 수 있을지 확신이 서지 않습니다.

현재 계획은 개발 팀에 계속해서 상위 전략과 버그 및 기능 개발에 투입할 대략적인 개발 시간 예산을 제공하는 것입니다. 지금까지는 이 방식이 잘 작동해 왔지만, 팀이 더 자율적으로 의사결정을 내릴 수 있도록 돕는 방법을 계속 모색하고 있습니다.

문서 작업을 더 잘 위임할 수 있을까?

저는 문서에 대해 까다로운 편입니다. 개선할 여지가 보이면 최대한 좋게 다듬을 때까지 공개하고 싶지 않습니다.

아직도 TinyPilot의 블로그 글, FAQ, 튜토리얼을 모두 제가 검토하고 있어, 제가 게시 과정의 병목이 되는 경우가 많습니다. 창업자로서 쓰는 시간 중 상당 부분이 문서 검토에 들어간다고 느껴집니다.

문서 작업에 절대적인 시간을 많이 쓴다기보다는, ‘깊이 생각하는’ 에너지를 문서 검토에 많이 소모합니다. 저는 하루에 한 시간 정도 글을 쓸 수 있습니다. 다른 사람이 쓴 글을 검토하는 일은 직접 글을 쓰는 것보다 더 많은 에너지가 듭니다. 아이디어를 어떻게 표현할지 고민하는 데 그치지 않고, 왜 그런 방식으로 표현해야 하는지까지 생각해야 하기 때문입니다.

예전에는 코드 리뷰에서도 완벽주의 때문에 고생했고, 사소한 것들은 그냥 넘기는 법을 배워야 했습니다. 코드가 최대한 아름답지 않아도 사용자 경험에 영향을 주지 않으니 괜찮습니다. 하지만 문서는 누구나 볼 수 있고, A등급 글과 B등급 글 사이에는 분명한 차이가 있습니다.

그렇다면 글의 수준을 높게 유지하면서도 제가 프로세스의 의존 요소가 되지 않으려면 어떻게 해야 할까요?

프리랜서 테크니컬 라이터를 투입하는 것도 고려해 봤지만, 그렇게 되면 글쓰기 프로세스가 복잡해질 것 같습니다. 또 전담 작가가 있으면 오히려 팀원들이 글쓰기 실력을 키우려는 의욕을 잃을까 걱정됩니다. “나는 대충 쓰고, 고치는 건 테크니컬 라이터가 할 일이야”라고 생각하게 될 수도 있습니다.

글을 검토할 때 겪는 어려움 중 하나는, 제가 머릿속에 일반적인 TinyPilot 고객에 대한 모델을 가지고 있지만 그 모델을 다른 사람에게 정확히 설명하는 방법을 모르겠다는 점입니다. 다른 사람들이 그 모델을 이해한다 해도, 그에 맞춰 글을 쓰는 것은 여전히 어렵습니다.

평균적인 TinyPilot 고객을 위해 글을 쓰세요. 평균적인 TinyPilot 고객이 이해하는 용어: Ethernet, WiFi, Local network, Keyboard / mouse input, USB / USB-C / USB 3.0, AC adapter, HDMI / VGA, Router / switch, Web browser, SSH. 평균적인 TinyPilot 고객이 이해하지 못한다고 가정하는 용어/개념: cached, PCB / HAT, audio breakout board, VPN, EDID, virtual display, NTP server. 고객을 혼란스럽게 하지 않는 가장 좋은 방법은 고객이 이미 이해하고 있는 용어로 설명하는 것입니다. 그게 불가능하다면 고객이 모를 수도 있는 용어를 사용해도 되지만, 먼저 정의를 제공해야 합니다.

TinyPilot 내부 스타일 가이드 중 기술 용어 사용 수준에 관한 발췌

이를 개선하는 한 가지 방법은 과거 리뷰를 되돌아보며 패턴을 찾는 것일지도 모릅니다. 패턴이 보이면 “리뷰를 요청하기 전에 스크린샷을 넣으면 좋을 부분이 있는지, 새로운 용어를 사용하기 전에 설명하고 있는지 등을 점검하세요”라고 안내할 수 있을 것입니다.

팀용 Grammarly 구독이 있지만 우리 워크플로우에는 잘 맞지 않습니다. 초안 작성할 때 한 번쯤은 쓸지 몰라도, 매번 수정할 때마다 글 전체를 Grammarly에 복사해 붙여 넣고 싶어 하는 사람은 없습니다. 개발자 친화적인 Vale도 살펴봤지만, Grammarly에 비하면 기능이 꽤 기초적인 수준으로 보입니다. 그래도 Vale에 노이즈가 적은 검사 규칙을 설정해 적용해 볼 수 있을 것 같아 한번 시도해 보려고 합니다.

Nix 배우기 vs. Zig 배우기

TinyPilot의 제조와 물류를 외부 업체에 맡기게 되면서 얻은 효과 중 하나는 새로운 기술을 배울 시간과 정신적 여유가 생겼다는 점입니다. 지난 2년간 멀리서 눈여겨봐 온 기술 두 가지는 NixZig였는데, 2023년 말에 드디어 두 기술 모두를 직접 실험해 볼 수 있었습니다.

두 기술 모두 초보 수준으로 배워 본 지금, Nix를 배운 경험과 Zig를 배운 경험을 비교해 보는 것이 흥미롭습니다.

Zig는 추론으로 배우고, Nix는 복사-붙여넣기로 배웁니다

Zig에 대해 들었던 불만 중 하나는 문서가 부실하다는 것이었습니다. 저도 문서가 꽤 간결하고 개발자보다는 컴파일러 설계자의 관점에서 쓰였다고 느꼈지만, 여러 논의를 뒤지고 직접 실험해 보는 과정을 통해 Zig에 대한 정확한 멘탈 모델을 갖출 수 있었습니다.

Nix를 6개월간 사용한 뒤에도 Nix에 대한 멘탈 모델은 여전히 엉망입니다. 여러 설명을 읽어 봤지만 개념이 좀처럼 명확해지지 않았습니다. Nix 파일을 만들 때는 기존 예제를 복사해 원하는 대로 조금 수정하는 방법밖에 쓸 수 없습니다. 파일 대부분은 정형 코드(보일러플레이트)인데, 왜 그렇게 되어 있는지 이해하지 못합니다.

Zig에서 오류가 발생하면 보통 추론을 통해 컴파일러가 무슨 말을 하는지 이해할 수 있습니다. 반면 Nix에서 오류가 나면 완전히 무력감을 느낍니다.

큰 차이점 중 하나는 제가 C 계열 언어로는 개발 경험이 많지만 순수 함수형 언어 경험은 전혀 없다는 점인 것 같습니다. Zig는 C와 C++ 개발자를 대상으로 하므로, 10년간 그런 언어들로 작업해 온 저에게는 개념이 잘 와닿습니다.

Nix는 제가 한 번도 배워 본 적 없는 Haskell 등 함수형 언어의 영향을 강하게 받은 것으로 보입니다. Haskell 개발자라면 Nix가 더 직관적으로 느껴질 것이고, 오히려 함수형 언어에서는 그다지 부각되지 않는 포인터나 메모리 할당자에 집중하는 Zig가 혼란스럽게 느껴질 수도 있을 것입니다.

Zig의 개발자 경험은 좁지만 깊고, Nix는 넓지만 얕게 느껴집니다

Zig에는 패키지 관리나 코드 커버리지를 위한 툴이 없습니다. 지금까지 Zig에 대해 실망했던 점 중 하나는 마이크로컨트롤러 지원이 거의 전무해 보인다는 것입니다.

Zig는 Raspberry Pi Pico를 제외한 모든 주요 마이크로컨트롤러에 대해 지원이 미숙하거나 아예 없습니다.

하지만 Zig가 무언가를 할 수 있다고 하면, 그건 정말 잘 해냅니다. gcc를 그대로 대체할 수 있다는 주장에 대해서는 회의적이었지만, gcczig로 교체할 때마다 모든 것이 문제없이 동작했습니다. Zig는 .c 파일을 Zig 파일로 그냥 가져올 수 있다고 주장하는데, 실제로 그렇게 할 수 있습니다.

Nix에 대한 제 경험으로는, Nix는 Node.js 프로젝트 빌드 같은 단순한 일부터 OS 전체를 빌드하고 관리하는 웅대한 일까지 훨씬 더 광범위한 일을 하려고 시도합니다.

제 프로젝트가 Nix 툴이 기대하는 형태와 정확히 일치하면 모든 것이 잘 동작합니다. 하지만 제 설정이 Nix 툴이 기대하는 것과 조금만 달라도 벽에 부딪히는 경우를 자주 겪습니다. 예를 들어, 아직도 Nix 환경에서 임의의 Python 프로젝트를 실행하는 방법을 모르겠습니다.

Nix에서 가장 놀라운 빈틈 중 하나는 설치하려는 패키지 버전을 지정하는 공식적인 방법이 없다는 점입니다. 8년간 논의가 이어졌지만 해결책도, 고쳐질지 아닐지에 대한 공식 입장도 없는 듯합니다.

Nix 리더십은 분산되어 있고, Zig에는 BDFL이 있습니다

Andrew Kelly는 Zig의 최초 개발자입니다. 이후 여러 명이 프로젝트에 합류했지만, Andrew는 여전히 사실상 종신 자애로운 독재자(BDFL)입니다. Zig 문서나 도움을 검색할 때 GitHub 이슈나 포럼 토론에서 Andrew나 프로젝트 공식 관계자가 답변하는 경우를 자주 접했습니다.

Nix를 처음 접했을 때 Eelco Dolstra가 Nix의 BDFL일 거라고 생각했지만, 적어도 공개적으로는 그렇지 않아 보입니다.

Nix는 Eelco의 2006년 박사 학위 논문에서 나온 그의 아이디어입니다. Eelco는 Nix Foundation의 회장이지만, Nix를 홍보하는 제3자 컨설팅 회사인 Determinate Systems에서도 일합니다. 하지만 Determinate Systems는 분명히 제3자이며 Nix의 핵심 조직은 아닙니다. 그들이 내놓는 결과물은 때때로 Nix 내부 팀의 작업과 논란을 일으키며 충돌하기도 합니다.

Zig가 중앙에서 계획되는 느낌이라면, Nix는 방향을 잃은 듯한 느낌입니다. 뭔가 이해가 안 되어 검색하면 대부분 GitHub나 Nix Discourse 포럼의 두서없는 토론으로 이어집니다. 대화는 마치 우연히 발견한 외계 기술을 논하는 것처럼 들립니다. Nix 코어 팀 누군가가 의견을 보태는 것을 본 적이 없고, 코어 팀이 존재하기는 하는지도 모르겠습니다.

Nix나 Zig에서는 오래된 해결책이 대개 동작하지 않습니다

Zig는 아직 안정적인 1.0 버전을 발표하지 않았기 때문에 컴파일러 업데이트로 호환성이 깨지는 변경이 생기는 것이 일반적입니다. Zig 0.8.0에서는 유효했던 코드가 Zig 0.11.0에서는 더 이상 유효하지 않을 수 있습니다. 제 경험상 Zig 툴은 코드를 자동으로 고치는 데 꽤 능숙하지만 100% 정확하지는 않습니다.

Nix에서도 오래된 예제 때문에 비슷한 문제를 겪었습니다. Nix는 아직 공식 기능이 아닌 비교적 새로운 기능인 flakes를 둘러싸고 논란이 많은 변혁의 한가운데에 있습니다. 하지만 최근 가이드는 모두 flakes를 사용하고 오래된 논의는 flakes 이전 방식을 사용하므로, flakes 이전의 해결책을 flakes 이후 환경에 적용하는 데 어려움을 겪습니다.

Zig는 팀 전체의 동의가 필요하지만, Nix는 부분적 도입이 용이합니다

Nix의 좋은 점 중 하나는 자체 완결적이라는 것입니다. 제 프로젝트 중 하나에 flake.nix 파일 하나만 넣으면 다른 것을 바꾸거나 팀원에게 뭔가 요청하지 않고도 의존성을 자동으로 관리할 수 있습니다.

팀에서 저만 Nix를 쓰더라도 flake.nix는 다른 사람에게 비용을 전가하거나 새 도구 사용을 강요하지 않으면서도 저에게는 큰 가치를 제공합니다. 프로젝트에 .vscode 디렉터리를 추가하는 것과 비슷합니다. VS Code를 쓰는 사람에게는 도움이 되지만 다른 사람에게는 별로 거슬리지 않습니다.

반면 Zig는 전념과 팀 전체의 동의가 필요합니다. C나 C++ 프로젝트가 있는데 Zig로 전환하고 싶다면, 혼자 더 나은 툴을 즐기면서 팀원들이 합류하기를 기다릴 수 없습니다. 프로젝트에 Zig 코드를 도입하는 순간, 모두가 C/C++ 컴파일러가 아니라 Zig 컴파일러로 빌드해야 합니다.

Zig의 잘못은 아니지만, 결과적으로 저는 코드를 만지작거리거나 Zig 프로젝트를 볼 때처럼 Zig 세계에 직접 들어갈 때만 Zig를 접하게 되는 반면, Nix는 이제 어디를 가든 함께 가지고 다닙니다.

마무리

완료한 일

배운 점

  • 문서 리뷰에 대한 주기적인 메타 리뷰가 도움이 될 수 있습니다.
    • 현재는 글 하나 단위로만 개선점을 논의하고 있지만, 여러 글에 걸쳐 반복되는 패턴을 검토하면 팀의 글쓰기 실력이 더 향상될 수 있습니다.
  • Vale는 문서 리뷰 전에 사소한 문제를 잡아내는 데 유용할 수 있습니다.

다음 달 목표

  • 연간 회고를 게시합니다.
  • TinyPilot 협업을 위해 블로거 5명에게 연락합니다.
  • 2023년 세금 신고를 위한 기록을 정리합니다.

도움 요청

원문은 Michael Lynch님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.