Fix stack-dependent related_integrations.version export#6208
Conversation
…tions Replace find_least_compatible_version with find_compatible_version_range so prebuilt rules export the same related_integrations.version across stack backports. Bump version.lock for rules whose export changes.
Bug - GuidelinesThese guidelines serve as a reminder set of considerations when addressing a bug in the code. Documentation and Context
Code Standards and Practices
Testing
Additional Checks
|
…tions Replace find_least_compatible_version with find_compatible_version_range so prebuilt rules export the same related_integrations.version across stack backports. Bump pyproject.toml patch version. Resolves #5601
There was a problem hiding this comment.
Pull request overview
This PR makes related_integrations.version exports stack-invariant by replacing single stack-dependent compatibility anchors with an OR’d compatibility range derived from integration manifests.
Changes:
- Adds
find_compatible_version_rangeand supporting helpers for manifest-derived compatibility ranges. - Updates rule export conversion to use the new range and union policy templates across selected anchors.
- Replaces related integration tests and bumps the package version to
1.6.44.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
detection_rules/integrations.py |
Adds the new compatibility range computation and removes the old least-compatible helper. |
detection_rules/rule.py |
Uses the new range API when populating related_integrations. |
tests/test_integrations.py |
Updates unit tests for the new range behavior. |
pyproject.toml |
Bumps the project version. |
Iterate all majors overlapped by parsed Kibana bounds, derive legacy stack walk versions from manifest range floors instead of 8.19.0, remove a dead aligned-major branch, and drop RST-style double backticks in new docstrings.
…e-in-security_detection_engine-package-versions
Walk every stack major whose band intersects a bounded Kibana clause (e.g. >=8.12.0 <9.1.0 includes major 9) and pick the earliest compatible stack point within a major for the legacy least-compatible walk.
| effective_stack_majors = sorted( | ||
| stack_major for stack_major in stack_majors if stack_major >= max(stack_majors) - 1 | ||
| ) |
| for lo, hi in _parse_kibana_range(version_requirement): | ||
| majors_to_check: list[int] | ||
| if hi is None: | ||
| majors_to_check = [lo.major] |
There was a problem hiding this comment.
For this if check:
fix(integrations): tighten stack-major overlap and anchor resolution
Walk every stack major whose band intersects a bounded Kibana clause
(e.g. >=8.12.0 <9.1.0 includes major 9) and pick the earliest compatible
stack point within a major for the legacy least-compatible walk.
I don't think any of our manifests include a situation where hi is None unless one were to have a manifest with an unbounded range (e.g. ">=8.12.0"). Fine to have this check, but given this I am not sure that this functions as intended.
For the case with an unbounded range majors_to_check only will have [8] and not any other stack majors. Not sure if this accomplishes the goal.
Whereas for the case in the note, it correctly has multiple stack versions to check.
| package: str, | ||
| packages_manifest: dict[str, Any], | ||
| ) -> CompatibleVersionRange: | ||
| """Return a stack-invariant OR'd caret range for related_integrations.version. |
There was a problem hiding this comment.
Nit. Should this doc string be updated to fit the existing format? Short one sentence doc string with more detail in separate comment?
| second = find_compatible_version_range("pkg", manifests) | ||
| self.assertEqual(first, second) | ||
|
|
||
| def test_single_major_appends_forward_anchor(self): |
There was a problem hiding this comment.
Nit. Akin to https://github.com/elastic/detection-rules/pull/6208/changes#r3325352838, if the goal is to support unbounded upper ranges like ">=8.12.0" should we include a test for that? The hi is none branch?
eric-forte-elastic
left a comment
There was a problem hiding this comment.
One main comment and a few nits. Otherwise LGTM 👍
Generally this PR is low risk, as the updated version computation logic in effect is not used in other workflows (like schema validation, etc.). Additionally, Kibana validates this to be a NonEmpty string just like we do in our dataclasses. (ref), so we have considerable freedom in what we populate it with.




Issue link(s): Resolves #5601
Summary - What I changed
find_least_compatible_versionpicked a single^X.Y.Zanchor from the build stack, so the same rule id shipped differentrelated_integrations.versionstrings on 8.19 vs 9.x backports while the prebuilt ruleversioninteger stayed the same.This replaces that with
find_compatible_version_range, which emits a stack-invariant OR range from integration manifests (for example^8.2.0 || ^9.0.0 || ^10.0.0for endpoint).policy_templatesare unioned across manifest anchors instead of parsing the OR string.Performance: the new path resolves more stack lines per package. Informal local timing was roughly 2 to 9x median vs the old function on
endpoint/aws/windowsmanifests, still sub-10ms per call and once per rule at package build. Not expected to movebuild-releasewall time in a meaningful way.How To Test
Spot check export: rule
8d366588-cbd6-43ba-95b4-0971c3f906e5should show^8.2.0 || ^9.0.0 || ^10.0.0for endpoint on every release line.Export toml and import into kibana to ensure it applies successfully.
20260528T154018L.ndjson.txt
Backport validation: cherry-pick this PR onto each release branch (or apply the four changed files from
73c07800d), then run the same pytest commands. Noversion.lockchanges required for that pass.Backport `8.19` (origin/8.19 + PR code)
Backport `9.2` (origin/9.2 + PR code)
Backport `9.3` (origin/9.3 + PR code)
Backport `9.4` (origin/9.4 + PR code)
Checklist
bugmeta:rapid-mergelabel if planning to merge within 24 hours