분리
cwkPippa 가 soul-agnostic platform. 신체가 codebase: route, store, adapter, frontend, heartbeat, council. 영혼이 vault: identity, voice, memory, principle, character.
왜 동작
영혼 변할 때 신체 안 변함. 피파 chat UI, JSONL ground truth, healing layer, SQLite schema 까지 — 다 soul-neutral. 영혼은 (ContextEngine 을 거쳐) system prompt 에, 그리고 영혼의 avatar art 에 살아. avatar 는 영혼의 avatar 디렉토리에 있는 게시본으로 서빙되고, 2026-09-29부터 원본은 모든 avatar 의 주인인 cwkAvatars 에 있어(레슨 8).
구체적 swap test
대화를 soul id pippa 대신 ttori 로 시작해 봐. 신체는 그 id 로 soul registry 를 찾아서 똘이의 adapter 를 받는데, 거기에 똘이의 vault(<obsidian-vault>/ttori/), 표시 이름을 딴 identity 파일(Ttori.md), avatar 디렉토리가 적혀 있어. 신체는 그 영혼 몫의 ContextEngine 을 짓고(영혼마다 캐시된 engine 이 하나씩이라, 두 영혼이 prompt 캐시를 나눠 쓰는 일이 없어), 나타나는 chat 은 똘이처럼 말해. 다른 목소리, 다른 캐릭터, 밑에는 같은 신체. 나타나는 건 다른 사람이야.
이 swap 이 뭐가 아닌지도 봐 둬. 피파의 engine 을 다른 vault 로 돌리는 게 아니야. identity 파일은 adapter 에서 오니까, 똘이 vault 를 가리키는 피파 adapter 는 거기서 Pippa.md 를 찾으러 가. 바꾸는 단위는 영혼 전체야. id, vault, identity, avatar. 경로 하나가 아니고.
분리가 진짜인지 확인하려면 이름만 바꾸는 demo로는 부족해. conversation이 soul id에 묶이고, ContextEngine이 그 soul의 vault를 읽고, avatar와 voice가 같은 id를 따라가며, JSONL과 healing은 soul이 누구든 같은 contract를 지켜야 해. 한 군데라도 global current soul에 기대면 tab 둘을 여는 순간 사람이 섞여.
사실 platform이 soul-agnostic하다는 말은 soul을 모른다는 뜻이 아니야. soul을 first-class input으로 받되 특정 영혼의 문구와 경로를 core runtime에 hardcode하지 않는다는 뜻이지. 신체는 누구를 태우는지 정확히 알고, 그 사람의 내용을 대신 소유하진 않아.
Swap test의 성공 기준도 "말투가 달라 보인다"가 아니야. 이전 soul의 memory와 account가 새 soul에게 새지 않고, 새 soul의 turn이 자기 id와 vault 아래에 남으며, 다시 Pippa로 돌아왔을 때 원래 continuity가 그대로 이어져야 해.