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

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

commit eaa15d2d5938db23a04d5f94f4372309dd88876c
Author: FreeOnePlus <[email protected]>
AuthorDate: Fri Jul 31 17:38:05 2026 +0800

    feat: add Pipeline domain runtime
---
 CHANGELOG.md                                   |    6 +
 doris_mcp_server/tools/capability_detector.py  |  195 ++-
 doris_mcp_server/tools/domain_catalog.py       |   20 +-
 doris_mcp_server/tools/domain_dispatcher.py    |   27 +-
 doris_mcp_server/tools/pipeline_handlers.py    |  109 ++
 doris_mcp_server/tools/tools_manager.py        |    3 +
 doris_mcp_server/utils/pipeline_runtime.py     | 1958 ++++++++++++++++++++++++
 test/integration/test_real_doris_transports.py |  122 ++
 test/tools/test_capability_detector.py         |   82 +-
 test/tools/test_domain_dispatcher.py           |   57 +-
 test/utils/test_pipeline_runtime.py            |  348 +++++
 11 files changed, 2906 insertions(+), 21 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 75cd49e..7ec61bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -51,6 +51,9 @@ under **Unreleased** until a new version is selected and 
published.
 - 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.
+- A read-only Pipeline domain with five capability-gated children for
+  ingestion status and diagnosis, materialized-view refresh state, recorded
+  table freshness, and bounded upstream or downstream dependency evidence.
 - Real Doris process tests covering Streamable HTTP and stdio.
 
 ### Changed
@@ -92,6 +95,9 @@ under **Unreleased** until a new version is selected and 
published.
 
 - Released failed capability-probe connections from their captured owner pools
   so a single-connection route cannot starve subsequent domain calls.
+- Isolated Doris domain probe statements in independent route-aware connection
+  contexts so one unsupported version-specific statement cannot poison later
+  capability evidence.
 - 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.
diff --git a/doris_mcp_server/tools/capability_detector.py 
b/doris_mcp_server/tools/capability_detector.py
index 7d78779..467c4e5 100644
--- a/doris_mcp_server/tools/capability_detector.py
+++ b/doris_mcp_server/tools/capability_detector.py
@@ -216,6 +216,45 @@ _DOMAIN_PROBES: Mapping[str, tuple[tuple[str, tuple[str, 
...]], ...]] = {
             ("metrics_history_readable",),
         ),
     ),
+    "doris_pipeline": (
+        (
+            "SHOW LOAD LIMIT 1",
+            ("batch_load_metadata_readable",),
+        ),
+        (
+            "SHOW STREAM LOAD LIMIT 1",
+            ("stream_load_metadata_readable",),
+        ),
+        (
+            "SHOW ALL ROUTINE LOAD",
+            ("routine_load_metadata_readable",),
+        ),
+        (
+            'SELECT Id, Name, Status FROM jobs("type"="insert") LIMIT 1',
+            (
+                "insert_job_metadata_readable",
+                "continuous_load_metadata_readable",
+            ),
+        ),
+        (
+            'SELECT Id, Name, Status FROM jobs("type"="mv") LIMIT 1',
+            ("materialized_view_job_metadata_readable",),
+        ),
+        (
+            'SELECT TaskId, Status FROM tasks("type"="mv") LIMIT 1',
+            ("materialized_view_task_metadata_readable",),
+        ),
+        (
+            (
+                "SELECT `time`, stmt "
+                "FROM internal.__internal_schema.audit_log LIMIT 1"
+            ),
+            (
+                "pipeline_audit_log_readable",
+                "audit_log_readable",
+            ),
+        ),
+    ),
 }
 
 
@@ -306,32 +345,33 @@ class DorisCapabilityDetector:
                     "Doris route changed before domain capability probing"
                 )
 
-            session_id = (
-                
f"capability-domain:{domain_name}:{requested_route.fingerprint[:12]}"
-            )
             async with asyncio.timeout(self._probe_timeout_seconds):
