[V10.358] add market intel MCP activation evidence review
All checks were successful
CD Pipeline / deploy (push) Successful in 1m7s

This commit is contained in:
OoO
2026-05-21 11:31:28 +08:00
parent 8bffd0307d
commit f4ec50cd30
9 changed files with 679 additions and 113 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,269 @@
"""市場情報 MCP 啟用證據審核 preview。
操作員可貼上外部 MCP 啟用後的 redacted evidence本模組只做結構化審核
不打 health endpoint、不開 DB、不寫入、不啟動 fetch。
"""
REQUIRED_ENV_VARS = ("MCP_POSTGRES_PASSWORD", "TAVILY_API_KEY", "EXA_API_KEY")
EXPECTED_HEALTH_TARGETS = (
"http://localhost:3001/health",
"http://localhost:3002/health",
"http://localhost:3003/health",
"http://localhost:3004/health",
)
SAFE_LITERAL_VALUES = {"redacted", "***", "set", "present", "true", "yes", "ok"}
PROHIBITED_EVIDENCE_FLAGS = (
"database_write_executed",
"database_commit_executed",
"scheduler_attached",
"crawler_job_started",
"external_fetch_executed",
"manual_fetch_executed",
)
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", "set", "present", "redacted", "***"}
return False
def _looks_like_secret_literal(value):
if not isinstance(value, str):
return False
normalized = value.strip().lower()
if not normalized or normalized in SAFE_LITERAL_VALUES:
return False
return len(value.strip()) > 2
def _evidence_map(evidence, key):
value = evidence.get(key)
return value if isinstance(value, dict) else {}
def _ack(evidence, key):
acknowledgements = _evidence_map(evidence, "operator_acknowledgements")
return _truthy(evidence.get(key)) or _truthy(acknowledgements.get(key))
def _env_statuses(evidence):
env = _evidence_map(evidence, "required_env_vars") or _evidence_map(evidence, "env")
statuses = []
for name in REQUIRED_ENV_VARS:
value = env.get(name)
statuses.append(
{
"name": name,
"present": _truthy(value),
"secret_literal_in_payload": _looks_like_secret_literal(value),
"value_redacted": bool(value) and not _looks_like_secret_literal(value),
}
)
return statuses
def _health_item_ok(item):
if isinstance(item, bool):
return item
if isinstance(item, (int, float)):
return int(item) == 200
if isinstance(item, str):
return item.strip().lower() in {"200", "ok", "pass", "passed", "healthy"}
if isinstance(item, dict):
return (
int(item.get("status_code") or item.get("code") or 0) == 200
or _truthy(item.get("healthy"))
or _truthy(item.get("passed"))
or _truthy(item.get("status"))
)
return False
def _health_item_for_target(health, target):
if isinstance(health, dict):
if target in health:
return health[target]
port = target.rsplit(":", 1)[-1].split("/", 1)[0]
return health.get(port) or health.get(f"localhost:{port}")
if isinstance(health, list):
for item in health:
if not isinstance(item, dict):
continue
value = item.get("url") or item.get("target") or item.get("endpoint")
port = str(item.get("port") or "")
if value == target or (port and port in target):
return item
return None
def _health_statuses(evidence):
health = evidence.get("health_checks") or evidence.get("health_targets") or {}
return [
{
"target": target,
"passed": _health_item_ok(_health_item_for_target(health, target)),
}
for target in EXPECTED_HEALTH_TARGETS
]
def _sample_evidence_template():
return {
"required_env_vars": {
"MCP_POSTGRES_PASSWORD": "redacted",
"TAVILY_API_KEY": "redacted",
"EXA_API_KEY": "redacted",
},
"health_checks": {
"http://localhost:3001/health": 200,
"http://localhost:3002/health": 200,
"http://localhost:3003/health": 200,
"http://localhost:3004/health": 200,
},
"mcp_router_enabled": True,
"market_intel_readonly_smoke_passed": True,
"telemetry": {
"mcp_calls_table_exists": True,
"read_only_query_executed": True,
},
"operator_acknowledgements": {
"no_remove_orphans": True,
"momo_db_preserved": True,
"router_enabled_after_health": True,
"rollback_plan_confirmed": True,
"fetch_gate_left_closed": True,
},
}
def build_mcp_activation_evidence_preview(*, evidence=None, phase=None):
"""審核 redacted MCP runtime evidence不執行任何外部動作。"""
evidence = evidence or {}
payload_received = bool(evidence)
env_statuses = _env_statuses(evidence)
health_statuses = _health_statuses(evidence)
telemetry = _evidence_map(evidence, "telemetry")
prohibited_flags = [
key for key in PROHIBITED_EVIDENCE_FLAGS
if _truthy(evidence.get(key))
]
secret_literal_keys = [
item["name"] for item in env_statuses
if item["secret_literal_in_payload"]
]
gates = [
{
"key": "evidence_payload_received",
"passed": payload_received,
"label": "已提供 redacted MCP runtime evidence payload",
},
{
"key": "no_secret_literals_in_payload",
"passed": not secret_literal_keys,
"label": "payload 只允許 redacted / boolean不接受真實 secret 字串",
},
{
"key": "required_env_vars_acknowledged",
"passed": all(item["present"] for item in env_statuses),
"label": "三個必要 env 已由操作員確認存在",
},
{
"key": "all_health_targets_passed",
"passed": all(item["passed"] for item in health_statuses),
"label": "四個 localhost MCP health target 全部 200 / healthy",
},
{
"key": "mcp_router_enabled_after_health",
"passed": _truthy(evidence.get("mcp_router_enabled"))
and _ack(evidence, "router_enabled_after_health"),
"label": "router 僅在 health 全過後啟用",
},
{
"key": "market_intel_readonly_smoke_passed",
"passed": _truthy(evidence.get("market_intel_readonly_smoke_passed")),
"label": "market_intel MCP read-only smoke 已通過",
},
{
"key": "telemetry_runtime_confirmed",
"passed": _truthy(telemetry.get("mcp_calls_table_exists"))
and _truthy(telemetry.get("read_only_query_executed")),
"label": "mcp_calls telemetry read-only 查詢鏈路已確認",
},
{
"key": "operator_fallback_confirmed",
"passed": _ack(evidence, "rollback_plan_confirmed"),
"label": "router kill switch 與 stop MCP stack fallback 已確認",
},
{
"key": "production_boundaries_acknowledged",
"passed": _ack(evidence, "no_remove_orphans")
and _ack(evidence, "momo_db_preserved"),
"label": "已確認不使用 remove-orphans 且不動 momo-db lifecycle",
},
{
"key": "manual_fetch_gate_left_closed",
"passed": _ack(evidence, "fetch_gate_left_closed"),
"label": "啟用 MCP 後仍未打開人工 fetch gate",
},
{
"key": "no_write_or_scheduler_evidence",
"passed": not prohibited_flags,
"label": "證據未宣告 DB write、scheduler 或 fetch 已執行",
},
]
blocked_reasons = [
gate["key"] for gate in gates
if not gate["passed"]
]
accepted = payload_received and not blocked_reasons
payload = {
"mode": (
"mcp_activation_evidence_review"
if payload_received
else "mcp_activation_evidence_preview"
),
"phase": phase,
"evidence_payload_received": payload_received,
"activation_evidence_accepted": accepted,
"ready_for_runtime_promotion": accepted,
"ready_for_fetch_gate_review": accepted,
"external_mcp_runtime_evidence_complete": accepted,
"internal_mcp_runtime_evidence_complete": accepted,
"gate_count": len(gates),
"passed_gate_count": sum(1 for gate in gates if gate["passed"]),
"blocked_reasons": blocked_reasons,
"gates": gates,
"env_statuses": env_statuses,
"health_statuses": health_statuses,
"secret_literal_keys": secret_literal_keys,
"prohibited_flags": prohibited_flags,
"sample_evidence_template": _sample_evidence_template(),
"next_operator_steps": [
"若本審核通過,再跑 /api/market_intel/mcp_readiness?execute=true&timeout=3 做只讀 runtime smoke",
"確認 completion audit 的 external/internal runtime 缺口被證據補齊",
"人工 fetch gate 仍需另行審核,不可因 MCP runtime ready 自動抓外站",
],
"payload_persisted": False,
"evidence_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,
}
return payload

View File

@@ -1,3 +1,3 @@
"""市場情報 rollout phase 單一來源。"""
MARKET_INTEL_PHASE = "phase_116_market_intel_mcp_completion_audit"
MARKET_INTEL_PHASE = "phase_117_market_intel_mcp_activation_evidence"