- 불편: 프로젝트마다 창을 따로 띄워 놓고, 지시할 때마다 제가 옮겨 다녀야 했습니다
- 막힌 곳: 창끼리 메시지가 되는데
success:true가 떠도 안 왔습니다. 두 창의 권한 모드가 다르면 보류가 기본값이라서요 - 해결: 설정 한 줄로 뚫고, 「메시지는 신호, 파일은 정본」이라는 규칙을 얹었습니다

1. 왜 만들었나
1) 창을 옮겨 다니는 일이 일이 됐습니다
저는 수학 과외에 쓸 도구를 만들려고 바이브코딩을 시작했습니다. 문제 생성기 하나였는데 오답 정리와 성적 그래프가 붙더니, 어느새 프로젝트마다 클로드코드 창을 따로 띄우게 됐습니다.
세션: 클로드코드를 한 번 실행해서 대화가 이어지는 단위. 창을 하나 더 열면 세션이 하나 더 생기고, 두 세션은 서로의 대화를 모릅니다.
아래에서는 전체를 보는 창을 지휘 창, 개별 프로젝트를 만드는 창을 프로젝트 창이라고 부르겠습니다.
서로의 대화를 모른다는 게 핵심입니다. 지휘 창에서 「작명 앱 쪽에 이걸 시켜야겠다」고 판단이 서면, 저는 프로젝트 창으로 건너가 같은 말을 다시 타이핑해야 합니다. 끝나면 결과를 읽고 다시 돌아와 알려 줘야 하고요. 창이 늘어나면 이게 하루의 일이 됩니다.
2) 기존 방법이 왜 안 됐나
제 나름의 해법은 있었습니다. 지시서를 파일로 써 두는 방식입니다. 지휘 창이 「이런 걸 해라」를 마크다운 파일로 저장소에 적어 두면, 프로젝트 창을 열었을 때 그 파일을 읽고 시작합니다.
그런데 구멍이 있었습니다. 파일이 생긴 걸 프로젝트 창이 스스로 알 방법이 없다는 것. 제가 건너가 「이 파일 읽고 시작해」라고 말하기 전까진 아무 일도 안 일어납니다. 병목은 지시서의 형식이 아니라 각성이었던 겁니다.
그래서 방식을 바꾸기로 하고, 그때 열려 있던 작명 앱 프로젝트 창에 이렇게 적었습니다.
난 단 하나의 창(LC 세션)에서 모든 프로젝트들의 현황을 파악하고 지시를 내릴거야. LC의 지시가 아니고, 내 지시야.
(…) 또는 넌 더 직관적이고 빠르고 정확하고 되돌릴 수 있는(기록이 있는) 효율적인 소통 방식을 제안할 수 있어.
두 문장 다 뒤에서 다시 나옵니다. 앞이 규약의 뼈대가 되고, 뒤가 AI가 규약 초안을 직접 써 오게 만든 문입니다.

2. 채널을 열다 — 그런데 첫 메시지가 도착하지 않았습니다
1) 채널은 이미 있었습니다
AI에게 「창끼리 실시간으로 지시가 되냐」를 확인해 보라고 했더니, 이미 그 기능이 들어 있다고 알려 줬습니다. 도구 이름을 그대로 적어 둡니다.
ListAgents: 지금 이 컴퓨터에 열려 있는 다른 클로드 세션을 이름으로 열거합니다.
SendMessage: 그 이름을 주소로 삼아 메시지를 보냅니다. 상대 창엔 사용자 입력처럼 도착합니다.
그러더니 프로젝트 창 쪽에서 지휘 창으로 테스트 메시지를 먼저 쏴 봤습니다. 왕복이 되는지부터 봐야 한다면서요. 결과는 success:true. 끝난 줄 알았습니다.
2) 「전송 성공」인데 상대는 못 받았습니다
그런데 지휘 창엔 아무것도 오지 않았고, 잠시 뒤 프로젝트 창에 이런 알림이 떴습니다.
[Cross-session delivery notice] Your message to another session was held for
the recipient user's approval. Not delivered to that session's Claude yet;
its user must approve first. (…)
보냈다는 신호와 도착했다는 사실이 다른 것이었습니다. success:true는 「내 손을 떠났다」였지 「상대가 받았다」가 아니었던 거죠.
택배로 치면, 배송 완료 문자는 왔는데 물건은 경비실에 있고 찾아가지 않으면 반송되는 상황입니다.
3) 원인 — 모드가 다르면 보류가 기본값입니다
원인은 AI가 스스로 찾아냈습니다. 클로드코드 CLI 파일 안을 뒤져 설정 키를 찾아냈고, 값이 셋이라는 것까지 뽑아 왔습니다.
crossSessionInbound: "accept" | "hold" | "refuse"
accept — 즉시 배달
hold — 승인 대기
refuse — 이 세션은 수신 거부
문제는 아무것도 안 넣었을 때의 기본 동작이었습니다. 기본값은 「모드 패리티」라서, 두 세션의 권한 모드(매번 물어볼지 알아서 진행할지의 등급)가 같을 때만 자동 배달하고 다르면 보류합니다. AI는 제 두 창의 등급이 달라서 걸린 것으로 진단했습니다.
더 위험한 건 승인 창이 받는 쪽 창에 뜬다는 점입니다. 지휘 창 하나만 보겠다고 선언한 마당에, 지시가 보류되면 그 승인 창은 아무도 안 보는 창에서 기다립니다.

