Skip to content

feat(plugins): enforce dialog-vtable contract at plugin load time#77

Merged
facontidavide merged 1 commit intodevelopmentfrom
feature/dialog-vtable-load-check
Apr 29, 2026
Merged

feat(plugins): enforce dialog-vtable contract at plugin load time#77
facontidavide merged 1 commit intodevelopmentfrom
feature/dialog-vtable-load-check

Conversation

@facontidavide
Copy link
Copy Markdown
Contributor

Summary

  • A plugin that advertises kCapabilityHasDialog / kToolboxCapabilityHasDialog but doesn't export a usable dialog vtable is buggy. Previously the host catalog accepted such plugins silently and the violation only surfaced at dialog-show time (by which point the user is staring at garbled curves with no diagnostic).
  • PluginRuntimeCatalog now calls resolveDialogVtable() during loadAndRegister{DataSource,Toolbox} when the capability bit is set, and refuses to register the plugin if resolution fails. The reason is reported through the existing DiagnosticSink as kError, so the marketplace UI can show the plugin as broken.
  • Downstream hosts (e.g. PJ4's DialogPresenter) can keep a runtime contract-violation path as defense-in-depth against ABI drift or hot-loaded plugins that bypass the catalog.

Test plan

  • Clean build, 52/52 tests pass
  • Add a unit test fixture that exercises the new rejection path: a DSO advertising the cap bit but omitting PJ_get_dialog_vtable, asserting kError emitted via DiagnosticSink + plugin absent from the loaded set (flagged as a follow-up; not blocking)

🤖 Generated with Claude Code

A plugin that advertises kCapabilityHasDialog (DataSource) or
kToolboxCapabilityHasDialog (Toolbox) but doesn't export a usable
dialog vtable is buggy. Previously the host catalog accepted such
plugins silently, and downstream consumers had to discover the
violation at use time — by which point the user is staring at
garbled curves with no diagnostic.

Move the check upstream: PluginRuntimeCatalog now calls
resolveDialogVtable() during loadAndRegister{DataSource,Toolbox}
when the capability bit is set, and refuses to register the plugin
if resolution fails. The reason (e.g. "PJ_get_dialog_vtable returned
null", "Dialog protocol version mismatch") is reported through the
existing DiagnosticSink as kError, so the marketplace UI can show
the plugin as broken.

The PJ4 host (`pj_app/src/DialogPresenter.cpp`) keeps its runtime
contract-violation path as defense-in-depth: any future ABI drift
between scanner and runtime, or a hypothetical hot-loaded plugin
that bypasses the catalog, still produces a sane error rather than
silent garbage.

Verified: clean build, 52/52 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@facontidavide facontidavide merged commit b05c096 into development Apr 29, 2026
2 checks passed
@facontidavide facontidavide deleted the feature/dialog-vtable-load-check branch April 29, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant