A council is one JSON file in <app-data>/councils/. It holds the seats, each participant with a slot_id like p1, a stable participant_id, a soul, and a brain; the mode and preset labels; and the rounds. A round records its type (broadcast to every seat, or point to one), Dad's prompt (an empty string means he stayed silent), and one turn per seat that answered, each keyed by seat and pointing at a conversation id and message ids. A picked answer and a finalized timestamp close the council out.
Rounds form a tree, not a list. Editing an earlier prompt or re-rolling a round makes a sibling branch, the same way editing a message forks a 1:1 chat, so every round records the round it branched from.
What it doesn't store
The answers themselves. Every answer lives in an ordinary conversation, in the same store and with the same JSONL ground truth as any 1:1 chat. A seat does not keep one conversation for the whole council: each turn starts a fresh conversation for that seat (the table reaches the seat through the addendum below, never through that conversation's history), the turn records its conversation id, and the council's map from participant to conversation points at the seat's latest one. Two seats on the same brain never share a conversation: same-brain × N must never collapse into one log.
Storing references only keeps ownership clear. Copy the message bodies into the council JSON too, and it soon gets murky which copy edits, archive, and healing should trust. Council holds conversation_id and message_id and reads content from the conversation store: a ledger that points at the original instead of copying it.
How the table reaches each seat
When a round runs, the orchestrator calls each seat's brain through its canonical chat route with two separate parts. The user message is only what Dad just said or, when he stays silent, a one-line floor signal. Everything about the table rides a system-only addendum: who this seat is and who else is at the table; private routing metadata (the council id, the round's position, the seat's ids) for tools and memory, never for the visible answer; and the whole conversation so far on the active branch.
The addendum is sent and never persisted, so each child conversation reads exactly like a 1:1: Dad said this, I answered that.
Recovery splits along the same line. If council metadata breaks, rebuild the seat references and round order; if a conversation log breaks, the Truth track's healing applies. The two failure modes never share one giant JSON document, and neither does the job of fixing them.
A meta-collection is stronger for owning less. Add seats or a new brain, and only the shape of the ids a round points at has to hold. Nothing about message schema or healing gets reimplemented per council.