This is an automated email from the ASF dual-hosted git repository.

FreeOnePlus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-mcp-server.git


The following commit(s) were added to refs/heads/master by this push:
     new 5daf1de  fix: preserve version brand provenance (#218)
5daf1de is described below

commit 5daf1deb26bc0db02c19bf5ca1d070acea4cfab9
Author: Yijia Su <[email protected]>
AuthorDate: Fri Aug 14 00:22:43 2026 +0800

    fix: preserve version brand provenance (#218)
---
 CHANGELOG.md                                   |  4 +++
 doris_mcp_server/tools/capability_detector.py  |  4 ++-
 doris_mcp_server/tools/doris_feature_matrix.py | 45 +++++++++++-------------
 doris_mcp_server/tools/doris_version.py        | 15 +++++---
 test/tools/test_capability_detector.py         | 47 ++++++++++++++++++++++++++
 test/tools/test_doris_feature_matrix.py        | 19 +++++++++++
 test/tools/test_doris_version.py               | 19 +++++++++++
 7 files changed, 123 insertions(+), 30 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 852778c..6b5363d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -69,6 +69,10 @@ under **Unreleased** until a new version is selected and 
published.
 
 ### Fixed
 
+- Preserved fail-closed distribution provenance across version parsing,
+  brandless FE/BE component fallback, and certification evidence validation,
+  preventing unknown or mismatched brands from inheriting Apache Doris
+  certification.
 - Updated the locked Marshmallow and Virtualenv transitive dependencies to
   releases that address CVE-2025-68480 and symlink-based TOCTOU vulnerabilities
   in development-environment creation.
diff --git a/doris_mcp_server/tools/capability_detector.py 
b/doris_mcp_server/tools/capability_detector.py
index 88c35be..765b6a3 100644
--- a/doris_mcp_server/tools/capability_detector.py
+++ b/doris_mcp_server/tools/capability_detector.py
@@ -2450,7 +2450,9 @@ def _component_version(
     # Brandless component builds (for example "4.0.6" or "4.0.6-abc1234")
     # carry no brand of their own; inherit the cluster brand observed in
     # @@version_comment so distribution provenance is not lost.
-    brand = default_brand or "doris"
+    if default_brand is None:
+        return parsed
+    brand = default_brand
     return parse_doris_version_comment(f"{brand} version {brand}-{raw}")
 
 
diff --git a/doris_mcp_server/tools/doris_feature_matrix.py 
b/doris_mcp_server/tools/doris_feature_matrix.py
index 9e93ab4..b19659d 100644
--- a/doris_mcp_server/tools/doris_feature_matrix.py
+++ b/doris_mcp_server/tools/doris_feature_matrix.py
@@ -462,29 +462,19 @@ class PatchCertificationEvidence(ContractModel):
             *self.backend_version_comments,
         )
         for comment in comments:
-            if self.brand == "doris":
-                observed = parse_doris_version_comment(comment)
-                if (
-                    not observed.is_parsed
-                    or observed.core != target_literal
-                ):
-                    raise ValueError(
-                        "every certified FE and BE must report the Doris core "
-                        f"version {target_literal}"
-                    )
-            else:
-                # Distribution evidence is validated without relying on the
-                # runtime brand registry: the comment must carry the declared
-                # brand token and the certified three-part core version.
-                if not _distribution_comment_matches(
-                    comment,
-                    brand=self.brand,
-                    core=target_literal,
-                ):
-                    raise ValueError(
-                        f"every certified FE and BE must report the 
{self.brand} "
-                        f"core version {target_literal}"
-                    )
+            # Evidence validation is independent of the mutable runtime brand
+            # registry. Every comment must carry the exact declared brand and
+            # three-part core version before it can certify that distribution.
+            if not _certification_comment_matches(
+                comment,
+                brand=self.brand,
+                core=target_literal,
+            ):
+                display_brand = "Doris" if self.brand == "doris" else 
self.brand
+                raise ValueError(
+                    f"every certified FE and BE must report the 
{display_brand} "
+                    f"core version {target_literal}"
+                )
 
         expected_cases = {
             ("stdio", "hierarchical"),
@@ -990,7 +980,7 @@ def _ordered_unique(values: Iterable[object]) -> tuple[str, 
...]:
     return tuple(dict.fromkeys(str(value) for value in values))
 
 
-def _distribution_comment_matches(
+def _certification_comment_matches(
     comment: str,
     *,
     brand: str,
@@ -998,11 +988,16 @@ def _distribution_comment_matches(
 ) -> bool:
     """Match one evidence brand and core without the mutable alias registry."""
     escaped_brand = re.escape(brand)
+    leading_brand = (
+        rf"(?:apache\s+{escaped_brand}|{escaped_brand})"
+        if brand == "doris"
+        else escaped_brand
+    )
     escaped_core = re.escape(core)
     pattern = re.compile(
         rf"""
         (?<![A-Za-z0-9_])
-        {escaped_brand}
+        {leading_brand}
         (?:\s*,?\s*version)?
         (?:\s+{escaped_brand}-|\s*-\s*|\s+)
         {escaped_core}
diff --git a/doris_mcp_server/tools/doris_version.py 
b/doris_mcp_server/tools/doris_version.py
index fbd192b..866c6e9 100644
--- a/doris_mcp_server/tools/doris_version.py
+++ b/doris_mcp_server/tools/doris_version.py
@@ -47,14 +47,16 @@ _known_brands: tuple[str, ...] = (_DEFAULT_BRAND,)
 
 
 def _compile_version_pattern(brands: tuple[str, ...]) -> re.Pattern[str]:
-    brand_alternatives = "|".join((r"apache\s+doris", *brands))
-    prefix_alternatives = "|".join(brands)
+    brand_alternatives = "|".join(
+        (r"apache\s+doris", *(re.escape(brand) for brand in brands))
+    )
+    prefix_alternatives = "|".join(re.escape(brand) for brand in brands)
     return re.compile(
         rf"""
         (?<![A-Za-z0-9_])
         (?P<brand>{brand_alternatives})
         (?:\s*,?\s*version)?
-        (?:\s+(?:{prefix_alternatives})-|\s*-\s*|\s+)
+        (?:\s+(?P<version_brand>{prefix_alternatives})-|\s*-\s*|\s+)
         (?P<core>\d+\.\d+\.\d+)
         (?:-(?P<prerelease>rc\d+|alpha\d*|beta\d*))?
         (?:-(?P<commit>[0-9a-f]{{7,40}}))?
@@ -161,6 +163,11 @@ def parse_doris_version_comment(comment: str) -> 
DorisVersion:
     if match is None:
         return DorisVersion(raw=comment, deployment_hint=deployment_hint)
 
+    brand = _normalize_brand(match.group("brand"))
+    version_brand = match.group("version_brand")
+    if version_brand is not None and _normalize_brand(version_brand) != brand:
+        return DorisVersion(raw=comment, deployment_hint=deployment_hint)
+
     major, minor, patch = (int(part) for part in 
match.group("core").split("."))
     prerelease = match.group("prerelease")
     commit = match.group("commit")
@@ -173,7 +180,7 @@ def parse_doris_version_comment(comment: str) -> 
DorisVersion:
         prerelease=prerelease.lower() if prerelease else None,
         commit=commit.lower() if commit else None,
         deployment_hint=deployment_hint,
-        brand=_normalize_brand(match.group("brand")),
+        brand=brand,
         parse_status=DorisVersionParseStatus.PARSED,
     )
 
diff --git a/test/tools/test_capability_detector.py 
b/test/tools/test_capability_detector.py
index f6f9acd..1922c73 100644
--- a/test/tools/test_capability_detector.py
+++ b/test/tools/test_capability_detector.py
@@ -1127,6 +1127,53 @@ async def 
test_detector_propagates_comment_brand_to_brandless_components(
     assert report.certified is False
 
 
[email protected]
+async def test_unknown_brand_keeps_brandless_components_unknown() -> None:
+    connection = _ProbeConnection()
+    connection.row_overrides["SELECT @@version_comment;"] = [
+        {"@@version_comment": "unregistereddb version 4.0.5"}
+    ]
+    connection.row_overrides["SHOW FRONTENDS"] = [
+        {
+            "Name": "fe-1",
+            "IsMaster": "true",
+            "Version": "4.0.5",
+        },
+    ]
+    connection.row_overrides["SHOW BACKENDS"] = [
+        {
+            "BackendId": "1",
+            "Version": "4.0.5",
+        },
+    ]
+    detector = DorisCapabilityDetector(  # type: ignore[arg-type]
+        _ProbeConnectionManager(connection)
+    )
+
+    snapshot = await detector.detect_base(
+        None,
+        capability_generation=1,
+        provider_generation="provider.a",
+    )
+    feature = DORIS_FEATURE_MATRIX.evaluate(
+        domain="doris_catalog",
+        child_name="list_tables",
+        versions=snapshot.version_vector,
+    )
+    report = DORIS_PATCH_CERTIFICATION_MATRIX.evaluate(snapshot.version_vector)
+
+    assert snapshot.version_vector.master_fe.is_parsed is False
+    assert snapshot.version_vector.master_fe.brand is None
+    assert snapshot.version_vector.backends[0].is_parsed is False
+    assert snapshot.version_vector.backends[0].brand is None
+    assert feature.compatible is False
+    assert feature.reason_code == "DORIS_VERSION_UNKNOWN"
+    assert feature.certified is False
+    assert report.status is VersionCertificationStatus.UNKNOWN
+    assert report.certified is False
+    assert report.evidence_ids == ()
+
+
 @pytest.mark.asyncio
 async def test_detector_does_not_treat_commit_substrings_as_brand_tokens() -> 
None:
     configure_version_brands(("db",))
diff --git a/test/tools/test_doris_feature_matrix.py 
b/test/tools/test_doris_feature_matrix.py
index 1f0651c..827cb2e 100644
--- a/test/tools/test_doris_feature_matrix.py
+++ b/test/tools/test_doris_feature_matrix.py
@@ -567,6 +567,25 @@ def 
test_distribution_evidence_validates_comments_without_brand_registry() -> No
             PatchCertificationEvidence.model_validate(payload)
 
 
+def test_apache_evidence_rejects_distribution_comments_with_registered_alias(
+    enterprise_brand_alias: str,
+) -> None:
+    evidence = _certification_evidence("4.0.5")
+    payload = evidence.model_dump(mode="python")
+    payload["master_fe_version_comment"] = (
+        f"{enterprise_brand_alias} version 4.0.5"
+    )
+    payload["backend_version_comments"] = (
+        f"{enterprise_brand_alias}-4.0.5-abc1234",
+    )
+
+    with pytest.raises(
+        ValidationError,
+        match="Doris core version 4.0.5",
+    ):
+        PatchCertificationEvidence.model_validate(payload)
+
+
 def test_patch_evidence_rejects_incomplete_host_or_component_proof() -> None:
     evidence = _certification_evidence()
     payload = evidence.model_dump(mode="python")
diff --git a/test/tools/test_doris_version.py b/test/tools/test_doris_version.py
index 41a83d5..8524e9c 100644
--- a/test/tools/test_doris_version.py
+++ b/test/tools/test_doris_version.py
@@ -130,6 +130,25 @@ def 
test_registered_brand_alias_comments_parse_three_part_version(
     assert version.brand_verified is False
 
 
[email protected](
+    "comment",
+    [
+        "Doris version enterprisedb-4.0.5",
+        "enterprisedb version doris-4.0.5",
+    ],
+)
+def test_mismatched_leading_and_version_brands_fail_closed(
+    comment: str,
+    enterprise_brand_alias: str,
+) -> None:
+    version = parse_doris_version_comment(comment)
+
+    assert version.parse_status is DorisVersionParseStatus.UNKNOWN
+    assert version.is_parsed is False
+    assert version.brand is None
+    assert version.core is None
+
+
 def test_brand_alias_configuration_replaces_previous_set(
     enterprise_brand_alias: str,
 ) -> None:


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to