Framein을 만든 이유
이미 쓰는 하네스 아래에, 작업 기준은 하나로.
시작은 불편한 작업 풍경
요즘 저는 대부분의 코딩을 터미널 에이전트와 함께 합니다. VS Code 안에 Claude Code, Codex, Gemini CLI를 나란히 띄워둡니다. 거창한 "멀티 에이전트" 구상을 실험하려던 것은 아니었습니다. 이유는 훨씬 실용적이었습니다.
- 기본 구현은 Claude에 맡기는 편입니다.
- 외부 시선이 필요할 때 — 보안 구멍, 회귀, 어딘가 어긋난 계획 — Codex가 Claude가 놓친 부분을 잡아냅니다.
- 결과를 다른 사람에게 설명해야 할 때는 Gemini의 정리가 더 친절할 때가 있습니다.
- 때로는 한쪽이 사용 한도에 걸려 다른 쪽으로 전환하며 작업을 이어가기도 합니다.
그 결과 터미널 세 개를 띄워두고, 제가 그 사이의 통합 레이어가 되어 있었습니다. 모델을 바꿀 때마다 같은 내용을 다시 설명해야 했습니다. 목표는 무엇인지, 절대 깨뜨리면 안 되는 것은 무엇인지, 직전 모델이 무엇을 시도했고 왜 실패했는지. 모델 사이를 채팅 요약으로 이어 붙이는 사람 클립보드에 가까웠습니다.
가장 불편했던 것은 타이핑의 양이 아니었습니다. 작업이 경계에서 계속 끊긴다는 점이었습니다. 모델을 바꾸는 순간 맥락 — 실제 계약, 실패한 시도, 결정, 검증 상태 — 이 사라졌습니다. 각 모델은 깨끗하고 자신감 있게 다시 시작했고, 저도 함께 처음부터 다시 시작해야 했습니다.
전환만 문제가 아니었습니다. 한 모델이 같은 해결책을 반복할 때도 있었습니다. 예를 들어 결제 webhook처럼 재시도와 idempotency가 얽힌 작업에서는, 구현 모델이 자신 있게 "됐다"고 말해도 어딘가 불안했습니다. 그때 필요한 것은 항상 새 리드 모델로 바꾸는 일이 아니었습니다. 같은 작업 계약과 diff, 검증 상태를 읽은 다른 모델이 "이 계획에서 빠진 위험은 무엇인가"를 물어봐 주는 일이 필요했습니다.
Framein의 challenge는 그 자리에서 시작했습니다. 새 채팅방에 상황을 다시 설명하는 대신, 이미 기록된 작업 기준을 바탕으로 다른 모델에게 범위가 좁은 감사와 반론을 요청하고, lead에게 한 번만 응답하게 한 뒤 사용자가 결정하게 합니다. 막힌 모델을 버리는 기능이라기보다, 작업이 아직 살아 있는 동안 옆에서 다른 시선을 붙이는 기능에 가깝습니다.
만들지 않을 뻔했습니다
설계를 시작하기 전에 먼저 해야 할 일을 했습니다. 이미 비슷한 도구가 있는지 찾아봤습니다. 있었습니다. 그것도 꽤 많이 있었습니다.
CCB, Claude Squad, CC Switch, 점점 커지는 SuperClaude 계열, gstack, Matt Pocock의 스킬팩 — 이미 많은 도구가 있었습니다. 처음에는 안도했지만 곧 힘이 빠졌습니다. 같은 불편을 느낀 사람이 이렇게 많고, 이미 여러 팀이 해결책을 내놓았구나. 냉정하게 보면, 평범한 "멀티 CLI 매니저"를 하나 더 만들면 이 도구들이 모두 듣는 질문을 똑같이 받게 될 것 같았습니다. "이거 CCB랑 뭐가 달라요?"
그런데 그 질문이 가장 쓸모 있었습니다. CLI 매니저를 만들려는 생각을 멈추고 나서야, 실제로 비어 있는 부분이 보였기 때문입니다.
통찰: 더 나은 핸드오프가 아니라, 핸드오프가 필요 없는 구조
제가 살펴본 도구들 — 그리고 첫 설계안 — 은 전환 문제를 더 나은 핸드오프 묶음으로 풀고 있었습니다. 요약, diff, 테스트 결과를 모아 다음 모델에 넘기는 방식입니다. 저도 거의 같은 것을 만들 뻔했습니다.
그러다 핸드오프 자체가 문제일 수 있다는 생각을 하게 되었습니다.
세 에이전트가 하나의 공유된 진실원천 — 작업 계약, 결정 기록(ADR), 검증 결과, 리스크 상태 — 을 읽는다면, "넘긴다"는 행위는 더 이상 별도의 단계가 아닙니다. 다음 모델은 제가 요약한 사실이 아니라 사실 그 자체를 읽습니다. 누군가가 뭔가를 넘기는 것을 기억할 필요가 없습니다. 애초에 작업 기준이 분리되지 않았기 때문입니다.
이 재정의가 제품의 핵심입니다. Framein은 세 에이전트를 격자로 띄우는 콕핏이 아니고, 또 하나의 에이전트 하네스도 아닙니다. 이미 쓰는 에이전트나 하네스 아래에 하나의 작업 프레임을 두는 얇은 로컬 레이어입니다. 그래서 작업이 어떤 단일 모델이나 세션보다 오래 유지됩니다.
실제로 하는 일
루프는 네 개의 동사로 이루어집니다.
start -> 구현이 흔들리기 전에 요청을 작업 계약으로 고정
challenge -> 리뷰어 판정, lead 1회 응답, 사용자 결정
capsule -> 다음 리드가 읽을 사실을 준비: 계약, diff, 검증, ADR, ledger
ship -> 모델이 "끝났다"고 말하는 게 아니라, 실제 빌드/테스트/리스크 게이트로 닫음
터미널에서 호출할 수도 있고, Claude/Gemini 안에서는 /fr:* 슬래시 명령으로, Codex에서는 $fr-* 스킬로 호출할 수 있습니다. 아래에서는 같은 엔진과 같은 로컬 상태를 사용합니다. 기존 하네스, 스킬팩, 페르소나는 그대로 둡니다. Framein은 그 아래에 계약·원장·게이트를 제공합니다.
가장 확신하는 결정들
컴플라이언스가 먼저입니다. 그렇지 않다면 출시하지 않습니다. 구독 트래픽을 라우팅하거나 자격증명을 모으는 도구에 대한 최근의 검토는 단순한 정책 각주가 아니라, 동의할 수 있는 설계 경계라고 보았습니다. 그래서 Framein은 자격증명을 수집하지 않고, 토큰을 중계하지 않고, 구독을 공유하지 않고, 터미널 입출력을 화면 스크래핑하지 않습니다. 필요할 때 공식 CLI를 로컬에서 호출할 뿐이고, 인증은 각 CLI가 그대로 갖습니다. README의 신뢰 경계는 마케팅 문구가 아니라, 이런 도구가 존재할 자격이 있는지를 가르는 선입니다.
결정은 append-only입니다. ADR은 수정하거나 삭제하지 않고, 새 기록으로 대체만 합니다. 조용히 고쳐 쓸 수 있는 결정 기록은, 두 번째 모델이나 두 번째 사람이 그 기록을 믿는 순간 무가치해집니다.
런타임 의존성은 0입니다. 전체가 Node 22의 내장 node:sqlite와 내장 테스트 러너로 동작합니다. 네이티브 빌드도, 반년 뒤 설치를 깨뜨릴 의존성 변동도 없습니다. SQLite store는 로컬 캐시이고, 정본 스냅샷은 git 친화 JSON입니다.
한 시점에 한 명만 씁니다. 공유 에이전트 메모리의 진짜 어려움은 공유 자체가 아니라, 두 에이전트가 같은 대상에 대해 일관되지 않은 사실을 쓰는 문제입니다. 그래서 지루하지만 안전한 답부터 시작했습니다. TTL이 있는 원자적 write lock입니다. 영리함보다 정확성을 먼저 두었습니다.
지금 상태
pre-release v0.0.6입니다. 코어 — store, CLAUDE.md / AGENTS.md / GEMINI.md에 걸친 managed block 투영, 작업 계약, verify/risk/ship 게이트, /fr:*와 $fr-* 래퍼, MCP 서버 — 는 구현되어 있고 2026-06-28 기준 249개 테스트로 다루고 있습니다.
npm 패키지는 현재 framein@0.0.6입니다. 아직 다듬는 중인 것은 Windows Authenticode 서명 경로, 서명/공증된 실행 파일 배포, 깨끗한 장비에서의 설치 검증, 다중 개발자 워크플로입니다.
Framein이 모든 분의 일하는 방식을 바꿀 것이라고 주장하지는 않습니다. 터미널 세 개와 사람 클립보드로 하루를 보내는 방식이 너무 불편해서 만들었습니다. 해법은 거창하거나 영리한 것이 아니라, 작고 로컬한 구조에 있었습니다. 두 개 이상의 코딩 에이전트를 오가며 일하고 있다면, Framein이 실제로 도움이 되는지 듣고 싶습니다.
MIT 라이선스이며, Frameout에서 만들었습니다. 이름은 영화 용어에서 왔습니다. 프레임아웃은 피사체가 화각을 벗어나 상상의 off-screen 공간에만 존재하게 되는 것입니다. 프레임인은 그것을 다시 들이는 일입니다 — 흩어진 세 에이전트를 실제로 볼 수 있는 하나의 프레임 안으로.
— 구자호, AX Center, 프레임아웃
— 레포·문서: framein.dev
