Two owners for one row
Every class in Sizzle has a status of proposed or adopted. A proposed class is Pippa's current understanding of something. An adopted class is Dad's. The difference decides one question that comes up on every reading: when Pippa describes a known class again, in different words, whose words stay?
The answer lives in a nine-line function called _refresh, and its docstring says the whole rule. A proposal is Pippa's current understanding, so a newer reading rewrites its description, a new rubric's voice included. An adopted class is Dad's and keeps its words.
What a newer reading may rewrite
During integrate, _refresh is called from three places, each with its own list of fields:
| Where | Fields refreshed while the class is proposed |
|---|---|
| A principle the reading resolved | summary, why, roles, method |
| A dish the reading found on the plate | gloss, cuisine, summary (Pippa's evidence from this plate), bindings |
| A sibling mentioned again, only if it began as a sibling | gloss, cuisine, summary (the new why_same) |
Three details make the rule safe. An empty value never overwrites a field, because the filter keeps only values that are present and different. A variant is never refreshed at all: _resolve_dish only refreshes a class whose kind is dish, and a variant is born adopted anyway. And name is in none of the lists. Even while a class is still Pippa's proposal, a reading cannot rename it. A class keeps the name it was born with until Dad renames it.
Every change goes through revise_class, which records a class.revised event. The journal therefore keeps every version of a proposal's description, in order, even though the class page shows only the newest.
Three doors into Dad's tree
A proposal becomes Dad's through exactly three doors, all of them his:
- Adopt. The "Adopt into my tree" button records
class.adopted. - Rename.
class.renamedsets the new name and the statusadoptedin the same update. Naming a thing is taking it. - Tie a plate. When Dad links a plate to a class himself,
linkrecords the link withsource: "dad"and thenclass.adoptedif the class was not adopted yet.
A variant skips the doors because Dad derived it, so it is born adopted with origin: "dad". In a conversation, Pippa can suggest any of the three as a typed action, and nothing happens until Dad presses the button (Track 6 covers that boundary). What never adopts anything is a reading. Its own link carries source: "reading" and changes no status, so a sibling Dad has eaten ten times is still a proposal until he says otherwise. Evidence and adoption are separate axes.
When the voice itself changed
The rule earned its docstring on Sizzle's first day. After the first real plate, Dad read the analysis and said:
plate에 나오는 분석은 피파 말투가 아니야. 이상해.
The analysis on the plate isn't in Pippa's voice. It's strange.
Rubric v2 told the reading to speak in Pippa's own 반말, and the bump re-read every plate. Through _refresh, each re-read rewrote in the new voice the description of every still-proposed class it named. Any class Dad had adopted would have kept the words he adopted. Nobody had to write a migration for the tree. The words followed the rubric exactly as far as Pippa owned them.
The engine test pins both halves. It re-reads a plate with a newer why for the principle and sees the proposal take it. Then it adopts the principle, re-reads with yet another why, and sees the adopted words survive.
One edit box away from a gap
The class route, PATCH /api/classes/{class_id}, accepts description fields such as summary and why as well as verdict and parameters, and it does not adopt. Both clients only ever send verdict and parameters, and no reading touches either of those, so nothing is lost today. If you add an edit box for a proposal's summary, though, the next reading that names that class would overwrite Dad's edit. In your own version, make a human edit to a refreshable field adopt the record, or move that field out of the refresh list.
The oo-quest's Track 9 is about a mold that hardens into a cage. Proposals in Sizzle stay soft on purpose: Pippa keeps reshaping them with each plate, and nothing sets until Dad's hand does it.