"Everything a transformation is — its name, its instruction, its trigger, its appetite for context — fits in one small record."
The Whole Transformation in One Record
A FlintMacro is a small value type that holds everything needed to run one transformation and nothing else. A stable id. A human name. The prompt template that defines what it does, with an {input} slot for the selection. Whether it's enabled. An optional chord. Its vault-context mode. When it was created. That's the entire object. There's no model, no state, no history hiding in it — a macro is a description of an intent, not an engine.
Why the UUID Is Stable
The id is a UUID assigned once, at creation, and never changed — not when the user renames the macro, not when they rebind its chord, not when they edit the template. That stability is what lets everything else refer to the macro safely: the hotkey center keys its registration by this id, the palette lists by it, and a rebind is 'unregister id, register id with new keys' rather than 'destroy and recreate.' A name can change and a chord can change, but the identity underneath stays fixed.
id : fixed forever (the true identity)
name : editable (what the human calls it)
template : editable (what it actually does)
hotkey : editable (how it's triggered)
vaultMode : editable (how much context it needs)
Everything mutable hangs off one immutable id.
A Value Type, Codable
Because a macro is just data, it's a Codable value type, and persistence is trivial: encode the list to a local JSON file Flint owns, decode it on launch. No database, no migration engine, no sync — a small array of small records in a file. The simplicity is deliberate and it's a feature: a macro store you can open, read, and understand as plain JSON is a macro store you can trust and debug.