GenericCompliance is the documented last-resort renderer, but it read the
universal attribute fields (Section, SubSection, SubGroup, Service, Type,
Comment) directly and raised AttributeError on frameworks whose schema does
not declare them (CIS, ENS, ISO27001), dropping the whole compliance CSV.
Read all six fields with getattr defaulting to None, and dedupe the finding
and manual rows into a single helper.
Resolve the provider<->models import cycle CodeQL flagged (py/cyclic-import
#7267, #7268). provider.py no longer imports models: get_output_options
stays override-only and __main__ falls back to a new default_output_options
helper in models.py when a provider does not implement it. models.py keeps
its original module-level Provider import (one-way, no cycle).
External providers that do not override get_summary_entity no longer cause
the summary table to be silently dropped. The base contract returns
(self.type, account_id), mirroring the get_output_options default.
Move the models.py Provider import (used only in the shodan path) to a
local import so models no longer depends on provider at module level. This
breaks the provider <-> models import cycle CodeQL flagged after the
generic OutputOptions default was added, and lets provider.py import
ProviderOutputOptions without a cycle. The output_file_timestamp import is
consolidated into the existing top-level config import.
External providers that do not override get_output_options no longer abort
the run with NotImplementedError. The base contract returns a generic
ProviderOutputOptions, honoring arguments.output_filename and otherwise
falling back to a provider-typed filename. Built-ins are unaffected.
- Compare the module's last dotted segment instead of substring
- Prevent a provider name from capturing overlapping built-ins
- Add parametrized regression test (cloud, git, work, open cases)
- Update get_bulk test mock to the real dotted module name
- Match shadowing entry point by name instead of calling ep.load()
- Prevent plug-in code from executing during a built-in run
- Update regression test to assert ep.load is never called
- Short-circuit on is_builtin_provider before loading entry points
- Prevent same-name plug-ins from flipping a built-in onto the tool-wrapper path
- Avoid executing plug-in code via ep.load() for built-in names
- Add regression test asserting ep.load is never called
- Add okta, scaleway, stackit to known_providers so they no longer
appear as dynamically-discovered "extra" providers
- Fix missing comma in usage string (stackitvercel -> stackit,vercel)
- Move "external/custom providers" (Added) and namespaced-config unwrap
(Fixed) out of the released 5.26.0/5.25.0 blocks
- Remove the duplicated Fixed section left in 5.25.0
- Azure/Cloudflare set per-finding mutelist args inside the loop;
the external else-branch was overwriting them
- Use is_builtin_provider to scope get_mutelist_finding_args to
truly external providers