여기 누가 나와?
Avatars로 들어오는 이미지 요청은 결국 하나를 물어. 그림에 누가 나오냐는 거. Avatars는 이 답을 자기 기억에서 꺼내지 않아. 소울은 피파의 소울 레지스트리에 살고, 등록된 사람은 피파의 휴먼 레지스트리에 살아. Avatars는 매번 물어보고, 레지스트리랑 어긋날 수 있는 사본은 따로 안 들고 있어. WebUI의 소울 목록에도 한 줄로 적혀 있어. Soul identity comes from Pippa’s registry. 소울의 정체성은 피파 레지스트리에서 온다는 뜻이야. 옆 링크를 누르면 피파가 열려. 새 소울은 거기서만 등록하라는 거지.
이 트랙의 첫수가 이거야. 정체성은 주인이 하나인 데이터고, 나머지는 전부 그 주인한테 물어봐.
왜 키가 soul_pk야?
소울을 부르는 방법은 셋이야. soul_pk는 절대 안 바뀌어. 지금 슬러그랑 표시 이름은 바뀔 수 있는 겉모습이고. 피파의 리졸버는 불변 키, 현재 슬러그, 살아 있는 별칭 중 뭘 줘도 찾아내. 그래도 돌려주는 레코드엔 언제나 soul_pk가 들어 있고, Avatars가 저장하는 것도 그거야. 세트에도, 레퍼런스 프로필에도, 에셋의 피사체 목록에도. 하우스 사인의 불변식은 짧아. 레지스트리에 묶인 활성 소울만 아바타 세트를 가질 수 있고, 안정된 soul_pk는 이름이 바뀌어도 살아남는다. 다음 달에 소울 이름을 바꿔도 아바타, 레퍼런스, 혈통은 여전히 제 주인을 가리켜. 애초에 이름을 들고 있던 데가 없으니까.
소울이 어떻게 태어나고 등록되는지는 Pippa Quest에서 다뤄. 여기선 그림이 소울을 어떻게 찾아가는지만 봐.
사람도 피사체야
등록된 사람이 나오는 그림도 있어. 아빠의 일기 표지나 채널 썸네일엔 아빠가 자주 들어가. 근데 사람은 AI 소울이 아니야. 두뇌도, 볼트도, 목소리도 없어. 아키텍처 문서는 사람을 소울로 바꾸지 않고 같은 와이어 필드에 태우는 길을 골랐어. 피파 쪽 어댑터가 휴먼 레지스트리에서 HumanAvatarSubject를 만들어. 사용자 ID가 soul_pk에 들어가고, kind는 "human", is_super는 언제나 false야.
그래서 필드 하나에 둘 다 실려. 어느 레지스트리가 보증했는지는 kind가 말해줘. perpetual이랑 guest는 소울 레지스트리에서, human은 휴먼 레지스트리에서 와. 세트, 레퍼런스 프로필, 생성, 발행은 둘 다 똑같이 굴러가. dad도 pippa와 똑같이 그냥 피사체 ID야. 그래서 Avatars 안엔 출신 레지스트리를 가르는 코드가 필요 없어.
들어올 땐 엄격하게
리졸버는 소울 레지스트리를 먼저 보고, 없으면 휴먼 레지스트리를 봐. 두 번째 조회가 엄격한 쪽이야. 피파의 사용자 레지스트리엔 조회 함수가 일부러 둘 있어. 너그러운 쪽은 모르는 ID가 오면 아빠라고 답해. 뷰어가 안 적힌 옛 로그 한 줄엔 그게 맞아. 엄격한 쪽은 예외를 던지고. 아바타 경로는 엄격한 쪽을 써. 그 줄에 붙은 주석 a typo must never become Dad가 이유 전부야. 오타가 아빠가 되는 일은 절대 없어야 한다는 거지. 철자 틀린 소울 ID가 조용히 아빠로 풀리면 그림에 엉뚱한 얼굴이 들어가. 뒤따르는 기록도 전부 그게 의도였다고 말할 거고.
이어서 validate_subjects가 피사체마다 두 가지를 더 봐. 하나, 활성 상태여야 해. 레지스트리에서 물러난 소울은 새 작업에 못 나와. 둘, 부탁한 소울이 적혀 있으면, 보호된 Super Soul은 자기 자신이 부탁했을 때만 통과해. 호출한 쪽이 어떤 종류의 거절인지 알 수 있게, 피파 라우트는 PermissionError를 403으로, ValueError를 409로 바꿔. 보호는 트랙 8에서 제대로 다뤄. 여기선 이 검사가 Avatars가 아니라 레지스트리가 사는 곳에서 돈다는 것만 잡고 가.
뷰어 모드는 사람이 아니야
피파 사용자 레지스트리엔 사람만 있는 게 아니야. 예를 들어 콰이어트 모드는 아빠 세션을 게스트 뷰로 바꿔서 screen_safe 표시가 붙은 대화를 숨겨. 이런 접근용 투영이 몇 개 더 있어. 다 사용자 레지스트리의 한 줄이라서, 대충 투영하면 전부 아바타 피사체가 돼버려. 베이스 클래스가 그 문을 닫아. avatar_root는 실제 사람이 직접 켜지 않는 한 None이야. human_subject는 그게 없는 사용자를 This user is a viewer context, not an avatar subject로 거절해. 뷰어 문맥이지 아바타 피사체가 아니라는 말이야. 피사체 목록도 같은 식으로, 아바타 루트가 있는 사용자만 모아서 만들어. 아키텍처 문서는 이걸 한 문장으로 적어 뒀어. 모르는 ID와 뷰어 모드는 거절한다.
Avatars는 매번 물어봐
Avatars의 Upstream.subjects는 ID 목록에 부탁한 소울을 곁들여 피파의 /api/avatar-studio/subjects로 보내. Studio.subjects는 묻기 전에 중복을 걸러내고. 계획을 세울 때, 레퍼런스 프로필을 읽거나 저장할 때, 에셋을 레퍼런스로 열 때, 두뇌한테 보여줄 피사체 디렉터리를 그릴 때 매번 물어. 레지스트리에서 멀어질 로컬 사본이 없어. 비용은 피파한테 거는 호출 한 번이야. 그 대신 오늘 아침 레지스트리에서 물러난 소울은, Avatars를 아무도 안 고쳤는데도 오후 계획부터 안 나와.
어디에도 안 묶인 사진도 받아. 레퍼런스가 전부 등록된 피사체를 그리는 건 아니거든. 빛이 좋아서 올린 풍경 사진은 피사체 목록이 빈 평범한 구도 레퍼런스야. 그걸 소울인 척 꾸밀 필요도 없고.