Skip to content

v0.7.0: Application identity gating

Choose a tag to compare

@astrapi69 astrapi69 released this 19 May 11:19
· 46 commits to main since this release
bfacced

For full design rationale, see docs/design/v0.7.0-application-identity.md.

Application identity release. Plugins can declare which host application they target; hosts can declare their own identity to validate plugin claims.

Added

  • BasePlugin.target_application: str | None = None attribute. Plugins declare the host application identifier they target (e.g. "bibliogon", "adaptivlearner"). None means "not declared."
  • PluginManager(app_id: str | None = None) constructor parameter. Hosts declare their application identifier. When set, plugin target_application declarations are validated against this value.
  • FilterReason extended with "wrong_application". Plugins whose target_application mismatches the host's app_id are filtered with this reason at activation.
  • ErrorPhase extended with "identity_check". New phase for identity-related diagnostics, sibling to version_check.
  • v0.7.0 deprecation warning path: plugins that have not declared target_application produce a PluginError(phase="identity_check", severity="warning") recorded in DiscoveryResult.errors and logged via logger.warning. Plugin still activates. The warning fires regardless of whether the host has adopted app_id, to nudge plugin authors during the deprecation cycle. Warning stops in v0.8.0 steady state.

Changed

  • DiscoveryResult.errors semantic widening: previously contained only severity="error" entries (every entry implied a filtered plugin). Now also contains severity="warning" entries from the identity deprecation path (entries do not imply filtering). Consumers iterating result.errors without filtering on severity should re-check their assumptions: render with severity == "error" to preserve previous behavior, or render warnings in a separate visual treatment. The type contract (list[PluginError]) is unchanged; only the operational meaning is widened.

Migration notes

  • DiscoveryResult.errors semantic widening (see Changed). New behavior may surprise consumers iterating the list without severity filtering. Adapt by filtering on severity == "error" for the previous error-only behavior, or by computing failure counts as len(states) - len(activated) rather than len(errors).

  • Plugin authors: declare target_application on your BasePlugin subclasses with the host application's identifier (e.g. target_application = "bibliogon"). In v0.7.0, plugins without target_application emit a deprecation warning but still activate. In v0.8.0, plugins without target_application will be filtered with FilterReason.missing_target_application when the host has adopted app_id. The v0.7.0 deprecation warning text, surfaced both in DiscoveryResult.errors[].user_facing_message and in the logger.warning log line:

    Plugin 'X' does not declare target_application. Hosts adopting app_id in v0.8.0 or later will filter this plugin. Authors should add target_application to remain compatible with identity-aware hosts.

  • Host application owners: pass app_id to PluginManager(app_id="my-app") to enable identity gating. Plugins whose target_application matches app_id activate normally; mismatches refuse activation with FilterReason.wrong_application. Without app_id, identity is not validated and behavior is identical to v0.6.x. This mirrors the v0.6.0 min_app_version / app_version pattern explicitly: a plugin's identity claim is enforced only when the host opts in by declaring its own identity. A host can run all of v0.6.x, v0.7.0, and v0.8.0 without ever adopting app_id, and continue to load plugins as it always has. Identity protection is available, not mandatory.

  • Identifier format: free string, lowercase-kebab-case recommended (e.g. bibliogon, acme-knowledge-base). Reverse-domain notation and a central registry are deferred as open questions in the design doc.