41 lines
2.1 KiB
Markdown
41 lines
2.1 KiB
Markdown
# Keyed load-once hooks have durable host receipts
|
|
|
|
Plugin `Load` callbacks are deliberately repeatable: startup, enable, update,
|
|
and provisioning-consent replay can all invoke them. Some initialization is
|
|
different. A plugin may add a suggested menu link on its first load, but must
|
|
not restore that link after an administrator later removes or renames it.
|
|
|
|
Decision: `PluginRegistration.LoadOnce` is an ordered slice of callbacks with
|
|
stable keys. DESCRIBE publishes those keys in `PluginManifest.load_once_keys`.
|
|
The host checks a durable `(plugin, key)` receipt before dispatching
|
|
`HOOK_LOAD_ONCE`; it records the receipt only after success. A completed key is
|
|
not removed when the plugin is disabled, updated, or uninstalled. A later
|
|
release that intentionally needs another one-time action declares a new key.
|
|
|
|
Load-once runs after the ordinary `Load` hook so repeatable provisioning can
|
|
create resources that a one-time callback references. Keys are lowercase,
|
|
MCP-style stable identifiers of at most 128 bytes and must be unique within a
|
|
registration. Failed callbacks may be retried because no completion receipt
|
|
exists. As with database migrations, callbacks should still make their own
|
|
external mutation idempotent to cover a process failure between the mutation
|
|
and receipt commit.
|
|
|
|
Encoding first-install booleans in plugin settings was rejected because it
|
|
mixes host lifecycle state with customer-visible configuration. Making all
|
|
provisioner operations one-shot was rejected because pages, settings defaults,
|
|
and other declarations intentionally reconcile on every load. Version-based
|
|
execution was rejected because an unrelated release must not repeat the side
|
|
effect.
|
|
|
|
Consequences:
|
|
|
|
- Native and WASM plugins share one keyed lifecycle abstraction.
|
|
- The host, not guest memory, owns durable completion state.
|
|
- Updating or re-enabling a plugin cannot recreate an administrator-removed
|
|
resource under an already completed key.
|
|
- Changing a key is an explicit request to run a new callback once.
|
|
|
|
Keywords: PluginRegistration.LoadOnce, LoadOnceHook, load_once_keys,
|
|
HOOK_LOAD_ONCE, durable receipt, first load, plugin update, idempotency,
|
|
one-time provisioning, lifecycle
|