更新: 5 个文件 - 2026-03-18 09:50:04

这个提交包含在:
hao
2026-03-18 09:50:04 -07:00
父节点 dc31e6e80f
当前提交 1d5cb533e3
修改 5 个文件,包含 277 行新增39 行删除

查看文件

@@ -43,6 +43,18 @@ STATUS_LABELS = {
}
def _failure_text(item: Any) -> str:
if isinstance(item, dict):
return item.get("summary") or f"{item.get('system_id')}::{item.get('source_name')}::{item.get('category')}::{item.get('message')}"
return str(item)
def _safe_read_text(path: Path, default: str = "") -> str:
if not path.exists():
return default
return path.read_text(encoding="utf-8")
def mermaid_from_steps(run: Dict[str, Any]) -> str:
lines = [
"flowchart LR",
@@ -229,6 +241,9 @@ def _build_completeness(
runs: List[Dict[str, Any]],
profile_map: Dict[str, Dict[str, Any]],
run_summary: Dict[str, Any],
source_health: Dict[str, Any],
alerts: List[Dict[str, Any]],
monitor_summary: Dict[str, Any],
) -> Dict[str, Any]:
latest_statuses: Dict[str, int] = {}
historical_statuses: Dict[str, int] = {}
@@ -284,7 +299,9 @@ def _build_completeness(
verified_synthetic = latest_statuses.get("verified-synthetic", 0)
blocked = sum(count for key, count in latest_statuses.items() if key.startswith("blocked-"))
manual = advisory_total - verified_real - verified_synthetic - blocked
complete = advisory_total > 0 and advisory_total == verified_real
source_failure_count = int(source_health.get("failure_count", 0))
open_alert_count = len([item for item in alerts if item.get("status") == "open"])
complete = advisory_total > 0 and advisory_total == verified_real and source_failure_count == 0
return {
"generated_at": isoformat(now_utc()),
"advisory_total": advisory_total,
@@ -299,13 +316,23 @@ def _build_completeness(
"systems": systems_list,
"ingest_health": {
"failure_count": len(run_summary.get("failures", []) or []),
"failures": run_summary.get("failures", []) or [],
"failures": [_failure_text(item) for item in (run_summary.get("failures", []) or [])],
},
"source_health": {
"active_source_count": int(source_health.get("active_source_count", 0)),
"green_source_count": int(source_health.get("green_source_count", 0)),
"failure_count": source_failure_count,
"last_fully_green_run": source_health.get("last_fully_green_run"),
"open_alert_count": open_alert_count,
"resolved_alert_count": len([item for item in alerts if item.get("status") == "resolved"]),
},
"monitor_summary": monitor_summary or {},
"historical_blockers": [
"Docker daemon unavailable caused provision-compose-environment blocked-artifact.",
"Family profiles previously used note-only attack runners and dry-run placeholders.",
"Baseline and browser steps were skipped when environment readiness was not enforced.",
"Latest completeness now uses one advisory -> latest run semantics instead of historical run piles.",
"Source health now counts only status=active sources; retired sources are audited separately with replacement links.",
],
}
@@ -320,6 +347,9 @@ def _write_testing_completeness_report(completeness: Dict[str, Any]) -> None:
f"- 阻塞数量: `{completeness['blocked']}`",
f"- 人工/待补证据数量: `{completeness['manual']}`",
f"- 完整度百分比: `{completeness['verified_ratio']}%`",
f"- active source 全绿: `{completeness['source_health']['green_source_count']}/{completeness['source_health']['active_source_count']}`",
f"- source open alerts: `{completeness['source_health']['open_alert_count']}`",
f"- 最近一次 source 全绿: `{completeness['source_health'].get('last_fully_green_run') or '-'}`",
"",
"## 系统覆盖矩阵",
"",
@@ -348,6 +378,9 @@ def _write_testing_completeness_report(completeness: Dict[str, Any]) -> None:
"## Ingest / Source 健康度",
"",
f"- source failures: `{completeness['ingest_health']['failure_count']}`",
f"- active sources: `{completeness['source_health']['active_source_count']}`",
f"- green sources: `{completeness['source_health']['green_source_count']}`",
f"- open alerts: `{completeness['source_health']['open_alert_count']}`",
]
)
for item in completeness["ingest_health"].get("failures", []):
@@ -384,6 +417,8 @@ def _build_architecture_data(summary: Dict[str, Any], source_map: Dict[str, Any]
_link("仓库入口镜像", "/docs/root-readme.html", "仓库根 README 的本地镜像。"),
_link("授权模型", "/docs/authorization-model.html", "允许目标范围、全局原则与记录要求。"),
_link("source-map 真值", "/docs/source-map.html", "系统覆盖、来源和输出目录真值。"),
_link("source catalog audit", "/docs/source-catalog-audit.html", "active/retired source 审计、替代关系与覆盖摘要。"),
_link("retired sources", "/docs/retired-sources.html", "退役源、退役原因与 replacement map。"),
_link("repro-map 真值", "/docs/repro-map.html", "复现族路由、浏览器要求和日志策略。"),
_link("覆盖矩阵", "/docs/coverage-matrix.html", "自动生成覆盖摘要的本地镜像。"),
_link("设计来源清单", "/docs/design-source.html", "Lovart 模板本地 vendor manifest。"),
@@ -393,11 +428,15 @@ def _build_architecture_data(summary: Dict[str, Any], source_map: Dict[str, Any]
data_links = [
_link("summary.json", "/summary.json", "全局摘要、状态分布和最近失败。"),
_link("completeness.json", "/data/completeness.json", "最新 advisory 完整度、系统/family 进度与 ingest 健康度。"),
_link("source-health.json", "/data/source-health.json", "active source 健康度、系统分布与失败分类。"),
_link("alerts.json", "/data/alerts.json", "source 告警状态机、failure streak 与 resolved 记录。"),
_link("monitor-summary.json", "/data/monitor-summary.json", "每日监控摘要、open alerts 与最近全绿时间。"),
_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。"),
_link("source-catalog-audit.json", "/data/source-catalog-audit.json", "source catalog 审计真值与 retired/replacement 关系。"),
]
category_items: List[Dict[str, Any]] = []
@@ -880,6 +919,18 @@ def _write_dashboard_docs(architecture: Dict[str, Any]) -> None:
SOURCE_MAP_PATH.read_text(encoding="utf-8"),
"工作台内置镜像页:系统覆盖、来源、输出目录和 secure-code 主题真值。",
),
(
"source-catalog-audit.html",
"Source Catalog Audit",
_safe_read_text(ROOT / "08-threat-intel" / "generated" / "source-catalog-audit.md", "source catalog audit has not been generated yet."),
"工作台内置镜像页active/retired source、replacement map 与覆盖摘要。",
),
(
"retired-sources.html",
"Retired Sources & Replacement Map",
json.dumps(read_json(ROOT / "08-threat-intel" / "generated" / "retired-sources.json", default=[]), indent=2, ensure_ascii=False),
"工作台内置镜像页:退役源、退役原因和 replacement_sources 真值。",
),
(
"repro-map.html",
"repro-map 真值镜像",
@@ -1144,6 +1195,10 @@ def render_dashboard() -> Dict[str, str]:
advisory_records = load_json_dir(ADVISORIES_DIR)
runs = load_json_dir(RUNS_DIR)
run_summary = read_json(ROOT / "08-threat-intel" / "generated" / "run-summary.json", default={}) or {}
source_health = read_json(ROOT / "08-threat-intel" / "generated" / "source-health.json", default={}) or {}
alerts = read_json(ROOT / "08-threat-intel" / "generated" / "alerts.json", default=[]) or []
monitor_summary = read_json(ROOT / "08-threat-intel" / "generated" / "monitor-summary.json", default={}) or {}
source_catalog_audit = read_json(ROOT / "08-threat-intel" / "generated" / "source-catalog-audit.json", default={}) or {}
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")}
@@ -1256,6 +1311,13 @@ def render_dashboard() -> Dict[str, str]:
"statuses": {},
"run_statuses": {},
"recent_failures": [],
"monitoring": {
"active_source_count": int(source_health.get("active_source_count", 0)),
"green_source_count": int(source_health.get("green_source_count", 0)),
"source_failure_count": int(source_health.get("failure_count", 0)),
"open_alert_count": len([item for item in alerts if item.get("status") == "open"]),
"last_fully_green_run": source_health.get("last_fully_green_run"),
},
}
for item in merged_advisories:
status = item.get("verification_status", "triage-manual")
@@ -1284,7 +1346,7 @@ def render_dashboard() -> Dict[str, str]:
for item in sorted(merged_advisories, key=lambda value: value.get("updated_at") or value.get("published_at") or "", reverse=True)
if item.get("verification_status") in {"triage-manual", "blocked-artifact", "blocked-destructive"}
][:20]
completeness = _build_completeness(merged_advisories, runs, profile_map, run_summary)
completeness = _build_completeness(merged_advisories, runs, profile_map, run_summary, source_health, alerts, monitor_summary)
summary["completeness"] = {
"advisory_total": completeness["advisory_total"],
"verified_real": completeness["verified_real"],
@@ -1293,6 +1355,9 @@ def render_dashboard() -> Dict[str, str]:
"manual": completeness["manual"],
"verified_ratio": completeness["verified_ratio"],
"complete": completeness["complete"],
"source_failure_count": completeness["source_health"]["failure_count"],
"active_source_count": completeness["source_health"]["active_source_count"],
"open_alert_count": completeness["source_health"]["open_alert_count"],
}
write_json(DASHBOARD_DIR / "summary.json", summary)
@@ -1301,6 +1366,10 @@ def render_dashboard() -> Dict[str, str]:
write_json(DASHBOARD_DIR / "advisories.json", {key: _advisory_meta(value) for key, value in advisory_map.items()})
write_json(DASHBOARD_DIR / "profiles.json", {key: _profile_meta(value) for key, value in profile_map.items()})
write_json(DASHBOARD_DIR / "data" / "completeness.json", completeness)
write_json(DASHBOARD_DIR / "data" / "source-health.json", source_health)
write_json(DASHBOARD_DIR / "data" / "alerts.json", alerts)
write_json(DASHBOARD_DIR / "data" / "monitor-summary.json", monitor_summary)
write_json(DASHBOARD_DIR / "data" / "source-catalog-audit.json", source_catalog_audit)
_write_testing_completeness_report(completeness)
architecture = _build_architecture_data(summary, source_map, repro_map)
write_json(DASHBOARD_DIR / "architecture.json", architecture)