한 좁은 boundary
cwkPippa 에 polymorphism 이 의도된 곳 정확히 한 군데: backend/adapters/base.py 의 streaming-API boundary. 그 boundary 위 의 모든 것 — route, store, service, frontend — 다 Claude-shape.
왜 좁은가
wire protocol 이 진짜로 다름. Claude 는 thinking block. Codex 는 server-side resume 없는 function-calling loop. Gemini 는 thoughtSignature 보존 + dual-path auth. Ollama 는 자기 tool schema wrapping. boundary 아래 차이 인정. 위 는 인정 안 해.
boundary 위에 뭐가 있나
- Routes:
chat.py가 Claude-shape 가정 (prefix-check escape hatch 박음). - Store:
conversations테이블이claude_session_id컬럼. 거기에 Codex/Gemini/Ollama id 저장 OK — Claude shape 에 fit (string id + history 다른 데서 reconstructed). - JSONL ground truth: 모든 line 이 Claude-Code-compatible message format. cwkPippa 별 field 가 nested
pippasub-object 에 — Rule 2 데이터 포맷 자체에 표현.
Boundary를 찾는 방법은 capability 목록을 늘어놓는 게 아니야. 위쪽 코드가 무엇을 알고 싶어 하는지 먼저 정해. 여기서는 "stream에서 어떤 typed event가 왔나"만 알면 돼. OAuth refresh 방식, provider별 request body, reasoning token 표현은 아래쪽 사정이야. 위에서 그 차이를 묻기 시작하면 boundary가 이미 새고 있어.
좁은 boundary는 테스트도 좁혀 줘. 각 adapter가 canonical event contract를 지키는지 검증하고, route와 store는 provider를 몰라도 같은 suite를 돌아. 모든 층을 polymorphic하게 만들 때보다 바뀌는 자리를 훨씬 또렷하게 가리켜.