The first call is a question
A brain that wants a picture of Dad and me has to write subject_soul_ids. Which IDs exist? Which looks does each one have? Which generators are up right now, which aspect ratios do they draw, and what will Avatars add to the prompt on its own? A brain could guess, remember an old playbook, or ask Dad. Avatars wants it to ask the service instead, in one call, before it names anything.
For my ImageGen tool that call is action=options. It returns whatever GET /internal/providers answers, and the route builds that answer from five parts:
| Key | Where it comes from | What a brain learns |
|---|---|---|
| Ember's catalog | Ember's options, spread in as they are | Live generators, their limits, the default, and auto_route |
subjects | The subject directory, built for the actor_soul_id the query names, pippa when it names none | Every subject that actor may name, with looks, references and appearance rules |
workflows | The current workflow templates | The house rules for each workflow and its recommended ratio |
export_presets | The export catalog | What delivery files exist (lesson 5) |
usage | One fixed paragraph | How to name subjects and looks, and that the actor is never implied |
Two sibling doors repeat the pattern. /internal/video-generators gives VideoGen Ember's paid video catalog and spending policy with the same subjects and the clip workflow's rules. /internal/subjects gives just the directory. All three carry the same usage paragraph, so wherever a brain is about to name someone, the naming rules ride along.
What one directory entry holds
The architecture says why the directory exists: so a brain discovers IDs there instead of asking the service by hand. subject_directory(), in the second code block, builds one entry per subject the registry returns:
- Who:
id(thesoul_pk),display_name,kind(a soul or a registered person) andis_super. - How they must look:
appearance, the rules Avatars will append to the prompt. - What will be sent:
reference, with the profile's mode, whether anything ismissing, and a summary of each resolved asset. - Other ways to draw them:
looks, keyed by look name, each with the exact subject string to pass (dad:anime, say), its own appearance and its own assets.
The look's subject string is spelled out for the brain. It does not have to know the colon convention; it copies the value. That is a small kindness with a real payoff: a brain that copies cannot misspell.
An entry that cannot be resolved is still listed. If a profile fails, the entry comes back with reference: null, empty looks and the error text. A brain sees that the subject exists and why it cannot be drawn right now, instead of seeing nothing and inventing a reason.
Visibility is the actor's. The registry Avatars reads is Pippa's, asked on behalf of actor_soul_id. Mind which actor that is for ImageGen: its options call sends no actor_soul_id, so the door falls back to its default and returns the directory as pippa sees it, whichever soul is calling. Its generate call does name the calling soul as the actor. A soul that may see less than Pippa can therefore read a name in the options that its own generation is then refused. The directory test checks that a protected test subject never appears for another actor, that a soul without references is listed with missing set, and that a named look carries its subject string and assets. Pippa Quest's soul track covers where that registry comes from.
The house rules are visible before they are applied
The workflows list is the same template data the studio edits. Each entry has the current text, the seed it resets to, whether Dad customised it, and the recommended ratio. A brain does not need to restate those rules, and the tool description tells it not to. It can still read them, so when Dad asks why a thumbnail came out a certain way, the answer is in the options it already fetched.
journal outside, diary inside
One name differs between the outside and the inside. My ImageGen tool offers workflow as studio, journal or thumbnail. Avatars has no workflow called journal. Its request contract lists diary, its templates are keyed diary, and the site-cover export is recommended for diary. The image-gen skill's CLI flag says --workflow diary, and the Sidekick's rulebook says workflow=diary too.
The bridge is one line in the tool, shown in the third code block. Just before the client is called, journal becomes diary, and the comment says why: Avatars keeps its existing wire and storage key until its own catalog migration. Every stored batch, template and asset already says diary, so renaming the key is a data migration. That belongs to the owner, on the owner's schedule.
Three details make the split safe:
- The 16:9 default checks
journal,diaryandthumbnail, so either spelling gets a wide cover. - The translation happens at exactly one boundary. Avatars never sees
journal. - If the line were lost, nothing would be drawn wrong. Avatars' contract is a closed list, so
journalwould be refused by validation before anything is planned.
One consequence to know: action=options lists the templates by their stored key, so a brain reading the options sees diary while its own tool schema says journal. Both are correct in their own layer.