The keyword list's own actions, each one undo step:
- create a keyword with its attributes, and tag photos with it at once;
one that exists already (listed or on a photo) is refused;
- move a keyword (with those below it) inside another or to the top
level; never inside itself or its children, and onto a name that is
taken only when merging is allowed (`CatalogError::KeywordExists`
otherwise, so the UI can ask);
- edit: rename its last level and set its attributes together; a taken
name is refused, merging being its own action;
- purge: take off the list the keywords no photo has.
Typed in any case, keywords keep the spelling the library has
(`keyword_path`).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>