The visible half of a soul had no owner
Lesson 1 says a soul is its vault, its identity file and its avatars, and that they travel together. For most of cwkPippa's life the avatars lived in the repo's avatars/ directory as plain files. A new soul's set was copied in; an emotion was regenerated by whoever was at hand and saved over the old frame. Nothing recorded which image was the original, which prompt and references made it, or what replaced what. The words of a soul had a vault with history; its face had a folder.
On 2026-09-29 that changed. cwkAvatars is now the ground truth for every avatar. Its own database holds the native originals, the reference profiles, the sets, the candidate selections and the publication history. cwkPippa's avatars/ directory holds published runtime copies only. Pippa still owns the soul registry, the super-soul policy and serving the images; she no longer authors or manages a second set of originals.
Adoption without pretending
The legacy sets were not regenerated to fit the new owner. Adoption copied the original bytes into Avatars, verified every hash, recorded a baseline publication, and attached an avatar-lineage.json manifest to each unchanged live set, naming cwkAvatars as owner and binding every frame to an immutable asset id. It does not claim the old images were newly generated, and it does not invent generation ids for them.
From then on, a changed or missing file in Pippa's copy is publication drift, and the rule is one-directional: never import such a change back as canonical art. Regenerating, editing, selecting, restoring and publishing all happen in Avatars, and a reviewed publication installs a complete snapshot while keeping a verified backup of the copies it replaced. If Avatars is offline, the existing copies keep working. The boundary was widened twice in the same week: guest placeholders stay outside published copies, and registered people, not only souls, sit inside the authority boundary.
Pictures, clips and music through gateways
The frontend track's binder lesson said heavy organs leave the body: voice went to Bellows, image generation to Ember. In the same days the avatars moved, those organs grew a gateway layer.
- Images. Every brain's
ImageGenruns one executor, and its download path goes through the cwkAvatars gateway: Avatars resolves who appears (each registered soul's reference profile), the references and the workflow's house rules, then asks Ember, which generates and keeps the canonical records. The default isprovider=auto, Ember's own published route; a provider is named only when Dad chooses one. Every result states the exact prompt, each reference with the absolute path of its original, and where the output was saved. - Clips.
VideoGenasks Avatars' clip workflow, which resolves the cast from the reference profiles and asks Ember's video model; Ember's spending policy decides what runs at once (up to 20,000 credits) and what waits for Dad, and a refused request spends nothing and returns the plan so the brain can ask. Which video provider to use at all is a separate route Dad set as a principle: Higgsfield first, ElevenLabs second when credits run short, Ember last. - Music.
MusicGencomposes through Bellows, which owns the ElevenLabs account; a track is its own file, never mixed into a clip.
Both new tools are volatile for the stateful resume guard: after an interrupted turn, the retry must first read what the interrupted turn saved before it may call either tool again, so it sees a clip that was already made before it asks for another. That is a guard, not a receipt. A second VideoGen call that does not carry the earlier request_id is a new request, and it is charged as one. A clip plays inline through a loopback relay from Avatars, byte range by byte range, so it needs no public URL. And media in the chat never starts by itself: a reload re-renders every part, so stored autoplay is not honored (Dad, 2026-09-30).