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

FreeOnePlus pushed a commit to branch feat/v1-09-cluster-domain
in repository https://gitbox.apache.org/repos/asf/doris-mcp-server.git

commit 8011aef0f41faf12e8665a31ef9802d3a14a4049
Author: FreeOnePlus <[email protected]>
AuthorDate: Fri Jul 31 16:58:32 2026 +0800

    feat: add Cluster domain runtime
---
 CHANGELOG.md                                   |    8 +
 doris_mcp_server/tools/capability_detector.py  |  428 ++++++++-
 doris_mcp_server/tools/capability_registry.py  |   24 +-
 doris_mcp_server/tools/cluster_handlers.py     |  198 ++++
 doris_mcp_server/tools/domain_dispatcher.py    |   47 +-
 doris_mcp_server/tools/doris_feature_matrix.py |   51 +-
 doris_mcp_server/tools/tools_manager.py        |  139 +--
 doris_mcp_server/utils/cluster_runtime.py      | 1185 ++++++++++++++++++++++++
 doris_mcp_server/utils/db.py                   |   17 +
 test/integration/test_real_doris_transports.py |  143 +++
 test/tools/test_capability_detector.py         |  139 +++
 test/tools/test_capability_registry.py         |   70 ++
 test/tools/test_domain_dispatcher.py           |   70 +-
 test/tools/test_domain_manifest.py             |   10 +-
 test/tools/test_manager_routing_boundaries.py  |  139 +--
 test/utils/test_cluster_runtime.py             |  313 +++++++
 test/utils/test_doris_user_pool_manager.py     |    2 +-
 17 files changed, 2697 insertions(+), 286 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e8daf8..75cd49e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,6 +48,9 @@ under **Unreleased** until a new version is selected and 
published.
 - Bounded query result streaming with deployment and absolute ceilings for
   rows, serialized bytes, and execution time, plus cancellation-safe database
   connection disposal.
+- A read-only Cluster domain with eleven capability-gated children for node
+  inventory, active tasks, metrics, memory, cache, compaction, workload and
+  compute groups, recorded resource growth, and sanitized runtime evidence.
 - Real Doris process tests covering Streamable HTTP and stdio.
 
 ### Changed
@@ -87,6 +90,11 @@ under **Unreleased** until a new version is selected and 
published.
 
 ### Fixed
 
+- Released failed capability-probe connections from their captured owner pools
+  so a single-connection route cannot starve subsequent domain calls.
+- Excluded explicitly dead Doris components from active version gating while
+  preserving them in node inventory, and kept live runtime manifests within
+  the 16 KiB domain budget.
 - Preserved service availability after malformed requests, unknown methods,
   header mismatches, unsupported versions, and missing capabilities.
 - Kept static-token Doris pools usable after repeated query timeouts, and
diff --git a/doris_mcp_server/tools/capability_detector.py 
b/doris_mcp_server/tools/capability_detector.py
index e1d5bd3..7d78779 100644
--- a/doris_mcp_server/tools/capability_detector.py
+++ b/doris_mcp_server/tools/capability_detector.py
@@ -34,6 +34,7 @@ from ..utils.doris_http_client import (
     DorisHTTPClient,
     DorisHTTPPolicyError,
     DorisHTTPRequestError,
+    DorisHTTPResponse,
     configured_fe_http_hosts,
     database_config_for_request,
 )
@@ -177,6 +178,44 @@ _DOMAIN_PROBES: Mapping[str, tuple[tuple[str, tuple[str, 
...]], ...]] = {
             ("audit_log_readable",),
         ),
     ),