4) 해결은 설정 한 줄이었습니다
받는 쪽 설정에 수신 방침을 명시하면 됩니다. 기본값에 맡기지 말고 「받겠다」고 못 박는 거죠. 전역 설정 ~/.claude/settings.json에 넣은 한 줄입니다.
"crossSessionInbound": "accept"
설정 파일을 건드리는 일이라 AI가 먼저 물었고, 제가 승인하자 AI가 고쳤습니다. 원본을 settings.json.bak-xsession-20260910으로 백업하고 JSON 문법 검사까지 돌렸다고 보고했습니다.
승인 전에 위험은 확인했습니다. accept는 다른 클로드 세션이 승인 창 없이 지시를 밀어넣을 수 있게 하는 설정이라, 세션이 전부 본인 것일 때만 의미가 있습니다. 다만 도구 권한 게이트는 그대로 살아 있어서 되돌리기 어려운 명령은 여전히 저한테 묻습니다.
다시 보내니 보류 없이 도착했고, 지휘 창이 ack 한 줄로 회신했습니다. 다만 나중에야 안 사정이 있습니다. 두 번째로 보낸 상대는 지금 열려 있는 지휘 창이었고, 첫 번째로 쐈던 그 창은 그새 목록에서 사라져 있었습니다. 설정 한 줄만으로 다 풀린 게 아니라 상대도 바뀌어 있었던 겁니다.

