"Every trigger resolves this data; neither visibility nor hotkeys own dispatch." — the doc comment on CommandBinding
The Shape of a Command
A CommandBinding has four fields: a stable id (the thing a link or the app door names), a human name, an operation, and an optional hotkey. The operation is a five-case enum: toggle, apply or restore a preset by ID; run one capability step directly; or release everything. That is the entire vocabulary a trigger can speak. A key chord, a URL and an app-door call name a saved command; a menu item names its preset directly. Either way they end in the same place — one of these operations handed to the same run() — and the engine never needs to know which door the request came through.
Presets Are Data Too
A Preset is an ID, a name and a list of CapabilitySteps, each naming a capability ID and its JSON input. The editing preset is one step, applications.hide with a list of bundle IDs. Nothing about "editing" or "Final Cut" lives in code; the words exist only in Dad's settings file. That is what lets Settings, the app door's preset.save and a hand-edited JSON file all change behaviour without a rebuild — and what makes the Configuration tab honest when it says "All capabilities, presets and command bindings are data."
Validation Is Part of the Data
Because anyone can write the document, Configuration.validate is strict. Schema version 1 only. Preset and command IDs unique. IDs limited to ASCII letters, digits, dot, underscore and hyphen, at most 120 characters — safe to put in a URL path and a journal owner name. Every preset needs a name and at least one step; every step must name a registered capability; every preset command must point at a preset that exists. Settings then asks each capability to validate each step's input. A document that fails is refused with the reason; the saved file is left as it was.
From Command to Plan
When a command runs, the app model turns its operation into a small plan: which journal owner it concerns (preset/edit or command/applications.hide), which steps, whether it is applying or restoring, and the subject's name for the status line. Toggle decides its direction by asking the journal whether that owner is active — not by remembering what it did last — so a toggle stays correct after a relaunch, a recovery or a change made through another door.
Edits Under an Active Preset
One rule protects the journal from the settings: a preset that is currently applied cannot be changed. Saving a configuration whose version of that preset differs is refused with "Restore … before editing it." The receipts would still undo correctly — they never read today's preset — but a preset whose list changes while it is active is a preset whose toggle no longer describes what it will do.