+    "doris_cluster": (
+        (
+            'SHOW PROC "/current_queries"',
+            (
+                "legacy_task_views_readable",
+                "unified_task_progress_readable",
+            ),
+        ),
+        (
+            (
+                "SELECT BE_ID, METRIC_NAME "
+                "FROM information_schema.file_cache_statistics LIMIT 1"
+            ),
+            (
+                "information_schema.file_cache_statistics",
+                "file_cache_metrics_readable",
+            ),
+        ),
+        (
+            ("SELECT * FROM information_schema.doris_be_compaction_tasks LIMIT 
1"),
+            (
+                "information_schema.doris_be_compaction_tasks",
+                "compaction_system_table_or_http_api",
+            ),
+        ),
+        (
+            "SHOW WORKLOAD GROUPS",
+            ("workload_group_metadata_and_metrics_readable",),
+        ),
+        (
+            "SHOW COMPUTE GROUPS",
+            ("compute_group_metadata_readable",),
+        ),
+        (
+            ("SELECT `time` FROM internal.__internal_schema.audit_log LIMIT 
1"),
+            ("metrics_history_readable",),
+        ),
+    ),
 }
 
 
@@ -298,6 +337,8 @@ class DorisCapabilityDetector:
                     probes["profile_or_audit_readable"] = 
_combine_query_evidence_probe(
                         probes
                     )
+                elif domain_name == "doris_cluster":
+                    probes.update(await 
self._safe_probe_cluster_services(auth_context))
                 completed_route = self.route_identity(auth_context)
                 if completed_route.fingerprint != base.route.fingerprint:
                     raise CapabilityRouteChangedError(
@@ -716,6 +757,111 @@ class DorisCapabilityDetector:
                 endpoint_reason="ADBC_RUNTIME_PROBE_FAILED",
             )
 
+    async def _safe_probe_cluster_services(
+        self,
+        auth_context: Any | None,
+    ) -> dict[str, CapabilityProbeEvidence]:
+        try:
+            async with asyncio.timeout(self._optional_probe_timeout()):
+                return await self._probe_cluster_services(auth_context)
+        except TimeoutError:
+            return _cluster_http_probe_failure(
+                status=CapabilityProbeStatus.DEGRADED,
+                reason_code="CLUSTER_HTTP_PROBE_TIMED_OUT",
+            )
+        except DorisHTTPPolicyError:
+            return _cluster_http_probe_failure(
+                status=CapabilityProbeStatus.MISCONFIGURED,
+                reason_code="CLUSTER_HTTP_ENDPOINT_MISCONFIGURED",
+            )
+        except DorisHTTPRequestError:
+            return _cluster_http_probe_failure(
+                status=CapabilityProbeStatus.DEGRADED,
+                reason_code="CLUSTER_HTTP_ENDPOINT_UNREACHABLE",
+            )
+        except Exception:
+            return _cluster_http_probe_failure(
+                status=CapabilityProbeStatus.UNKNOWN,
+                reason_code="CLUSTER_HTTP_PROBE_FAILED",
+            )
+
+    async def _probe_cluster_services(
+        self,
+        auth_context: Any | None,
+    ) -> dict[str, CapabilityProbeEvidence]:
+        if getattr(auth_context, "auth_method", "") == "doris_oauth":
+            return _cluster_http_probe_failure(
+                status=CapabilityProbeStatus.MISCONFIGURED,
+                reason_code="CLUSTER_HTTP_CREDENTIAL_ROUTE_UNAVAILABLE",
+            )
+        config_resolver = getattr(
+            self._connection_manager,
+            "get_database_config_for_auth_context",
+            None,
+        )
+        db_config = (
+            config_resolver(auth_context)
+            if callable(config_resolver)
+            else database_config_for_request(self._connection_manager)
+        )
+        client = DorisHTTPClient.from_database_config(db_config)
+        fe_hosts = configured_fe_http_hosts(db_config)
+        raw_be_hosts = getattr(db_config, "be_hosts", []) or []
+        if not isinstance(raw_be_hosts, list) or any(
+            not isinstance(host, str) for host in raw_be_hosts
+        ):
+            return _cluster_http_probe_failure(
+                status=CapabilityProbeStatus.MISCONFIGURED,
+                reason_code="BE_METRICS_ENDPOINT_MISCONFIGURED",
+            )
+        be_hosts = tuple(dict.fromkeys(raw_be_hosts))
+        fe_response, be_response = await asyncio.gather(
+            client.get_first_available(
+                role="fe",
+                hosts=fe_hosts,
+                port=db_config.fe_http_port,
+                path="/metrics",
+                headers={"Accept": "text/plain"},
+            ),
+            (
+                client.get_first_available(
+                    role="be",
+                    hosts=be_hosts,
+                    port=db_config.be_webserver_port,
+                    path="/metrics",
+                    headers={"Accept": "text/plain"},
+                )
+                if be_hosts
+                else _missing_be_metrics_response()
+            ),
+        )
+        fe_status, fe_reason = _classify_metrics_response(
+            fe_response.status,
+            configured=True,
+        )
+        be_status, be_reason = _classify_metrics_response(
+            be_response.status,
+            configured=bool(be_hosts),
+        )
+        fe_names = (
+            _prometheus_metric_names(fe_response.text())
+            if fe_status is CapabilityProbeStatus.SUPPORTED
+            else frozenset()
+        )
+        be_names = (
+            _prometheus_metric_names(be_response.text())
+            if be_status is CapabilityProbeStatus.SUPPORTED
+            else frozenset()
+        )
+        return _cluster_http_probe_evidence(
+            fe_status=fe_status,
+            fe_reason=fe_reason,
+            be_status=be_status,
+            be_reason=be_reason,
+            fe_metric_names=fe_names,
+            be_metric_names=be_names,
+        )
+
     def _optional_probe_timeout(self) -> float:
         return max(
             0.25,
@@ -748,6 +894,277 @@ def _classify_probe_error(
     return CapabilityProbeStatus.UNKNOWN, "RUNTIME_PROBE_FAILED"
 
 
+async def _missing_be_metrics_response() -> DorisHTTPResponse:
+    return DorisHTTPResponse(
+        status=0,
+        headers={},
+        body=b"",
+        url="",
+    )
+
+
+def _classify_metrics_response(
+    status_code: int,
+    *,
+    configured: bool,
+) -> tuple[CapabilityProbeStatus, str]:
+    if not configured:
+        return (
+            CapabilityProbeStatus.MISCONFIGURED,
+            "METRICS_ENDPOINT_NOT_CONFIGURED",
+        )
+    if status_code == 200:
+        return CapabilityProbeStatus.SUPPORTED, "METRICS_ENDPOINT_READABLE"
+    if status_code in {401, 403}:
+        return CapabilityProbeStatus.UNKNOWN, 
"METRICS_ENDPOINT_PERMISSION_DENIED"
+    if status_code in {502, 503, 504}:
+        return CapabilityProbeStatus.DEGRADED, "METRICS_ENDPOINT_UNREACHABLE"
+    return CapabilityProbeStatus.UNSUPPORTED, "METRICS_ENDPOINT_UNSUPPORTED"
+
+
+def _prometheus_metric_names(payload: str) -> frozenset[str]:
+    names: set[str] = set()
+    for raw_line in payload.splitlines():
+        line = raw_line.strip()
+        if not line or line.startswith("#"):
+            continue
+        token = line.split(maxsplit=1)[0]
+        name = token.split("{", 1)[0]
+        if name:
+            names.add(name)
+        if len(names) >= 10_000:
+            break
+    return frozenset(names)
+
+
+def _cluster_http_probe_failure(
+    *,
+    status: CapabilityProbeStatus,
+    reason_code: str,
+) -> dict[str, CapabilityProbeEvidence]:
+    probe_ids = (
+        "fe_metrics",
+        "be_metrics",
+        "metrics_endpoints_readable",
+        "memory_tracker_metrics_readable",
+        "legacy_compaction_status_readable",
+        "connection_limit_metrics",
+        "routine_load_metrics",
+        "file_cache_queue_metrics",
+        "enhanced_metrics_present",
+        "file_cache_queue_metrics_present",
+        "condition_cache",
+        "parquet_page_cache",
+        "advanced_cache_metrics_present",
+    )
+    return {
+        probe_id: CapabilityProbeEvidence(
+            probe_id=probe_id,
+            status=status,
+            reason_code=reason_code,
+            evidence_sources=("doris_http_metrics", "runtime_probe"),
+        )
+        for probe_id in probe_ids
+    }
+
+
+def _cluster_http_probe_evidence(
+    *,
+    fe_status: CapabilityProbeStatus,
+    fe_reason: str,
+    be_status: CapabilityProbeStatus,
+    be_reason: str,
+    fe_metric_names: frozenset[str],
+    be_metric_names: frozenset[str],
+) -> dict[str, CapabilityProbeEvidence]:
+    probes: dict[str, CapabilityProbeEvidence] = {
+        "fe_metrics": CapabilityProbeEvidence(
+            probe_id="fe_metrics",
+            status=fe_status,
+            reason_code=fe_reason,
+            evidence_sources=("doris_fe_metrics", "runtime_probe"),
+        ),
+        "be_metrics": CapabilityProbeEvidence(
+            probe_id="be_metrics",
+            status=be_status,
+            reason_code=be_reason,
+            evidence_sources=("doris_be_metrics", "runtime_probe"),
+        ),
+    }
+    combined_status, combined_reason = _combine_endpoint_status(
+        fe_status,
+        be_status,
+    )
+    probes["metrics_endpoints_readable"] = CapabilityProbeEvidence(
+        probe_id="metrics_endpoints_readable",
+        status=combined_status,
+        reason_code=combined_reason,
+        evidence_sources=(
+            "doris_fe_metrics",
+            "doris_be_metrics",
+            "runtime_probe",
+        ),
+    )
+
+    all_names = fe_metric_names | be_metric_names
+    memory_present = _has_metric_marker(
+        be_metric_names,
+        ("memory", "mem_tracker", "jemalloc"),
+    )
+    probes["memory_tracker_metrics_readable"] = _metric_presence_evidence(
+        "memory_tracker_metrics_readable",
+        endpoint_status=be_status,
+        present=memory_present,
+        present_reason="MEMORY_TRACKER_METRICS_READABLE",
+        absent_reason="MEMORY_TRACKER_METRICS_NOT_PRESENT",
+        source="doris_be_metrics",
+    )
+
+    compaction_present = _has_metric_marker(all_names, ("compaction",))
+    if compaction_present:
+        probes["legacy_compaction_status_readable"] = CapabilityProbeEvidence(
+            probe_id="legacy_compaction_status_readable",
+            status=CapabilityProbeStatus.DEGRADED,
+            reason_code="LEGACY_COMPACTION_SUMMARY_READABLE",
+            evidence_sources=("doris_metrics", "runtime_probe"),
+        )
+    else:
+        probes["legacy_compaction_status_readable"] = 
_metric_presence_evidence(
+            "legacy_compaction_status_readable",
+            endpoint_status=combined_status,
+            present=False,
+            present_reason="LEGACY_COMPACTION_SUMMARY_READABLE",
+            absent_reason="LEGACY_COMPACTION_METRICS_NOT_PRESENT",
+            source="doris_metrics",
+        )
+
+    marker_contracts = {
+        "connection_limit_metrics": ("connection", "limit"),
+        "routine_load_metrics": ("routine_load",),
+        "file_cache_queue_metrics": ("file_cache", "queue"),
+        "condition_cache": ("condition_cache",),
+        "parquet_page_cache": ("parquet", "page_cache"),
+    }
+    for probe_id, markers in marker_contracts.items():
+        probes[probe_id] = _metric_presence_evidence(
+            probe_id,
+            endpoint_status=combined_status,
+            present=all(marker in " ".join(all_names) for marker in markers),
+            present_reason=f"{probe_id.upper()}_PRESENT",
+            absent_reason=f"{probe_id.upper()}_NOT_PRESENT",
+            source="doris_metrics",
+        )
+
+    queue_probe = probes["file_cache_queue_metrics"]
+    probes["file_cache_queue_metrics_present"] = CapabilityProbeEvidence(
+        probe_id="file_cache_queue_metrics_present",
+        status=queue_probe.status,
+        reason_code=queue_probe.reason_code,
+        evidence_sources=queue_probe.evidence_sources,
+    )
+    enhanced_candidates = (
+        probes["connection_limit_metrics"],
+        probes["routine_load_metrics"],
+        probes["file_cache_queue_metrics"],
+    )
+    probes["enhanced_metrics_present"] = _combine_metric_presence(
+        "enhanced_metrics_present",
+        enhanced_candidates,
+        supported_reason="ENHANCED_METRICS_PRESENT",
+    )
+    advanced_candidates = (
+        probes["condition_cache"],
+        probes["parquet_page_cache"],
+    )
+    probes["advanced_cache_metrics_present"] = _combine_metric_presence(
+        "advanced_cache_metrics_present",
+        advanced_candidates,
+        supported_reason="ADVANCED_CACHE_METRICS_PRESENT",
+    )
+    return probes
+
+
+def _combine_endpoint_status(
+    *statuses: CapabilityProbeStatus,
+) -> tuple[CapabilityProbeStatus, str]:
+    if all(status is CapabilityProbeStatus.SUPPORTED for status in statuses):
+        return (
+            CapabilityProbeStatus.SUPPORTED,
+            "FE_BE_METRICS_ENDPOINTS_READABLE",
+        )
+    for status in (
+        CapabilityProbeStatus.MISCONFIGURED,
+        CapabilityProbeStatus.DEGRADED,
+        CapabilityProbeStatus.UNKNOWN,
+        CapabilityProbeStatus.UNSUPPORTED,
+    ):
+        if status in statuses:
+            return status, f"FE_BE_METRICS_{status.value.upper()}"
+    return CapabilityProbeStatus.UNKNOWN, "FE_BE_METRICS_UNKNOWN"
+
+
+def _has_metric_marker(
+    names: frozenset[str],
+    markers: tuple[str, ...],
+) -> bool:
+    return any(any(marker in name.casefold() for marker in markers) for name 
in names)
+
+
+def _metric_presence_evidence(
+    probe_id: str,
+    *,
+    endpoint_status: CapabilityProbeStatus,
+    present: bool,
+    present_reason: str,
+    absent_reason: str,
+    source: str,
+) -> CapabilityProbeEvidence:
+    if present:
+        status = CapabilityProbeStatus.SUPPORTED
+        reason = present_reason
+    elif endpoint_status is CapabilityProbeStatus.SUPPORTED:
+        status = CapabilityProbeStatus.UNSUPPORTED
+        reason = absent_reason
+    else:
+        status = endpoint_status
+        reason = absent_reason
+    return CapabilityProbeEvidence(
+        probe_id=probe_id,
+        status=status,
+        reason_code=reason,
+        evidence_sources=(source, "runtime_probe"),
+    )
+
+
+def _combine_metric_presence(
+    probe_id: str,
+    candidates: tuple[CapabilityProbeEvidence, ...],
+    *,
+    supported_reason: str,
+) -> CapabilityProbeEvidence:
+    if all(
+        candidate.status is CapabilityProbeStatus.SUPPORTED for candidate in 
candidates
+    ):
+        status = CapabilityProbeStatus.SUPPORTED
+        reason = supported_reason
+    else:
+        status = next(
+            (
+                candidate.status
+                for candidate in candidates
+                if candidate.status is not CapabilityProbeStatus.SUPPORTED
+            ),
+            CapabilityProbeStatus.UNKNOWN,
+        )
+        reason = f"{probe_id.upper()}_INCOMPLETE"
+    return CapabilityProbeEvidence(
+        probe_id=probe_id,
+        status=status,
+        reason_code=reason,
+        evidence_sources=("doris_metrics", "runtime_probe"),
+    )
+
+
 def _profile_api_code(payload: Mapping[str, Any] | None) -> int | None:
     if payload is None or "code" not in payload:
         return None
@@ -880,6 +1297,8 @@ def _frontend_versions(
 ) -> tuple[DorisVersion, tuple[DorisVersion, ...]]:
     observed: list[tuple[DorisVersion, bool]] = []
     for row in rows:
+        if not _component_is_active(row):
+            continue
         version = _component_version(_row_value(row, "Version", "FeVersion"))
         observed.append(
             (
@@ -907,10 +1326,17 @@ def _backend_versions(
     rows: Sequence[Mapping[str, Any]],
 ) -> tuple[DorisVersion, ...]:
     return tuple(
-        _component_version(_row_value(row, "Version", "BeVersion")) for row in 
rows
+        _component_version(_row_value(row, "Version", "BeVersion"))
+        for row in rows
+        if _component_is_active(row)
     )
 
 
+def _component_is_active(row: Mapping[str, Any]) -> bool:
+    alive = _row_value(row, "Alive")
+    return alive is None or str(alive).strip() == "" or _truthy(alive)
+
+
 def _cluster_fingerprint(
     route: DorisRouteIdentity,
     frontend_rows: Sequence[Mapping[str, Any]],
diff --git a/doris_mcp_server/tools/capability_registry.py 
b/doris_mcp_server/tools/capability_registry.py
index e495c49..df7ff8b 100644
--- a/doris_mcp_server/tools/capability_registry.py
+++ b/doris_mcp_server/tools/capability_registry.py
@@ -287,16 +287,10 @@ class CapabilityEvaluator:
                     limitations=limitations,
                 )
 
-            if (
+            uncertified = (
                 version_result.certification_status
                 is not VersionCertificationStatus.CERTIFIED
-            ):
-                limitations = _ordered_unique(
-                    (
-                        *limitations,
-                        "The observed Doris patch is not certified by this 
project.",
-                    )
-                )
+            )
             if snapshot.stale:
                 degraded = True
                 limitations = _ordered_unique(
@@ -313,9 +307,17 @@ class CapabilityEvaluator:
                 ),
                 callable=True,
                 reason_code=(
-                    "CAPABILITY_VERIFIED_DEGRADED"
-                    if degraded
-                    else "CAPABILITY_VERIFIED"
+                    "CAPABILITY_VERIFIED_DEGRADED_UNCERTIFIED"
+                    if degraded and uncertified
+                    else (
+                        "CAPABILITY_VERIFIED_DEGRADED"
+                        if degraded
+                        else (
+                            "CAPABILITY_VERIFIED_UNCERTIFIED"
+                            if uncertified
+                            else "CAPABILITY_VERIFIED"
+                        )
+                    )
                 ),
                 detected_versions=detected_versions,
                 active_variant=variant.name,
diff --git a/doris_mcp_server/tools/cluster_handlers.py 
b/doris_mcp_server/tools/cluster_handlers.py
new file mode 100644
index 0000000..c1bbd39
--- /dev/null
+++ b/doris_mcp_server/tools/cluster_handlers.py
@@ -0,0 +1,198 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Formal Cluster-domain handlers backed by one strict runtime."""
+
+from __future__ import annotations
+
+from typing import Any, Protocol, cast
+
+from ..utils.cluster_runtime import DorisClusterRuntime
+from ..utils.db import DorisConnectionManager
+from ..utils.monitoring_tools import DorisMonitoringTools
+from ..utils.security import get_current_auth_context
+from .capability_registry import CapabilityRegistry
+
+
+class _ClusterHandlerOwner(Protocol):
+    """State supplied by ``DorisToolsManager`` to the mixin."""
+
+    cluster_runtime: DorisClusterRuntime
+    _capability_registry: CapabilityRegistry | None
+
+
+class ClusterToolHandlersMixin:
+    """Route every Cluster child through the strict evidence runtime."""
+
+    def _initialize_cluster_handlers(
+        self: _ClusterHandlerOwner,
+        connection_manager: DorisConnectionManager,
+        monitoring_tools: DorisMonitoringTools,
+    ) -> None:
+        self.cluster_runtime = DorisClusterRuntime(
+            connection_manager,
+            monitoring_tools,
+        )
+
+    async def _formal_doris_cluster_get_cluster_overview_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.get_cluster_overview(
+            include=cast(list[str] | None, arguments.get("include")),
+        )
+
+    async def _formal_doris_cluster_list_cluster_nodes_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.list_cluster_nodes(
+            node_types=cast(list[str] | None, arguments.get("node_types")),
+            include_metrics=bool(arguments.get("include_metrics", False)),
+        )
+
+    async def _formal_doris_cluster_list_active_tasks_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.list_active_tasks(
+            task_types=cast(list[str] | None, arguments.get("task_types")),
+            states=cast(list[str] | None, arguments.get("states")),
+            limit=cast(int | None, arguments.get("limit")),
+        )
+
+    async def _formal_doris_cluster_get_cache_status_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.get_cache_status(
+            scope=cast(str | None, arguments.get("scope")),
+            node_ids=cast(list[str] | None, arguments.get("node_ids")),
+            include_queues=bool(arguments.get("include_queues", False)),
+        )
+
+    async def _formal_doris_cluster_get_compaction_status_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.get_compaction_status(
+            database=cast(str | None, arguments.get("database")),
+            table=cast(str | None, arguments.get("table")),
+            state=cast(str | None, arguments.get("state")),
+            limit=cast(int | None, arguments.get("limit")),
+        )
+
+    async def _formal_doris_cluster_get_workload_group_status_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.get_workload_group_status(
+            name=cast(str | None, arguments.get("name")),
+            include_usage=bool(arguments.get("include_usage", False)),
+        )
+
+    async def _formal_doris_cluster_get_compute_group_status_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.cluster_runtime.get_compute_group_status(
+            name=cast(str | None, arguments.get("name")),
+            include_nodes=bool(arguments.get("include_nodes", False)),
+            include_usage=bool(arguments.get("include_usage", False)),
+        )
+
+    async def _formal_doris_cluster_get_runtime_capabilities_tool(
+        self: _ClusterHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        registry = self._capability_registry
+        if registry is None:
+            return {
+                "status": "partial",
+                "data": {
+                    "detail": arguments.get("detail", "summary"),
+                    "capability_registry": "external",
+                },
+                "warnings": [
+                    "Runtime capability evidence is supplied by an external "
+                    "availability provider."
+                ],
+                "metadata": {"source": "availability_provider"},
+                "evidence": [],
+            }
+        snapshot = await registry.ensure_fresh(
+            "doris_cluster",
+            get_current_auth_context(),
+        )
+        detail = str(arguments.get("detail", "summary"))
+        versions = {
+            "master_fe": snapshot.version_vector.master_fe.normalized,
+            "follower_fes": [
+                version.normalized for version in 
snapshot.version_vector.follower_fes
+            ],
+            "backends": [
+                version.normalized for version in 
snapshot.version_vector.backends
+            ],
+        }
+        statuses: dict[str, int] = {}
+        for probe in snapshot.probes.values():
+            statuses[probe.status.value] = statuses.get(probe.status.value, 0) 
+ 1
+        data: dict[str, Any] = {
+            "detail": detail,
+            "versions": versions,
+            "deployment_mode": snapshot.deployment_mode,
+            "mixed_versions": snapshot.mixed_versions,
+            "stale": snapshot.stale,
+            "probe_status_counts": statuses,
+            "probed_domains": sorted(snapshot.probed_domains),
+        }
+        if detail == "full":
+            data["probes"] = {
+                probe_id: {
+                    "status": probe.status.value,
+                    "reason_code": probe.reason_code,
+                    "evidence_sources": list(probe.evidence_sources),
+                }
+                for probe_id, probe in sorted(snapshot.probes.items())
+            }
+        warnings = (
+            ["Capability evidence is stale and may be retried."]
+            if snapshot.stale
+            else []
+        )
+        return {
+            "status": "partial" if warnings else "success",
+            "data": data,
+            "warnings": warnings,
+            "metadata": {
+                "source": "route_private_capability_snapshot",
+                "created_at": snapshot.created_at.isoformat(),
+                "expires_at": snapshot.expires_at.isoformat(),
+            },
+            "evidence": [
+                {
+                    "source": "SELECT @@version_comment",
+                    "probe": "version_probe_completed",
+                },
+                {
+                    "source": "SHOW FRONTENDS, SHOW BACKENDS",
+                    "probe": "cluster_components_discoverable",
+                },
+            ],
+        }
+
+
+__all__ = ["ClusterToolHandlersMixin"]
diff --git a/doris_mcp_server/tools/domain_dispatcher.py 
b/doris_mcp_server/tools/domain_dispatcher.py
index e9eb6bd..0d8b60b 100644
--- a/doris_mcp_server/tools/domain_dispatcher.py
+++ b/doris_mcp_server/tools/domain_dispatcher.py
@@ -43,6 +43,7 @@ from ..schema_validation import (
 )
 from ..state_handles import StateHandleCodec, StateHandleError
 from ..utils.catalog_metadata import CatalogMetadataFailure
+from ..utils.cluster_runtime import ClusterRuntimeFailure
 from ..utils.logger import get_audit_logger, get_logger
 from ..utils.query_runtime import QueryRuntimeFailure
 from . import domain_catalog as domain_catalog_module
@@ -640,6 +641,25 @@ class DomainDispatcher:
                     "status_code": exc.status_code,
                 },
             )
+        except ClusterRuntimeFailure as exc:
+            self._audit(feature_id, arguments, "error", started)
+            return self._error(
+                domain.name,
+                (
+                    DomainErrorCode.CHILD_ARGUMENTS_INVALID
+                    if exc.reason_code == "CLUSTER_ARGUMENT_INVALID"
+                    else DomainErrorCode.CHILD_EXECUTION_FAILED
+                ),
+                str(exc),
+                child_tool=child.name,
+                manifest_version=manifest.manifest_version,
+                retryable=exc.retryable,
+                details={
+                    "rediscover": False,
+                    "reason_code": exc.reason_code,
+                    "status_code": exc.status_code,
+                },
+            )
         except ToolOutputValidationError:
             logger.exception("Formal child output validation failed for %s", 
feature_id)
             self._audit(
@@ -1131,24 +1151,9 @@ def _adapt_arguments(
         prepared["single_replica"] = False
         prepared["_formal_catalog"] = True
     elif adapter_name == "adapt:monitoring_arguments":
-        if prepared:
-            warnings.append(
-                "Metric and node filters are not supported by the active 
handler."
-            )
-        prepared = {}
+        pass
     elif adapter_name == "adapt:memory_arguments":
-        detail = prepared.pop("detail", None)
-        if prepared.pop("node_ids", None) is not None:
-            warnings.append(
-                "Memory node filtering is not supported by the active handler."
-            )
-        prepared["data_type"] = "realtime"
-        prepared["tracker_type"] = {
-            None: "overview",
-            "summary": "overview",
-            "trackers": "all",
-            "top_consumers": "all",
-        }.get(detail, "overview")
+        pass
     elif adapter_name == "adapt:audit_filters":
         window_minutes = prepared.pop("window_minutes", None)
         if window_minutes is not None:
@@ -1214,13 +1219,7 @@ def _adapt_arguments(
             1000,
         )
     elif adapter_name == "adapt:resource_growth_arguments":
-        resource = prepared.pop("resource", None)
-        prepared["days"] = prepared.pop("window_days", 30)
-        prepared["resource_types"] = [resource] if resource else []
-        if prepared.pop("granularity", None) is not None:
-            warnings.append(
-                "Growth granularity is not supported by the active handler."
-            )
+        pass
     elif adapter_name == "adapt:adbc_query_arguments":
         timeout_ms = prepared.pop("timeout_ms", None)
         if timeout_ms is not None:
diff --git a/doris_mcp_server/tools/doris_feature_matrix.py 
b/doris_mcp_server/tools/doris_feature_matrix.py
index 3c9d9ae..1067e80 100644
--- a/doris_mcp_server/tools/doris_feature_matrix.py
+++ b/doris_mcp_server/tools/doris_feature_matrix.py
@@ -1059,28 +1059,22 @@ FEATURE_DEFINITIONS = (
         "doris_cluster",
         "list_active_tasks",
         A,
-        _variant(
-            "legacy_task_views",
-            probes=("legacy_task_views_readable",),
-            callable_when_degraded=True,
-        ),
         _variant(
             "unified_task_progress",
             ranges=(">=4.1.1",),
-            system_objects=("information_schema.active_tasks",),
             probes=("unified_task_progress_readable",),
             sources=("DORIS_RELEASE_4_1_1",),
         ),
+        _variant(
+            "legacy_task_views",
+            probes=("legacy_task_views_readable",),
+            callable_when_degraded=True,
+        ),
     ),
     _feature(
         "doris_cluster",
         "get_monitoring_metrics",
         A,
-        _variant(
-            "base_metrics",
-            endpoints=("fe_metrics", "be_metrics"),
-            probes=("metrics_endpoints_readable",),
-        ),
         _variant(
             "observability_4_0_7",
             ranges=(">=4.0.7,<4.1.0",),
@@ -1092,6 +1086,11 @@ FEATURE_DEFINITIONS = (
             probes=("enhanced_metrics_present",),
             sources=("DORIS_RELEASE_4_0_7",),
         ),
+        _variant(
+            "base_metrics",
+            endpoints=("fe_metrics", "be_metrics"),
+            probes=("metrics_endpoints_readable",),
+        ),
     ),
     _feature(
         "doris_cluster",
@@ -1109,9 +1108,11 @@ FEATURE_DEFINITIONS = (
         "get_cache_status",
         B,
         _variant(
-            "file_cache",
-            endpoints=("be_metrics",),
-            probes=("file_cache_metrics_readable",),
+            "advanced_cache_types",
+            ranges=(">=4.1.0",),
+            features=("condition_cache", "parquet_page_cache"),
+            probes=("advanced_cache_metrics_present",),
+            sources=("DORIS_RELEASE_4_1_0",),
         ),
         _variant(
             "file_cache_queue_metrics",
@@ -1120,31 +1121,29 @@ FEATURE_DEFINITIONS = (
             sources=("DORIS_RELEASE_4_0_7",),
         ),
         _variant(
-            "advanced_cache_types",
-            ranges=(">=4.1.0",),
-            features=("condition_cache", "parquet_page_cache"),
-            probes=("advanced_cache_metrics_present",),
-            sources=("DORIS_RELEASE_4_1_0",),
+            "file_cache",
+            system_objects=("information_schema.file_cache_statistics",),
+            probes=("file_cache_metrics_readable",),
         ),
     ),
     _feature(
         "doris_cluster",
         "get_compaction_status",
         B,
-        _variant(
-            "legacy_compaction_summary",
-            probes=("legacy_compaction_status_readable",),
-            evidence_quality="summary",
-            callable_when_degraded=True,
-        ),
         _variant(
             "compaction_task_tracker",
             ranges=(">=4.0.6,<4.1.0", ">=4.1.1"),
             excluded_ranges=(">=4.1.0-alpha0,<4.1.1",),
-            endpoints=("be_compaction_api",),
+            system_objects=("information_schema.doris_be_compaction_tasks",),
             probes=("compaction_system_table_or_http_api",),
             sources=("DORIS_RELEASE_4_0_6", "DORIS_RELEASE_4_1_1"),
         ),
+        _variant(
+            "legacy_compaction_summary",
+            probes=("legacy_compaction_status_readable",),
+            evidence_quality="summary",
+            callable_when_degraded=True,
+        ),
     ),
     _feature(
         "doris_cluster",
diff --git a/doris_mcp_server/tools/tools_manager.py 
b/doris_mcp_server/tools/tools_manager.py
index e654f2a..246903c 100644
--- a/doris_mcp_server/tools/tools_manager.py
+++ b/doris_mcp_server/tools/tools_manager.py
@@ -29,7 +29,7 @@ from mcp.types import Tool
 from ..auth.operation_policy import authorize_operation
 from ..state_handles import StateHandleCodec
 from ..utils.adbc_query_tools import DorisADBCQueryTools
-from ..utils.analysis_tools import MemoryTracker, SQLAnalyzer, TableAnalyzer
+from ..utils.analysis_tools import SQLAnalyzer, TableAnalyzer
 from ..utils.data_exploration_tools import DataExplorationTools
 from ..utils.data_governance_tools import DataGovernanceTools
 from ..utils.data_quality_tools import DataQualityTools
@@ -37,7 +37,6 @@ from ..utils.db import DorisConnectionManager
 from ..utils.dependency_analysis_tools import DependencyAnalysisTools
 from ..utils.logger import get_audit_logger, get_logger
 from ..utils.monitoring_tools import DorisMonitoringTools
-from ..utils.performance_analytics_tools import PerformanceAnalyticsTools
 from ..utils.query_executor import DorisQueryExecutor
 from ..utils.schema_extractor import MetadataExtractor
 from ..utils.security import get_current_auth_context
@@ -49,6 +48,7 @@ from .capability_registry import (
     CapabilityRegistry,
 )
 from .catalog_handlers import CatalogToolHandlersMixin
+from .cluster_handlers import ClusterToolHandlersMixin
 from .domain_catalog import CURRENT_FLAT_TOOL_NAMES
 from .domain_dispatcher import (
     BoundHandlerAvailabilityProvider,
@@ -73,6 +73,7 @@ logger = get_logger(__name__)
 class DorisToolsManager(
     QueryToolHandlersMixin,
     CatalogToolHandlersMixin,
+    ClusterToolHandlersMixin,
     DomainManifestManagerMixin,
 ):
     """Apache Doris Tools Manager"""
@@ -96,7 +97,10 @@ class DorisToolsManager(
         )
         self._initialize_catalog_handlers(connection_manager)
         self.monitoring_tools = DorisMonitoringTools(connection_manager)
-        self.memory_tracker = MemoryTracker(connection_manager)
+        self._initialize_cluster_handlers(
+            connection_manager,
+            self.monitoring_tools,
+        )
 
         # Initialize v0.5.0 advanced analytics tools
         self.data_governance_tools = DataGovernanceTools(connection_manager)
@@ -106,7 +110,6 @@ class DorisToolsManager(
         )
         self.security_analytics_tools = 
SecurityAnalyticsTools(connection_manager)
         self.dependency_analysis_tools = 
DependencyAnalysisTools(connection_manager)
-        self.performance_analytics_tools = 
PerformanceAnalyticsTools(connection_manager)
 
         # Initialize ADBC query tools
         self.adbc_query_tools = DorisADBCQueryTools(connection_manager)
@@ -311,98 +314,26 @@ class DorisToolsManager(
     async def _get_monitoring_metrics_tool(
         self, arguments: dict[str, Any]
     ) -> dict[str, Any]:
-        """Unified monitoring metrics tool routing"""
-        content_type = arguments.get("content_type", "data")
-        role = arguments.get("role", "all")
-        monitor_type = arguments.get("monitor_type", "all")
-        priority = arguments.get("priority", "core")
-        include_raw_metrics = arguments.get("include_raw_metrics", False)
-
-        if content_type == "definitions":
-            # Only get definitions
-            return await self.monitoring_tools.get_monitoring_metrics(
-                role, monitor_type, priority, info_only=True, 
format_type="prometheus"
-            )
-        elif content_type == "data":
-            # Only get data
-            return await self.monitoring_tools.get_monitoring_metrics(
-                role,
-                monitor_type,
-                priority,
-                info_only=False,
-                format_type="prometheus",
-                include_raw_metrics=include_raw_metrics,
-            )
-        elif content_type == "both":
-            # Get both definitions and data
-            definitions = await self.monitoring_tools.get_monitoring_metrics(
-                role, monitor_type, priority, info_only=True, 
format_type="prometheus"
-            )
-            data = await self.monitoring_tools.get_monitoring_metrics(
-                role,
-                monitor_type,
-                priority,
-                info_only=False,
-                format_type="prometheus",
-                include_raw_metrics=include_raw_metrics,
-            )
-            return {
-                "content_type": "both",
-                "definitions": definitions,
-                "data": data,
-                "timestamp": data.get("timestamp"),
-                "_execution_info": {
-                    "combined_response": True,
-                    "definitions_available": definitions.get("success", False),
-                    "data_available": data.get("success", False),
-                },
-            }
-        else:
-            return {
-                "error": f"Invalid content_type: {content_type}. Must be 
'definitions', 'data', or 'both'"
-            }
+        """Route the migrated metric child through the strict Cluster 
runtime."""
+        return await self.cluster_runtime.get_monitoring_metrics(
+            metric_names=arguments.get("metric_names"),
+            node_ids=arguments.get("node_ids"),
+            window=arguments.get("window"),
+        )
 
     async def _get_memory_stats_tool(self, arguments: dict[str, Any]) -> 
dict[str, Any]:
-        """Unified memory statistics tool routing"""
-        data_type = arguments.get("data_type", "realtime")
-        tracker_type = arguments.get("tracker_type", "overview")
-        tracker_names = arguments.get("tracker_names")
-        time_range = arguments.get("time_range", "1h")
-        include_details = arguments.get("include_details", True)
-
-        if data_type == "realtime":
-            # Only get real-time data
-            return await self.memory_tracker.get_realtime_memory_stats(
-                tracker_type, include_details
-            )
-        elif data_type == "historical":
-            # Only get historical data
-            return await self.memory_tracker.get_historical_memory_stats(
-                tracker_names, time_range
-            )
-        elif data_type == "both":
-            # Get both real-time and historical data
-            realtime = await self.memory_tracker.get_realtime_memory_stats(
-                tracker_type, include_details
-            )
-            historical = await self.memory_tracker.get_historical_memory_stats(
-                tracker_names, time_range
-            )
-            return {
-                "data_type": "both",
-                "realtime": realtime,
-                "historical": historical,
-                "timestamp": realtime.get("timestamp"),
-                "_execution_info": {
-                    "combined_response": True,
-                    "realtime_available": realtime.get("success", False),
-                    "historical_available": historical.get("success", False),
-                },
-            }
-        else:
-            return {
-                "error": f"Invalid data_type: {data_type}. Must be 'realtime', 
'historical', or 'both'"
-            }
+        """Route the migrated memory child without placeholder values."""
+        detail = {
+            "overview": "summary",
+            "all": "trackers",
+        }.get(
+            str(arguments.get("tracker_type", "")),
+            arguments.get("detail", "summary"),
+        )
+        return await self.cluster_runtime.get_memory_stats(
+            node_ids=arguments.get("node_ids"),
+            detail=detail,
+        )
 
     # Legacy tool methods (for backward compatibility)
     async def _get_monitoring_metrics_info_tool(
@@ -618,15 +549,15 @@ class DorisToolsManager(
     async def _analyze_resource_growth_curves_tool(
         self, arguments: dict[str, Any]
     ) -> dict[str, Any]:
-        """Resource growth curves analysis tool routing"""
-        days = arguments.get("days", 30)
-        resource_types = arguments.get(
-            "resource_types", ["storage", "query_volume", "user_activity"]
+        """Route the migrated growth child through recorded Doris evidence."""
+        resource_types = arguments.get("resource_types")
+        resource = (
+            resource_types[0]
+            if isinstance(resource_types, list) and len(resource_types) == 1
+            else arguments.get("resource")
         )
-        include_predictions = arguments.get("include_predictions", False)
-        detailed_response = arguments.get("detailed_response", False)
-
-        # Delegate to performance analytics tools for processing
-        return await 
self.performance_analytics_tools.analyze_resource_growth_curves(
-            days, resource_types, include_predictions, detailed_response
+        return await self.cluster_runtime.analyze_resource_growth(
+            resource=resource,
+            window_days=arguments.get("days", arguments.get("window_days")),
+            granularity=arguments.get("granularity"),
         )
diff --git a/doris_mcp_server/utils/cluster_runtime.py 
b/doris_mcp_server/utils/cluster_runtime.py
new file mode 100644
index 0000000..ce88fa2
--- /dev/null
+++ b/doris_mcp_server/utils/cluster_runtime.py
@@ -0,0 +1,1185 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Strict, evidence-bearing runtime for the read-only Cluster domain."""
+
+from __future__ import annotations
+
+import re
+import uuid
+from collections.abc import Mapping, Sequence
+from datetime import datetime
+from typing import Any
+
+from .db import DorisConnectionManager
+from .monitoring_tools import DorisMonitoringTools
+from .redaction import redact_sensitive_data
+from .security import get_current_auth_context
+
+_MAX_ROWS = 1_000
+_MAX_METRIC_NAMES = 100
+_MAX_METRICS_PER_NODE = 256
+_MEMORY_MARKERS = ("memory", "mem_tracker", "memtable", "jemalloc")
+_CACHE_MARKERS = ("cache", "file_cache")
+_COMPACTION_MARKERS = ("compaction",)
+_SNAKE_BOUNDARY = re.compile(r"(?<!^)(?=[A-Z])")
+_SAFE_KEY = re.compile(r"[^a-z0-9]+")
+_GROWTH_SQL = {
+    ("query_volume", "hour"): (
+        "SELECT DATE_FORMAT(`time`, '%%Y-%%m-%%dT%%H:00:00') AS bucket, "
+        "COUNT(*) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("query_volume", "day"): (
+        "SELECT DATE(`time`) AS bucket, COUNT(*) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("query_volume", "week"): (
+        "SELECT DATE_FORMAT("
+        "DATE_SUB(DATE(`time`), INTERVAL WEEKDAY(`time`) DAY), "
+        "'%%Y-%%m-%%d') AS bucket, COUNT(*) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("user_activity", "hour"): (
+        "SELECT DATE_FORMAT(`time`, '%%Y-%%m-%%dT%%H:00:00') AS bucket, "
+        "COUNT(DISTINCT `user`) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("user_activity", "day"): (
+        "SELECT DATE(`time`) AS bucket, COUNT(DISTINCT `user`) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("user_activity", "week"): (
+        "SELECT DATE_FORMAT("
+        "DATE_SUB(DATE(`time`), INTERVAL WEEKDAY(`time`) DAY), "
+        "'%%Y-%%m-%%d') AS bucket, COUNT(DISTINCT `user`) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("storage", "hour"): (
+        "SELECT DATE_FORMAT(CREATE_TIME, '%%Y-%%m-%%dT%%H:00:00') AS bucket, "
+        "SUM(COALESCE(DATA_LENGTH, 0) + COALESCE(INDEX_LENGTH, 0)) AS value "
+        "FROM information_schema.partitions "
+        "WHERE CREATE_TIME >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("storage", "day"): (
+        "SELECT DATE(CREATE_TIME) AS bucket, "
+        "SUM(COALESCE(DATA_LENGTH, 0) + COALESCE(INDEX_LENGTH, 0)) AS value "
+        "FROM information_schema.partitions "
+        "WHERE CREATE_TIME >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+    ("storage", "week"): (
+        "SELECT DATE_FORMAT("
+        "DATE_SUB(DATE(CREATE_TIME), INTERVAL WEEKDAY(CREATE_TIME) DAY), "
+        "'%%Y-%%m-%%d') AS bucket, "
+        "SUM(COALESCE(DATA_LENGTH, 0) + COALESCE(INDEX_LENGTH, 0)) AS value "
+        "FROM information_schema.partitions "
+        "WHERE CREATE_TIME >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    ),
+}
+
+
+class ClusterRuntimeFailure(RuntimeError):
+    """Sanitized Cluster-domain failure with a stable reason code."""
+
+    def __init__(
+        self,
+        message: str,
+        *,
+        reason_code: str,
+        status_code: int,
+        retryable: bool = False,
+    ) -> None:
+        super().__init__(message)
+        self.reason_code = reason_code
+        self.status_code = status_code
+        self.retryable = retryable
+
+
+class DorisClusterRuntime:
+    """Read bounded cluster metadata and monitoring evidence without 
invention."""
+
+    def __init__(
+        self,
+        connection_manager: DorisConnectionManager,
+        monitoring_tools: DorisMonitoringTools,
+    ) -> None:
+        self._connection_manager = connection_manager
+        self._monitoring_tools = monitoring_tools
+        self._session_prefix = f"formal_cluster_{uuid.uuid4().hex[:8]}"
+
+    async def get_cluster_overview(
+        self,
+        *,
+        include: Sequence[str] | None,
+    ) -> dict[str, Any]:
+        sections = tuple(
+            dict.fromkeys(
+                include
+                or (
+                    "nodes",
+                    "tasks",
+                    "metrics",
+                    "memory",
+                    "cache",
+                    "compaction",
+                )
+            )
+        )
+        data: dict[str, Any] = {}
+        evidence: list[dict[str, Any]] = []
+        warnings: list[str] = []
+        operations = {
+            "nodes": lambda: self.list_cluster_nodes(
+                node_types=None,
+                include_metrics=False,
+            ),
+            "tasks": lambda: self.list_active_tasks(
+                task_types=None,
+                states=None,
+                limit=100,
+            ),
+            "metrics": lambda: self.get_monitoring_metrics(
+                metric_names=None,
+                node_ids=None,
+                window=None,
+            ),
+            "memory": lambda: self.get_memory_stats(
+                node_ids=None,
+                detail="summary",
+            ),
+            "cache": lambda: self.get_cache_status(
+                scope=None,
+                node_ids=None,
+                include_queues=False,
+            ),
+            "compaction": lambda: self.get_compaction_status(
+                database=None,
+                table=None,
+                state=None,
+                limit=100,
+            ),
+        }
+        for section in sections:
+            operation = operations[section]
+            try:
+                result = await operation()
+            except ClusterRuntimeFailure as exc:
+                data[section] = {
+                    "status": "unavailable",
+                    "reason_code": exc.reason_code,
+                }
+                warnings.append(
+                    f"{section} evidence is unavailable ({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "section": section,
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+                continue
+            data[section] = {
+                "status": result["status"],
+                "data": result["data"],
+            }
+            warnings.extend(result["warnings"])
+            evidence.append(
+                {
+                    "section": section,
+                    "success": True,
+                    "source": result["metadata"].get("source"),
+                }
+            )
+        if not any(item["success"] for item in evidence):
+            raise ClusterRuntimeFailure(
+                "Doris cluster evidence is unavailable.",
+                reason_code="CLUSTER_EVIDENCE_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        return _result(
+            data,
+            source="cluster_composite",
+            warnings=warnings,
+            evidence=evidence,
+            metadata={"sections": list(sections)},
+        )
+
+    async def list_cluster_nodes(
+        self,
+        *,
+        node_types: Sequence[str] | None,
+        include_metrics: bool,
+    ) -> dict[str, Any]:
+        requested = set(node_types or ("fe", "be", "broker"))
+        statements = {
+            "fe": "SHOW FRONTENDS",
+            "be": "SHOW BACKENDS",
+            "broker": "SHOW BROKER",
+        }
+        items: list[dict[str, Any]] = []
+        warnings: list[str] = []
+        successful_sources: list[str] = []
+        for node_type in ("fe", "be", "broker"):
+            if node_type not in requested:
+                continue
+            try:
+                rows = await self._execute(statements[node_type], max_rows=512)
+            except ClusterRuntimeFailure as exc:
+                if node_type in {"fe", "be"}:
+                    warnings.append(
+                        f"{node_type.upper()} metadata is unavailable "
+                        f"({exc.reason_code})."
+                    )
+                continue
+            successful_sources.append(statements[node_type])
+            items.extend(_node_item(node_type, row) for row in rows)
+        if not successful_sources:
+            raise ClusterRuntimeFailure(
+                "Doris node metadata is unavailable.",
+                reason_code="CLUSTER_NODE_METADATA_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+
+        metric_nodes: dict[str, dict[str, Any]] = {}
+        if include_metrics:
+            try:
+                monitoring_result = await self.get_monitoring_metrics(
+                    metric_names=None,
+                    node_ids=None,
+                    window=None,
+                )
+            except ClusterRuntimeFailure as exc:
+                warnings.append(f"Node metrics are unavailable 
({exc.reason_code}).")
+            else:
+                for node in monitoring_result["data"].get("nodes", []):
+                    for identity in (
+                        node.get("node_id"),
+                        node.get("host"),
+                    ):
+                        if identity:
+                            metric_nodes[str(identity)] = node.get("metrics", 
{})
+        for item in items:
+            node_metrics: dict[str, Any] | None = None
+            for identity in (item.get("node_id"), item.get("host")):
+                if identity is not None and str(identity) in metric_nodes:
+                    node_metrics = metric_nodes[str(identity)]
+                    break
+            if node_metrics is not None:
+                item["metrics"] = node_metrics
+        items.sort(
+            key=lambda item: (
+                str(item.get("node_type", "")),
+                str(item.get("node_id", "")),
+                str(item.get("host", "")),
+            )
+        )
+        return _collection(
+            items,
+            source=",".join(successful_sources),
+            warnings=warnings,
+        )
+
+    async def list_active_tasks(
+        self,
+        *,
+        task_types: Sequence[str] | None,
+        states: Sequence[str] | None,
+        limit: int | None,
+    ) -> dict[str, Any]:
+        requested_types = {value.casefold() for value in (task_types or 
("query",))}
+        max_rows = _bounded_limit(limit, default=100)
+        items: list[dict[str, Any]] = []
+        warnings: list[str] = []
+        sources: list[str] = []
+
+        if "query" in requested_types:
+            query_rows: list[Mapping[str, Any]] | None = None
+            for statement in (
+                'SHOW PROC "/current_queries"',
+                "SELECT * FROM information_schema.active_queries",
+                "SHOW FULL PROCESSLIST",
+            ):
+                try:
+                    query_rows = await self._execute(
+                        statement,
+                        max_rows=max_rows + 1,
+                    )
+                except ClusterRuntimeFailure:
+                    continue
+                sources.append(statement)
+                break
+            if query_rows is None:
+                warnings.append("Active query tasks are unavailable.")
+            else:
+                for row in query_rows:
+                    item = _normalized_row(row)
+                    command = str(item.get("command", "")).casefold()
+                    if command == "sleep":
+                        continue
+                    item["task_type"] = "query"
+                    items.append(item)
+
+        if "compaction" in requested_types:
+            try:
+                rows = await self._execute(
+                    "SELECT * FROM 
information_schema.doris_be_compaction_tasks",
+                    max_rows=max_rows + 1,
+                )
+            except ClusterRuntimeFailure:
+                warnings.append(
+                    "Compaction task detail is unavailable; use "
+                    "get_compaction_status for a summary fallback."
+                )
+            else:
+                sources.append("information_schema.doris_be_compaction_tasks")
+                for row in rows:
+                    item = _normalized_row(row)
+                    item["task_type"] = "compaction"
+                    items.append(item)
+
+        unsupported = requested_types - {"query", "compaction"}
+        if unsupported:
+            warnings.append(
+                "No cluster-wide read-only source is available for requested "
+                f"task types: {', '.join(sorted(unsupported))}."
+            )
+
+        state_filter = {value.casefold() for value in (states or ())}
+        if state_filter:
+            items = [
+                item for item in items if _task_state(item).casefold() in 
state_filter
+            ]
+        items.sort(
+            key=lambda item: (
+                str(item.get("task_type", "")),
+                str(
+                    item.get("query_id") or item.get("task_id") or 
item.get("id") or ""
+                ),
+            )
+        )
+        truncated = len(items) > max_rows
+        items = items[:max_rows]
+        if not sources and not items:
+            raise ClusterRuntimeFailure(
+                "Doris active task metadata is unavailable.",
+                reason_code="CLUSTER_TASK_METADATA_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        return _collection(
+            items,
+            source=",".join(sources) or "cluster_task_views",
+            warnings=warnings,
+            truncated=truncated,
+        )
+
+    async def get_monitoring_metrics(
+        self,
+        *,
+        metric_names: Sequence[str] | None,
+        node_ids: Sequence[str] | None,
+        window: str | None,
+    ) -> dict[str, Any]:
+        requested_names = tuple(dict.fromkeys(metric_names or ()))
+        if len(requested_names) > _MAX_METRIC_NAMES:
+            raise _argument_failure("At most 100 metric names may be 
requested.")
+        raw = await self._monitoring_tools.get_monitoring_metrics(
+            role="all",
+            monitor_type="all",
+            priority="all" if requested_names else "p0",
+            info_only=False,
+            include_raw_metrics=bool(requested_names),
+            format_type="prometheus",
+        )
+        if raw.get("success") is False:
+            raise ClusterRuntimeFailure(
+                "Doris monitoring metrics are unavailable.",
+                reason_code="CLUSTER_METRICS_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        nodes, warnings = _monitoring_nodes(
+            raw,
+            metric_names=requested_names,
+            node_ids=node_ids,
+        )
+        if not nodes:
+            raise ClusterRuntimeFailure(
+                "No readable Doris monitoring endpoint returned metrics.",
+                reason_code="CLUSTER_METRICS_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        if window:
+            warnings.append(
+                "The Doris metrics endpoint returns a point-in-time snapshot; "
+                "the requested window was not synthesized."
+            )
+        return _result(
+            {"nodes": nodes},
+            source="doris_http_metrics",
+            warnings=warnings,
+            metadata={
+                "snapshot_at": raw.get("timestamp"),
+                "requested_metric_names": list(requested_names),
+            },
+        )
+
+    async def get_memory_stats(
+        self,
+        *,
+        node_ids: Sequence[str] | None,
+        detail: str | None,
+    ) -> dict[str, Any]:
+        nodes, warnings = await self._metric_family(
+            markers=_MEMORY_MARKERS,
+            node_ids=node_ids,
+        )
+        if not nodes:
+            raise ClusterRuntimeFailure(
+                "No real Doris memory metrics were observed.",
+                reason_code="MEMORY_METRICS_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        effective_detail = detail or "summary"
+        if effective_detail == "top_consumers":
+            for node in nodes:
+                metrics = node["metrics"]
+                node["metrics"] = dict(
+                    sorted(
+                        metrics.items(),
+                        key=lambda item: _metric_total(item[1]),
+                        reverse=True,
+                    )[:20]
+                )
+        return _result(
+            {"detail": effective_detail, "nodes": nodes},
+            source="doris_be_metrics",
+            warnings=warnings,
+            metadata={"invented_values": False},
+        )
+
+    async def get_cache_status(
+        self,
+        *,
+        scope: str | None,
+        node_ids: Sequence[str] | None,
+        include_queues: bool,
+    ) -> dict[str, Any]:
+        warnings: list[str] = []
+        try:
+            rows = await self._execute(
+                "SELECT * FROM information_schema.file_cache_statistics",
+                max_rows=_MAX_ROWS,
+            )
+        except ClusterRuntimeFailure as exc:
+            warnings.append(
+                "File-cache system table is unavailable; using BE metrics "
+                f"({exc.reason_code})."
+            )
+        else:
+            items = [_normalized_row(row) for row in rows]
+            if node_ids:
+                allowed = {str(value) for value in node_ids}
+                items = [
+                    item
+                    for item in items
+                    if str(item.get("be_id", "")) in allowed
+                    or str(item.get("be_ip", "")) in allowed
+                ]
+            if scope:
+                scope_folded = scope.casefold()
+                items = [
+                    item
+                    for item in items
+                    if scope_folded
+                    in " ".join(str(value) for value in 
item.values()).casefold()
+                ]
+            if not include_queues:
+                items = [
+                    item
+                    for item in items
+                    if "queue" not in str(item.get("metric_name", 
"")).casefold()
+                ]
+            return _result(
+                {"mode": "system_table", "items": items},
+                source="information_schema.file_cache_statistics",
+                warnings=warnings,
+                metadata={"row_count": len(items)},
+            )
+
+        nodes, metric_warnings = await self._metric_family(
+            markers=_CACHE_MARKERS,
+            node_ids=node_ids,
+        )
+        warnings.extend(metric_warnings)
+        if not include_queues:
+            for node in nodes:
+                node["metrics"] = {
+                    name: value
+                    for name, value in node["metrics"].items()
+                    if "queue" not in name.casefold()
+                }
+        if scope:
+            scope_folded = scope.casefold()
+            for node in nodes:
+                node["metrics"] = {
+                    name: value
+                    for name, value in node["metrics"].items()
+                    if scope_folded in name.casefold()
+                }
+        if not any(node["metrics"] for node in nodes):
+            raise ClusterRuntimeFailure(
+                "No real Doris cache metrics were observed.",
+                reason_code="CACHE_METRICS_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        return _result(
+            {"mode": "metrics", "nodes": nodes},
+            source="doris_be_metrics",
+            warnings=warnings,
+        )
+
+    async def get_compaction_status(
+        self,
+        *,
+        database: str | None,
+        table: str | None,
+        state: str | None,
+        limit: int | None,
+    ) -> dict[str, Any]:
+        max_rows = _bounded_limit(limit, default=100)
+        try:
+            rows = await self._execute(
+                "SELECT * FROM information_schema.doris_be_compaction_tasks",
+                max_rows=max_rows + 1,
+            )
+        except ClusterRuntimeFailure as exc:
+            native_failure = exc
+        else:
+            items = [_normalized_row(row) for row in rows]
+            items = _filter_rows(
+                items,
+                database=database,
+                table=table,
+                state=state,
+            )
+            truncated = len(items) > max_rows
+            return _result(
+                {
+                    "mode": "native_task_tracker",
+                    "items": items[:max_rows],
+                    "truncated": truncated,
+                },
+                source="information_schema.doris_be_compaction_tasks",
+                metadata={"native_tracker": True},
+            )
+
+        nodes, warnings = await self._metric_family(
+            markers=_COMPACTION_MARKERS,
+            node_ids=None,
+        )
+        if not any(node["metrics"] for node in nodes):
+            raise ClusterRuntimeFailure(
+                "Doris compaction evidence is unavailable.",
+                reason_code=native_failure.reason_code,
+                status_code=native_failure.status_code,
+                retryable=native_failure.retryable,
+            )
+        warnings.insert(
+            0,
+            "Native CompactionTaskTracker is unavailable; returning aggregate "
+            "metrics without database, table, state, or task-level detail.",
+        )
+        return _result(
+            {
+                "mode": "legacy_summary",
+                "nodes": nodes,
+                "native_tracker": False,
+            },
+            source="doris_metrics_compaction_summary",
+            warnings=warnings,
+            metadata={"native_tracker": False},
+        )
+
+    async def get_workload_group_status(
+        self,
+        *,
+        name: str | None,
+        include_usage: bool,
+    ) -> dict[str, Any]:
+        rows = await self._execute("SHOW WORKLOAD GROUPS", max_rows=_MAX_ROWS)
+        items = [_normalized_row(row) for row in rows]
+        if name:
+            items = [
+                item
+                for item in items
+                if str(item.get("name", "")).casefold() == name.casefold()
+            ]
+        if not include_usage:
+            usage_markers = (
+                "current_",
+                "running_",
+                "waiting_",
+                "queue_",
+                "usage",
+            )
+            items = [
+                {
+                    key: value
+                    for key, value in item.items()
+                    if not key.startswith(usage_markers)
+                }
+                for item in items
+            ]
+        return _result(
+            {"items": items},
+            source="SHOW WORKLOAD GROUPS",
+            metadata={"row_count": len(items)},
+        )
+
+    async def get_compute_group_status(
+        self,
+        *,
+        name: str | None,
+        include_nodes: bool,
+        include_usage: bool,
+    ) -> dict[str, Any]:
+        rows = await self._execute("SHOW COMPUTE GROUPS", max_rows=_MAX_ROWS)
+        items = [_normalized_row(row) for row in rows]
+        if name:
+            items = [
+                item
+                for item in items
+                if str(
+                    item.get("name") or item.get("compute_group_name") or ""
+                ).casefold()
+                == name.casefold()
+            ]
+        if not include_nodes:
+            for item in items:
+                for key in tuple(item):
+                    if "node" in key or "backend" in key:
+                        item.pop(key, None)
+        if not include_usage:
+            for item in items:
+                for key in tuple(item):
+                    if any(
+                        marker in key
+                        for marker in ("usage", "cpu", "memory", "running", 
"queue")
+                    ):
+                        item.pop(key, None)
+        return _result(
+            {"items": items},
+            source="SHOW COMPUTE GROUPS",
+            metadata={"row_count": len(items)},
+        )
+
+    async def analyze_resource_growth(
+        self,
+        *,
+        resource: str | None,
+        window_days: int | None,
+        granularity: str | None,
+    ) -> dict[str, Any]:
+        days = _bounded_limit(window_days, default=30, maximum=3650)
+        bucket = granularity or "day"
+        requested = (
+            (resource,) if resource else ("storage", "query_volume", 
"user_activity")
+        )
+        series: dict[str, list[dict[str, Any]]] = {}
+        evidence: list[dict[str, Any]] = []
+        warnings: list[str] = []
+        for resource_name in requested:
+            sql, params = _growth_sql(resource_name, days, bucket)
+            try:
+                rows = await self._execute(
+                    sql,
+                    params=params,
+                    max_rows=_MAX_ROWS,
+                )
+            except ClusterRuntimeFailure as exc:
+                warnings.append(
+                    f"{resource_name} history is unavailable 
({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "resource": resource_name,
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+                continue
+            points = [
+                {
+                    "bucket": _row_lookup(row, "bucket"),
+                    "value": _number(_row_lookup(row, "value")),
+                }
+                for row in rows
+            ]
+            series[resource_name] = points
+            evidence.append(
+                {
+                    "resource": resource_name,
+                    "success": True,
+                    "source": _growth_source(resource_name),
+                    "points": len(points),
+                }
+            )
+            if resource_name == "storage":
+                warnings.append(
+                    "Storage growth uses partition creation evidence inside 
the "
+                    "window, not synthesized historical cluster snapshots."
+                )
+        if not series:
+            raise ClusterRuntimeFailure(
+                "Recorded Doris resource history is unavailable.",
+                reason_code="RESOURCE_HISTORY_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        summaries = {name: _growth_summary(points) for name, points in 
series.items()}
+        return _result(
+            {
+                "window_days": days,
+                "granularity": bucket,
+                "series": series,
+                "summaries": summaries,
+            },
+            source="recorded_doris_metadata",
+            warnings=warnings,
+            evidence=evidence,
+            metadata={"invented_history": False},
+        )
+
+    async def _metric_family(
+        self,
+        *,
+        markers: Sequence[str],
+        node_ids: Sequence[str] | None,
+    ) -> tuple[list[dict[str, Any]], list[str]]:
+        raw = await self._monitoring_tools.get_monitoring_metrics(
+            role="be",
+            monitor_type="all",
+            priority="all",
+            info_only=False,
+            include_raw_metrics=True,
+            format_type="prometheus",
+        )
+        if raw.get("success") is False:
+            return [], ["BE monitoring metrics are unavailable."]
+        nodes, warnings = _monitoring_nodes(
+            raw,
+            metric_names=None,
+            node_ids=node_ids,
+            markers=markers,
+        )
+        return nodes, warnings
+
+    async def _execute(
+        self,
+        sql: str,
+        *,
+        params: Mapping[str, Any] | tuple[Any, ...] | None = None,
+        max_rows: int,
+    ) -> list[Mapping[str, Any]]:
+        auth_context = get_current_auth_context()
+        session_id = f"{self._session_prefix}:{uuid.uuid4().hex[:8]}"
+        try:
+            async with (
+                
self._connection_manager.get_connection_context_for_auth_context(
+                    session_id,
+                    auth_context,
+                ) as connection
+            ):
+                result = await connection.execute(
+                    sql,
+                    params=params,
+                    auth_context=auth_context,
+                    mask_result=False,
+                    max_rows=max_rows,
+                    max_bytes=2 * 1024 * 1024,
+                )
+        except Exception as exc:
+            raise _classify_failure(exc) from exc
+        rows: list[Mapping[str, Any]] = [
+            row for row in (result.data or ()) if isinstance(row, Mapping)
+        ]
+        return rows[:max_rows]
+
+
+def _result(
+    data: Mapping[str, Any],
+    *,
+    source: str,
+    warnings: Sequence[str] = (),
+    metadata: Mapping[str, Any] | None = None,
+    evidence: Sequence[Mapping[str, Any]] | None = None,
+) -> dict[str, Any]:
+    unique_warnings = list(dict.fromkeys(str(item) for item in warnings))
+    response: dict[str, Any] = {
+        "status": "partial" if unique_warnings else "success",
+        "data": redact_sensitive_data(dict(data)),
+        "warnings": unique_warnings,
+        "metadata": {
+            "source": source,
+            **dict(metadata or {}),
+        },
+    }
+    if evidence is not None:
+        response["evidence"] = [redact_sensitive_data(dict(item)) for item in 
evidence]
+    return response
+
+
+def _collection(
+    items: Sequence[Mapping[str, Any]],
+    *,
+    source: str,
+    warnings: Sequence[str] = (),
+    truncated: bool = False,
+) -> dict[str, Any]:
+    return _result(
+        {
+            "items": [dict(item) for item in items],
+            "next_cursor": None,
+            "truncated": truncated,
+        },
+        source=source,
+        warnings=warnings,
+        metadata={"returned_items": len(items)},
+    )
+
+
+def _node_item(node_type: str, row: Mapping[str, Any]) -> dict[str, Any]:
+    normalized = _normalized_row(row)
+    node_id = next(
+        (
+            normalized.get(key)
+            for key in (
+                "backend_id",
+                "frontend_id",
+                "broker_id",
+                "name",
+                "host",
+            )
+            if normalized.get(key) not in (None, "")
+        ),
+        None,
+    )
+    host = next(
+        (
+            normalized.get(key)
+            for key in ("host", "ip", "host_name", "hostname")
+            if normalized.get(key) not in (None, "")
+        ),
+        None,
+    )
+    return {
+        "node_type": node_type,
+        "node_id": None if node_id is None else str(node_id),
+        "host": None if host is None else str(host),
+        **normalized,
+    }
+
+
+def _normalized_row(row: Mapping[str, Any]) -> dict[str, Any]:
+    return {_normalize_key(str(key)): _safe_value(value) for key, value in 
row.items()}
+
+
+def _normalize_key(value: str) -> str:
+    snake = (
+        value.casefold()
+        if value.upper() == value
+        else _SNAKE_BOUNDARY.sub("_", value).casefold()
+    )
+    return _SAFE_KEY.sub("_", snake).strip("_")
+
+
+def _safe_value(value: Any) -> Any:
+    if isinstance(value, datetime):
+        return value.isoformat()
+    if isinstance(value, bytes):
+        return value.decode("utf-8", errors="replace")
+    return value
+
+
+def _monitoring_nodes(
+    raw: Mapping[str, Any],
+    *,
+    metric_names: Sequence[str] | None,
+    node_ids: Sequence[str] | None,
+    markers: Sequence[str] | None = None,
+) -> tuple[list[dict[str, Any]], list[str]]:
+    data = raw.get("data")
+    if not isinstance(data, Mapping):
+        return [], ["Monitoring response did not contain metric data."]
+    allowed_nodes = {str(value) for value in (node_ids or ())}
+    requested_names = set(metric_names or ())
+    nodes: list[dict[str, Any]] = []
+    warnings: list[str] = []
+    be_data = data.get("be")
+    be_candidates = be_data if isinstance(be_data, list) else []
+    role_values: tuple[tuple[str, list[Any]], ...] = (
+        ("fe", [data.get("fe")]),
+        ("be", be_candidates),
+    )
+    for role, candidates in role_values:
+        for candidate in candidates:
+            if not isinstance(candidate, Mapping):
+                continue
+            if candidate.get("success") is False:
+                warnings.append(f"{role.upper()} metrics endpoint was 
unavailable.")
+                continue
+            node_info = candidate.get("node_info")
+            node_info = node_info if isinstance(node_info, Mapping) else {}
+            node_id = (
+                node_info.get("backend_id")
+                or node_info.get("name")
+                or node_info.get("host")
+                or role
+            )
+            host = node_info.get("host")
+            if (
+                allowed_nodes
+                and not {
+                    str(node_id),
+                    str(host),
+                }
+                & allowed_nodes
+            ):
+                continue
+            metrics = candidate.get("raw_metrics")
+            if not isinstance(metrics, Mapping):
+                metrics = candidate.get("metrics")
+            if not isinstance(metrics, Mapping):
+                metrics = {}
+            selected: dict[str, Any] = {}
+            for name, value in metrics.items():
+                metric_name = str(name)
+                if requested_names and metric_name not in requested_names:
+                    continue
+                if markers and not any(
+                    marker in metric_name.casefold() for marker in markers
+                ):
+                    continue
+                selected[metric_name] = _safe_value(value)
+                if len(selected) >= _MAX_METRICS_PER_NODE:
+                    warnings.append(
+                        f"{role.upper()} metric output was truncated to "
+                        f"{_MAX_METRICS_PER_NODE} names per node."
+                    )
+                    break
+            nodes.append(
+                {
+                    "role": role,
+                    "node_id": str(node_id),
+                    "host": None if host is None else str(host),
+                    "metrics": selected,
+                }
+            )
+    return nodes, list(dict.fromkeys(warnings))
+
+
+def _metric_total(value: Any) -> float:
+    if isinstance(value, int | float):
+        return float(value)
+    if isinstance(value, list):
+        return sum(
+            _metric_total(item.get("value"))
+            for item in value
+            if isinstance(item, Mapping)
+        )
+    return 0.0
+
+
+def _task_state(item: Mapping[str, Any]) -> str:
+    return str(
+        item.get("query_status")
+        or item.get("state")
+        or item.get("status")
+        or item.get("command")
+        or ""
+    )
+
+
+def _filter_rows(
+    rows: Sequence[dict[str, Any]],
+    *,
+    database: str | None,
+    table: str | None,
+    state: str | None,
+) -> list[dict[str, Any]]:
+    filters = tuple(value.casefold() for value in (database, table, state) if 
value)
+    if not filters:
+        return list(rows)
+    return [
+        row
+        for row in rows
+        if all(
+            expected in " ".join(str(value) for value in 
row.values()).casefold()
+            for expected in filters
+        )
+    ]
+
+
+def _growth_sql(
+    resource: str,
+    days: int,
+    granularity: str,
+) -> tuple[str, tuple[int]]:
+    try:
+        return _GROWTH_SQL[(resource, granularity)], (days,)
+    except KeyError:
+        if resource not in {"storage", "query_volume", "user_activity"}:
+            raise _argument_failure(
+                "resource must be storage, query_volume, or user_activity."
+            ) from None
+        raise _argument_failure("granularity must be hour, day, or week.") 
from None
+
+
+def _growth_source(resource: str) -> str:
+    if resource == "storage":
+        return "information_schema.partitions"
+    return "internal.__internal_schema.audit_log"
+
+
+def _growth_summary(points: Sequence[Mapping[str, Any]]) -> dict[str, Any]:
+    values = [
+        float(value)
+        for point in points
+        if isinstance((value := point.get("value")), int | float)
+    ]
+    if not values:
+        return {"point_count": 0, "growth_percent": None}
+    growth = None
+    if len(values) > 1 and values[0] != 0:
+        growth = round((values[-1] - values[0]) / values[0] * 100, 4)
+    return {
+        "point_count": len(values),
+        "first_value": values[0],
+        "last_value": values[-1],
+        "growth_percent": growth,
+    }
+
+
+def _row_lookup(row: Mapping[str, Any], name: str) -> Any:
+    expected = name.casefold()
+    return next(
+        (value for key, value in row.items() if str(key).casefold() == 
expected),
+        None,
+    )
+
+
+def _number(value: Any) -> int | float | None:
+    if value is None:
+        return None
+    if isinstance(value, int | float):
+        return value
+    try:
+        parsed = float(value)
+    except (TypeError, ValueError):
+        return None
+    return int(parsed) if parsed.is_integer() else parsed
+
+
+def _bounded_limit(
+    value: int | None,
+    *,
+    default: int,
+    maximum: int = _MAX_ROWS,
+) -> int:
+    if value is None:
+        return default
+    if isinstance(value, bool) or not isinstance(value, int) or value < 1:
+        raise _argument_failure("limit must be a positive integer.")
+    return min(value, maximum)
+
+
+def _argument_failure(message: str) -> ClusterRuntimeFailure:
+    return ClusterRuntimeFailure(
+        message,
+        reason_code="CLUSTER_ARGUMENT_INVALID",
+        status_code=400,
+    )
+
+
+def _classify_failure(exc: Exception) -> ClusterRuntimeFailure:
+    if isinstance(exc, ClusterRuntimeFailure):
+        return exc
+    numeric_code = next(
+        (value for value in getattr(exc, "args", ()) if isinstance(value, 
int)),
+        None,
+    )
+    message = str(exc).casefold()
+    if numeric_code in {1044, 1045, 1142, 1227} or any(
+        marker in message
+        for marker in ("access denied", "permission denied", "privilege")
+    ):
+        return ClusterRuntimeFailure(
+            "Doris denied access to cluster metadata.",
+            reason_code="CLUSTER_PERMISSION_DENIED",
+            status_code=403,
+        )
+    if numeric_code in {1064, 1109, 1146} or any(
+        marker in message
+        for marker in (
+            "doesn't exist",
+            "does not exist",
+            "not supported",
+            "unsupported",
+            "unknown table",
+        )
+    ):
+        return ClusterRuntimeFailure(
+            "The requested Doris cluster evidence source is unsupported.",
+            reason_code="CLUSTER_SOURCE_UNSUPPORTED",
+            status_code=501,
+        )
+    if isinstance(exc, TimeoutError | ConnectionError | OSError):
+        return ClusterRuntimeFailure(
+            "Doris cluster evidence is temporarily unavailable.",
+            reason_code="CLUSTER_BACKEND_UNAVAILABLE",
+            status_code=503,
+            retryable=True,
+        )
+    return ClusterRuntimeFailure(
+        "Doris cluster metadata execution failed.",
+        reason_code="CLUSTER_EXECUTION_FAILED",
+        status_code=502,
+    )
+
+
+__all__ = ["ClusterRuntimeFailure", "DorisClusterRuntime"]
diff --git a/doris_mcp_server/utils/db.py b/doris_mcp_server/utils/db.py
index 4cb03a0..934cb4a 100644
--- a/doris_mcp_server/utils/db.py
+++ b/doris_mcp_server/utils/db.py
@@ -2618,6 +2618,23 @@ class DorisConnectionManager:
                 raw_connection,
                 "unhealthy routed connection",
             )
+            if owner_pool is not None:
+                try:
+                    owner_pool.release(raw_connection)
+                    self.logger.debug(
+                        "Discarded unhealthy %s connection for route=%s 
owner=%s",
+                        getattr(connection, "pool_kind", ""),
+                        getattr(connection, "route_key", ""),
+                        getattr(connection, "owner_id", ""),
+                    )
+                except Exception as release_error:
+                    self.logger.warning(
+                        "Failed to discard unhealthy connection for route=%s "
+                        "owner=%s: %s",
+                        getattr(connection, "route_key", ""),
+                        getattr(connection, "owner_id", ""),
+                        release_error,
+                    )
             return
         if owner_pool is None:
             self.logger.warning(
diff --git a/test/integration/test_real_doris_transports.py 
b/test/integration/test_real_doris_transports.py
index 48e1236..eb9f40f 100644
--- a/test/integration/test_real_doris_transports.py
+++ b/test/integration/test_real_doris_transports.py
@@ -71,6 +71,19 @@ pytestmark = [
 
 PROJECT_ROOT = Path(__file__).resolve().parents[2]
 SAFE_IDENTIFIER = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
+CLUSTER_CHILD_NAMES = (
+    "get_cluster_overview",
+    "list_cluster_nodes",
+    "list_active_tasks",
+    "get_monitoring_metrics",
+    "get_memory_stats",
+    "get_cache_status",
+    "get_compaction_status",
+    "get_workload_group_status",
+    "get_compute_group_status",
+    "analyze_resource_growth",
+    "get_runtime_capabilities",
+)
 
 
 @dataclass(frozen=True)
@@ -419,6 +432,35 @@ async def _exec_query(
     return result, result.structured_content
 
 
+async def _call_domain_child(
+    client: Client,
+    *,
+    domain: str,
+    child_tool: str,
+    arguments: dict[str, Any],
+    manifest_version: str,
+) -> dict[str, Any]:
+    result = await client.call_tool(
+        domain,
+        {
+            "child_tool": child_tool,
+            "arguments": arguments,
+            "manifest_version": manifest_version,
+        },
+    )
+    assert result.is_error is False, json.dumps(
+        result.model_dump(by_alias=True, mode="json"),
+        ensure_ascii=False,
+    )
+    assert isinstance(result.structured_content, dict)
+    payload = result.structured_content
+    assert payload["mode"] == "result"
+    assert payload["domain"] == domain
+    assert payload["child_tool"] == child_tool
+    assert isinstance(payload["data"], dict)
+    return payload["data"]
+
+
 @pytest.mark.parametrize("transport", ["http", "stdio"])
 async def test_real_doris_result_boundaries_and_cancellation(
     transport: str,
@@ -1045,6 +1087,107 @@ async def test_real_doris_tool_regression_paths(
         assert recovered_payload["data"][0]["recovered"] == 1
 
 
[email protected](
+    os.getenv("DORIS_REAL_HTTP_INTEGRATION") != "1",
+    reason="set DORIS_REAL_HTTP_INTEGRATION=1 with independent FE/BE HTTP 
endpoints",
+)
[email protected]("transport", ["http", "stdio"])
+async def test_real_doris_hierarchical_cluster_domain_is_read_only_and_live(
+    transport: str,
+) -> None:
+    settings = _real_doris_settings()
+    environment = _server_environment(
+        settings,
+        user=settings.user,
+        password=settings.password,
+    )
+    environment["MCP_TOOL_EXPOSURE_MODE"] = "hierarchical"
+    assert environment.get("DORIS_FE_HTTP_HOST")
+    assert environment.get("DORIS_BE_HOSTS")
+
+    async with _transport_client(
+        transport,
+        environment,
+        read_timeout_seconds=60,
+    ) as client:
+        tools = {
+            tool.name: tool
+            for tool in (await client.list_tools(cache_mode="bypass")).tools
+        }
+        assert "doris_catalog" in tools
+        assert "doris_cluster" in tools
+
+        catalog_result = await client.call_tool("doris_catalog", {})
+        assert catalog_result.is_error is False
+        assert isinstance(catalog_result.structured_content, dict)
+        assert catalog_result.structured_content["mode"] == "manifest"
+        assert catalog_result.structured_content["domain"] == "doris_catalog"
+
+        cluster_result = await client.call_tool("doris_cluster", {})
+        assert cluster_result.is_error is False, json.dumps(
+            cluster_result.model_dump(by_alias=True, mode="json"),
+            ensure_ascii=False,
+        )
+        assert isinstance(cluster_result.structured_content, dict)
+        cluster_manifest = cluster_result.structured_content
+        assert cluster_manifest["mode"] == "manifest"
+        assert cluster_manifest["domain"] == "doris_cluster"
+        children = {
+            child["name"]: child
+            for child in cluster_manifest["children"]
+        }
+        assert tuple(children) == CLUSTER_CHILD_NAMES
+        manifest_version = cluster_manifest["manifest_version"]
+
+        runtime = await _call_domain_child(
+            client,
+            domain="doris_cluster",
+            child_tool="get_runtime_capabilities",
+            arguments={"detail": "full"},
+            manifest_version=manifest_version,
+        )
+        master_fe_version = runtime["data"]["versions"]["master_fe"]
+        assert master_fe_version
+
+        nodes = await _call_domain_child(
+            client,
+            domain="doris_cluster",
+            child_tool="list_cluster_nodes",
+            arguments={"node_types": ["fe", "be"], "include_metrics": False},
+            manifest_version=manifest_version,
+        )
+        assert nodes["data"]["items"]
+        assert {"fe", "be"}.issubset(
+            {item["node_type"] for item in nodes["data"]["items"]}
+        )
+
+        memory = await _call_domain_child(
+            client,
+            domain="doris_cluster",
+            child_tool="get_memory_stats",
+            arguments={"detail": "summary"},
+            manifest_version=manifest_version,
+        )
+        assert memory["metadata"]["invented_values"] is False
+
+        compaction_availability = 
children["get_compaction_status"]["availability"]
+        if master_fe_version.startswith("4.0.5"):
+            assert compaction_availability["callable"] is True
+            assert (
+                compaction_availability["active_variant"]
+                == "legacy_compaction_summary"
+            )
+            compaction = await _call_domain_child(
+                client,
+                domain="doris_cluster",
+                child_tool="get_compaction_status",
+                arguments={"limit": 20},
+                manifest_version=manifest_version,
+            )
+            assert compaction["data"]["mode"] == "legacy_summary"
+            assert compaction["data"]["native_tracker"] is False
+
+
 @pytest.mark.skipif(
     os.getenv("DORIS_REAL_HTTP_INTEGRATION") != "1",
     reason="set DORIS_REAL_HTTP_INTEGRATION=1 with independent FE/BE HTTP 
endpoints",
diff --git a/test/tools/test_capability_detector.py 
b/test/tools/test_capability_detector.py
index c452ffa..6124029 100644
--- a/test/tools/test_capability_detector.py
+++ b/test/tools/test_capability_detector.py
@@ -34,6 +34,7 @@ from doris_mcp_server.tools.capability_detector import (
 )
 from doris_mcp_server.tools.doris_feature_matrix import DORIS_FEATURE_MATRIX
 from doris_mcp_server.utils.db import DorisRouteIdentity
+from doris_mcp_server.utils.doris_http_client import DorisHTTPResponse
 from doris_mcp_server.utils.security import AuthContext
 
 
@@ -475,6 +476,42 @@ async def 
test_detector_retains_visible_backend_with_unknown_version() -> None:
     assert evaluation.reason_code == "DORIS_VERSION_UNKNOWN"
 
 
[email protected]
+async def test_detector_ignores_explicitly_dead_backend_for_version_gating() 
-> None:
+    connection = _ProbeConnection()
+    connection.row_overrides["SHOW BACKENDS"] = [
+        {
+            "BackendId": "1",
+            "Alive": "true",
+            "Version": "doris-4.0.5-rc01-59de8c4c524",
+        },
+        {
+            "BackendId": "2",
+            "Alive": "false",
+            "Version": "",
+        },
+    ]
+    detector = DorisCapabilityDetector(  # type: ignore[arg-type]
+        _ProbeConnectionManager(connection)
+    )
+
+    snapshot = await detector.detect_base(
+        None,
+        capability_generation=1,
+        provider_generation="provider.a",
+    )
+    evaluation = DORIS_FEATURE_MATRIX.evaluate(
+        domain="doris_cluster",
+        child_name="list_cluster_nodes",
+        versions=snapshot.version_vector,
+    )
+
+    assert tuple(
+        version.normalized for version in snapshot.version_vector.backends
+    ) == ("4.0.5rc1",)
+    assert evaluation.compatible is True
+
+
 @pytest.mark.asyncio
 async def 
test_detector_uses_fallback_for_unknown_master_and_retains_follower() -> None:
     connection = _ProbeConnection()
@@ -640,3 +677,105 @@ async def 
test_detector_wraps_domain_connection_failures() -> None:
         match="probe failed for doris_query",
     ):
         await detector.detect_domain(base, "doris_query", None)
+
+
[email protected]
+async def test_cluster_probe_keeps_405_compaction_on_real_legacy_evidence(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    connection = _ProbeConnection()
+    manager = _ProbeConnectionManager(connection)
+    database_config = SimpleNamespace(
+        user="root",
+        password="secret",
+        host="fe-1",
+        hosts=["fe-1"],
+        fe_http_host="fe-1",
+        fe_http_hosts=["fe-1"],
+        fe_http_port=8030,
+        be_hosts=["be-1"],
+        be_webserver_port=8040,
+    )
+    manager.config.database = database_config
+    manager.selected_database_config = database_config
+
+    native_compaction = (
+        "SELECT * "
+        "FROM information_schema.doris_be_compaction_tasks LIMIT 1"
+    )
+    connection.failures[native_compaction] = RuntimeError(
+        1146,
+        "table does not exist",
+    )
+    connection.row_overrides.update(
+        {
+            'SHOW PROC "/current_queries"': [],
+            (
+                "SELECT BE_ID, METRIC_NAME "
+                "FROM information_schema.file_cache_statistics LIMIT 1"
+            ): [{"BE_ID": 1, "METRIC_NAME": "hits_ratio"}],
+            "SHOW WORKLOAD GROUPS": [],
+            "SHOW COMPUTE GROUPS": [],
+            (
+                "SELECT `time` "
+                "FROM internal.__internal_schema.audit_log LIMIT 1"
+            ): [],
+        }
+    )
+
+    class _HTTPClient:
+        async def get_first_available(
+            self,
+            *,
+            role: str,
+            **_kwargs: Any,
+        ) -> DorisHTTPResponse:
+            metrics = (
+                "doris_fe_tablet_max_compaction_score 4\n"
+                if role == "fe"
+                else (
+                    "doris_be_memory_allocated_bytes 1024\n"
+                    "doris_be_file_cache_hits_ratio 0.8\n"
+                    "doris_be_tablet_base_max_compaction_score 7\n"
+                )
+            )
+            return DorisHTTPResponse(
+                status=200,
+                headers={},
+                body=metrics.encode(),
+                url=f"http://{role}/metrics";,
+            )
+
+    monkeypatch.setattr(
+        "doris_mcp_server.tools.capability_detector."
+        "DorisHTTPClient.from_database_config",
+        lambda _config: _HTTPClient(),
+    )
+    detector = DorisCapabilityDetector(manager)  # type: ignore[arg-type]
+    base = await detector.detect_base(
+        None,
+        capability_generation=1,
+        provider_generation="provider.a",
+    )
+
+    snapshot = await detector.detect_domain(base, "doris_cluster", None)
+
+    assert snapshot.version_vector.master_fe.normalized == "4.0.5rc1"
+    assert (
+        snapshot.probe("information_schema.doris_be_compaction_tasks").status
+        is CapabilityProbeStatus.UNSUPPORTED
+    )
+    assert (
+        snapshot.probe("compaction_system_table_or_http_api").status
+        is CapabilityProbeStatus.UNSUPPORTED
+    )
+    legacy = snapshot.probe("legacy_compaction_status_readable")
+    assert legacy is not None
+    assert legacy.status is CapabilityProbeStatus.DEGRADED
+    assert legacy.reason_code == "LEGACY_COMPACTION_SUMMARY_READABLE"
+    assert snapshot.probe("fe_metrics").status is 
CapabilityProbeStatus.SUPPORTED
+    assert snapshot.probe("be_metrics").status is 
CapabilityProbeStatus.SUPPORTED
+    assert (
+        snapshot.probe("file_cache_metrics_readable").status
+        is CapabilityProbeStatus.SUPPORTED
+    )
diff --git a/test/tools/test_capability_registry.py 
b/test/tools/test_capability_registry.py
index d5fac09..ff3a6e0 100644
--- a/test/tools/test_capability_registry.py
+++ b/test/tools/test_capability_registry.py
@@ -184,6 +184,8 @@ def 
test_evaluator_requires_version_probes_handler_and_call_permission() -> None
     assert available.status is AvailabilityStatus.AVAILABLE
     assert available.callable is True
     assert available.active_variant == "mysql_read_only"
+    assert available.reason_code == "CAPABILITY_VERIFIED_UNCERTIFIED"
+    assert available.limitations == ()
     assert missing_probe.status is AvailabilityStatus.UNKNOWN
     assert missing_probe.reason_code == "CAPABILITY_PROBE_PENDING"
     assert mixed_backends.status is AvailabilityStatus.AVAILABLE
@@ -193,6 +195,74 @@ def 
test_evaluator_requires_version_probes_handler_and_call_permission() -> None
     assert allowed.callable is True
 
 
+def test_compaction_prefers_native_tracker_and_uses_legacy_on_405() -> None:
+    evaluator = CapabilityEvaluator(
+        matrix=DORIS_FEATURE_MATRIX,
+        bound_handlers=_BoundHandlers(
+            "doris_cluster.get_compaction_status"
+        ),  # type: ignore[arg-type]
+    )
+    domain = DORIS_DOMAIN_CATALOG.resolve_domain("doris_cluster")
+    child = DORIS_DOMAIN_CATALOG.resolve_child(
+        "doris_cluster",
+        "get_compaction_status",
+    )
+    probes = {
+        "information_schema.doris_be_compaction_tasks": (
+            CapabilityProbeEvidence(
+                probe_id="information_schema.doris_be_compaction_tasks",
+                status=CapabilityProbeStatus.SUPPORTED,
+                reason_code="TEST_NATIVE_TRACKER",
+            )
+        ),
+        "compaction_system_table_or_http_api": CapabilityProbeEvidence(
+            probe_id="compaction_system_table_or_http_api",
+            status=CapabilityProbeStatus.SUPPORTED,
+            reason_code="TEST_NATIVE_TRACKER",
+        ),
+        "legacy_compaction_status_readable": CapabilityProbeEvidence(
+            probe_id="legacy_compaction_status_readable",
+            status=CapabilityProbeStatus.DEGRADED,
+            reason_code="TEST_LEGACY_SUMMARY",
+        ),
+    }
+    providers = CapabilityProviderRegistry({}).snapshot()
+    snapshot_405 = _snapshot(probes=probes)
+    snapshot_406 = replace(
+        snapshot_405,
+        version_vector=DorisClusterVersionVector.from_comments(
+            master_fe="Doris version doris-4.0.6",
+            follower_fes=("Doris version doris-4.0.6",),
+            backends=("Doris version doris-4.0.6",),
+        ),
+    )
+
+    native = evaluator.evaluate(
+        snapshot=snapshot_406,
+        providers=providers,
+        domain=domain,
+        child=child,
+        auth_context=None,
+    )
+    legacy = evaluator.evaluate(
+        snapshot=snapshot_405,
+        providers=providers,
+        domain=domain,
+        child=child,
+        auth_context=None,
+    )
+
+    assert native.callable is True
+    assert native.status is AvailabilityStatus.AVAILABLE
+    assert native.active_variant == "compaction_task_tracker"
+    assert legacy.callable is True
+    assert legacy.status is AvailabilityStatus.DEGRADED
+    assert legacy.active_variant == "legacy_compaction_summary"
+    assert legacy.reason_code == (
+        "CAPABILITY_VERIFIED_DEGRADED_UNCERTIFIED"
+    )
+
+
 def test_evaluator_normalizes_system_object_probe_evidence_for_manifest() -> 
None:
     evaluator = CapabilityEvaluator(
         matrix=DORIS_FEATURE_MATRIX,
diff --git a/test/tools/test_domain_dispatcher.py 
b/test/tools/test_domain_dispatcher.py
index 9466998..83b7738 100644
--- a/test/tools/test_domain_dispatcher.py
+++ b/test/tools/test_domain_dispatcher.py
@@ -31,6 +31,7 @@ from doris_mcp_server.tools.domain_catalog import (
     DORIS_DOMAIN_CATALOG,
 )
 from doris_mcp_server.tools.domain_dispatcher import (
+    BoundHandlerAvailabilityProvider,
     ChildArgumentsAdapterError,
     DomainDispatcher,
     ToolExposureMode,
@@ -137,6 +138,52 @@ def 
test_dispatcher_registers_exactly_47_formal_flat_names() -> None:
     assert not manager.domain_dispatcher.handles_flat("exec_query")
 
 
+def test_cluster_domain_binds_all_eleven_children() -> None:
+    manager = _manager()
+    bound = BoundHandlerAvailabilityProvider(manager)
+    cluster = DORIS_DOMAIN_CATALOG.resolve_domain("doris_cluster")
+
+    assert len(cluster.children) == 11
+    assert all(
+        bound.is_bound(cluster.name, child.name)
+        for child in cluster.children
+    )
+
+
[email protected]
+async def test_cluster_metric_filters_reach_strict_runtime_unchanged() -> None:
+    manager = _manager("doris_cluster.get_monitoring_metrics")
+    manager.cluster_runtime.get_monitoring_metrics = AsyncMock(
+        return_value={
+            "status": "success",
+            "data": {"nodes": []},
+            "warnings": [],
+            "metadata": {"source": "test_metrics"},
+        }
+    )
+
+    response = json.loads(
+        await manager.call_tool(
+            "doris_cluster",
+            {
+                "child_tool": "get_monitoring_metrics",
+                "arguments": {
+                    "metric_names": ["doris_be_cpu"],
+                    "node_ids": ["be-1"],
+                    "window": "instant",
+                },
+            },
+        )
+    )
+
+    assert response["mode"] == "result"
+    manager.cluster_runtime.get_monitoring_metrics.assert_awaited_once_with(
+        metric_names=["doris_be_cpu"],
+        node_ids=["be-1"],
+        window="instant",
+    )
+
+
 @pytest.mark.asyncio
 async def test_default_manager_fails_closed_without_capability_snapshot() -> 
None:
     manager = DorisToolsManager(_connection_manager())
@@ -476,12 +523,12 @@ async def 
test_manifest_version_unavailable_and_unbound_fail_closed() -> None:
             },
         )
     )
-    unbound_manager = _manager("doris_cluster.list_cluster_nodes")
+    unbound_manager = _manager("doris_pipeline.get_ingestion_status")
     unbound = json.loads(
         await unbound_manager.call_tool(
-            "doris_cluster",
+            "doris_pipeline",
             {
-                "child_tool": "list_cluster_nodes",
+                "child_tool": "get_ingestion_status",
                 "arguments": {},
             },
         )
@@ -1558,14 +1605,14 @@ def 
test_detail_result_normalization_adds_formal_evidence() -> None:
         (
             "adapt:monitoring_arguments",
             {"metric_names": ["qps"]},
-            {},
-            1,
+            {"metric_names": ["qps"]},
+            0,
         ),
         (
             "adapt:memory_arguments",
             {"detail": "trackers", "node_ids": ["be-1"]},
-            {"data_type": "realtime", "tracker_type": "all"},
-            1,
+            {"detail": "trackers", "node_ids": ["be-1"]},
+            0,
         ),
         (
             "adapt:audit_filters",
@@ -1683,15 +1730,16 @@ def 
test_detail_result_normalization_adds_formal_evidence() -> None:
         (
             "adapt:resource_growth_arguments",
             {
-                "resource": "memory",
+                "resource": "storage",
                 "window_days": 9,
                 "granularity": "day",
             },
             {
-                "days": 9,
-                "resource_types": ["memory"],
+                "resource": "storage",
+                "window_days": 9,
+                "granularity": "day",
             },
-            1,
+            0,
         ),
         (
             "adapt:adbc_query_arguments",
diff --git a/test/tools/test_domain_manifest.py 
b/test/tools/test_domain_manifest.py
index d53836a..9cef6f8 100644
--- a/test/tools/test_domain_manifest.py
+++ b/test/tools/test_domain_manifest.py
@@ -304,15 +304,19 @@ async def 
test_detected_version_has_priority_in_dynamic_description() -> None:
 async def test_realistic_runtime_evidence_stays_within_manifest_budget() -> 
None:
     provider = StaticAvailabilityProvider(
         _availability(
+            status=AvailabilityStatus.DEGRADED,
+            reason_code="CAPABILITY_VERIFIED_DEGRADED_UNCERTIFIED",
+            active_variant="legacy_compaction_summary",
             detected_versions={
-                "master_fe": ("4.1.3",),
-                "fe": ("4.1.3",),
-                "be": ("4.1.3",),
+                "master_fe": ("4.0.5rc1",),
+                "be": ("4.0.5rc1",),
             },
             evidence_sources=(
                 "version_probe",
                 "sql_probe",
                 "provider_config",
+                "show_frontends",
+                "show_backends",
             ),
         )
     )
diff --git a/test/tools/test_manager_routing_boundaries.py 
b/test/tools/test_manager_routing_boundaries.py
index 75d7695..f8131fa 100644
--- a/test/tools/test_manager_routing_boundaries.py
+++ b/test/tools/test_manager_routing_boundaries.py
@@ -18,7 +18,7 @@
 """Branch coverage for the manager's thin routing helpers."""
 
 from types import SimpleNamespace
-from unittest.mock import AsyncMock, call
+from unittest.mock import AsyncMock
 
 import pytest
 
@@ -35,15 +35,22 @@ def _manager() -> DorisToolsManager:
             ]
         )
     )
-    manager.memory_tracker = SimpleNamespace(
-        get_realtime_memory_stats=AsyncMock(
+    manager.cluster_runtime = SimpleNamespace(
+        get_monitoring_metrics=AsyncMock(
             return_value={
-                "success": True,
-                "timestamp": "2026-07-30T00:00:00Z",
+                "status": "success",
+                "data": {"nodes": []},
+                "warnings": [],
+                "metadata": {"source": "test"},
             }
         ),
-        get_historical_memory_stats=AsyncMock(
-            return_value={"success": True, "points": []}
+        get_memory_stats=AsyncMock(
+            return_value={
+                "status": "success",
+                "data": {"nodes": []},
+                "warnings": [],
+                "metadata": {"source": "test"},
+            }
         ),
     )
     manager.data_governance_tools = SimpleNamespace(
@@ -59,119 +66,41 @@ def _manager() -> DorisToolsManager:
 
 
 @pytest.mark.asyncio
-async def test_monitoring_metrics_routes_definitions_data_and_both():
-    definitions_manager = _manager()
-    definitions_manager.monitoring_tools.get_monitoring_metrics.side_effect = 
None
-    definitions_manager.monitoring_tools.get_monitoring_metrics.return_value = 
{
-        "success": True
-    }
-    definitions = await definitions_manager._get_monitoring_metrics_tool(
-        {
-            "content_type": "definitions",
-            "role": "fe",
-            "monitor_type": "system",
-            "priority": "all",
-        }
-    )
+async def test_monitoring_metrics_routes_formal_filters_to_cluster_runtime():
+    manager = _manager()
 
-    data_manager = _manager()
-    data_manager.monitoring_tools.get_monitoring_metrics.side_effect = None
-    data_manager.monitoring_tools.get_monitoring_metrics.return_value = {
-        "success": True
-    }
-    data = await data_manager._get_monitoring_metrics_tool(
+    result = await manager._get_monitoring_metrics_tool(
         {
-            "content_type": "data",
-            "role": "be",
-            "monitor_type": "query",
-            "priority": "core",
-            "include_raw_metrics": True,
+            "metric_names": ["doris_be_cpu"],
+            "node_ids": ["be-1"],
+            "window": "instant",
         }
     )
 
-    both_manager = _manager()
-    both = await both_manager._get_monitoring_metrics_tool({"content_type": 
"both"})
-
-    assert definitions == {"success": True}
-    
definitions_manager.monitoring_tools.get_monitoring_metrics.assert_awaited_once_with(
-        "fe", "system", "all", info_only=True, format_type="prometheus"
-    )
-    assert data == {"success": True}
-    
data_manager.monitoring_tools.get_monitoring_metrics.assert_awaited_once_with(
-        "be",
-        "query",
-        "core",
-        info_only=False,
-        format_type="prometheus",
-        include_raw_metrics=True,
+    assert result["status"] == "success"
+    manager.cluster_runtime.get_monitoring_metrics.assert_awaited_once_with(
+        metric_names=["doris_be_cpu"],
+        node_ids=["be-1"],
+        window="instant",
     )
-    assert both["content_type"] == "both"
-    assert both["timestamp"] == "2026-07-30T00:00:00Z"
-    assert both["_execution_info"] == {
-        "combined_response": True,
-        "definitions_available": True,
-        "data_available": True,
-    }
 
 
 @pytest.mark.asyncio
-async def test_monitoring_metrics_rejects_unknown_content_type():
+async def test_memory_stats_routes_formal_detail_to_cluster_runtime():
     manager = _manager()
 
-    result = await manager._get_monitoring_metrics_tool({"content_type": 
"unknown"})
-
-    assert "Invalid content_type" in result["error"]
-    manager.monitoring_tools.get_monitoring_metrics.assert_not_awaited()
-
-
[email protected]
-async def test_memory_stats_routes_realtime_historical_and_both():
-    manager = _manager()
-
-    realtime = await manager._get_memory_stats_tool(
-        {
-            "data_type": "realtime",
-            "tracker_type": "process",
-            "include_details": False,
-        }
-    )
-    historical = await manager._get_memory_stats_tool(
+    result = await manager._get_memory_stats_tool(
         {
-            "data_type": "historical",
-            "tracker_names": ["query"],
-            "time_range": "24h",
+            "detail": "top_consumers",
+            "node_ids": ["be-1"],
         }
     )
-    both = await manager._get_memory_stats_tool({"data_type": "both"})
-
-    assert realtime["success"] is True
-    assert historical == {"success": True, "points": []}
-    assert both["data_type"] == "both"
-    assert both["timestamp"] == "2026-07-30T00:00:00Z"
-    assert both["_execution_info"] == {
-        "combined_response": True,
-        "realtime_available": True,
-        "historical_available": True,
-    }
-    assert manager.memory_tracker.get_realtime_memory_stats.await_args_list == 
[
-        call("process", False),
-        call("overview", True),
-    ]
-    assert manager.memory_tracker.get_historical_memory_stats.await_args_list 
== [
-        call(["query"], "24h"),
-        call(None, "1h"),
-    ]
 
-
[email protected]
-async def test_memory_stats_rejects_unknown_data_type():
-    manager = _manager()
-
-    result = await manager._get_memory_stats_tool({"data_type": "unknown"})
-
-    assert "Invalid data_type" in result["error"]
-    manager.memory_tracker.get_realtime_memory_stats.assert_not_awaited()
-    manager.memory_tracker.get_historical_memory_stats.assert_not_awaited()
+    assert result["status"] == "success"
+    manager.cluster_runtime.get_memory_stats.assert_awaited_once_with(
+        node_ids=["be-1"],
+        detail="top_consumers",
+    )
 
 
 @pytest.mark.asyncio
diff --git a/test/utils/test_cluster_runtime.py 
b/test/utils/test_cluster_runtime.py
new file mode 100644
index 0000000..08cd3b1
--- /dev/null
+++ b/test/utils/test_cluster_runtime.py
@@ -0,0 +1,313 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Production evidence contracts for the formal Cluster runtime."""
+
+from __future__ import annotations
+
+from collections.abc import Mapping
+from contextlib import asynccontextmanager
+from types import SimpleNamespace
+from typing import Any
+
+import pytest
+
+from doris_mcp_server.utils.cluster_runtime import (
+    ClusterRuntimeFailure,
+    DorisClusterRuntime,
+)
+
+
+class _ConnectionManager:
+    def __init__(
+        self,
+        rows: dict[str, list[dict[str, Any]]] | None = None,
+        failures: dict[str, Exception] | None = None,
+    ) -> None:
+        self.rows = rows or {}
+        self.failures = failures or {}
+        self.calls: list[str] = []
+        self.params: list[Mapping[str, Any] | tuple[Any, ...] | None] = []
+
+    @asynccontextmanager
+    async def get_connection_context_for_auth_context(
+        self,
+        _session_id: str,
+        _auth_context: Any,
+    ):
+        manager = self
+
+        class _Connection:
+            async def execute(
+                self,
+                sql: str,
+                params: Mapping[str, Any] | tuple[Any, ...] | None = None,
+                **_kwargs: Any,
+            ) -> SimpleNamespace:
+                manager.calls.append(sql)
+                manager.params.append(params)
+                if sql in manager.failures:
+                    raise manager.failures[sql]
+                return SimpleNamespace(data=manager.rows.get(sql, []))
+
+        yield _Connection()
+
+
+class _MonitoringTools:
+    def __init__(self, response: dict[str, Any]) -> None:
+        self.response = response
+        self.calls: list[dict[str, Any]] = []
+
+    async def get_monitoring_metrics(self, **kwargs: Any) -> dict[str, Any]:
+        self.calls.append(kwargs)
+        return self.response
+
+
+def _metrics_response() -> dict[str, Any]:
+    return {
+        "success": True,
+        "timestamp": "2026-07-31T00:00:00Z",
+        "data": {
+            "fe": {
+                "success": True,
+                "node_info": {"host": "fe-1"},
+                "metrics": {"doris_fe_query_total": 7},
+                "raw_metrics": {
+                    "doris_fe_query_total": 7,
+                    "doris_fe_tablet_max_compaction_score": 3,
+                },
+            },
+            "be": [
+                {
+                    "success": True,
+                    "node_info": {
+                        "backend_id": "1",
+                        "host": "be-1",
+                    },
+                    "metrics": {
+                        "memory_allocated_bytes": 1024,
+                    },
+                    "raw_metrics": {
+                        "doris_be_memory_allocated_bytes": 1024,
+                        "doris_be_memory_jemalloc_active_bytes": 2048,
+                        "doris_be_file_cache_hits_ratio": 0.75,
+                        "doris_be_tablet_base_max_compaction_score": 4,
+                    },
+                }
+            ],
+        },
+    }
+
+
+def _runtime(
+    *,
+    rows: dict[str, list[dict[str, Any]]] | None = None,
+    failures: dict[str, Exception] | None = None,
+    metrics: dict[str, Any] | None = None,
+) -> tuple[DorisClusterRuntime, _ConnectionManager, _MonitoringTools]:
+    manager = _ConnectionManager(rows, failures)
+    monitoring = _MonitoringTools(metrics or _metrics_response())
+    return (
+        DorisClusterRuntime(manager, monitoring),  # type: ignore[arg-type]
+        manager,
+        monitoring,  # type: ignore[return-value]
+    )
+
+
[email protected]
+async def test_list_cluster_nodes_normalizes_real_fe_and_be_rows() -> None:
+    runtime, manager, _ = _runtime(
+        rows={
+            "SHOW FRONTENDS": [
+                {
+                    "Name": "fe-1",
+                    "Host": "10.0.0.1",
+                    "IsMaster": "true",
+                    "Version": "doris-4.0.5-rc01",
+                }
+            ],
+            "SHOW BACKENDS": [
+                {
+                    "BackendId": 10001,
+                    "Host": "10.0.0.2",
+                    "Alive": "true",
+                    "Version": "doris-4.0.5-rc01",
+                }
+            ],
+            "SHOW BROKER": [],
+        }
+    )
+
+    result = await runtime.list_cluster_nodes(
+        node_types=["fe", "be"],
+        include_metrics=False,
+    )
+
+    assert result["status"] == "success"
+    assert result["data"]["items"] == [
+        {
+            "node_type": "be",
+            "node_id": "10001",
+            "host": "10.0.0.2",
+            "backend_id": 10001,
+            "alive": "true",
+            "version": "doris-4.0.5-rc01",
+        },
+        {
+            "node_type": "fe",
+            "node_id": "fe-1",
+            "host": "10.0.0.1",
+            "name": "fe-1",
+            "is_master": "true",
+            "version": "doris-4.0.5-rc01",
+        },
+    ]
+    assert manager.calls == ["SHOW FRONTENDS", "SHOW BACKENDS"]
+
+
[email protected]
+async def test_memory_stats_only_returns_observed_metrics() -> None:
+    runtime, _, _ = _runtime()
+
+    result = await runtime.get_memory_stats(
+        node_ids=["1"],
+        detail="top_consumers",
+    )
+
+    assert result["metadata"]["invented_values"] is False
+    metrics = result["data"]["nodes"][0]["metrics"]
+    assert metrics == {
+        "doris_be_memory_jemalloc_active_bytes": 2048,
+        "doris_be_memory_allocated_bytes": 1024,
+    }
+    assert "8 GB" not in str(result)
+    assert "4.5 GB" not in str(result)
+
+
[email protected]
+async def test_cache_status_prefers_supported_system_table() -> None:
+    statement = "SELECT * FROM information_schema.file_cache_statistics"
+    runtime, manager, monitoring = _runtime(
+        rows={
+            statement: [
+                {
+                    "BE_ID": 1,
+                    "BE_IP": "be-1",
+                    "CACHE_PATH": "/cache",
+                    "METRIC_NAME": "hits_ratio",
+                    "METRIC_VALUE": 0.9,
+                },
+                {
+                    "BE_ID": 1,
+                    "BE_IP": "be-1",
+                    "CACHE_PATH": "/cache",
+                    "METRIC_NAME": "normal_queue_curr_size",
+                    "METRIC_VALUE": 10,
+                },
+            ]
+        }
+    )
+
+    result = await runtime.get_cache_status(
+        scope=None,
+        node_ids=None,
+        include_queues=False,
+    )
+
+    assert result["data"]["mode"] == "system_table"
+    assert [item["metric_name"] for item in result["data"]["items"]] == [
+        "hits_ratio"
+    ]
+    assert manager.calls == [statement]
+    assert monitoring.calls == []
+
+
[email protected]
+async def test_compaction_falls_back_to_real_metrics_without_task_detail() -> 
None:
+    native = "SELECT * FROM information_schema.doris_be_compaction_tasks"
+    runtime, _, _ = _runtime(
+        failures={native: RuntimeError(1146, "table does not exist")}
+    )
+
+    result = await runtime.get_compaction_status(
+        database="analytics",
+        table="orders",
+        state="running",
+        limit=10,
+    )
+
+    assert result["status"] == "partial"
+    assert result["data"]["mode"] == "legacy_summary"
+    assert result["data"]["native_tracker"] is False
+    assert "task-level detail" in result["warnings"][0]
+    be_node = next(
+        node for node in result["data"]["nodes"] if node["role"] == "be"
+    )
+    assert be_node["metrics"] == {
+        "doris_be_tablet_base_max_compaction_score": 4
+    }
+
+
[email protected]
+async def 
test_resource_growth_uses_recorded_rows_and_reports_partial_sources() -> None:
+    query_sql = (
+        "SELECT DATE(`time`) AS bucket, COUNT(*) AS value "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s DAY) "
+        "GROUP BY bucket ORDER BY bucket"
+    )
+    runtime, manager, _ = _runtime(
+        rows={
+            query_sql: [
+                {"bucket": "2026-07-30", "value": 10},
+                {"bucket": "2026-07-31", "value": 15},
+            ]
+        }
+    )
+
+    result = await runtime.analyze_resource_growth(
+        resource="query_volume",
+        window_days=7,
+        granularity="day",
+    )
+
+    assert manager.calls == [query_sql]
+    assert manager.params == [(7,)]
+    assert result["metadata"]["invented_history"] is False
+    assert result["data"]["summaries"]["query_volume"] == {
+        "point_count": 2,
+        "first_value": 10.0,
+        "last_value": 15.0,
+        "growth_percent": 50.0,
+    }
+    assert result["evidence"][0]["source"] == (
+        "internal.__internal_schema.audit_log"
+    )
+
+
[email protected]
+async def test_resource_growth_rejects_unknown_resource_before_sql() -> None:
+    runtime, manager, _ = _runtime()
+
+    with pytest.raises(ClusterRuntimeFailure) as error:
+        await runtime.analyze_resource_growth(
+            resource="forecast",
+            window_days=7,
+            granularity="day",
+        )
+
+    assert error.value.reason_code == "CLUSTER_ARGUMENT_INVALID"
+    assert manager.calls == []
diff --git a/test/utils/test_doris_user_pool_manager.py 
b/test/utils/test_doris_user_pool_manager.py
index 53827b7..f453892 100644
--- a/test/utils/test_doris_user_pool_manager.py
+++ b/test/utils/test_doris_user_pool_manager.py
@@ -455,7 +455,7 @@ async def 
test_release_routed_connection_force_closes_unhealthy_raw(manager):
 
     await manager.release_routed_connection(connection)
 
-    assert owner.release_calls == []
+    assert owner.release_calls == [raw_connection]
     assert raw_connection.ensure_closed_calls == 1
 
 


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

Reply via email to