[V10.366] add market intel MCP runtime smoke receipt
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s
This commit is contained in:
@@ -60,6 +60,7 @@ from services.market_intel.candidate_queue_review_ai_summary_persistence_transac
|
||||
from services.market_intel.candidate_queue_review_ai_summary_persistence_writer_preflight import build_candidate_queue_review_ai_summary_persistence_writer_preflight
|
||||
from services.market_intel.candidate_queue_review_ai_summary_run_package import build_candidate_queue_review_ai_summary_run_package
|
||||
from services.market_intel.mcp_activation_evidence import build_mcp_activation_evidence_preview
|
||||
from services.market_intel.mcp_runtime_smoke_receipt import build_mcp_runtime_smoke_receipt_preview
|
||||
BLOCKED_RUN_REVIEW_KEYS = (
|
||||
"ready_for_api_database_write",
|
||||
"ready_for_scheduler_attach",
|
||||
@@ -137,6 +138,11 @@ PRODUCTION_SMOKE_TARGETS = (
|
||||
)
|
||||
+ PRODUCTION_SMOKE_TARGETS[-1:]
|
||||
)
|
||||
PRODUCTION_SMOKE_TARGETS = (
|
||||
PRODUCTION_SMOKE_TARGETS[:-1]
|
||||
+ ("/api/market_intel/mcp_runtime_smoke_receipt",)
|
||||
+ PRODUCTION_SMOKE_TARGETS[-1:]
|
||||
)
|
||||
def _run_review_preview_safe(payload, mode):
|
||||
return bool(payload["mode"] == mode and all(not payload.get(key) for key in BLOCKED_RUN_REVIEW_KEYS))
|
||||
def build_deployment_readiness_preview(*, service, market_intel_tables, schema_smoke_builder):
|
||||
@@ -151,6 +157,9 @@ def build_deployment_readiness_preview(*, service, market_intel_tables, schema_s
|
||||
mcp_activation_evidence = build_mcp_activation_evidence_preview(
|
||||
phase=service.phase,
|
||||
)
|
||||
mcp_runtime_smoke_receipt = build_mcp_runtime_smoke_receipt_preview(
|
||||
phase=service.phase,
|
||||
)
|
||||
scheduler_plan = service.build_scheduler_plan()
|
||||
manual_sample_plan = service.build_manual_sample_plan()
|
||||
manual_sample_acceptance = service.build_manual_sample_acceptance()
|
||||
@@ -384,6 +393,15 @@ def build_deployment_readiness_preview(*, service, market_intel_tables, schema_s
|
||||
and not mcp_activation_evidence["api_writes_database"]
|
||||
and not mcp_activation_evidence["api_uses_external_network"]
|
||||
),
|
||||
"mcp_runtime_smoke_receipt_preview_safe": bool(
|
||||
mcp_runtime_smoke_receipt["mode"] == "mcp_runtime_smoke_receipt_preview"
|
||||
and not mcp_runtime_smoke_receipt["payload_persisted"]
|
||||
and not mcp_runtime_smoke_receipt["receipt_persisted"]
|
||||
and not mcp_runtime_smoke_receipt["api_executes_health_check"]
|
||||
and not mcp_runtime_smoke_receipt["api_opens_database_connection"]
|
||||
and not mcp_runtime_smoke_receipt["api_writes_database"]
|
||||
and not mcp_runtime_smoke_receipt["api_uses_external_network"]
|
||||
),
|
||||
"scheduler_plan_preview_safe": bool(
|
||||
scheduler_plan["mode"] == "scheduler_attach_plan_preview"
|
||||
and not scheduler_plan["scheduler_registration_executed"]
|
||||
@@ -816,6 +834,7 @@ def build_deployment_readiness_preview(*, service, market_intel_tables, schema_s
|
||||
"mcp_fetch_gate": mcp_fetch_gate,
|
||||
"mcp_completion_audit": mcp_completion_audit,
|
||||
"mcp_activation_evidence": mcp_activation_evidence,
|
||||
"mcp_runtime_smoke_receipt": mcp_runtime_smoke_receipt,
|
||||
"scheduler_plan": scheduler_plan,
|
||||
"manual_sample_plan": manual_sample_plan,
|
||||
"manual_sample_acceptance": manual_sample_acceptance,
|
||||
|
||||
317
services/market_intel/mcp_runtime_smoke_receipt.py
Normal file
317
services/market_intel/mcp_runtime_smoke_receipt.py
Normal file
@@ -0,0 +1,317 @@
|
||||
"""市場情報 MCP runtime smoke 收據審核 preview。
|
||||
|
||||
操作員可貼上 /api/market_intel/mcp_readiness?execute=true&timeout=3
|
||||
的實際 JSON 結果;本模組只審核收據,不打 health、不開 DB、不連外。
|
||||
"""
|
||||
|
||||
EXPECTED_EXTERNAL_SERVERS = ("postgres", "omnisearch", "firecrawl", "filesystem")
|
||||
PROHIBITED_RECEIPT_FLAGS = (
|
||||
"database_write_executed",
|
||||
"database_commit_executed",
|
||||
"scheduler_attached",
|
||||
"writes_executed",
|
||||
"would_write_database",
|
||||
)
|
||||
|
||||
|
||||
def _truthy(value):
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
if isinstance(value, (int, float)):
|
||||
return bool(value)
|
||||
if isinstance(value, str):
|
||||
return value.strip().lower() in {
|
||||
"1",
|
||||
"true",
|
||||
"yes",
|
||||
"y",
|
||||
"ok",
|
||||
"pass",
|
||||
"passed",
|
||||
"healthy",
|
||||
"ready",
|
||||
}
|
||||
return False
|
||||
|
||||
|
||||
def _mapping(value):
|
||||
return value if isinstance(value, dict) else {}
|
||||
|
||||
|
||||
def _server_statuses(receipt):
|
||||
statuses = receipt.get("server_statuses") or []
|
||||
if not isinstance(statuses, list):
|
||||
return []
|
||||
normalized = []
|
||||
for item in statuses:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
server = str(item.get("server") or item.get("name") or "").strip().lower()
|
||||
if not server:
|
||||
continue
|
||||
healthy = (
|
||||
_truthy(item.get("healthy"))
|
||||
if "healthy" in item
|
||||
else str(item.get("status") or "").strip().lower() in {"healthy", "ok"}
|
||||
)
|
||||
normalized.append(
|
||||
{
|
||||
"server": server,
|
||||
"health_checked": _truthy(item.get("health_checked"))
|
||||
or _truthy(item.get("checked")),
|
||||
"healthy": healthy,
|
||||
"status": item.get("status") or "unknown",
|
||||
"base_url": item.get("base_url"),
|
||||
"error_message": item.get("error_message"),
|
||||
}
|
||||
)
|
||||
return normalized
|
||||
|
||||
|
||||
def _sample_receipt_template():
|
||||
return {
|
||||
"mode": "mcp_readiness_read_only",
|
||||
"execute_requested": True,
|
||||
"router_enabled": True,
|
||||
"external_mcp_complete": True,
|
||||
"internal_mcp_complete": True,
|
||||
"market_intel_mcp_integrated": True,
|
||||
"server_statuses": [
|
||||
{
|
||||
"server": "postgres",
|
||||
"health_checked": True,
|
||||
"healthy": True,
|
||||
"status": "healthy",
|
||||
},
|
||||
{
|
||||
"server": "omnisearch",
|
||||
"health_checked": True,
|
||||
"healthy": True,
|
||||
"status": "healthy",
|
||||
},
|
||||
{
|
||||
"server": "firecrawl",
|
||||
"health_checked": True,
|
||||
"healthy": True,
|
||||
"status": "healthy",
|
||||
},
|
||||
{
|
||||
"server": "filesystem",
|
||||
"health_checked": True,
|
||||
"healthy": True,
|
||||
"status": "healthy",
|
||||
},
|
||||
],
|
||||
"mcp_tool_contract": {
|
||||
"contract_ready": True,
|
||||
"tool_count": 3,
|
||||
"checks": {
|
||||
"market_intel_caller_registered": True,
|
||||
"all_router_tools_whitelisted": True,
|
||||
"all_tools_read_only": True,
|
||||
"no_database_write_allowed": True,
|
||||
"no_scheduler_attach_allowed": True,
|
||||
},
|
||||
"database_write_executed": False,
|
||||
"scheduler_attached": False,
|
||||
},
|
||||
"telemetry": {
|
||||
"mode": "mcp_telemetry_read_only",
|
||||
"table_exists": True,
|
||||
"read_only_query_executed": True,
|
||||
"database_session_created": False,
|
||||
"database_write_executed": False,
|
||||
"database_commit_executed": False,
|
||||
},
|
||||
"database_session_created": False,
|
||||
"database_write_executed": False,
|
||||
"database_commit_executed": False,
|
||||
"scheduler_attached": False,
|
||||
"writes_executed": False,
|
||||
"would_write_database": False,
|
||||
}
|
||||
|
||||
|
||||
def _tool_contract_read_only(contract):
|
||||
checks = _mapping(contract.get("checks"))
|
||||
return bool(
|
||||
_truthy(contract.get("contract_ready"))
|
||||
and _truthy(checks.get("market_intel_caller_registered"))
|
||||
and _truthy(checks.get("all_router_tools_whitelisted"))
|
||||
and _truthy(checks.get("all_tools_read_only"))
|
||||
and _truthy(checks.get("no_database_write_allowed"))
|
||||
and _truthy(checks.get("no_scheduler_attach_allowed"))
|
||||
and not _truthy(contract.get("database_write_executed"))
|
||||
and not _truthy(contract.get("scheduler_attached"))
|
||||
)
|
||||
|
||||
|
||||
def _telemetry_read_only(telemetry):
|
||||
return bool(
|
||||
telemetry.get("mode") == "mcp_telemetry_read_only"
|
||||
and _truthy(telemetry.get("table_exists"))
|
||||
and _truthy(telemetry.get("read_only_query_executed"))
|
||||
and not _truthy(telemetry.get("database_session_created"))
|
||||
and not _truthy(telemetry.get("database_write_executed"))
|
||||
and not _truthy(telemetry.get("database_commit_executed"))
|
||||
)
|
||||
|
||||
|
||||
def build_mcp_runtime_smoke_receipt_preview(*, receipt=None, phase=None):
|
||||
"""審核 runtime smoke 收據;不執行任何 health、DB 或 network 動作。"""
|
||||
receipt = receipt or {}
|
||||
payload_received = bool(receipt)
|
||||
statuses = _server_statuses(receipt)
|
||||
status_map = {item["server"]: item for item in statuses}
|
||||
expected_present = all(server in status_map for server in EXPECTED_EXTERNAL_SERVERS)
|
||||
all_checked = bool(statuses) and all(
|
||||
status_map.get(server, {}).get("health_checked")
|
||||
for server in EXPECTED_EXTERNAL_SERVERS
|
||||
)
|
||||
all_healthy = bool(statuses) and all(
|
||||
status_map.get(server, {}).get("healthy")
|
||||
for server in EXPECTED_EXTERNAL_SERVERS
|
||||
)
|
||||
telemetry = _mapping(receipt.get("telemetry"))
|
||||
contract = _mapping(receipt.get("mcp_tool_contract"))
|
||||
prohibited_flags = [
|
||||
key for key in PROHIBITED_RECEIPT_FLAGS
|
||||
if _truthy(receipt.get(key))
|
||||
]
|
||||
blocked_from_receipt = [
|
||||
str(item) for item in receipt.get("blocked_reasons", [])
|
||||
] if isinstance(receipt.get("blocked_reasons"), list) else []
|
||||
|
||||
gates = [
|
||||
{
|
||||
"key": "receipt_payload_received",
|
||||
"passed": payload_received,
|
||||
"label": "已提供 runtime smoke receipt payload",
|
||||
},
|
||||
{
|
||||
"key": "readiness_execute_true",
|
||||
"passed": receipt.get("mode") == "mcp_readiness_read_only"
|
||||
and _truthy(receipt.get("execute_requested")),
|
||||
"label": "收據來自 execute=true 的 read-only readiness",
|
||||
},
|
||||
{
|
||||
"key": "router_enabled",
|
||||
"passed": _truthy(receipt.get("router_enabled")),
|
||||
"label": "MCP router 已啟用",
|
||||
},
|
||||
{
|
||||
"key": "external_mcp_complete",
|
||||
"passed": _truthy(receipt.get("external_mcp_complete")),
|
||||
"label": "外部 MCP runtime 已完整",
|
||||
},
|
||||
{
|
||||
"key": "internal_mcp_complete",
|
||||
"passed": _truthy(receipt.get("internal_mcp_complete")),
|
||||
"label": "內部 MCP telemetry / contract 已完整",
|
||||
},
|
||||
{
|
||||
"key": "market_intel_mcp_integrated",
|
||||
"passed": _truthy(receipt.get("market_intel_mcp_integrated")),
|
||||
"label": "market_intel caller 與 MCP tool contract 已整合",
|
||||
},
|
||||
{
|
||||
"key": "all_expected_servers_present",
|
||||
"passed": expected_present,
|
||||
"label": "四個必要 MCP server 都出現在收據中",
|
||||
},
|
||||
{
|
||||
"key": "all_servers_health_checked",
|
||||
"passed": all_checked,
|
||||
"label": "四個 MCP server 都已被 health check",
|
||||
},
|
||||
{
|
||||
"key": "all_servers_healthy",
|
||||
"passed": all_healthy,
|
||||
"label": "四個 MCP server health 全部 healthy",
|
||||
},
|
||||
{
|
||||
"key": "tool_contract_ready_and_read_only",
|
||||
"passed": _tool_contract_read_only(contract),
|
||||
"label": "MCP tool contract ready,且工具全為 read-only",
|
||||
},
|
||||
{
|
||||
"key": "telemetry_read_only_confirmed",
|
||||
"passed": _telemetry_read_only(telemetry),
|
||||
"label": "mcp_calls telemetry 只做 read-only 查詢",
|
||||
},
|
||||
{
|
||||
"key": "no_database_write_or_scheduler_flags",
|
||||
"passed": not prohibited_flags,
|
||||
"label": "收據未宣告 DB write、commit、scheduler 或 writes 已執行",
|
||||
},
|
||||
{
|
||||
"key": "receipt_has_no_blocked_reasons",
|
||||
"passed": not blocked_from_receipt,
|
||||
"label": "原始 readiness 收據沒有 blocked reasons",
|
||||
},
|
||||
]
|
||||
blocked_reasons = [
|
||||
gate["key"] for gate in gates
|
||||
if not gate["passed"]
|
||||
]
|
||||
accepted = payload_received and not blocked_reasons
|
||||
|
||||
return {
|
||||
"mode": (
|
||||
"mcp_runtime_smoke_receipt_review"
|
||||
if payload_received
|
||||
else "mcp_runtime_smoke_receipt_preview"
|
||||
),
|
||||
"phase": phase,
|
||||
"receipt_payload_received": payload_received,
|
||||
"runtime_smoke_receipt_accepted": accepted,
|
||||
"ready_for_completion_runtime_promotion": accepted,
|
||||
"ready_for_manual_fetch_gate_review": accepted,
|
||||
"external_mcp_runtime_receipt_complete": accepted,
|
||||
"internal_mcp_runtime_receipt_complete": accepted,
|
||||
"gate_count": len(gates),
|
||||
"passed_gate_count": sum(1 for gate in gates if gate["passed"]),
|
||||
"blocked_reasons": blocked_reasons,
|
||||
"receipt_blocked_reasons": blocked_from_receipt,
|
||||
"gates": gates,
|
||||
"server_statuses": statuses,
|
||||
"server_summary": {
|
||||
"expected_servers": list(EXPECTED_EXTERNAL_SERVERS),
|
||||
"present_servers": sorted(status_map.keys()),
|
||||
"healthy_count": sum(1 for item in statuses if item["healthy"]),
|
||||
"health_checked_count": sum(1 for item in statuses if item["health_checked"]),
|
||||
"all_expected_servers_present": expected_present,
|
||||
"all_servers_health_checked": all_checked,
|
||||
"all_servers_healthy": all_healthy,
|
||||
},
|
||||
"telemetry_summary": {
|
||||
"mode": telemetry.get("mode"),
|
||||
"table_exists": bool(telemetry.get("table_exists")),
|
||||
"read_only_query_executed": bool(telemetry.get("read_only_query_executed")),
|
||||
"database_session_created": bool(telemetry.get("database_session_created")),
|
||||
"database_write_executed": bool(telemetry.get("database_write_executed")),
|
||||
"database_commit_executed": bool(telemetry.get("database_commit_executed")),
|
||||
},
|
||||
"prohibited_flags": prohibited_flags,
|
||||
"sample_receipt_template": _sample_receipt_template(),
|
||||
"next_operator_steps": [
|
||||
"若收據通過,回到 MCP 完整度稽核確認 runtime 缺口可被補齊",
|
||||
"人工 fetch gate 仍需另行審核,不可因 runtime smoke 通過自動抓外站",
|
||||
"保留原始收據於外部變更紀錄,API/UI 不保存 payload",
|
||||
],
|
||||
"payload_persisted": False,
|
||||
"receipt_persisted": False,
|
||||
"api_executes_health_check": False,
|
||||
"api_executes_docker": False,
|
||||
"api_executes_ssh": False,
|
||||
"api_opens_database_connection": False,
|
||||
"api_writes_database": False,
|
||||
"api_uses_external_network": False,
|
||||
"database_session_created": False,
|
||||
"database_write_executed": False,
|
||||
"database_commit_executed": False,
|
||||
"external_network_executed": False,
|
||||
"scheduler_attached": False,
|
||||
"writes_executed": False,
|
||||
"would_write_database": False,
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
"""市場情報 rollout phase 單一來源。"""
|
||||
|
||||
MARKET_INTEL_PHASE = "phase_117_market_intel_mcp_activation_evidence"
|
||||
MARKET_INTEL_PHASE = "phase_118_market_intel_mcp_runtime_smoke_receipt"
|
||||
|
||||
Reference in New Issue
Block a user