diff --git a/deploy/profile-scripts/mofin_health.py b/deploy/profile-scripts/mofin_health.py index ac102412..6c4fe9cf 100644 --- a/deploy/profile-scripts/mofin_health.py +++ b/deploy/profile-scripts/mofin_health.py @@ -132,10 +132,51 @@ def load_cron_jobs(): if jid in seen: continue seen.add(jid) j["profile"] = profile_tag + j["source"] = "hermes" # 2026-08-12 cron来源标记:统一 hermes 体系 jobs.append(j) except: pass return jobs + +def load_system_crontab_tasks(): + """扫描系统 crontab 里 MoFin 相关任务(2026-08-12 老莫要求:显著提示违规系统 cron)。 + 开发原则:自动任务必须部署在 hermes(position-analyst),禁止系统 crontab。 + 返回含 MoFin/profile-scripts 路径的 crontab 条目,source='system_crontab'(违规警告)。""" + import subprocess as _sp + tasks = [] + try: + out = _sp.run(["crontab", "-l"], capture_output=True, text=True, timeout=10).stdout + for line in out.splitlines(): + line = line.strip() + if not line or line.startswith("#"): + continue + # 只关心 MoFin 相关(含 MoFin 或 profile-scripts 路径) + if "MoFin" not in line and "profile-scripts" not in line: + continue + # 提取调度(前 5 个字段或 @reboot)和命令/脚本 + script = "" + m = line.split("python3")[-1].split("python")[-1].strip() + import re as _re + sm = _re.search(r'([\w./-]*profile-scripts/([\w.-]+\.py)|([\w.-]+\.py))', line) + if sm: + script = sm.group(2) or sm.group(3) or "" + sched = " ".join(line.split()[:5]) if not line.startswith("@") else line.split()[0] + tasks.append({ + "name": f"[系统cron] {script or line[:40]}", + "script": script, + "schedule": sched, + "status": "unknown", + "last_run": "", + "profile": "system", + "source": "system_crontab", # 违规:应迁移到 hermes + "no_agent": True, + "type": "no_agent", + "enabled": True, + }) + except Exception: + pass + return tasks + def get_db_stats(): conn = get_conn() tables = conn.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").fetchall() @@ -1018,6 +1059,7 @@ def build_report(): "type": "no_agent" if no_agent else "LLM", "script": script, "layer": _pipeline_layer(script, name), # 2026-08-12 三层架构层归属 + "source": j.get("source", "hermes"), # 2026-08-12 cron来源(hermes 统一体系) "schedule": schedule, "status": status, "last_run": last_run, @@ -1029,6 +1071,17 @@ def build_report(): feature_tree["status"] = "fail" feature_tree.setdefault("warn_detail", {})[name] = output_missing_reason + # ── 2026-08-12 系统 crontab 违规任务(老莫要求:显著提示。开发原则:自动任务统一 hermes,禁止系统 crontab)── + _sys_tasks = load_system_crontab_tasks() + for _t in _sys_tasks: + _t["layer"] = _pipeline_layer(_t.get("script", ""), _t.get("name", "")) + _t["output_missing"] = False + _t["output_missing_reason"] = "" + pipelines.append(_t) + if _sys_tasks: + feature_tree.setdefault("warn_detail", {})["system_crontab"] = ( + f"发现 {len(_sys_tasks)} 个系统 crontab 部署的 MoFin 任务(违规:应迁移到 hermes)") + # ── 自检体系状态(L1功能健康/L3修复记录/L4元监控/L2卫生)── self_check = {} LOGS = Path('/home/hmo/MoFin/gateway/logs') diff --git a/static/mofin_health.html b/static/mofin_health.html index 004ca565..4630f6b7 100644 --- a/static/mofin_health.html +++ b/static/mofin_health.html @@ -347,7 +347,16 @@ function renderPipelineTable(pipelines) { ['monitor', '🩺 监控运维层', '健康检查/审计/备份/推送/自修复'], ]; const selStyle = 'background:#21262d;color:#c9d1d9;border:1px solid #30363d;border-radius:4px;padding:5px 8px;font-size:12px'; - let html = '
'; + // 2026-08-12 系统 crontab 违规统计(老莫:显著提示) + const sysCnt = pipelines.filter(p => p.source === 'system_crontab').length; + let html = ''; + // 显著横幅:开发原则——禁止系统 crontab 部署自动任务,统一 hermes + html += `
` + + `
🚫 开发原则(强制):自动任务必须部署在 hermes(position-analyst),严禁使用系统 crontab
` + + `
来源标记:✅ hermes(合规)| ⚠️ 系统cron(违规,需迁移)。当前检测到 ${sysCnt} 个系统 crontab 部署的 MoFin 任务。
` + + (sysCnt > 0 ? `
⚠️ 存在违规系统 cron,请迁移到 hermes 后从系统 crontab 移除(统一体系,避免新旧一起跑)。
` : `
✅ 无违规系统 cron,体系统一。
`) + + `
`; + html += '
'; html += ''; html += `'; @@ -367,10 +376,16 @@ function renderPipelineTable(pipelines) { const tagCls = p.status==='ok'?'ok':p.status==='error'?'error':'warn'; const statusDisplay = p.last_run ? p.status : '待首次运行'; const profileBadge = p.profile==='position-analyst' ? '📋' : '📦'; + // 2026-08-12 cron来源标记:系统 crontab 违规用红色警告(老莫要求显著提示) + const isSys = p.source === 'system_crontab'; + const srcBadge = isSys + ? '⚠️ 系统cron(违规)' + : '✅ hermes'; + const rowStyle = isSys ? ' style="background:#2d1515;border-left:3px solid #f85149"' : ''; const encName = encodeURIComponent(p.name || ''); const encScript = encodeURIComponent(p.script || ''); - html += `${p.name||p.script||'LLM'}`; - html += `${profileBadge} ${p.profile||'?'}`; + html += `${p.name||p.script||'LLM'}`; + html += `${srcBadge} ${profileBadge}${p.profile||'?'}`; html += `${p.script||'LLM'}`; html += `${p.type||'cron'}`; html += `${p.schedule||'-'}`;