"이 앱은 cwkPippa 가 call 할 서버를 안 돌려서, 매 턴이 플레이어 context 랑 정지-프레임 attachment 를 질문과 함께 밀어."
설계를 빚는 제약
Ashen Reel 은 일부러 서버가 없어: listening 포트 없고, 콜백 엔드포인트 없고, cwkPippa 가 "플레이어가 지금 뭐 해?" 라고 물으려 손 뻗을 게 아무것도 없어. 그건 보안이자 단순함 승리야 — 근데 네가 설계로 돌아야 할 결과가 있어. 뇌가 context 를 위해 널 콜백 못 하면, 답이 필요한 모든 context 조각이 질문과 함께 여행해야 해. 넌 밀지; 절대 당겨지지 않아.
그래서 각 사이드킥 턴은 자기 세계를 실어: media identity, 관찰된 재생 위치, A-B 루프 마커, 현재 순간 주변 자막 창, 그리고 — 논할 만한 프레임에 정지했으면 — 그 프레임의 스크린샷. "여기 무슨 일이야?" 질문이 이미 '여기' 가 뭔지 알고 도착해, 앱이 '여기' 를 요청에 번들했으니까.
콜백당할 수 없으면, 답이 필요한 모든 걸 질문과 함께 보내. 서버 없는 표면은 질의당할 수 없는 표면이야 — 그러니 매 턴 자기-기술적이어야 해. context 를 번들해, 상대가 가져올 수 있다고 가정하지 마.
턴 payload 는 context-더하기-질문이야, 관찰된 상태에서 조립돼:
이게 PippaGo posture 야. 모바일 Pippa 클라이언트가 같은 문제를 같은 방식으로 풀어: 걔도 서버가 없어서, 질문이 콜백에 의존하는 대신 자기 attachment 랑 context 를 실어. 클라이언트가 콜백을 호스팅 못 할 때 — 모바일, 네이티브, 샌드박스, 오프라인-관용 — 'context 가 턴과 함께 여행' 이 걔가 그래도 풍부하게 해주는 패턴이야. 콜백 문이 닫힌 데마다 재사용되는 가족 모양이야.
공유하면 안 되는 타임아웃
날카롭고 구체적인 gotcha 가 여기 있어. 주어진 릴리스의 맨 첫 Pippa handoff 는 답하기 전에 전체 upstream kickoff 턴을 돌려 — 그게 초가 아니라 몇 분 걸릴 수 있어. 한편 재생 경로 해석은 거의 즉각적이어야 하고, 빡빡한 몇 초 타임아웃에. 그 둘을 같은 네트워크 세션에 두면 재앙을 얻어: kickoff 가 짧은 타임아웃에 죽거나, 경로 해석이 절대 안 가져야 할 5분 참을성을 물려받거나. Ashen Reel 은 일부러 걜 별도 세션에 둬 — Pippa kickoff 용 전용 긴-타임아웃 세션, 재생 해석용 빡빡한 것.
다른 시간 프로필의 연산끼리 타임아웃 예산을 공유하지 마. '경로 가져오기' 랑 '전체 AI kickoff 돌리기' 는 정직한 지속시간이 완전 달라. 타임아웃 하나 가진 HTTP 클라이언트 하나는 둘 중 하나에 대해 거짓말 안 하곤 둘 다 못 섬겨. 각 시간 프로필한테 자기 세션이랑 자기 예산을 줘; 공유 타임아웃은 네가 테스트 안 한 느린 경우에만 나타나는 버그야.
Exercise
네 시스템에서 필요한 context 를 얻으려고 서버 콜백, 캐시 질의, 세션 상태 조회에 의존하는 요청을 찾아. 물어봐: 호출자가 닿을 수 없으면, 캐시가 차갑거나, 세션이 사라졌으면? 그런 요청 하나를 전체 context 를 인라인으로 싣게 다시 설계해. 별도로, 기대 지속시간이 아주 다른데 HTTP 클라이언트/타임아웃 하나를 공유하는 연산 둘을 찾아서, 각각 자기 예산을 줘.
Hint
독립적인 두 냄새: (1) 호출자가 안 보낸 context 를 가져올 수 있다고 가정하는 핸들러 — 출처가 못 닿거나 비는 순간 취약해; 요청을 자기-기술적으로 만들어. (2) 밀리초 조회랑 다초(나 다분) 작업을 둘 다 덮는 타임아웃 값 하나 — 하나엔 너무 길고 다른 하나엔 너무 짧아. 세션을 시간 프로필로 쪼개.