Council 이 실제 저장하는 것
council 이 <app-data>/councils/ 의 JSON 파일. 저장: 두뇌 정체성 list, round list (각 round = transcript snapshot + 어느 두뇌 발언), 아빠의 optional 코멘트, picked round (finalized 시).
저장 안 하는 것
실제 chat log. 그건 자기 JSONL file 에 살아 <app-data>/sessions/ 아래, (brain, conversation_id) 당 하나. council 이 그냥 reference.
Transcript 조립
아빠가 Council 에 또 round 요청 시, council orchestrator 가 existing round 들로 transcript prefix 빌드, 새 turn 의 user message 앞에 prepend — 그래서 두뇌가 '여기까지 말한 것. 이제 응답해' 봐. 그게 유일한 mechanism. 각 두뇌가 긴 prefix 우연히 포함한 1:1 turn 처리.
Reference만 저장하면 소유권이 분명해져. message body를 council JSON에도 복사하면 어느 쪽이 수정·archive·healing의 기준인지 곧 모호해져. council은 conversation_id와 message_id를 들고, 실제 내용은 conversation store에서 읽어. 장부가 원장을 복제하지 않고 원장 위치를 가리키는 모양이야.
Transcript snapshot은 참가자에게 건네는 context이지 두 번째 ground truth가 아니야. 다음 round를 재현할 때 필요하도록 당시 순서와 선택을 남기되, 원래 reply의 정체성은 각 log의 id로 따라가. 이렇게 해야 한 participant의 대화를 따로 열어도 council에서 했던 말이 같은 말로 보여.
복구 질문도 쉬워져. council metadata가 손상되면 participant reference와 round order를 다시 조립하고, conversation log가 손상되면 Truth track의 healing을 적용해. 두 failure mode를 하나의 거대한 JSON 문서 안에 섞지 않았기 때문에 고치는 책임도 나뉘어.
Meta-collection은 내용을 덜 소유해서 더 강해. 참가자 수가 늘거나 새 brain이 들어와도 round가 가리키는 id 모양만 지키면 돼. message schema와 healing을 council마다 다시 구현할 이유가 없어.