From 4e3b4bf107b31d696edc64a91c6943120d5ec53f Mon Sep 17 00:00:00 2001 From: hao Date: Tue, 17 Mar 2026 02:15:00 -0700 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0:=202=20=E4=B8=AA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20-=202026-03-17=2002:15:00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/intel/validators.py | 12 ++++++ scripts/lab/render.py | 81 +++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/scripts/intel/validators.py b/scripts/intel/validators.py index d96fd018..32843ef6 100644 --- a/scripts/intel/validators.py +++ b/scripts/intel/validators.py @@ -90,6 +90,12 @@ def validate(source_map: Dict[str, Any]) -> List[str]: GENERATED_DIR / "latest-ingest.md", GENERATED_DIR / "run-summary.json", GENERATED_DIR / "dashboard" / "index.html", + GENERATED_DIR / "dashboard" / "overview" / "index.html", + GENERATED_DIR / "dashboard" / "runs" / "index.html", + GENERATED_DIR / "dashboard" / "systems" / "index.html", + GENERATED_DIR / "dashboard" / "architecture" / "index.html", + GENERATED_DIR / "dashboard" / "docs" / "index.html", + GENERATED_DIR / "dashboard" / "data" / "index.html", GENERATED_DIR / "dashboard" / "legacy" / "index.html", GENERATED_DIR / "dashboard" / "summary.json", GENERATED_DIR / "dashboard" / "systems.json", @@ -120,6 +126,12 @@ def validate(source_map: Dict[str, Any]) -> List[str]: runtime_files = [ GENERATED_DIR / "dashboard" / "index.html", + GENERATED_DIR / "dashboard" / "overview" / "index.html", + GENERATED_DIR / "dashboard" / "runs" / "index.html", + GENERATED_DIR / "dashboard" / "systems" / "index.html", + GENERATED_DIR / "dashboard" / "architecture" / "index.html", + GENERATED_DIR / "dashboard" / "docs" / "index.html", + GENERATED_DIR / "dashboard" / "data" / "index.html", GENERATED_DIR / "dashboard" / "assets" / "app.js", GENERATED_DIR / "dashboard" / "assets" / "styles.css", GENERATED_DIR / "dashboard" / "legacy" / "index.html", diff --git a/scripts/lab/render.py b/scripts/lab/render.py index 399ab769..05f33cb8 100644 --- a/scripts/lab/render.py +++ b/scripts/lab/render.py @@ -18,6 +18,7 @@ LEGACY_TEMPLATE_DIR = TEMPLATES_DIR / "legacy" LOVART_VENDOR_MANIFEST = LOVART_TEMPLATE_DIR / "vendor" / "source-manifest.json" ROOT_JSON_FILES = ["summary.json", "runs.json", "systems.json", "advisories.json", "profiles.json"] ROOT_JSON_FILES.append("architecture.json") +SECTION_ROUTE_DIRS = ["overview", "runs", "systems", "architecture", "data"] CATEGORY_LABELS = { "cms": "CMS / 内容平台", @@ -69,7 +70,7 @@ def _dashboard_ref(run: Dict[str, Any], ref: str) -> str: try: bundle_dir = Path(run["report_refs"]["bundle_dir"]).resolve() relative = Path(ref).resolve().relative_to(bundle_dir) - return f"./runs/{run['run_id']}/{relative.as_posix()}" + return f"/runs/{run['run_id']}/{relative.as_posix()}" except Exception: return ref @@ -215,27 +216,32 @@ def _build_architecture_data(summary: Dict[str, Any], source_map: Dict[str, Any] repro_by_system = {item.get("system_id"): item for item in (repro_map.get("systems", []) or []) if item.get("system_id")} route_links = [ - _link("正式工作台", "./index.html", "本地化主 UI,默认入口。"), - _link("旧版工作台", "./legacy/index.html", "保留的 legacy 回退入口。"), - _link("项目功能文档", "./docs/project-features.html", "项目能力、目录结构与自动化链路总览。"), - _link("前端设计文档", "./docs/frontend-dashboard-design.html", "当前本地工作台的交互与视觉规范。"), - _link("安全编码索引", "./docs/secure-code-index.html", "secure-code 修复库本地镜像。"), - _link("仓库入口镜像", "./docs/root-readme.html", "仓库根 README 的本地镜像。"), - _link("授权模型", "./docs/authorization-model.html", "允许目标范围、全局原则与记录要求。"), - _link("source-map 真值", "./docs/source-map.html", "系统覆盖、来源和输出目录真值。"), - _link("repro-map 真值", "./docs/repro-map.html", "复现族路由、浏览器要求和日志策略。"), - _link("覆盖矩阵", "./docs/coverage-matrix.html", "自动生成覆盖摘要的本地镜像。"), - _link("设计来源清单", "./docs/design-source.html", "Lovart 模板本地 vendor manifest。"), - _link("架构库镜像", "./docs/architecture-library.html", "当前架构库的结构化镜像页。"), + _link("总览首页", "/overview/index.html", "工作台总览、最新运行和全局摘要。"), + _link("运行中心", "/runs/index.html", "运行队列、详情、证据和日志入口。"), + _link("系统分组", "/systems/index.html", "按系统和分类浏览覆盖情况。"), + _link("架构库", "/architecture/index.html", "查看控制面、数据层和授权边界。"), + _link("文档中心", "/docs/index.html", "集中查看项目文档、本地镜像和说明。"), + _link("数据中心", "/data/index.html", "查看 summary、runs、systems 等 JSON 入口。"), + _link("旧版工作台", "/legacy/index.html", "保留的 legacy 回退入口。"), + _link("项目功能文档", "/docs/project-features.html", "项目能力、目录结构与自动化链路总览。"), + _link("前端设计文档", "/docs/frontend-dashboard-design.html", "当前本地工作台的交互与视觉规范。"), + _link("安全编码索引", "/docs/secure-code-index.html", "secure-code 修复库本地镜像。"), + _link("仓库入口镜像", "/docs/root-readme.html", "仓库根 README 的本地镜像。"), + _link("授权模型", "/docs/authorization-model.html", "允许目标范围、全局原则与记录要求。"), + _link("source-map 真值", "/docs/source-map.html", "系统覆盖、来源和输出目录真值。"), + _link("repro-map 真值", "/docs/repro-map.html", "复现族路由、浏览器要求和日志策略。"), + _link("覆盖矩阵", "/docs/coverage-matrix.html", "自动生成覆盖摘要的本地镜像。"), + _link("设计来源清单", "/docs/design-source.html", "Lovart 模板本地 vendor manifest。"), + _link("架构库镜像", "/docs/architecture-library.html", "当前架构库的结构化镜像页。"), ] data_links = [ - _link("summary.json", "./summary.json", "全局摘要、状态分布和最近失败。"), - _link("runs.json", "./runs.json", "最近 run 的结构化详情。"), - _link("systems.json", "./systems.json", "系统级覆盖与浏览器证据摘要。"), - _link("advisories.json", "./advisories.json", "advisory 元数据与来源。"), - _link("profiles.json", "./profiles.json", "repro profile 元数据。"), - _link("architecture.json", "./architecture.json", "当前架构库结构化 JSON。"), + _link("summary.json", "/summary.json", "全局摘要、状态分布和最近失败。"), + _link("runs.json", "/runs.json", "最近 run 的结构化详情。"), + _link("systems.json", "/systems.json", "系统级覆盖与浏览器证据摘要。"), + _link("advisories.json", "/advisories.json", "漏洞条目元数据与来源。"), + _link("profiles.json", "/profiles.json", "复现档案元数据。"), + _link("architecture.json", "/architecture.json", "当前架构库结构化 JSON。"), ] category_items: List[Dict[str, Any]] = [] @@ -492,7 +498,13 @@ def _build_architecture_data(summary: Dict[str, Any], source_map: Dict[str, Any] "fields": [ _field("工作台根目录", "08-threat-intel/generated/dashboard/"), _field("运行归档根目录", "06-case-studies/generated-runs//"), - _field("工作台入口", "/index.html"), + _field("默认入口", "/index.html"), + _field("总览入口", "/overview/index.html"), + _field("运行入口", "/runs/index.html"), + _field("系统入口", "/systems/index.html"), + _field("架构入口", "/architecture/index.html"), + _field("文档入口", "/docs/index.html"), + _field("数据入口", "/data/index.html"), _field("旧版入口", "/legacy/index.html"), ], }, @@ -630,7 +642,7 @@ def _dashboard_doc_page(title: str, body: str, description: str) -> str:

{html.escape(title)}

{html.escape(description)}
@@ -763,6 +775,18 @@ def _render_root_dashboard_shell() -> None: _copy_tree(LOVART_TEMPLATE_DIR / "assets", assets_dir) +def _render_section_dashboard_shells() -> None: + source_index = LOVART_TEMPLATE_DIR / "index.html" + for section in SECTION_ROUTE_DIRS: + section_dir = DASHBOARD_DIR / section + _remove_path(section_dir) + ensure_dir(section_dir) + shutil.copy2(source_index, section_dir / "index.html") + docs_dir = DASHBOARD_DIR / "docs" + ensure_dir(docs_dir) + shutil.copy2(source_index, docs_dir / "index.html") + + def _render_legacy_dashboard_shell() -> None: legacy_dir = DASHBOARD_DIR / "legacy" _remove_path(legacy_dir) @@ -951,6 +975,7 @@ def render_dashboard() -> Dict[str, str]: runs = load_json_dir(RUNS_DIR) source_map = read_yaml(SOURCE_MAP_PATH, default={}) or {} repro_map = read_yaml(REPRO_MAP_PATH, default={}) or {} + source_system_map = {item["system_id"]: item for item in source_map.get("systems", []) if item.get("system_id")} advisory_map = {item["canonical_id"]: item for item in advisory_records if item.get("canonical_id")} profile_map = load_profiles() @@ -971,6 +996,9 @@ def render_dashboard() -> Dict[str, str]: "browser_required": 0, "browser_present": 0, "latest_update": "", + "category": source_system_map.get(advisory["system_id"], {}).get("category", advisory.get("category")), + "tier": source_system_map.get(advisory["system_id"], {}).get("tier"), + "output_dir": source_system_map.get(advisory["system_id"], {}).get("output_dir"), }, ) system["total"] += 1 @@ -1005,10 +1033,10 @@ def render_dashboard() -> Dict[str, str]: } request_only_refs = [ref for ref in item.get("request_log_refs", []) if ref not in item.get("baseline_refs", [])] cloned["dashboard_refs"] = { - "report_html": f"./runs/{item['run_id']}/report.html", - "report_md": f"./runs/{item['run_id']}/report.md", - "timeline": f"./runs/{item['run_id']}/timeline.mmd", - "bundle": f"./runs/{item['run_id']}/run.json", + "report_html": f"/runs/{item['run_id']}/report.html", + "report_md": f"/runs/{item['run_id']}/report.md", + "timeline": f"/runs/{item['run_id']}/timeline.mmd", + "bundle": f"/runs/{item['run_id']}/run.json", } cloned["browser_evidence"] = browser_evidence cloned["browser_links"] = [_dashboard_ref(item, ref) for ref in item.get("browser_refs", [])] @@ -1075,11 +1103,14 @@ def render_dashboard() -> Dict[str, str]: _write_dashboard_docs(architecture) _write_design_source_manifest() _render_root_dashboard_shell() + _render_section_dashboard_shells() _render_legacy_dashboard_shell() return { "dashboard_dir": str(DASHBOARD_DIR), "index": str(DASHBOARD_DIR / "index.html"), + "overview_index": str(DASHBOARD_DIR / "overview" / "index.html"), + "runs_index": str(DASHBOARD_DIR / "runs" / "index.html"), "legacy_index": str(DASHBOARD_DIR / "legacy" / "index.html"), "summary_json": str(DASHBOARD_DIR / "summary.json"), }