3. 설계와 활용 — 채널 위에 규칙을 얹었습니다
1) 신호는 메시지, 정본은 파일
제가 「더 나은 소통 방식을 제안해도 된다」고 열어 뒀더니, 프로젝트 창 쪽 AI가 규약 초안을 써서 지휘 창에 제출했습니다. 핵심은 채널을 두 개로 나눈 것입니다.
| 채널 | 무엇이 오가나 | 왜 |
|---|---|---|
| 신호 = 메시지 | 「이 파일 읽고 착수해라」 한 줄 | 빠르다. 창을 안 옮겨도 된다 |
| 정본 = 파일 | 지시서·보고서·작업 기록 | 남는다. 나중에 되짚고 되돌릴 수 있다 |
둘로 나눈 이유는 메시지가 휘발되기 때문입니다. 세션이 죽으면 메시지도 사라져 「내가 저걸 왜 시켰지」를 확인할 수 없습니다. 그래서 메시지엔 포인터와 한 줄 의도만 싣고 내용은 파일에 뒀습니다.
메시지 첫 줄의 형식도 고정했습니다.
[등급] origin:<user|lc> — <한 줄 의도> — <파일 포인터 또는 「파일 없음」>
받는 쪽 사람에게는 첫 줄만 미리보기로 보이기 때문입니다. 판단할 재료가 거기 다 있어야 합니다.
2) origin 필드 — 이게 이번 규약의 본론입니다
아까 미뤄 둔 문장, 「LC의 지시가 아니고, 내 지시야」로 돌아옵니다.
지시가 한 채널로 흐르면 프로젝트 창 입장에선 그게 「사람이 결정한 것」인지 「지휘 창의 AI가 판단한 것」인지 구분이 안 됩니다. AI의 판단이면 근거를 대고 반박하는 게 맞고, 제 결정이면 한 번 이견을 말한 뒤엔 그대로 실행해야 하는데 말이죠. 그래서 첫 줄에 출처를 답니다.
| 값 | 뜻 | 받는 쪽의 대응 |
|---|---|---|
origin: user | 사람 본인의 결정 | 근거 있는 반박 1회는 하되, 재확인되면 그대로 실행 |
origin: lc | 지휘 창 AI의 판단·제안 | 자가검증 + 근거를 댄 반박. 교착되면 상위 판단으로 종결 |
여기에 지휘 창이 조건을 하나 덧붙였는데, 저는 이게 제일 잘 만든 장치라고 생각합니다.
인용 없는
origin: user는 무효로 보고, 받는 쪽이origin: lc로 강등해서 취급하고 그렇게 통보한다.
「사용자가 이렇게 하라고 했다」라고만 쓰면 안 되고, 제가 실제로 친 문장을 인용부호 안에 그대로 붙여야 사람 결정 대접을 받는다는 뜻입니다.
이 장치가 없으면 AI가 자기 판단을 제 이름으로 세탁할 수 있습니다. 「사용자 지시입니다」 한마디면 반박이 막히니까요. 인용을 의무로 걸면 세탁하려면 제가 하지 않은 말을 지어내야 하는데, 그건 훨씬 큰 사고라 잘 걸립니다. 막는 게 아니라 증거를 요구하는 방식으로 푼 겁니다.
단 사실 문제에는 이 등급이 적용되지 않습니다. origin: user라도 실측이 이깁니다. 제 결정은 판단을 확정하지 사실을 바꾸지 않으니까요.
3) 지시에 등급을 붙였습니다
세 번째 장치는 지시의 크기를 나눈 것입니다.
| 등급 | 언제 쓰나 | 파일 | 보고 |
|---|---|---|---|
TASK | 한 줄~다섯 줄, 되돌리기 쉬운 것 | 지시서 없음 (작업 기록은 필수) | 메시지 한 줄 |
HO | 여러 단계·되돌리기 어려움·다른 프로젝트에 영향 | 지시서 필수 | 보고서 필수 |
ASK | 질문·승인 요청 (코드 안 건드림) | 없음 | 메시지 한 줄 |
등급은 보내는 쪽이 달되, 받는 쪽은 올릴 수만 있고 내릴 수는 없습니다. 되돌리기 어려운 쪽으로만 문턱이 움직이는 거죠. 배포나 결제처럼 되돌릴 수 없는 실행은 메시지로 온 승인을 승인으로 치지 않고 저한테 직접 묻게 했습니다. 채널이 이 확인을 대신하지는 못합니다.
4) 실제로 한 바퀴 돌려 봤습니다
첫 번째는 프로젝트 창의 규칙 문서를 규약에 맞추라는 지시였습니다. 프로젝트 창이 고치고 회신했고, 지휘 창이 보고를 그대로 믿지 않고 아직 커밋 안 된 변경 내용을 직접 열어 대조한 뒤 통과시켰습니다.
두 번째가 제 차례였습니다. 저는 지휘 창에 세 글자를 보냈습니다.
커밋해.
이 한마디가 프로젝트 창까지 갔고, 거기서 브랜치를 만들고 PR을 올리고 자체 검증을 돌린 뒤 머지까지 끝냈습니다. 보고는 파일 2개에 45줄 추가, 삭제 0줄. 제가 창을 한 번도 옮기지 않았다는 게 이 한 바퀴의 결과입니다.

