Repository navigation
refactor(core)!: trim the plugin protocol and standardize on register_handlers (#487 part 2, #451) - #569
Merged
mlieberman85 merged 4 commits intoOct 8, 2026
Conversation
…e handler hook (darnitdevorg#487, darnitdevorg#451) ComplianceImplementation keeps only name, display_name, version, spec_version and get_framework_config_path. get_all_controls, get_controls_by_level, get_rules_catalog, get_remediation_registry and register_controls move to Appendix C: no production path called the first four, and register_controls was required to be a no-op. Section 6.4 names register_handlers() as the handler registration hook, accepts register_sieve_handlers() only for compatibility, and notes that import-time registration works but cannot be introspected. Section 12 points at it. Version 1.0.0-alpha.16. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
…arnitdevorg#487) BREAKING CHANGE: ComplianceImplementation no longer declares get_all_controls, get_controls_by_level, get_rules_catalog, get_remediation_registry or register_controls, and the framework no longer calls register_controls(). Controls, SARIF rules and remediations come from the framework TOML. Plugins that still define the methods are discovered as before; the methods are not called. Removes the methods from every in-tree implementation (baseline, csl, example, gittuf, hello, reproducibility) together with the Protocol, since discovery checks isinstance() against it. darnit-example also loses the _RULES catalog, remediation/registry.py and the empty controls package that only fed them. Implementation tests that read controls through get_all_controls now load the framework TOML with load_controls_from_framework. New tests show a plugin with and without the removed methods both pass discovery, and one without get_framework_config_path does not. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
…plugin (darnitdevorg#451) register_handlers() is the one handler hook (framework-design 6.4): - darnit-gittuf and darnit-reproducibility rename register_sieve_handlers to register_handlers, and their register() entry points no longer register handlers as a side effect of discovery. - darnit-example folds its step types into register_handlers. - darnit-csl stops registering csl_llm_if_present at package import and registers it from register_handlers; register_implementation_handlers and the strict loader already call the hook on every audit and load. - darnit-hello gains register_handlers as a documented no-op. discovery still calls register_sieve_handlers, now documented as a compatibility shim for out-of-tree plugins. Tests cover a plugin with only the old name, the csl step type after a registry reset, and that every in-tree plugin defines only register_handlers. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
…col (darnitdevorg#487, darnitdevorg#451) CHANGELOG: BREAKING bullets for the removed ComplianceImplementation methods (Removed) and for register_handlers() as the one handler hook (Changed). CLAUDE.md, ARCHITECTURE.md, the darnit README, IMPLEMENTATION_GUIDE, packaging-plugins, HANDLER_AUTHORING, the getting-started pages, the tutorial, the example-plugin spec and the reproducibility design sketch now show the five-member protocol and register sieve step types in register_handlers(), with register_sieve_handlers() described as a compatibility shim and import-time registration as not introspectable. IMPLEMENTATION_GUIDE section 7 no longer describes the Python REMEDIATION_REGISTRY that only get_remediation_registry() read. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
Merged
7 of 12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Part 2 of #487, plus #451. Both change the same plugin classes, the
darnit-hellotemplate and the plugin-author docs, so they're in one PR as separate commits. Spec first.#487: trim
ComplianceImplementation. Five protocol methods had no production caller:get_all_controlsandget_controls_by_level: only called by the implementations themselves;get_rules_catalogandget_remediation_registry: no callers;register_controls: called behindhasattr, and a no-op in every implementation.Controls, SARIF rules and remediations come from the framework TOML. This PR removes the methods from:
hasattrcall sites;The Protocol is
@runtime_checkableand discovery checks it withisinstance, so dropping members only loosens that check. A third-party plugin that still defines the old methods is still discovered. A new test covers both a plugin with the legacy methods and one without them. The protocol is nowname,display_name,version,spec_versionandget_framework_config_path, plus the optionalregister_handlers().#451: one handler-registration hook.
register_handlers()is the protocol hook. gittuf and reproducibility renameregister_sieve_handlers, and darnit-example drops its duplicate. Theirregister()functions no longer register handlers as a side effect of discovery; the framework calls the hook itself.register_handlers(), so a registry reset no longer loses its step type (new test).register_handlers()to show the shape.core/discovery.pystill callsregister_sieve_handlersfor out-of-tree plugins, with a comment that it's kept for compatibility and isn't a supported choice. A new test checks that a plugin with onlyregister_sieve_handlersstill registers.Spec:
framework-design.md§6 has the trimmed protocol, and §6.4 names the hook. Appendix C gets a "Removed" entry. Version 1.0.0-alpha.16.Closes #451
Refs #487
Type of Change
Framework Changes Checklist
docs/architecture/framework-design.md) if behavior changeduv run python scripts/validate_sync.py --verboseand it passesTesting
uv run pytest tests/ -v): 5150 passed, 26 skipped (main: 5148)uv run ruff check .)Also run:
darnit audit .with-f reproducibility,-f gittufand-f community-spec: each plugin's own step types run, and none is reported as unregistered;create_server: each registers its plugin's step types;plugin_discovery_smokechecks from CI, run locally against darnit-hello: pass.AI assistance
Claude (Claude Code, claude-opus-5-5) made this change: spec, code, tests and docs. This description was also drafted with Claude. Commits carry an
Assisted-by: Claude:claude-opus-5-5trailer.Additional Notes
Left for later:
server/factory.pyhas its own copy of the handler-registration helper, which calls onlyregister_handlers. Audits register throughregister_implementation_handlers, so this has no effect in practice, but the factory could delegate to it.core/plugin.pycomment block listsget_check_handlers,get_context_handlersandget_remediation_handlers, which nothing calls.darnit-helloand some guide snippets still usePath(__file__)rather thanimportlib.resources(feature 021). The CLAUDE.md example now usesimportlib.resources.darnit-exampleintodarnit-testchecks) is next.🤖 Generated with Claude Code