-                async with (
-                    
self._connection_manager.get_connection_context_for_auth_context(
-                        session_id,
-                        auth_context,
-                    ) as connection
+                probes = dict(base.probes)
+                for index, (sql, probe_ids) in enumerate(
+                    _DOMAIN_PROBES.get(domain_name, ())
                 ):
                     current_route = self.route_identity(auth_context)
                     if current_route.fingerprint != base.route.fingerprint:
                         raise CapabilityRouteChangedError(
                             "Doris route changed during domain capability 
probing"
                         )
-                    probes = dict(base.probes)
-                    for sql, probe_ids in _DOMAIN_PROBES.get(
-                        domain_name,
-                        (),
+                    session_id = (
+                        f"capability-domain:{domain_name}:{index}:"
+                        f"{requested_route.fingerprint[:12]}"
+                    )
+                    async with (
+                        self._connection_manager
+                        .get_connection_context_for_auth_context(
+                            session_id,
+                            auth_context,
+                        ) as connection
                     ):
                         evidence = await self._probe_statement(
                             connection,
                             sql,
                             probe_ids,
                         )
-                        probes.update(evidence)
+                    probes.update(evidence)
                 if domain_name == "doris_query":
                     probes.update(await 
self._probe_query_services(auth_context))
                     probes["profile_or_audit_readable"] = 
_combine_query_evidence_probe(
@@ -339,6 +379,8 @@ class DorisCapabilityDetector:
                     )
                 elif domain_name == "doris_cluster":
                     probes.update(await 
self._safe_probe_cluster_services(auth_context))
+                elif domain_name == "doris_pipeline":
+                    probes.update(_combine_pipeline_evidence_probes(probes))
                 completed_route = self.route_identity(auth_context)
                 if completed_route.fingerprint != base.route.fingerprint:
                     raise CapabilityRouteChangedError(
@@ -1264,6 +1306,133 @@ def _combine_query_evidence_probe(
     )
 
 
+def _combine_pipeline_evidence_probes(
+    probes: Mapping[str, CapabilityProbeEvidence],
+) -> dict[str, CapabilityProbeEvidence]:
+    ingestion_source_ids = (
+        "batch_load_metadata_readable",
+        "stream_load_metadata_readable",
+        "routine_load_metadata_readable",
+    )
+    all_ingestion_source_ids = (
+        *ingestion_source_ids,
+        "insert_job_metadata_readable",
+    )
+    ingestion = _combine_any_runtime_probe(
+        "stream_broker_routine_load_readable",
+        probes,
+        ingestion_source_ids,
+        supported_reason="LOAD_JOB_METADATA_READABLE",
+    )
+    ingestion_status = _combine_any_runtime_probe(
+        "ingestion_status_readable",
+        probes,
+        all_ingestion_source_ids,
+        supported_reason="INGESTION_STATUS_READABLE",
+    )
+    materialized_views = _combine_any_runtime_probe(
+        "materialized_view_tasks_readable",
+        probes,
+        (
+            "materialized_view_job_metadata_readable",
+            "materialized_view_task_metadata_readable",
+        ),
+        supported_reason="MATERIALIZED_VIEW_METADATA_READABLE",
+    )
+
+    freshness_candidates = tuple(
+        probe
+        for probe_id in (
+            "routine_load_metadata_readable",
+            "pipeline_audit_log_readable",
+        )
+        if (probe := probes.get(probe_id)) is not None
+    )
+    if any(
+        probe.probe_id == "routine_load_metadata_readable"
+        and probe.status is CapabilityProbeStatus.SUPPORTED
+        for probe in freshness_candidates
+    ):
+        freshness_status = CapabilityProbeStatus.SUPPORTED
+        freshness_reason = "LOAD_OFFSET_OR_TIME_EVIDENCE_READABLE"
+    elif any(
+        probe.status is CapabilityProbeStatus.SUPPORTED
+        for probe in freshness_candidates
+    ):
+        freshness_status = CapabilityProbeStatus.DEGRADED
+        freshness_reason = "AUDIT_TIME_FALLBACK_READABLE"
+    else:
+        freshness_status, freshness_reason = _best_candidate_status(
+            freshness_candidates,
+            reason_prefix="FRESHNESS_EVIDENCE",
+        )
+    freshness = CapabilityProbeEvidence(
+        probe_id="freshness_evidence_readable",
+        status=freshness_status,
+        reason_code=freshness_reason,
+        evidence_sources=("runtime_probe",),
+    )
+    load_offset = CapabilityProbeEvidence(
+        probe_id="load_offset_or_time_evidence_readable",
+        status=freshness_status,
+        reason_code=freshness_reason,
+        evidence_sources=("runtime_probe",),
+    )
+    return {
+        ingestion.probe_id: ingestion,
+        ingestion_status.probe_id: ingestion_status,
+        materialized_views.probe_id: materialized_views,
+        freshness.probe_id: freshness,
+        load_offset.probe_id: load_offset,
+    }
+
+
+def _combine_any_runtime_probe(
+    probe_id: str,
+    probes: Mapping[str, CapabilityProbeEvidence],
+    candidate_ids: Sequence[str],
+    *,
+    supported_reason: str,
+) -> CapabilityProbeEvidence:
+    candidates = tuple(
+        probe
+        for candidate_id in candidate_ids
+        if (probe := probes.get(candidate_id)) is not None
+    )
+    if any(
+        probe.status is CapabilityProbeStatus.SUPPORTED for probe in candidates
+    ):
+        status = CapabilityProbeStatus.SUPPORTED
+        reason = supported_reason
+    else:
+        status, reason = _best_candidate_status(
+            candidates,
+            reason_prefix=probe_id.upper(),
+        )
+    return CapabilityProbeEvidence(
+        probe_id=probe_id,
+        status=status,
+        reason_code=reason,
+        evidence_sources=("runtime_probe",),
+    )
+
+
+def _best_candidate_status(
+    candidates: Sequence[CapabilityProbeEvidence],
+    *,
+    reason_prefix: str,
+) -> tuple[CapabilityProbeStatus, str]:
+    for status in (
+        CapabilityProbeStatus.DEGRADED,
+        CapabilityProbeStatus.MISCONFIGURED,
+        CapabilityProbeStatus.UNKNOWN,
+        CapabilityProbeStatus.UNSUPPORTED,
+    ):
+        if any(probe.status is status for probe in candidates):
+            return status, f"{reason_prefix}_{status.value.upper()}"
+    return CapabilityProbeStatus.UNKNOWN, f"{reason_prefix}_UNKNOWN"
+
+
 def _row_value(
     row: Mapping[str, Any],
     *names: str,
diff --git a/doris_mcp_server/tools/domain_catalog.py 
b/doris_mcp_server/tools/domain_catalog.py
index 63ce689..8c55845 100644
--- a/doris_mcp_server/tools/domain_catalog.py
+++ b/doris_mcp_server/tools/domain_catalog.py
@@ -1332,11 +1332,24 @@ DOMAIN_DEFINITIONS = (
                 "Read streaming and batch load job status.",
                 _input_schema(
                     {
-                        "job_types": _string_array("Load job types."),
+                        "job_types": _string_array(
+                            "Ingestion job types.",
+                            enum=(
+                                "batch_load",
+                                "stream_load",
+                                "routine_load",
+                                "insert_job",
+                                "continuous_load",
+                            ),
+                        ),
                         "database": _string("Database filter."),
                         "table": _string("Table filter."),
                         "states": _string_array("Job states."),
-                        "limit": _integer("Maximum results.", minimum=1),
+                        "limit": _integer(
+                            "Maximum results.",
+                            minimum=1,
+                            maximum=200,
+                        ),
                     }
                 ),
                 _COLLECTION_OUTPUT,
@@ -1355,6 +1368,7 @@ DOMAIN_DEFINITIONS = (
                         "window_minutes": _integer(
                             "Lookback window in minutes.",
                             minimum=1,
+                            maximum=43_200,
                         ),
                         "include_dependencies": _boolean(
                             "Include dependency evidence."
@@ -1397,6 +1411,7 @@ DOMAIN_DEFINITIONS = (
                         "threshold_seconds": _integer(
                             "Freshness threshold in seconds.",
                             minimum=1,
+                            maximum=31_536_000,
                         ),
                         "time_column": _string("Optional event-time column."),
                     },
@@ -1421,6 +1436,7 @@ DOMAIN_DEFINITIONS = (
                         "depth": _integer(
                             "Maximum traversal depth.",
                             minimum=1,
+                            maximum=5,
                         ),
                     },
                     required=("object",),
diff --git a/doris_mcp_server/tools/domain_dispatcher.py 
b/doris_mcp_server/tools/domain_dispatcher.py
index 0d8b60b..41e1ae3 100644
--- a/doris_mcp_server/tools/domain_dispatcher.py
+++ b/doris_mcp_server/tools/domain_dispatcher.py
@@ -45,6 +45,7 @@ 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.pipeline_runtime import PipelineRuntimeFailure
 from ..utils.query_runtime import QueryRuntimeFailure
 from . import domain_catalog as domain_catalog_module
 from .domain_catalog import (
@@ -168,7 +169,8 @@ def _build_bindings(
     for domain in catalog.domains:
         for child in domain.children:
             feature_id = f"{domain.name}.{child.name}"
-            if feature_id in bindings:
+            existing = bindings.get(feature_id)
+            if isinstance(existing, tuple):
                 continue
             handler_name = _formal_handler_name(domain.name, child.name)
             if callable(getattr(owner, handler_name, None)):
@@ -660,6 +662,29 @@ class DomainDispatcher:
                     "status_code": exc.status_code,
                 },
             )
+        except PipelineRuntimeFailure as exc:
+            self._audit(feature_id, arguments, "error", started)
+            return self._error(
+                domain.name,
+                (
+                    DomainErrorCode.CHILD_ARGUMENTS_INVALID
+                    if exc.reason_code
+                    in {
+                        "PIPELINE_ARGUMENT_INVALID",
+                        "PIPELINE_DATABASE_REQUIRED",
+                    }
+                    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(
diff --git a/doris_mcp_server/tools/pipeline_handlers.py 
b/doris_mcp_server/tools/pipeline_handlers.py
new file mode 100644
index 0000000..c091110
--- /dev/null
+++ b/doris_mcp_server/tools/pipeline_handlers.py
@@ -0,0 +1,109 @@
+# 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 Pipeline-domain handlers backed by one strict runtime."""
+
+from __future__ import annotations
+
+from typing import Any, Protocol, cast
+
+from ..utils.db import DorisConnectionManager
+from ..utils.pipeline_runtime import DorisPipelineRuntime
+
+
+class _PipelineHandlerOwner(Protocol):
+    """State supplied by ``DorisToolsManager`` to the mixin."""
+
+    pipeline_runtime: DorisPipelineRuntime
+
+
+class PipelineToolHandlersMixin:
+    """Route every Pipeline child through the evidence-bearing runtime."""
+
+    def _initialize_pipeline_handlers(
+        self: _PipelineHandlerOwner,
+        connection_manager: DorisConnectionManager,
+    ) -> None:
+        self.pipeline_runtime = DorisPipelineRuntime(connection_manager)
+
+    async def _formal_doris_pipeline_get_ingestion_status_tool(
+        self: _PipelineHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.pipeline_runtime.get_ingestion_status(
+            job_types=cast(list[str] | None, arguments.get("job_types")),
+            database=cast(str | None, arguments.get("database")),
+            table=cast(str | None, arguments.get("table")),
+            states=cast(list[str] | None, arguments.get("states")),
+            limit=cast(int | None, arguments.get("limit")),
+        )
+
+    async def _formal_doris_pipeline_diagnose_ingestion_tool(
+        self: _PipelineHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.pipeline_runtime.diagnose_ingestion(
+            job_id=cast(str | None, arguments.get("job_id")),
+            database=cast(str | None, arguments.get("database")),
+            table=cast(str | None, arguments.get("table")),
+            window_minutes=cast(int | None, arguments.get("window_minutes")),
+            include_dependencies=bool(
+                arguments.get("include_dependencies", True)
+            ),
+        )
+
+    async def _formal_doris_pipeline_get_materialized_view_status_tool(
+        self: _PipelineHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.pipeline_runtime.get_materialized_view_status(
+            database=cast(str | None, arguments.get("database")),
+            view=cast(str | None, arguments.get("view")),
+            states=cast(list[str] | None, arguments.get("states")),
+            include_refresh_history=bool(
+                arguments.get("include_refresh_history", False)
+            ),
+        )
+
+    async def _formal_doris_pipeline_monitor_data_freshness_tool(
+        self: _PipelineHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.pipeline_runtime.monitor_data_freshness(
+            database=cast(str, arguments.get("database")),
+            table=cast(str, arguments.get("table")),
+            threshold_seconds=cast(
+                int | None,
+                arguments.get("threshold_seconds"),
+            ),
+            time_column=cast(str | None, arguments.get("time_column")),
+        )
+
+    async def _formal_doris_pipeline_analyze_data_dependencies_tool(
+        self: _PipelineHandlerOwner,
+        arguments: dict[str, Any],
+    ) -> dict[str, Any]:
+        return await self.pipeline_runtime.analyze_data_dependencies(
+            catalog=cast(str | None, arguments.get("catalog")),
+            database=cast(str | None, arguments.get("database")),
+            object_name=cast(str, arguments.get("object")),
+            direction=cast(str | None, arguments.get("direction")),
+            depth=cast(int | None, arguments.get("depth")),
+        )
+
+
+__all__ = ["PipelineToolHandlersMixin"]
diff --git a/doris_mcp_server/tools/tools_manager.py 
b/doris_mcp_server/tools/tools_manager.py
index 246903c..78dfa73 100644
--- a/doris_mcp_server/tools/tools_manager.py
+++ b/doris_mcp_server/tools/tools_manager.py
@@ -63,6 +63,7 @@ from .domain_manifest import (
     DomainManifestService,
 )
 from .doris_feature_matrix import DORIS_FEATURE_MATRIX
+from .pipeline_handlers import PipelineToolHandlersMixin
 from .query_handlers import QueryToolHandlersMixin
 from .tool_provider import CustomToolProvider, ToolProviderRuntime
 from .tool_registry import ToolRegistryError
@@ -74,6 +75,7 @@ class DorisToolsManager(
     QueryToolHandlersMixin,
     CatalogToolHandlersMixin,
     ClusterToolHandlersMixin,
+    PipelineToolHandlersMixin,
     DomainManifestManagerMixin,
 ):
     """Apache Doris Tools Manager"""
@@ -101,6 +103,7 @@ class DorisToolsManager(
             connection_manager,
             self.monitoring_tools,
         )
+        self._initialize_pipeline_handlers(connection_manager)
 
         # Initialize v0.5.0 advanced analytics tools
         self.data_governance_tools = DataGovernanceTools(connection_manager)
diff --git a/doris_mcp_server/utils/pipeline_runtime.py 
b/doris_mcp_server/utils/pipeline_runtime.py
new file mode 100644
index 0000000..641cc16
--- /dev/null
+++ b/doris_mcp_server/utils/pipeline_runtime.py
@@ -0,0 +1,1958 @@
+# 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 Pipeline domain."""
+
+from __future__ import annotations
+
+import json
+import re
+import uuid
+from collections import deque
+from collections.abc import Mapping, Sequence
+from datetime import UTC, datetime
+from typing import Any
+
+import sqlparse
+from sqlparse import tokens as sql_tokens
+
+from .db import DorisConnectionManager
+from .redaction import redact_sensitive_data
+from .security import get_current_auth_context
+from .sql_security_utils import (
+    SQLSecurityError,
+    build_table_reference,
+    quote_identifier,
+    validate_identifier,
+)
+
+_MAX_BYTES = 2 * 1024 * 1024
+_MAX_LIMIT = 200
+_MAX_SOURCE_ROWS = 500
+_MAX_PARTITIONS = 1_000
+_MAX_DEPENDENCY_DEPTH = 5
+_MAX_DEPENDENCY_EDGES = 500
+_DEFAULT_FRESHNESS_THRESHOLD_SECONDS = 86_400
+_DEFAULT_DIAGNOSIS_WINDOW_MINUTES = 60
+_DEFAULT_DEPENDENCY_WINDOW_DAYS = 30
+_JOB_TYPES = frozenset(
+    {
+        "batch_load",
+        "stream_load",
+        "routine_load",
+        "insert_job",
+        "continuous_load",
+    }
+)
+_REFERENCE_IDENTIFIER = (
+    r"(?:`[^`]+`|[A-Za-z_][A-Za-z0-9_$]*)"
+    r"(?:\s*\.\s*(?:`[^`]+`|[A-Za-z_][A-Za-z0-9_$]*)){0,2}"
+)
+_SOURCE_REFERENCE = re.compile(
+    rf"\b(?:FROM|JOIN)\s+({_REFERENCE_IDENTIFIER})",
+    re.IGNORECASE,
+)
+_WRITE_TARGET = re.compile(
+    rf"\b(?:INSERT\s+INTO|CREATE\s+(?:MATERIALIZED\s+)?VIEW|"
+    rf"CREATE\s+TABLE)\s+({_REFERENCE_IDENTIFIER})",
+    re.IGNORECASE,
+)
+_CTE_NAME = re.compile(
+    r"(?:\bWITH|,)\s*(`[^`]+`|[A-Za-z_][A-Za-z0-9_$]*)\s+AS\s*\(",
+    re.IGNORECASE,
+)
+_ERROR_STATES = frozenset(
+    {
+        "cancelled",
+        "canceled",
+        "failed",
+        "fail",
+        "paused",
+        "stopped",
+        "error",
+    }
+)
+_RUNNING_STATES = frozenset(
+    {
+        "pending",
+        "etl",
+        "loading",
+        "running",
+        "need_schedule",
+        "waiting_txn",
+    }
+)
+_SUCCESS_STATES = frozenset({"finished", "success", "visible", "succeeded"})
+
+
+class PipelineRuntimeFailure(RuntimeError):
+    """Sanitized Pipeline-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 DorisPipelineRuntime:
+    """Read bounded ingestion, freshness, MV, and dependency evidence."""
+
+    def __init__(self, connection_manager: DorisConnectionManager) -> None:
+        self._connection_manager = connection_manager
+        self._session_prefix = f"formal_pipeline_{uuid.uuid4().hex[:8]}"
+
+    async def get_ingestion_status(
+        self,
+        *,
+        job_types: Sequence[str] | None,
+        database: str | None,
+        table: str | None,
+        states: Sequence[str] | None,
+        limit: int | None,
+    ) -> dict[str, Any]:
+        selected_types = _job_types(job_types)
+        selected_states = _normalized_filter(states)
+        result_limit = _bounded_int(limit, default=100, minimum=1, 
maximum=_MAX_LIMIT)
+        database_name = await self._resolve_database(database)
+        table_name = _optional_identifier(table, "table name")
+        fetch_limit = min(max(result_limit * 2, result_limit), 
_MAX_SOURCE_ROWS)
+
+        items: list[dict[str, Any]] = []
+        warnings: list[str] = []
+        evidence: list[dict[str, Any]] = []
+        possibly_truncated = False
+
+        async def read_source(
+            source: str,
+            statement: str,
+            normalizer: Any,
+            *,
+            database_context: str | None = None,
+        ) -> None:
+            nonlocal possibly_truncated
+            try:
+                rows = await self._execute(
+                    statement,
+                    max_rows=fetch_limit,
+                    database_context=database_context,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(f"{source} evidence is unavailable 
({exc.reason_code}).")
+                evidence.append(
+                    {
+                        "source": source,
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+                return
+            normalized_items = [
+                item
+                for row in rows
+                if (item := normalizer(row)) is not None
+            ]
+            items.extend(normalized_items)
+            possibly_truncated = possibly_truncated or len(rows) >= fetch_limit
+            evidence.append(
+                {
+                    "source": source,
+                    "success": True,
+                    "rows_observed": len(rows),
+                }
+            )
+
+        quoted_database = quote_identifier(database_name, "database name")
+        if "batch_load" in selected_types:
+            await read_source(
+                "SHOW LOAD",
+                f"SHOW LOAD FROM {quoted_database} LIMIT {fetch_limit}",
+                lambda row: _batch_load_item(row, database_name),
+            )
+        if "stream_load" in selected_types:
+            await read_source(
+                "SHOW STREAM LOAD",
+                f"SHOW STREAM LOAD FROM {quoted_database} LIMIT {fetch_limit}",
+                _stream_load_item,
+            )
+        if "routine_load" in selected_types:
+            await read_source(
+                "SHOW ALL ROUTINE LOAD",
+                "SHOW ALL ROUTINE LOAD",
+                _routine_load_item,
+                database_context=database_name,
+            )
+        if {"insert_job", "continuous_load"} & selected_types:
+            try:
+                rows = await self._execute(
+                    'SELECT * FROM jobs("type"="insert") '
+                    "ORDER BY CreateTime DESC LIMIT %s",
+                    params=(fetch_limit,),
+                    max_rows=fetch_limit,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    "Insert/continuous job evidence is unavailable "
+                    f"({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": 'jobs("type"="insert")',
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                for row in rows:
+                    item = _insert_job_item(row, database_name)
+                    if item["job_type"] in selected_types:
+                        items.append(item)
+                possibly_truncated = possibly_truncated or len(rows) >= 
fetch_limit
+                evidence.append(
+                    {
+                        "source": 'jobs("type"="insert")',
+                        "success": True,
+                        "rows_observed": len(rows),
+                    }
+                )
+
+        if not any(item.get("success") for item in evidence):
+            raise PipelineRuntimeFailure(
+                "Doris ingestion evidence is unavailable.",
+                reason_code="PIPELINE_INGESTION_EVIDENCE_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+
+        filtered: list[dict[str, Any]] = []
+        omitted_unscoped = 0
+        for item in items:
+            if selected_states and _state(item) not in selected_states:
+                continue
+            if table_name is not None:
+                observed_table = item.get("table")
+                if not isinstance(observed_table, str):
+                    omitted_unscoped += 1
+                    continue
+                if observed_table.casefold() != table_name.casefold():
+                    continue
+            observed_database = item.get("database")
+            if isinstance(observed_database, str) and (
+                observed_database.casefold() != database_name.casefold()
+            ):
+                continue
+            filtered.append(item)
+        if omitted_unscoped:
+            warnings.append(
+                "Ingestion rows without an explicit target table were omitted "
+                "from the table-scoped result."
+            )
+
+        filtered.sort(key=_job_sort_key, reverse=True)
+        truncated = possibly_truncated or len(filtered) > result_limit
+        return _collection(
+            filtered[:result_limit],
+            sources=[item["source"] for item in evidence if 
item.get("success")],
+            warnings=warnings,
+            truncated=truncated,
+            metadata={
+                "database": database_name,
+                "requested_job_types": sorted(selected_types),
+                "evidence": evidence,
+            },
+        )
+
+    async def diagnose_ingestion(
+        self,
+        *,
+        job_id: str | None,
+        database: str | None,
+        table: str | None,
+        window_minutes: int | None,
+        include_dependencies: bool,
+    ) -> dict[str, Any]:
+        normalized_job_id = _optional_text(job_id, "job identifier")
+        table_name = _optional_identifier(table, "table name")
+        if normalized_job_id is None and (database is None or table_name is 
None):
+            raise PipelineRuntimeFailure(
+                "Provide job_id or both database and table.",
+                reason_code="PIPELINE_ARGUMENT_INVALID",
+                status_code=400,
+            )
+        lookback = _bounded_int(
+            window_minutes,
+            default=_DEFAULT_DIAGNOSIS_WINDOW_MINUTES,
+            minimum=1,
+            maximum=43_200,
+        )
+        database_name = await self._resolve_database(database)
+        status_result = await self.get_ingestion_status(
+            job_types=None,
+            database=database_name,
+            table=table_name,
+            states=None,
+            limit=_MAX_LIMIT,
+        )
+        jobs = list(status_result["data"]["items"])
+        if normalized_job_id is not None:
+            jobs = [
+                item
+                for item in jobs
+                if str(item.get("job_id", "")).casefold()
+                == normalized_job_id.casefold()
+                or str(item.get("label", "")).casefold()
+                == normalized_job_id.casefold()
+                or str(item.get("name", "")).casefold()
+                == normalized_job_id.casefold()
+            ]
+
+        warnings = list(status_result["warnings"])
+        evidence: list[dict[str, Any]] = [
+            {
+                "source": "ingestion_status",
+                "matched_jobs": len(jobs),
+            }
+        ]
+        freshness: dict[str, Any] | None = None
+        dependencies: dict[str, Any] | None = None
+        if table_name is not None:
+            try:
+                freshness_result = await self.monitor_data_freshness(
+                    database=database_name,
+                    table=table_name,
+                    threshold_seconds=None,
+                    time_column=None,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    f"Freshness evidence is unavailable ({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": "freshness",
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                freshness = freshness_result["data"]
+                warnings.extend(freshness_result["warnings"])
+                evidence.extend(freshness_result["evidence"])
+            if include_dependencies:
+                try:
+                    dependency_result = await self.analyze_data_dependencies(
+                        catalog=None,
+                        database=database_name,
+                        object_name=table_name,
+                        direction="upstream",
+                        depth=2,
+                    )
+                except PipelineRuntimeFailure as exc:
+                    warnings.append(
+                        f"Dependency evidence is unavailable 
({exc.reason_code})."
+                    )
+                    evidence.append(
+                        {
+                            "source": "dependencies",
+                            "success": False,
+                            "reason_code": exc.reason_code,
+                        }
+                    )
+                else:
+                    dependencies = dependency_result["data"]
+                    warnings.extend(dependency_result["warnings"])
+                    evidence.extend(dependency_result["evidence"])
+
+        audit_events, audit_warning = await self._recent_ingestion_audit(
+            job_id=normalized_job_id,
+            database=database_name,
+            table=table_name,
+            window_minutes=lookback,
+        )
+        if audit_warning:
+            warnings.append(audit_warning)
+        evidence.append(
+            {
+                "source": "internal.__internal_schema.audit_log",
+                "rows_observed": len(audit_events),
+                "success": audit_warning is None,
+            }
+        )
+
+        findings = _ingestion_findings(jobs, freshness)
+        if not jobs:
+            warnings.append("No ingestion job matched the requested scope.")
+        data: dict[str, Any] = {
+            "scope": {
+                "job_id": normalized_job_id,
+                "database": database_name,
+                "table": table_name,
+                "window_minutes": lookback,
+            },
+            "summary": {
+                "matched_jobs": len(jobs),
+                "failed_jobs": sum(_state(item) in _ERROR_STATES for item in 
jobs),
+                "running_jobs": sum(_state(item) in _RUNNING_STATES for item 
in jobs),
+                "completed_jobs": sum(
+                    _state(item) in _SUCCESS_STATES for item in jobs
+                ),
+                "finding_count": len(findings),
+            },
+            "jobs": jobs,
+            "freshness": freshness,
+            "dependencies": dependencies,
+            "recent_audit_events": audit_events,
+            "findings": findings,
+        }
+        return _result(
+            data,
+            source="deterministic_ingestion_diagnosis",
+            warnings=warnings,
+            evidence=evidence,
+            metadata={"invented_evidence": False},
+        )
+
+    async def get_materialized_view_status(
+        self,
+        *,
+        database: str | None,
+        view: str | None,
+        states: Sequence[str] | None,
+        include_refresh_history: bool,
+    ) -> dict[str, Any]:
+        database_name = await self._resolve_database(database)
+        view_name = _optional_identifier(view, "materialized view name")
+        selected_states = _normalized_filter(states)
+        database_property = _doris_property_string(database_name)
+        source_warnings: list[str] = []
+        successful_sources: list[str] = []
+        source_evidence: list[dict[str, Any]] = []
+
+        async def optional_rows(
+            source: str,
+            statement: str,
+            *,
+            max_rows: int = _MAX_SOURCE_ROWS,
+            params: tuple[Any, ...] | None = None,
+        ) -> list[dict[str, Any]]:
+            try:
+                rows = await self._execute(
+                    statement,
+                    params=params,
+                    max_rows=max_rows,
+                )
+            except PipelineRuntimeFailure as exc:
+                source_warnings.append(
+                    f"{source} evidence is unavailable ({exc.reason_code})."
+                )
+                source_evidence.append(
+                    {
+                        "source": source,
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+                return []
+            successful_sources.append(source)
+            source_evidence.append(
+                {"source": source, "success": True, "rows_observed": len(rows)}
+            )
+            return rows
+
+        infos = await optional_rows(
+            'mv_infos("database"=...)',
+            # SQL sink audit: database_name is accepted only after
+            # validate_identifier and encoded as a Doris TVF property before
+            # DorisConnection.execute.
+            (
+                "SELECT Id, Name, JobName, State, SchemaChangeDetail, "  # 
nosec B608
+                "RefreshState, RefreshInfo, SyncWithBaseTables "
+                f'FROM mv_infos("database"={database_property}) LIMIT '
+                "500"
+            ),
+        )
+        jobs = await optional_rows(
+            'jobs("type"="mv")',
+            (
+                "SELECT Id, Name, MvId, MvName, MvDatabaseName, ExecuteType, "
+                "RecurringStrategy, Status, CreateTime "
+                'FROM jobs("type"="mv") '
+                "WHERE MvDatabaseName = %s LIMIT 500"
+            ),
+            params=(database_name,),
+        )
+        tasks: list[dict[str, Any]] = []
+        if include_refresh_history:
+            tasks = await optional_rows(
+                'tasks("type"="mv")',
+                (
+                    "SELECT TaskId, JobId, JobName, MvId, MvName, "
+                    "MvDatabaseName, Status, ErrorMsg, CreateTime, StartTime, "
+                    "FinishTime, DurationMs, RefreshMode, "
+                    "NeedRefreshPartitions, CompletedPartitions, Progress, "
+                    "LastQueryId "
+                    'FROM tasks("type"="mv") '
+                    "WHERE MvDatabaseName = %s ORDER BY CreateTime DESC LIMIT "
+                    "500"
+                ),
+                params=(database_name,),
+            )
+
+        quoted_database = quote_identifier(database_name, "database name")
+        sync_rows = await optional_rows(
+            "SHOW ALTER TABLE MATERIALIZED VIEW",
+            f"SHOW ALTER TABLE MATERIALIZED VIEW FROM {quoted_database}",
+        )
+        if not successful_sources:
+            raise PipelineRuntimeFailure(
+                "Doris materialized-view evidence is unavailable.",
+                reason_code="PIPELINE_MV_EVIDENCE_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+
+        jobs_by_view = {
+            str(_value(row, "mv_name", "MvName", "name", "Name")).casefold(): 
row
+            for row in jobs
+            if _value(row, "mv_name", "MvName", "name", "Name") not in (None, 
"")
+        }
+        tasks_by_view: dict[str, list[Mapping[str, Any]]] = {}
+        for row in tasks:
+            name = _value(row, "mv_name", "MvName")
+            if name not in (None, ""):
+                tasks_by_view.setdefault(str(name).casefold(), []).append(row)
+
+        items: list[dict[str, Any]] = []
+        seen_views: set[str] = set()
+        for row in infos:
+            normalized = _normalized_row(row)
+            name = str(normalized.get("name", ""))
+            if not name:
+                continue
+            seen_views.add(name.casefold())
+            job = jobs_by_view.get(name.casefold())
+            history = tasks_by_view.get(name.casefold(), [])
+            item = _async_mv_item(
+                normalized,
+                _normalized_row(job) if job is not None else None,
+                [_normalized_row(task) for task in history],
+                database_name=database_name,
+                include_history=include_refresh_history,
+            )
+            items.append(item)
+        for row in jobs:
+            normalized = _normalized_row(row)
+            name = str(normalized.get("mv_name") or normalized.get("name") or 
"")
+            if not name or name.casefold() in seen_views:
+                continue
+            items.append(
+                _async_mv_item(
+                    None,
+                    normalized,
+                    [
+                        _normalized_row(task)
+                        for task in tasks_by_view.get(name.casefold(), [])
+                    ],
+                    database_name=database_name,
+                    include_history=include_refresh_history,
+                )
+            )
+        items.extend(_sync_mv_item(row, database_name) for row in sync_rows)
+
+        filtered = [
+            item
+            for item in items
+            if (
+                view_name is None
+                or str(item.get("view", "")).casefold() == view_name.casefold()
+            )
+            and (
+                not selected_states
+                or str(item.get("state", "")).casefold() in selected_states
+                or str(item.get("refresh_state", "")).casefold()
+                in selected_states
+            )
+        ]
+        filtered.sort(
+            key=lambda item: (
+                str(item.get("database", "")),
+                str(item.get("view", "")),
+                str(item.get("kind", "")),
+            )
+        )
+        truncated = len(filtered) > _MAX_LIMIT or any(
+            item.get("rows_observed", 0) >= _MAX_SOURCE_ROWS
+            for item in source_evidence
+        )
+        return _collection(
+            filtered[:_MAX_LIMIT],
+            sources=successful_sources,
+            warnings=source_warnings,
+            truncated=truncated,
+            metadata={
+                "database": database_name,
+                "include_refresh_history": include_refresh_history,
+                "evidence": source_evidence,
+            },
+        )
+
+    async def monitor_data_freshness(
+        self,
+        *,
+        database: str,
+        table: str,
+        threshold_seconds: int | None,
+        time_column: str | None,
+    ) -> dict[str, Any]:
+        database_name = _required_identifier(database, "database name")
+        table_name = _required_identifier(table, "table name")
+        threshold = _bounded_int(
+            threshold_seconds,
+            default=_DEFAULT_FRESHNESS_THRESHOLD_SECONDS,
+            minimum=1,
+            maximum=31_536_000,
+        )
+        column_name = _optional_identifier(time_column, "time column")
+        table_reference = build_table_reference(table_name, database_name)
+        warnings: list[str] = []
+        evidence: list[dict[str, Any]] = []
+        observed_at: Any | None = None
+        lag_seconds: int | None = None
+        method = "unknown"
+        partitions_observed = 0
+
+        if column_name is not None:
+            quoted_column = quote_identifier(column_name, "time column")
+            try:
+                # SQL sink audit: column_name and the table components pass
+                # quote_identifier/build_table_reference before
+                # DorisConnection.execute.
+                rows = await self._execute(
+                    (
+                        f"SELECT MAX({quoted_column}) AS observed_at, "  # 
nosec B608
+                        f"TIMESTAMPDIFF(SECOND, MAX({quoted_column}), NOW()) "
+                        f"AS lag_seconds FROM {table_reference}"
+                    ),
+                    max_rows=1,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    f"Event-time evidence is unavailable ({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": f"MAX({column_name})",
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                if rows:
+                    normalized = _normalized_row(rows[0])
+                    observed_at = normalized.get("observed_at")
+                    lag_seconds = _as_int(normalized.get("lag_seconds"))
+                if observed_at is not None:
+                    method = "event_time_column"
+                evidence.append(
+                    {
+                        "source": f"MAX({column_name})",
+                        "success": observed_at is not None,
+                        "evidence_quality": "recorded_event_time",
+                    }
+                )
+
+        if observed_at is None:
+            try:
+                partitions = await self._execute(
+                    f"SHOW PARTITIONS FROM {table_reference} LIMIT 
{_MAX_PARTITIONS}",
+                    max_rows=_MAX_PARTITIONS,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    f"Visible-version evidence is unavailable 
({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": "SHOW PARTITIONS",
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                timestamps = [
+                    value
+                    for row in partitions
+                    if (
+                        value := _value(
+                            row,
+                            "VisibleVersionTime",
+                            "visible_version_time",
+                        )
+                    )
+                    not in (None, "", "N/A")
+                ]
+                partitions_observed = len(partitions)
+                if timestamps:
+                    observed_at = max(timestamps, key=lambda value: str(value))
+                    lag_seconds = _seconds_since(observed_at)
+                    method = "partition_visible_version"
+                if len(partitions) >= _MAX_PARTITIONS:
+                    warnings.append(
+                        "Partition evidence reached the server-side row limit."
+                    )
+                evidence.append(
+                    {
+                        "source": "SHOW PARTITIONS.VisibleVersionTime",
+                        "success": observed_at is not None,
+                        "rows_observed": len(partitions),
+                        "evidence_quality": "recorded_visible_version",
+                    }
+                )
+
+        if observed_at is None:
+            pattern = f"%{_escape_like(table_name)}%"
+            try:
+                rows = await self._execute(
+                    (
+                        "SELECT MAX(`time`) AS observed_at "
+                        "FROM internal.__internal_schema.audit_log "
+                        "WHERE stmt LIKE %s AND "
+                        "(UPPER(stmt) LIKE '%INSERT%' OR "
+                        "UPPER(stmt) LIKE '%LOAD%')"
+                    ),
+                    params=(pattern,),
+                    max_rows=1,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    f"Audit freshness fallback is unavailable 
({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": "audit_log",
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                if rows:
+                    observed_at = _value(rows[0], "observed_at")
+                if observed_at is not None:
+                    lag_seconds = _seconds_since(observed_at)
+                    method = "audit_statement_time"
+                    warnings.append(
+                        "Freshness is inferred from an audit statement 
timestamp, "
+                        "not a committed data version."
+                    )
+                evidence.append(
+                    {
+                        "source": "internal.__internal_schema.audit_log",
+                        "success": observed_at is not None,
+                        "evidence_quality": "inferred",
+                    }
+                )
+
+        if observed_at is None or lag_seconds is None:
+            status = "unknown"
+            warnings.append("No recorded freshness evidence was found.")
+        elif lag_seconds <= threshold:
+            status = "fresh"
+        else:
+            status = "stale"
+
+        return _result(
+            {
+                "database": database_name,
+                "table": table_name,
+                "time_column": column_name,
+                "threshold_seconds": threshold,
+                "status": status,
+                "observed_at": _json_value(observed_at),
+                "lag_seconds": lag_seconds,
+                "method": method,
+                "partitions_observed": partitions_observed,
+            },
+            source=method,
+            warnings=warnings,
+            evidence=evidence,
+            metadata={"invented_evidence": False},
+        )
+
+    async def analyze_data_dependencies(
+        self,
+        *,
+        catalog: str | None,
+        database: str | None,
+        object_name: str,
+        direction: str | None,
+        depth: int | None,
+    ) -> dict[str, Any]:
+        catalog_name = _optional_identifier(catalog, "catalog name") or 
"internal"
+        database_name = await self._resolve_database(database)
+        target_object = _required_identifier(object_name, "object name")
+        traversal_direction = direction or "both"
+        if traversal_direction not in {"upstream", "downstream", "both"}:
+            raise PipelineRuntimeFailure(
+                "Dependency direction must be upstream, downstream, or both.",
+                reason_code="PIPELINE_ARGUMENT_INVALID",
+                status_code=400,
+            )
+        max_depth = _bounded_int(
+            depth,
+            default=3,
+            minimum=1,
+            maximum=_MAX_DEPENDENCY_DEPTH,
+        )
+        target = _canonical_object(
+            target_object,
+            default_catalog=catalog_name,
+            default_database=database_name,
+        )
+        warnings: list[str] = []
+        evidence: list[dict[str, Any]] = []
+        edges: list[dict[str, Any]] = []
+
+        if catalog_name == "internal":
+            database_property = _doris_property_string(database_name)
+            try:
+                # SQL sink audit: database_name is accepted only after
+                # validate_identifier and encoded as a Doris TVF property
+                # before DorisConnection.execute.
+                mv_rows = await self._execute(
+                    (
+                        "SELECT Name, QuerySql "  # nosec B608
+                        f'FROM mv_infos("database"={database_property}) '
+                        "LIMIT 500"
+                    ),
+                    max_rows=_MAX_DEPENDENCY_EDGES,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    f"Materialized-view dependency evidence is unavailable "
+                    f"({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": "mv_infos",
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                edges.extend(
+                    _declared_edges(
+                        mv_rows,
+                        target_key="Name",
+                        sql_key="QuerySql",
+                        default_catalog=catalog_name,
+                        default_database=database_name,
+                        evidence_source="mv_infos.QuerySql",
+                        kind="materialized_view",
+                    )
+                )
+                evidence.append(
+                    {
+                        "source": "mv_infos.QuerySql",
+                        "success": True,
+                        "rows_observed": len(mv_rows),
+                    }
+                )
+
+            try:
+                view_rows = await self._execute(
+                    (
+                        "SELECT TABLE_NAME, VIEW_DEFINITION "
+                        "FROM information_schema.views "
+                        "WHERE TABLE_SCHEMA = %s "
+                        "LIMIT 500"
+                    ),
+                    params=(database_name,),
+                    max_rows=_MAX_DEPENDENCY_EDGES,
+                )
+            except PipelineRuntimeFailure as exc:
+                warnings.append(
+                    f"View dependency evidence is unavailable 
({exc.reason_code})."
+                )
+                evidence.append(
+                    {
+                        "source": "information_schema.views",
+                        "success": False,
+                        "reason_code": exc.reason_code,
+                    }
+                )
+            else:
+                edges.extend(
+                    _declared_edges(
+                        view_rows,
+                        target_key="TABLE_NAME",
+                        sql_key="VIEW_DEFINITION",
+                        default_catalog=catalog_name,
+                        default_database=database_name,
+                        evidence_source="information_schema.views",
+                        kind="view",
+                    )
+                )
+                evidence.append(
+                    {
+                        "source": "information_schema.views",
+                        "success": True,
+                        "rows_observed": len(view_rows),
+                    }
+                )
+
+        try:
+            audit_rows = await self._execute(
+                (
+                    "SELECT stmt, `time` AS observed_at "
+                    "FROM internal.__internal_schema.audit_log "
+                    "WHERE `time` >= DATE_SUB(NOW(), INTERVAL 30 DAY) "
+                    "AND (UPPER(stmt) LIKE '%INSERT%' OR "
+                    "UPPER(stmt) LIKE '%CREATE%VIEW%') "
+                    "ORDER BY `time` DESC "
+                    "LIMIT 500"
+                ),
+                max_rows=_MAX_SOURCE_ROWS,
+            )
+        except PipelineRuntimeFailure as exc:
+            warnings.append(
+                f"Audit dependency evidence is unavailable 
({exc.reason_code})."
+            )
+            evidence.append(
+                {
+                    "source": "audit_log",
+                    "success": False,
+                    "reason_code": exc.reason_code,
+                }
+            )
+        else:
+            edges.extend(
+                _audit_edges(
+                    audit_rows,
+                    default_catalog=catalog_name,
+                    default_database=database_name,
+                )
+            )
+            evidence.append(
+                {
+                    "source": "internal.__internal_schema.audit_log",
+                    "success": True,
+                    "rows_observed": len(audit_rows),
+                    "evidence_quality": "inferred",
+                }
+            )
+
+        if not any(item.get("success") for item in evidence):
+            raise PipelineRuntimeFailure(
+                "Doris dependency evidence is unavailable.",
+                reason_code="PIPELINE_DEPENDENCY_EVIDENCE_UNAVAILABLE",
+                status_code=503,
+                retryable=True,
+            )
+        merged_edges = _merge_edges(edges)[:_MAX_DEPENDENCY_EDGES]
+        graph = _traverse_dependencies(
+            target,
+            merged_edges,
+            direction=traversal_direction,
+            max_depth=max_depth,
+        )
+        if not graph["edges"]:
+            warnings.append("No recorded dependency evidence matched the 
object.")
+        return _result(
+            {
+                "target": target,
+                "direction": traversal_direction,
+                "max_depth": max_depth,
+                **graph,
+            },
+            source="recorded_dependency_graph",
+            warnings=warnings,
+            evidence=evidence,
+            metadata={
+                "invented_evidence": False,
+                "total_recorded_edges": len(merged_edges),
+            },
+        )
+
+    async def _recent_ingestion_audit(
+        self,
+        *,
+        job_id: str | None,
+        database: str,
+        table: str | None,
+        window_minutes: int,
+    ) -> tuple[list[dict[str, Any]], str | None]:
+        marker = table or job_id
+        if marker is None:
+            return [], None
+        pattern = f"%{_escape_like(marker)}%"
+        try:
+            rows = await self._execute(
+                (
+                    "SELECT `time` AS observed_at, query_id, stmt "
+                    "FROM internal.__internal_schema.audit_log "
+                    "WHERE `time` >= DATE_SUB(NOW(), INTERVAL %s MINUTE) "
+                    "AND stmt LIKE %s ORDER BY `time` DESC LIMIT 50"
+                ),
+                params=(window_minutes, pattern),
+                max_rows=50,
+            )
+        except PipelineRuntimeFailure as exc:
+            return [], f"Recent audit evidence is unavailable 
({exc.reason_code})."
+        events: list[dict[str, Any]] = []
+        for row in rows:
+            statement = str(_value(row, "stmt") or "")
+            events.append(
+                {
+                    "observed_at": _json_value(_value(row, "observed_at")),
+                    "query_id": _value(row, "query_id"),
+                    "operation": _statement_operation(statement),
+                    "referenced_objects": _extract_sources(
+                        statement,
+                        default_catalog="internal",
+                        default_database=database,
+                    )[:20],
+                }
+            )
+        return events, None
+
+    async def _resolve_database(self, database: str | None) -> str:
+        if database is not None:
+            return _required_identifier(database, "database name")
+        try:
+            rows = await self._execute(
+                "SELECT DATABASE() AS database_name",
+                max_rows=1,
+            )
+        except PipelineRuntimeFailure as exc:
+            raise PipelineRuntimeFailure(
+                "A database is required for this Pipeline operation.",
+                reason_code="PIPELINE_DATABASE_REQUIRED",
+                status_code=400,
+            ) from exc
+        value = _value(rows[0], "database_name") if rows else None
+        if not isinstance(value, str) or not value:
+            raise PipelineRuntimeFailure(
+                "A database is required for this Pipeline operation.",
+                reason_code="PIPELINE_DATABASE_REQUIRED",
+                status_code=400,
+            )
+        return _required_identifier(value, "database name")
+
+    async def _execute(
+        self,
+        sql: str,
+        *,
+        params: Mapping[str, Any] | tuple[Any, ...] | None = None,
+        max_rows: int,
+        database_context: str | None = None,
+    ) -> list[dict[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
+            ):
+                if database_context is not None:
+                    safe_database = quote_identifier(
+                        database_context,
+                        "database name",
+                    )
+                    await connection.execute(
+                        f"USE {safe_database}",
+                        auth_context=auth_context,
+                        mask_result=False,
+                        max_rows=1,
+                        max_bytes=1024,
+                    )
+                result = await connection.execute(
+                    sql,
+                    params=params,
+                    auth_context=auth_context,
+                    mask_result=False,
+                    max_rows=max_rows,
+                    max_bytes=_MAX_BYTES,
+                )
+        except Exception as exc:
+            raise _classify_failure(exc) from exc
+        return [
+            dict(row)
+            for row in (result.data or ())
+            if isinstance(row, Mapping)
+        ][: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]],
+    *,
+    sources: Sequence[str],
+    warnings: Sequence[str] = (),
+    truncated: bool,
+    metadata: Mapping[str, Any] | None = None,
+) -> dict[str, Any]:
+    return _result(
+        {
+            "items": [dict(item) for item in items],
+            "next_cursor": None,
+            "truncated": truncated,
+        },
+        source=",".join(dict.fromkeys(sources)) or "pipeline_metadata",
+        warnings=warnings,
+        metadata={
+            "returned_items": len(items),
+            **dict(metadata or {}),
+        },
+    )
+
+
+def _job_types(values: Sequence[str] | None) -> frozenset[str]:
+    if not values:
+        return _JOB_TYPES
+    normalized = frozenset(str(value).casefold() for value in values)
+    unsupported = normalized - _JOB_TYPES
+    if unsupported:
+        raise PipelineRuntimeFailure(
+            "Unsupported ingestion job type.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        )
+    return normalized
+
+
+def _normalized_filter(values: Sequence[str] | None) -> frozenset[str]:
+    return frozenset(str(value).strip().casefold() for value in values or ())
+
+
+def _bounded_int(
+    value: int | None,
+    *,
+    default: int,
+    minimum: int,
+    maximum: int,
+) -> int:
+    candidate = default if value is None else value
+    if isinstance(candidate, bool) or not isinstance(candidate, int):
+        raise PipelineRuntimeFailure(
+            "Pipeline numeric arguments must be integers.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        )
+    if candidate < minimum or candidate > maximum:
+        raise PipelineRuntimeFailure(
+            "Pipeline numeric argument is outside the supported range.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        )
+    return candidate
+
+
+def _required_identifier(value: str, label: str) -> str:
+    if not isinstance(value, str) or not value.strip():
+        raise PipelineRuntimeFailure(
+            f"{label.capitalize()} is required.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        )
+    try:
+        return validate_identifier(value.strip(), label)
+    except SQLSecurityError as exc:
+        raise PipelineRuntimeFailure(
+            f"Invalid {label}.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        ) from exc
+
+
+def _optional_identifier(value: str | None, label: str) -> str | None:
+    return None if value is None else _required_identifier(value, label)
+
+
+def _optional_text(value: str | None, label: str) -> str | None:
+    if value is None:
+        return None
+    if not isinstance(value, str) or not value.strip() or len(value) > 256:
+        raise PipelineRuntimeFailure(
+            f"Invalid {label}.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        )
+    return value.strip()
+
+
+def _normalized_row(row: Mapping[str, Any] | None) -> dict[str, Any]:
+    if row is None:
+        return {}
+    return {_snake_case(str(key)): value for key, value in row.items()}
+
+
+def _snake_case(value: str) -> str:
+    value = re.sub(r"(?<!^)(?=[A-Z])", "_", value)
+    return re.sub(r"[^a-z0-9]+", "_", value.casefold()).strip("_")
+
+
+def _value(row: Mapping[str, Any], *names: str) -> Any | None:
+    normalized = _normalized_row(row)
+    for name in names:
+        key = _snake_case(name)
+        if key in normalized:
+            return normalized[key]
+    return None
+
+
+def _batch_load_item(
+    row: Mapping[str, Any],
+    database_name: str,
+) -> dict[str, Any] | None:
+    item = _normalized_row(row)
+    job_id = item.get("job_id")
+    if job_id in (None, ""):
+        return None
+    target = _find_named_value(
+        (item.get("job_details"), item.get("task_info")),
+        {"table", "table_name", "tablename", "tbl"},
+    )
+    return {
+        "job_type": "batch_load",
+        "job_id": str(job_id),
+        "label": item.get("label"),
+        "database": database_name,
+        "table": target,
+        "state": _normalized_state(item.get("state")),
+        "progress": item.get("progress"),
+        "load_type": item.get("type"),
+        "create_time": _json_value(item.get("create_time")),
+        "start_time": _json_value(
+            item.get("load_start_time") or item.get("etl_start_time")
+        ),
+        "finish_time": _json_value(
+            item.get("load_finish_time") or item.get("etl_finish_time")
+        ),
+        "transaction_id": item.get("transaction_id"),
+        "error": item.get("first_error_msg") or item.get("error_msg"),
+        "comment": item.get("comment"),
+    }
+
+
+def _stream_load_item(row: Mapping[str, Any]) -> dict[str, Any] | None:
+    item = _normalized_row(row)
+    label = item.get("label")
+    if label in (None, ""):
+        return None
+    return {
+        "job_type": "stream_load",
+        "job_id": str(label),
+        "label": label,
+        "database": item.get("db"),
+        "table": item.get("table"),
+        "state": _normalized_state(item.get("status")),
+        "total_rows": _as_int(item.get("total_rows")),
+        "loaded_rows": _as_int(item.get("loaded_rows")),
+        "filtered_rows": _as_int(item.get("filtered_rows")),
+        "unselected_rows": _as_int(item.get("unselected_rows")),
+        "load_bytes": _as_int(item.get("load_bytes")),
+        "start_time": _json_value(item.get("start_time")),
+        "finish_time": _json_value(item.get("finish_time")),
+        "error": item.get("first_error_msg") or item.get("message"),
+        "comment": item.get("comment"),
+    }
+
+
+def _routine_load_item(row: Mapping[str, Any]) -> dict[str, Any] | None:
+    item = _normalized_row(row)
+    job_id = item.get("id")
+    if job_id in (None, ""):
+        return None
+    return {
+        "job_type": "routine_load",
+        "job_id": str(job_id),
+        "name": item.get("name"),
+        "database": item.get("db_name"),
+        "table": item.get("table_name"),
+        "state": _normalized_state(item.get("state")),
+        "data_source_type": item.get("data_source_type"),
+        "current_task_count": _as_int(item.get("current_task_num")),
+        "lag": _safe_json(item.get("lag")),
+        "progress": _safe_json(item.get("progress")),
+        "statistics": _safe_json(item.get("statistic")),
+        "create_time": _json_value(item.get("create_time")),
+        "pause_time": _json_value(item.get("pause_time")),
+        "finish_time": _json_value(item.get("end_time")),
+        "error": item.get("reason_of_state_changed") or item.get("other_msg"),
+        "compute_group": item.get("compute_group"),
+        "comment": item.get("comment"),
+    }
+
+
+def _insert_job_item(
+    row: Mapping[str, Any],
+    database_name: str,
+) -> dict[str, Any]:
+    item = _normalized_row(row)
+    statement = str(item.get("execute_sql") or "")
+    target = _extract_write_target(
+        statement,
+        default_catalog="internal",
+        default_database=database_name,
+    )
+    current_offset = item.get("current_offset")
+    end_offset = item.get("end_offset")
+    runtime_message = str(item.get("job_runtime_msg") or "")
+    continuous = any(
+        value not in (None, "", "null", "NULL")
+        for value in (current_offset, end_offset)
+    ) or "stream" in runtime_message.casefold()
+    target_parts = target.split(".") if target else []
+    return {
+        "job_type": "continuous_load" if continuous else "insert_job",
+        "job_id": str(item.get("id") or item.get("name") or ""),
+        "name": item.get("name"),
+        "database": target_parts[-2] if len(target_parts) >= 2 else None,
+        "table": target_parts[-1] if target_parts else None,
+        "state": _normalized_state(item.get("status")),
+        "execute_type": item.get("execute_type"),
+        "recurring_strategy": item.get("recurring_strategy"),
+        "create_time": _json_value(item.get("create_time")),
+        "succeeded_task_count": _as_int(item.get("succeed_task_count")),
+        "failed_task_count": _as_int(item.get("failed_task_count")),
+        "canceled_task_count": _as_int(item.get("canceled_task_count")),
+        "current_offset": _safe_json(current_offset),
+        "end_offset": _safe_json(end_offset),
+        "load_statistics": _safe_json(item.get("load_statistic")),
+        "error": item.get("error_msg"),
+        "comment": item.get("comment"),
+    }
+
+
+def _async_mv_item(
+    info: Mapping[str, Any] | None,
+    job: Mapping[str, Any] | None,
+    tasks: Sequence[Mapping[str, Any]],
+    *,
+    database_name: str,
+    include_history: bool,
+) -> dict[str, Any]:
+    view = (
+        (info or {}).get("name")
+        or (job or {}).get("mv_name")
+        or (job or {}).get("name")
+    )
+    history = [_mv_task_item(task) for task in tasks[:20]]
+    item: dict[str, Any] = {
+        "kind": "asynchronous",
+        "database": database_name,
+        "view": view,
+        "state": _normalized_state(
+            (info or {}).get("state") or (job or {}).get("status")
+        ),
+        "refresh_state": _normalized_state((info or {}).get("refresh_state")),
+        "sync_with_base_tables": _as_bool(
+            (info or {}).get("sync_with_base_tables")
+        ),
+        "refresh_info": (info or {}).get("refresh_info"),
+        "schema_change_detail": (info or {}).get("schema_change_detail"),
+        "job": {
+            "job_id": (job or {}).get("id"),
+            "job_name": (info or {}).get("job_name")
+            or (job or {}).get("name"),
+            "status": _normalized_state((job or {}).get("status")),
+            "execute_type": (job or {}).get("execute_type"),
+            "recurring_strategy": (job or {}).get("recurring_strategy"),
+            "create_time": _json_value((job or {}).get("create_time")),
+        },
+        "latest_refresh": history[0] if history else None,
+    }
+    if include_history:
+        item["refresh_history"] = history
+    return item
+
+
+def _mv_task_item(task: Mapping[str, Any]) -> dict[str, Any]:
+    return {
+        "task_id": task.get("task_id"),
+        "status": _normalized_state(task.get("status")),
+        "error": task.get("error_msg"),
+        "create_time": _json_value(task.get("create_time")),
+        "start_time": _json_value(task.get("start_time")),
+        "finish_time": _json_value(task.get("finish_time")),
+        "duration_ms": _as_int(task.get("duration_ms")),
+        "refresh_mode": task.get("refresh_mode"),
+        "progress": task.get("progress"),
+        "needed_partitions": _safe_json(task.get("need_refresh_partitions")),
+        "completed_partitions": _safe_json(task.get("completed_partitions")),
+        "last_query_id": task.get("last_query_id"),
+    }
+
+
+def _sync_mv_item(
+    row: Mapping[str, Any],
+    database_name: str,
+) -> dict[str, Any]:
+    item = _normalized_row(row)
+    return {
+        "kind": "synchronous_build",
+        "database": database_name,
+        "view": item.get("rollup_index_name") or item.get("index_name"),
+        "base_table": item.get("table_name"),
+        "job_id": item.get("job_id"),
+        "state": _normalized_state(item.get("state")),
+        "progress": item.get("progress"),
+        "create_time": _json_value(item.get("create_time")),
+        "finish_time": _json_value(item.get("finish_time")),
+        "error": item.get("msg"),
+    }
+
+
+def _ingestion_findings(
+    jobs: Sequence[Mapping[str, Any]],
+    freshness: Mapping[str, Any] | None,
+) -> list[dict[str, Any]]:
+    findings: list[dict[str, Any]] = []
+    for item in jobs:
+        state = _state(item)
+        if state in _ERROR_STATES:
+            findings.append(
+                {
+                    "severity": "high",
+                    "code": "INGESTION_JOB_NOT_HEALTHY",
+                    "job_id": item.get("job_id"),
+                    "state": state,
+                    "message": "The recorded ingestion job is not healthy.",
+                }
+            )
+        lag = _numeric_total(item.get("lag"))
+        if lag is not None and lag > 0:
+            findings.append(
+                {
+                    "severity": "medium",
+                    "code": "ROUTINE_LOAD_LAG_RECORDED",
+                    "job_id": item.get("job_id"),
+                    "lag_total": lag,
+                    "message": "Routine Load reports a positive source lag.",
+                }
+            )
+        failed_tasks = _as_int(item.get("failed_task_count"))
+        if failed_tasks is not None and failed_tasks > 0:
+            findings.append(
+                {
+                    "severity": "medium",
+                    "code": "INGESTION_TASK_FAILURES_RECORDED",
+                    "job_id": item.get("job_id"),
+                    "failed_task_count": failed_tasks,
+                    "message": "The ingestion job records failed tasks.",
+                }
+            )
+    if freshness and freshness.get("status") == "stale":
+        findings.append(
+            {
+                "severity": "medium",
+                "code": "TARGET_TABLE_STALE",
+                "lag_seconds": freshness.get("lag_seconds"),
+                "message": "The target table exceeds the freshness threshold.",
+            }
+        )
+    return findings
+
+
+def _declared_edges(
+    rows: Sequence[Mapping[str, Any]],
+    *,
+    target_key: str,
+    sql_key: str,
+    default_catalog: str,
+    default_database: str,
+    evidence_source: str,
+    kind: str,
+) -> list[dict[str, Any]]:
+    edges: list[dict[str, Any]] = []
+    for row in rows:
+        target_value = _value(row, target_key)
+        statement = _value(row, sql_key)
+        if not isinstance(target_value, str) or not isinstance(statement, str):
+            continue
+        target = _canonical_object(
+            target_value,
+            default_catalog=default_catalog,
+            default_database=default_database,
+        )
+        for source in _extract_sources(
+            statement,
+            default_catalog=default_catalog,
+            default_database=default_database,
+        ):
+            if source != target:
+                edges.append(
+                    {
+                        "source": source,
+                        "target": target,
+                        "kind": kind,
+                        "confidence": 1.0,
+                        "evidence_source": evidence_source,
+                        "observed_at": None,
+                    }
+                )
+    return edges
+
+
+def _audit_edges(
+    rows: Sequence[Mapping[str, Any]],
+    *,
+    default_catalog: str,
+    default_database: str,
+) -> list[dict[str, Any]]:
+    edges: list[dict[str, Any]] = []
+    for row in rows:
+        statement = _value(row, "stmt")
+        if not isinstance(statement, str):
+            continue
+        target = _extract_write_target(
+            statement,
+            default_catalog=default_catalog,
+            default_database=default_database,
+        )
+        if target is None:
+            continue
+        for source in _extract_sources(
+            statement,
+            default_catalog=default_catalog,
+            default_database=default_database,
+        ):
+            if source != target:
+                edges.append(
+                    {
+                        "source": source,
+                        "target": target,
+                        "kind": "audit_sql_inference",
+                        "confidence": 0.7,
+                        "evidence_source": 
"internal.__internal_schema.audit_log",
+                        "observed_at": _json_value(_value(row, "observed_at")),
+                    }
+                )
+    return edges
+
+
+def _merge_edges(edges: Sequence[Mapping[str, Any]]) -> list[dict[str, Any]]:
+    merged: dict[tuple[str, str], dict[str, Any]] = {}
+    for edge in edges:
+        source = str(edge.get("source", ""))
+        target = str(edge.get("target", ""))
+        if not source or not target:
+            continue
+        key = (source, target)
+        current = merged.get(key)
+        if current is None:
+            merged[key] = {
+                "source": source,
+                "target": target,
+                "kind": edge.get("kind"),
+                "confidence": edge.get("confidence"),
+                "evidence_sources": [edge.get("evidence_source")],
+                "observed_at": edge.get("observed_at"),
+            }
+            continue
+        current["confidence"] = max(
+            float(current.get("confidence") or 0),
+            float(edge.get("confidence") or 0),
+        )
+        current["evidence_sources"] = list(
+            dict.fromkeys(
+                [
+                    *current["evidence_sources"],
+                    edge.get("evidence_source"),
+                ]
+            )
+        )
+        if edge.get("observed_at") is not None:
+            current["observed_at"] = max(
+                str(current.get("observed_at") or ""),
+                str(edge["observed_at"]),
+            )
+    return sorted(merged.values(), key=lambda item: (item["source"], 
item["target"]))
+
+
+def _traverse_dependencies(
+    target: str,
+    edges: Sequence[Mapping[str, Any]],
+    *,
+    direction: str,
+    max_depth: int,
+) -> dict[str, Any]:
+    adjacency_up: dict[str, list[Mapping[str, Any]]] = {}
+    adjacency_down: dict[str, list[Mapping[str, Any]]] = {}
+    for edge in edges:
+        source = str(edge["source"])
+        destination = str(edge["target"])
+        adjacency_up.setdefault(destination, []).append(edge)
+        adjacency_down.setdefault(source, []).append(edge)
+
+    selected_edges: dict[tuple[str, str], Mapping[str, Any]] = {}
+    paths: list[dict[str, Any]] = []
+    directions = (
+        ("upstream", adjacency_up)
+        if direction == "upstream"
+        else (
+            ("downstream", adjacency_down)
+            if direction == "downstream"
+            else None
+        )
+    )
+    direction_pairs = (
+        (directions,)
+        if directions is not None
+        else (("upstream", adjacency_up), ("downstream", adjacency_down))
+    )
+    for traversal_name, adjacency in direction_pairs:
+        queue: deque[tuple[str, list[str], int]] = deque([(target, [target], 
0)])
+        visited: set[tuple[str, int]] = {(target, 0)}
+        while queue:
+            current, path, current_depth = queue.popleft()
+            if current_depth >= max_depth:
+                continue
+            for edge in adjacency.get(current, ()):
+                source = str(edge["source"])
+                destination = str(edge["target"])
+                next_node = (
+                    source if traversal_name == "upstream" else destination
+                )
+                selected_edges[(source, destination)] = edge
+                next_path = [*path, next_node]
+                paths.append(
+                    {
+                        "direction": traversal_name,
+                        "depth": current_depth + 1,
+                        "nodes": next_path,
+                    }
+                )
+                marker = (next_node, current_depth + 1)
+                if marker not in visited:
+                    visited.add(marker)
+                    queue.append((next_node, next_path, current_depth + 1))
+
+    edge_items = sorted(
+        (dict(edge) for edge in selected_edges.values()),
+        key=lambda item: (item["source"], item["target"]),
+    )
+    nodes = sorted(
+        {
+            target,
+            *(
+                str(value)
+                for edge in edge_items
+                for value in (edge["source"], edge["target"])
+            ),
+        }
+    )
+    paths.sort(key=lambda item: (item["direction"], item["depth"], 
item["nodes"]))
+    return {"nodes": nodes, "edges": edge_items, "paths": paths}
+
+
+def _extract_sources(
+    sql: str,
+    *,
+    default_catalog: str,
+    default_database: str,
+) -> list[str]:
+    cleaned = _sql_structure(sql)
+    cte_names = {
+        _strip_identifier(match.group(1)).casefold()
+        for match in _CTE_NAME.finditer(cleaned)
+    }
+    sources = []
+    for match in _SOURCE_REFERENCE.finditer(cleaned):
+        raw = match.group(1)
+        if _strip_identifier(raw).casefold() in cte_names:
+            continue
+        try:
+            source = _canonical_object(
+                raw,
+                default_catalog=default_catalog,
+                default_database=default_database,
+            )
+        except PipelineRuntimeFailure:
+            continue
+        sources.append(source)
+    return list(dict.fromkeys(sources))
+
+
+def _extract_write_target(
+    sql: str,
+    *,
+    default_catalog: str,
+    default_database: str,
+) -> str | None:
+    cleaned = _sql_structure(sql)
+    match = _WRITE_TARGET.search(cleaned)
+    if match is None:
+        return None
+    try:
+        return _canonical_object(
+            match.group(1),
+            default_catalog=default_catalog,
+            default_database=default_database,
+        )
+    except PipelineRuntimeFailure:
+        return None
+
+
+def _sql_structure(sql: str) -> str:
+    statements = sqlparse.parse(sql)
+    if not statements:
+        return ""
+    parts: list[str] = []
+    for token in statements[0].flatten():
+        token_type = token.ttype
+        if token_type in sql_tokens.Comment or token_type in 
sql_tokens.Literal.String:
+            parts.append(" ")
+        else:
+            parts.append(token.value)
+    return "".join(parts)
+
+
+def _canonical_object(
+    value: str,
+    *,
+    default_catalog: str,
+    default_database: str,
+) -> str:
+    parts = [
+        _strip_identifier(part)
+        for part in re.split(r"\s*\.\s*", value.strip())
+        if part.strip()
+    ]
+    if len(parts) == 1:
+        parts = [default_catalog, default_database, parts[0]]
+    elif len(parts) == 2:
+        parts = [default_catalog, *parts]
+    elif len(parts) != 3:
+        raise PipelineRuntimeFailure(
+            "Invalid object reference.",
+            reason_code="PIPELINE_ARGUMENT_INVALID",
+            status_code=400,
+        )
+    validated = [
+        _required_identifier(part, "object identifier")
+        for part in parts
+    ]
+    return ".".join(validated)
+
+
+def _strip_identifier(value: str) -> str:
+    return value.strip().strip("`").strip('"')
+
+
+def _statement_operation(statement: str) -> str:
+    cleaned = _sql_structure(statement).lstrip()
+    match = re.match(r"([A-Za-z]+)", cleaned)
+    return match.group(1).upper() if match else "UNKNOWN"
+
+
+def _find_named_value(
+    values: Sequence[Any],
+    keys: set[str],
+) -> str | None:
+    for value in values:
+        parsed = _safe_json(value)
+        if isinstance(parsed, Mapping):
+            for key, candidate in parsed.items():
+                if _snake_case(str(key)) in keys and isinstance(candidate, 
str):
+                    try:
+                        return validate_identifier(candidate, "table name")
+                    except SQLSecurityError:
+                        continue
+    return None
+
+
+def _safe_json(value: Any) -> Any:
+    if not isinstance(value, str):
+        return _json_value(value)
+    stripped = value.strip()
+    if not stripped:
+        return None
+    try:
+        parsed = json.loads(stripped)
+    except (TypeError, ValueError):
+        return stripped[:512]
+    return _json_value(parsed)
+
+
+def _json_value(value: Any) -> Any:
+    if isinstance(value, datetime):
+        return value.isoformat()
+    if isinstance(value, Mapping):
+        return {str(key): _json_value(item) for key, item in value.items()}
+    if isinstance(value, Sequence) and not isinstance(value, str | bytes):
+        return [_json_value(item) for item in value]
+    if isinstance(value, bytes):
+        return value.decode("utf-8", errors="replace")
+    return value
+
+
+def _normalized_state(value: Any) -> str | None:
+    if value in (None, ""):
+        return None
+    return str(value).strip().casefold()
+
+
+def _state(item: Mapping[str, Any]) -> str:
+    return str(item.get("state") or "").casefold()
+
+
+def _job_sort_key(item: Mapping[str, Any]) -> str:
+    for key in ("finish_time", "start_time", "create_time"):
+        value = item.get(key)
+        if value not in (None, ""):
+            return str(value)
+    return ""
+
+
+def _as_int(value: Any) -> int | None:
+    if value in (None, "") or isinstance(value, bool):
+        return None
+    try:
+        return int(value)
+    except (TypeError, ValueError):
+        return None
+
+
+def _as_bool(value: Any) -> bool | None:
+    if isinstance(value, bool):
+        return value
+    if isinstance(value, int):
+        return value != 0
+    if isinstance(value, str):
+        if value.casefold() in {"1", "true", "yes"}:
+            return True
+        if value.casefold() in {"0", "false", "no"}:
+            return False
+    return None
+
+
+def _numeric_total(value: Any) -> float | None:
+    if isinstance(value, int | float) and not isinstance(value, bool):
+        return float(value)
+    if isinstance(value, Mapping):
+        numbers = [
+            float(item)
+            for item in value.values()
+            if isinstance(item, int | float) and not isinstance(item, bool)
+        ]
+        return sum(numbers) if numbers else None
+    return None
+
+
+def _seconds_since(value: Any) -> int | None:
+    if isinstance(value, datetime):
+        observed = value
+    elif isinstance(value, str):
+        try:
+            observed = datetime.fromisoformat(value.replace("Z", "+00:00"))
+        except ValueError:
+            return None
+    else:
+        return None
+    now = datetime.now(UTC) if observed.tzinfo is not None else datetime.now()
+    return max(0, int((now - observed).total_seconds()))
+
+
+def _escape_like(value: str) -> str:
+    return value.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
+
+
+def _doris_property_string(value: str) -> str:
+    return '"' + value.replace("\\", "\\\\").replace('"', '\\"') + '"'
+
+
+def _classify_failure(exc: Exception) -> PipelineRuntimeFailure:
+    if isinstance(exc, PipelineRuntimeFailure):
+        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 PipelineRuntimeFailure(
+            "Doris denied access to Pipeline metadata.",
+            reason_code="PIPELINE_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",
+            "no viable alternative",
+        )
+    ):
+        return PipelineRuntimeFailure(
+            "The requested Doris Pipeline evidence source is unsupported.",
+            reason_code="PIPELINE_SOURCE_UNSUPPORTED",
+            status_code=501,
+        )
+    if isinstance(exc, TimeoutError | ConnectionError | OSError):
+        return PipelineRuntimeFailure(
+            "Doris Pipeline evidence is temporarily unavailable.",
+            reason_code="PIPELINE_BACKEND_UNAVAILABLE",
+            status_code=503,
+            retryable=True,
+        )
+    return PipelineRuntimeFailure(
+        "Doris Pipeline metadata execution failed.",
+        reason_code="PIPELINE_EXECUTION_FAILED",
+        status_code=502,
+    )
+
+
+__all__ = ["DorisPipelineRuntime", "PipelineRuntimeFailure"]
diff --git a/test/integration/test_real_doris_transports.py 
b/test/integration/test_real_doris_transports.py
index eb9f40f..cfbfa50 100644
--- a/test/integration/test_real_doris_transports.py
+++ b/test/integration/test_real_doris_transports.py
@@ -84,6 +84,13 @@ CLUSTER_CHILD_NAMES = (
     "analyze_resource_growth",
     "get_runtime_capabilities",
 )
+PIPELINE_CHILD_NAMES = (
+    "get_ingestion_status",
+    "diagnose_ingestion",
+    "get_materialized_view_status",
+    "monitor_data_freshness",
+    "analyze_data_dependencies",
+)
 
 
 @dataclass(frozen=True)
@@ -1188,6 +1195,121 @@ async def 
test_real_doris_hierarchical_cluster_domain_is_read_only_and_live(
             assert compaction["data"]["native_tracker"] is False
 
 
[email protected]("transport", ["http", "stdio"])
+async def test_real_doris_hierarchical_pipeline_domain_is_read_only_and_live(
+    transport: str,
+    doris_sandbox: DorisSandbox,
+) -> None:
+    environment = _server_environment(
+        doris_sandbox.settings,
+        user=doris_sandbox.settings.user,
+        password=doris_sandbox.settings.password,
+    )
+    environment["MCP_TOOL_EXPOSURE_MODE"] = "hierarchical"
+    with doris_sandbox.admin_connection.cursor() as cursor:
+        cursor.execute(
+            f"INSERT INTO {doris_sandbox.qualified_table} VALUES (1, %s)",
+            (doris_sandbox.marker,),
+        )
+
+    async with _transport_client(
+        transport,
+        environment,
+        read_timeout_seconds=60,
+    ) as client:
+        pipeline_result = await client.call_tool("doris_pipeline", {})
+        assert pipeline_result.is_error is False
+        assert isinstance(pipeline_result.structured_content, dict)
+        manifest = pipeline_result.structured_content
+        assert manifest["mode"] == "manifest"
+        assert manifest["domain"] == "doris_pipeline"
+        children = {child["name"]: child for child in manifest["children"]}
+        assert tuple(children) == PIPELINE_CHILD_NAMES
+        assert all(child["availability"]["callable"] for child in 
children.values())
+        manifest_version = manifest["manifest_version"]
+
+        ingestion = await _call_domain_child(
+            client,
+            domain="doris_pipeline",
+            child_tool="get_ingestion_status",
+            arguments={
+                "database": doris_sandbox.settings.database,
+                "table": doris_sandbox.table,
+                "limit": 20,
+            },
+            manifest_version=manifest_version,
+        )
+        assert ingestion["metadata"]["database"] == (
+            doris_sandbox.settings.database
+        )
+        assert ingestion["data"]["truncated"] is False
+
+        diagnosis = await _call_domain_child(
+            client,
+            domain="doris_pipeline",
+            child_tool="diagnose_ingestion",
+            arguments={
+                "database": doris_sandbox.settings.database,
+                "table": doris_sandbox.table,
+                "window_minutes": 60,
+                "include_dependencies": False,
+            },
+            manifest_version=manifest_version,
+        )
+        assert diagnosis["data"]["summary"]["matched_jobs"] >= 0
+        assert diagnosis["metadata"]["invented_evidence"] is False
+
+        freshness = await _call_domain_child(
+            client,
+            domain="doris_pipeline",
+            child_tool="monitor_data_freshness",
+            arguments={
+                "database": doris_sandbox.settings.database,
+                "table": doris_sandbox.table,
+                "threshold_seconds": 3600,
+            },
+            manifest_version=manifest_version,
+        )
+        assert freshness["data"]["status"] in {"fresh", "stale"}
+        assert freshness["data"]["method"] == "partition_visible_version"
+        assert freshness["metadata"]["invented_evidence"] is False
+
+        materialized_views = await _call_domain_child(
+            client,
+            domain="doris_pipeline",
+            child_tool="get_materialized_view_status",
+            arguments={
+                "database": doris_sandbox.settings.database,
+                "include_refresh_history": True,
+            },
+            manifest_version=manifest_version,
+        )
+        assert isinstance(materialized_views["data"]["items"], list)
+
+        dependencies = await _call_domain_child(
+            client,
+            domain="doris_pipeline",
+            child_tool="analyze_data_dependencies",
+            arguments={
+                "database": doris_sandbox.settings.database,
+                "object": doris_sandbox.table,
+                "direction": "both",
+                "depth": 2,
+            },
+            manifest_version=manifest_version,
+        )
+        assert dependencies["metadata"]["invented_evidence"] is False
+        assert "unknown_source" not in str(dependencies)
+
+        with doris_sandbox.admin_connection.cursor() as cursor:
+            cursor.execute(
+                f"SELECT COUNT(*) AS row_count "
+                f"FROM {doris_sandbox.qualified_table}"
+            )
+            row = cursor.fetchone()
+        assert row == (1,)
+
+
 @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 6124029..025aa54 100644
--- a/test/tools/test_capability_detector.py
+++ b/test/tools/test_capability_detector.py
@@ -125,6 +125,7 @@ class _ProbeConnectionManager:
             fingerprint="route-a",
         )
         self.context_error: Exception | None = None
+        self.context_sessions: list[str] = []
 
     def get_route_identity(self, _auth_context: Any) -> DorisRouteIdentity:
         return self.route
@@ -138,11 +139,12 @@ class _ProbeConnectionManager:
     @asynccontextmanager
     async def get_connection_context_for_auth_context(
         self,
-        _session_id: str,
+        session_id: str,
         _auth_context: Any,
     ):
         if self.context_error is not None:
             raise self.context_error
+        self.context_sessions.append(session_id)
         yield self.connection
 
 
@@ -204,6 +206,84 @@ async def 
test_detector_builds_version_vector_and_extends_domains_lazily() -> No
     assert connection.statements.count("SELECT @@version_comment;") == 1
 
 
[email protected]
+async def test_pipeline_probes_isolate_an_unsupported_source_connection() -> 
None:
+    base_connection = _ProbeConnection()
+
+    class _PoisoningConnection(_ProbeConnection):
+        def __init__(self, *, fail_load: bool) -> None:
+            super().__init__()
+            self.fail_load = fail_load
+            self.poisoned = False
+
+        async def execute(
+            self,
+            sql: str,
+            *_args: Any,
+            **_kwargs: Any,
+        ) -> SimpleNamespace:
+            if self.poisoned:
+                raise ConnectionError("connection was poisoned")
+            if self.fail_load and sql == "SHOW LOAD LIMIT 1":
+                self.poisoned = True
+                raise RuntimeError(1064, "unsupported statement")
+            return await super().execute(sql, *_args, **_kwargs)
+
+    class _IsolatingManager(_ProbeConnectionManager):
+        def __init__(self) -> None:
+            super().__init__(base_connection)
+            self.domain_connections: list[_PoisoningConnection] = []
+
+        @asynccontextmanager
+        async def get_connection_context_for_auth_context(
+            self,
+            session_id: str,
+            _auth_context: Any,
+        ):
+            self.context_sessions.append(session_id)
+            if not session_id.startswith("capability-domain:doris_pipeline:"):
+                yield self.connection
+                return
+            connection = _PoisoningConnection(
+                fail_load=":0:" in session_id,
+            )
+            self.domain_connections.append(connection)
+            yield connection
+
+    manager = _IsolatingManager()
+    detector = DorisCapabilityDetector(manager)  # type: ignore[arg-type]
+    base = await detector.detect_base(
+        None,
+        capability_generation=1,
+        provider_generation="provider.a",
+    )
+
+    pipeline = await detector.detect_domain(base, "doris_pipeline", None)
+
+    assert (
+        pipeline.probe("batch_load_metadata_readable").status
+        is CapabilityProbeStatus.UNSUPPORTED
+    )
+    assert (
+        pipeline.probe("stream_load_metadata_readable").status
+        is CapabilityProbeStatus.SUPPORTED
+    )
+    assert (
+        pipeline.probe("stream_broker_routine_load_readable").status
+        is CapabilityProbeStatus.SUPPORTED
+    )
+    assert (
+        pipeline.probe("ingestion_status_readable").status
+        is CapabilityProbeStatus.SUPPORTED
+    )
+    assert (
+        pipeline.probe("materialized_view_tasks_readable").status
+        is CapabilityProbeStatus.SUPPORTED
+    )
+    assert len(manager.domain_connections) == 7
+    assert len({id(connection) for connection in manager.domain_connections}) 
== 7
+
+
 @pytest.mark.asyncio
 async def test_detector_marks_permission_failure_unknown_not_unsupported() -> 
None:
     connection = _ProbeConnection()
diff --git a/test/tools/test_domain_dispatcher.py 
b/test/tools/test_domain_dispatcher.py
index 83b7738..ac094e2 100644
--- a/test/tools/test_domain_dispatcher.py
+++ b/test/tools/test_domain_dispatcher.py
@@ -523,13 +523,17 @@ async def 
test_manifest_version_unavailable_and_unbound_fail_closed() -> None:
             },
         )
     )
-    unbound_manager = _manager("doris_pipeline.get_ingestion_status")
+    unbound_manager = _manager("doris_search.search_data")
     unbound = json.loads(
         await unbound_manager.call_tool(
-            "doris_pipeline",
+            "doris_search",
             {
-                "child_tool": "get_ingestion_status",
-                "arguments": {},
+                "child_tool": "search_data",
+                "arguments": {
+                    "database": "analytics",
+                    "table": "events",
+                    "mode": "text",
+                },
             },
         )
     )
@@ -543,6 +547,51 @@ async def 
test_manifest_version_unavailable_and_unbound_fail_closed() -> None:
     assert unbound["error"]["details"]["reason_code"] == "HANDLER_NOT_BOUND"
 
 
[email protected]
+async def test_formal_pipeline_handler_overrides_legacy_migration_binding() -> 
None:
+    manager = _manager("doris_pipeline.monitor_data_freshness")
+    formal_result = {
+        "status": "success",
+        "data": {
+            "database": "analytics",
+            "table": "orders",
+            "status": "fresh",
+        },
+        "warnings": [],
+        "metadata": {"source": "partition_visible_version"},
+        "evidence": [],
+    }
+    manager.pipeline_runtime.monitor_data_freshness = AsyncMock(
+        return_value=formal_result
+    )
+    manager.data_governance_tools.monitor_data_freshness = AsyncMock(
+        side_effect=AssertionError("legacy Pipeline handler must not run")
+    )
+
+    response = json.loads(
+        await manager.call_tool(
+            "doris_pipeline",
+            {
+                "child_tool": "monitor_data_freshness",
+                "arguments": {
+                    "database": "analytics",
+                    "table": "orders",
+                },
+            },
+        )
+    )
+
+    assert response["mode"] == "result"
+    assert response["data"] == formal_result
+    manager.pipeline_runtime.monitor_data_freshness.assert_awaited_once_with(
+        database="analytics",
+        table="orders",
+        threshold_seconds=None,
+        time_column=None,
+    )
+    manager.data_governance_tools.monitor_data_freshness.assert_not_awaited()
+
+
 @pytest.mark.asyncio
 async def test_runtime_provider_down_is_rechecked_before_execution() -> None:
     provider = SelectiveAvailabilityProvider({"doris_query.execute_query"})
diff --git a/test/utils/test_pipeline_runtime.py 
b/test/utils/test_pipeline_runtime.py
new file mode 100644
index 0000000..d378a8d
--- /dev/null
+++ b/test/utils/test_pipeline_runtime.py
@@ -0,0 +1,348 @@
+# 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 Pipeline runtime."""
+
+from __future__ import annotations
+
+from collections.abc import AsyncIterator, Mapping
+from contextlib import asynccontextmanager
+from datetime import datetime
+from types import SimpleNamespace
+from typing import Any
+
+import pytest
+
+from doris_mcp_server.utils.pipeline_runtime import (
+    DorisPipelineRuntime,
+    PipelineRuntimeFailure,
+)
+
+
+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] = []
+        self.context_count = 0
+
+    @asynccontextmanager
+    async def get_connection_context_for_auth_context(
+        self,
+        _session_id: str,
+        _auth_context: Any,
+    ) -> AsyncIterator[Any]:
+        self.context_count += 1
+        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()
+
+
+def _runtime(
+    *,
+    rows: dict[str, list[dict[str, Any]]] | None = None,
+    failures: dict[str, Exception] | None = None,
+) -> tuple[DorisPipelineRuntime, _ConnectionManager]:
+    manager = _ConnectionManager(rows=rows, failures=failures)
+    return DorisPipelineRuntime(manager), manager  # type: ignore[arg-type]
+
+
[email protected]
+async def 
test_ingestion_status_normalizes_real_rows_and_omits_sensitive_fields() -> None:
+    batch_sql = "SHOW LOAD FROM `analytics` LIMIT 20"
+    routine_sql = "SHOW ALL ROUTINE LOAD"
+    runtime, manager = _runtime(
+        rows={
+            batch_sql: [
+                {
+                    "JobId": 101,
+                    "Label": "orders_20260731",
+                    "State": "FINISHED",
+                    "Progress": "100%",
+                    "JobDetails": '{"table_name":"orders"}',
+                    "URL": "http://fe:8030/api/load?token=secret";,
+                    "CreateTime": "2026-07-31 01:00:00",
+                    "LoadFinishTime": "2026-07-31 01:01:00",
+                }
+            ],
+            routine_sql: [
+                {
+                    "Id": 202,
+                    "Name": "orders_kafka",
+                    "DbName": "analytics",
+                    "TableName": "orders",
+                    "State": "RUNNING",
+                    "DataSourceType": "KAFKA",
+                    "CurrentTaskNum": 3,
+                    "Lag": '{"0": 4}',
+                    "Progress": '{"0": "17"}',
+                    "ErrorLogUrls": "http://be:8040/error?password=secret";,
+                },
+                {
+                    "Id": 203,
+                    "Name": "other_db",
+                    "DbName": "other",
+                    "TableName": "orders",
+                    "State": "RUNNING",
+                },
+            ],
+        }
+    )
+
+    result = await runtime.get_ingestion_status(
+        job_types=["batch_load", "routine_load"],
+        database="analytics",
+        table="orders",
+        states=None,
+        limit=10,
+    )
+
+    assert result["status"] == "success"
+    assert [item["job_type"] for item in result["data"]["items"]] == [
+        "batch_load",
+        "routine_load",
+    ]
+    assert result["data"]["items"][1]["lag"] == {"0": 4}
+    serialized = str(result)
+    assert "ErrorLogUrls" not in serialized
+    assert "http://fe:8030"; not in serialized
+    assert "password=secret" not in serialized
+    assert manager.calls == [
+        batch_sql,
+        "USE `analytics`",
+        routine_sql,
+    ]
+    assert manager.context_count == 2
+
+
[email protected]
+async def test_ingestion_status_fails_closed_without_any_evidence_source() -> 
None:
+    sql = "SHOW LOAD FROM `analytics` LIMIT 20"
+    runtime, _ = _runtime(
+        failures={sql: RuntimeError(1146, "source does not exist")}
+    )
+
+    with pytest.raises(
+        PipelineRuntimeFailure,
+        match="ingestion evidence is unavailable",
+    ) as failure:
+        await runtime.get_ingestion_status(
+            job_types=["batch_load"],
+            database="analytics",
+            table=None,
+            states=None,
+            limit=10,
+        )
+
+    assert failure.value.reason_code == 
"PIPELINE_INGESTION_EVIDENCE_UNAVAILABLE"
+
+
[email protected]
+async def test_freshness_prefers_recorded_partition_visibility_time() -> None:
+    sql = "SHOW PARTITIONS FROM `analytics`.`orders` LIMIT 1000"
+    now = datetime.now()
+    runtime, _ = _runtime(
+        rows={
+            sql: [
+                {
+                    "PartitionName": "p20260731",
+                    "VisibleVersion": 12,
+                    "VisibleVersionTime": now,
+                }
+            ]
+        }
+    )
+
+    result = await runtime.monitor_data_freshness(
+        database="analytics",
+        table="orders",
+        threshold_seconds=60,
+        time_column=None,
+    )
+
+    assert result["data"]["status"] == "fresh"
+    assert result["data"]["method"] == "partition_visible_version"
+    assert result["data"]["partitions_observed"] == 1
+    assert result["metadata"]["invented_evidence"] is False
+
+
[email protected]
+async def test_freshness_rejects_identifier_injection_before_execution() -> 
None:
+    runtime, manager = _runtime()
+
+    with pytest.raises(PipelineRuntimeFailure) as failure:
+        await runtime.monitor_data_freshness(
+            database="analytics",
+            table="orders; DROP TABLE users",
+            threshold_seconds=60,
+            time_column=None,
+        )
+
+    assert failure.value.reason_code == "PIPELINE_ARGUMENT_INVALID"
+    assert manager.calls == []
+
+
[email protected]
+async def test_materialized_view_status_uses_recorded_jobs_and_refresh_tasks() 
-> None:
+    info_sql = (
+        "SELECT Id, Name, JobName, State, SchemaChangeDetail, RefreshState, "
+        'RefreshInfo, SyncWithBaseTables FROM mv_infos("database"="analytics") 
'
+        "LIMIT 500"
+    )
+    job_sql = (
+        "SELECT Id, Name, MvId, MvName, MvDatabaseName, ExecuteType, "
+        'RecurringStrategy, Status, CreateTime FROM jobs("type"="mv") '
+        "WHERE MvDatabaseName = %s LIMIT 500"
+    )
+    task_sql = (
+        "SELECT TaskId, JobId, JobName, MvId, MvName, MvDatabaseName, Status, "
+        "ErrorMsg, CreateTime, StartTime, FinishTime, DurationMs, RefreshMode, 
"
+        "NeedRefreshPartitions, CompletedPartitions, Progress, LastQueryId "
+        'FROM tasks("type"="mv") WHERE MvDatabaseName = %s '
+        "ORDER BY CreateTime DESC LIMIT 500"
+    )
+    sync_sql = "SHOW ALTER TABLE MATERIALIZED VIEW FROM `analytics`"
+    runtime, manager = _runtime(
+        rows={
+            info_sql: [
+                {
+                    "Id": 1,
+                    "Name": "mv_orders",
+                    "JobName": "inner_mtmv_1",
+                    "State": "NORMAL",
+                    "RefreshState": "SUCCESS",
+                    "SyncWithBaseTables": "true",
+                }
+            ],
+            job_sql: [
+                {
+                    "Id": 11,
+                    "Name": "inner_mtmv_1",
+                    "MvName": "mv_orders",
+                    "MvDatabaseName": "analytics",
+                    "Status": "RUNNING",
+                }
+            ],
+            task_sql: [
+                {
+                    "TaskId": 21,
+                    "MvName": "mv_orders",
+                    "Status": "SUCCESS",
+                    "DurationMs": 45,
+                    "LastQueryId": "query-1",
+                }
+            ],
+            sync_sql: [],
+        }
+    )
+
+    result = await runtime.get_materialized_view_status(
+        database="analytics",
+        view="mv_orders",
+        states=None,
+        include_refresh_history=True,
+    )
+
+    item = result["data"]["items"][0]
+    assert item["view"] == "mv_orders"
+    assert item["sync_with_base_tables"] is True
+    assert item["latest_refresh"]["task_id"] == 21
+    assert item["refresh_history"][0]["duration_ms"] == 45
+    assert manager.params[1] == ("analytics",)
+    assert manager.params[2] == ("analytics",)
+    assert "query_sql" not in str(result).casefold()
+
+
[email protected]
+async def 
test_dependency_graph_uses_only_recorded_edges_without_synthetic_nodes() -> 
None:
+    mv_sql = (
+        'SELECT Name, QuerySql FROM mv_infos("database"="analytics") LIMIT 500'
+    )
+    view_sql = (
+        "SELECT TABLE_NAME, VIEW_DEFINITION FROM information_schema.views "
+        "WHERE TABLE_SCHEMA = %s LIMIT 500"
+    )
+    audit_sql = (
+        "SELECT stmt, `time` AS observed_at "
+        "FROM internal.__internal_schema.audit_log "
+        "WHERE `time` >= DATE_SUB(NOW(), INTERVAL 30 DAY) "
+        "AND (UPPER(stmt) LIKE '%INSERT%' OR "
+        "UPPER(stmt) LIKE '%CREATE%VIEW%') "
+        "ORDER BY `time` DESC LIMIT 500"
+    )
+    runtime, _ = _runtime(
+        rows={
+            mv_sql: [
+                {
+                    "Name": "daily_orders",
+                    "QuerySql": "SELECT * FROM raw_orders",
+                }
+            ],
+            view_sql: [
+                {
+                    "TABLE_NAME": "order_view",
+                    "VIEW_DEFINITION": "SELECT * FROM analytics.daily_orders",
+                }
+            ],
+            audit_sql: [
+                {
+                    "stmt": (
+                        "INSERT INTO final_orders "
+                        "SELECT * FROM analytics.order_view"
+                    ),
+                    "observed_at": "2026-07-31 02:00:00",
+                }
+            ],
+        }
+    )
+
+    result = await runtime.analyze_data_dependencies(
+        catalog="internal",
+        database="analytics",
+        object_name="final_orders",
+        direction="upstream",
+        depth=5,
+    )
+
+    assert result["data"]["nodes"] == [
+        "internal.analytics.daily_orders",
+        "internal.analytics.final_orders",
+        "internal.analytics.order_view",
+        "internal.analytics.raw_orders",
+    ]
+    assert len(result["data"]["edges"]) == 3
+    assert "unknown_source" not in str(result)
+    assert result["metadata"]["invented_evidence"] is False


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

Reply via email to