모든 진지한 protocol 의 plumbing 안에는 compatibility 약속 이 숨어있어. 이 약속은 — 어떤 변화를 기존 client 깨뜨리지 않고 허용하고, 어떤 변화는 version bump 가 필요한 breaking change 인지 — 를 정해. 이 약속의 모양이 protocol 주변에 ecosystem 이 형성될 수 있게 하는 거야. HTTP, SQL, MCP 가 ecosystem 을 키운 비결이 그거야.
어휘는 RFC 2119 에서 와: MUST, SHOULD, MAY. MUST 는 협상 불가 — 안 하면 비-conforming 이고 깨져. SHOULD 는 '진짜 해야 하고 안 하면 사람들이 불행해지지만, 즉사하진 않음.' MAY 는 '원하면 해도 되지만, 누구도 했다고 가정 못 함.'
LLM 과 agent 를 만지는 protocol 들에서는 패턴 세 개가 자주 나와. 첫째, 필드는 보통 추가 되지 이름 변경 안 돼: 새 revision 이 content 옆에 annotations 를 추가하지, content 의 의미를 조용히 바꾸진 않아. 둘째, deprecation 은 긴 window 로 굴러가: 필드는 한 revision 이상 deprecated 마크 후에야 제거되고, 새 필드는 병렬 출시해서 옛 client 가 계속 동작. 셋째, capability negotiation 이 version 부담을 옮겨: 양쪽이 handshake 시점에 뭘 지원하는지 광고하면, protocol 이 모든 디테일을 글로벌 version 번호에 lock-step 묶을 필요 없어.
Compatibility 약속은 '내 server 를 client 안 깨고 업그레이드할 수 있나?' 라고 물을 때 읽는 거야. 답이 'changelog 보고 기도해' 면 — 진짜 protocol 다루는 게 아니라, protocol 처럼 옷 입은 움직이는 표적 다루는 거야. 진짜 protocol 은 약속을 하고, 적어두고, 위반을 bug 로 다뤄.