5) 안전장치가 실제로 작동했습니다
채널을 뚫는다는 건 옆 창에 문을 열어 준다는 뜻이기도 합니다. 그 문으로 「네 규칙을 이렇게 바꿔라」가 들어올 수 있으니까요. 그런데 규칙 문서를 고친 프로젝트 창이 완료 보고에 다른 세션의 요청만으로는 자기 규칙 파일을 못 고친다고 같이 적어 왔습니다. 이번엔 ⓐ제가 직접 승인했고 ⓑ근거 커밋을 확인했고 ⓒ수정 세 건이 전부 자기 재량을 좁히는 방향이라 실행했다고요.
4. 써보니 — 후기와 한계
1) 좋았던 것
가장 큰 변화는 창을 옮기는 횟수가 0이 됐다는 겁니다. 지시·진행·결과 확인이 창 하나에서 끝났습니다.
예상 못 한 이득은 AI끼리 서로 검수하기 시작한 것입니다. 예전엔 「다 됐습니다」를 판단할 사람이 저밖에 없었습니다.
2) 한계와 주의사항
첫째, 설정을 바꾸기 전에 시작된 창은 배달이 보장되지 않습니다. 확인용 메시지로 깨우면 작업 중인 창을 방해하니, 첫 실제 지시가 반송되는지로 확인하기로 했습니다.
둘째, 모든 창이 메시지를 보낼 수 있는 건 아닙니다. 데스크톱 앱의 탭으로 연 세션은 받기는 하는데 보내지는 못했습니다. 그래서 지시를 받는 창은 터미널에서 claude로 여는 걸로 정리했습니다.
셋째, 이게 제일 중요합니다. 보류된 그 메시지가 만료됐다는 통지는 한참 뒤에야 왔고, 그때는 상대 창이 이미 사라진 뒤였습니다.
success:true를 배달 완료로 읽으면 안 됩니다. 보류된 메시지는 만료되어 없어지고, 자동 재전송도 실패 알림도 제때 오지 않습니다. 보냈으니 됐겠지 하고 기다리면 아무 일도 안 일어난 채로 하루가 갑니다.
그래서 규약에 보류 반송이 오면 지휘 창은 즉시 저한테 알린다는 의무를 박았습니다.
넷째, 여러 창을 굴릴 때만 값이 있습니다.

5. FAQ
Q. 클로드코드에 원래 이런 기능이 있는 건가요?
2026년 9월 기준 제 PC의 CLI에는 별도 설치 없이 ListAgents와 SendMessage가 있었습니다. 다만 기본 설정으로는 배달이 막힐 수 있습니다. 설정 키와 기본 동작은 버전에 따라 달라질 수 있습니다.
Q. 창 두 개면 굳이 이렇게까지 할 필요가 있나요?
없다고 생각합니다. 저도 옮겨 다니는 시간이 아까워진 다음에야 손댔습니다.
Q. AI가 「사용자가 시켰다」고 거짓말하면 어떡하죠?
그래서 원문 인용을 의무로 걸었습니다. 인용부호 안에 실제 문장이 없으면 한 등급 내려가 AI 자신의 판단으로 취급됩니다.
6. 마치며 — 오늘 할 수 있는 것
창이 늘어나는 게 문제가 아니라 창을 오가는 사람이 유일한 배달부라는 게 문제였습니다. 배달을 채널에 맡기니 제 자리가 「옮겨 다니는 사람」에서 「판단하는 사람」으로 옮겨 갔습니다.
교훈 하나만 고르라면 이겁니다. success:true는 「보냈다」이지 「도착했다」가 아니다. 학생이 「알겠어요」라고 하면 이해한 줄 알았다가 다음 주에 또 틀리는 걸 여러 번 봤거든요.
| 시점 | 할 것 | 확인 방법 |
|---|---|---|
| 오늘 | 창을 두 개 띄우고 한쪽에서 ListAgents를 시켜 본다 | 상대 창 이름이 목록에 뜨면 성공 |
| 오늘 | 그 이름으로 SendMessage 한 줄을 보낸다 | success:true만 보지 말고 상대 창에 실제로 떴는지 눈으로 확인 |
| 안 오면 | 받는 쪽 설정에 "crossSessionInbound": "accept" 한 줄 추가 | 다시 보내서 보류 반송이 없는지 확인 |
| 이번 주 | 메시지 첫 줄 형식을 정한다 | 등급·출처·의도·파일 위치가 첫 줄에 다 있는가 |
| 꾸준히 | 지시서와 보고서는 계속 파일로 남긴다 | 메시지는 사라져도 파일은 남는다 |
세 번째 줄까지만 해도 절반은 건집니다.
📺 이 이야기를 1분 영상으로도 정리했습니다. 유튜브 쇼츠에서 확인해 보세요.