更新: 109 个文件 - 2026-03-18 10:55:52

这个提交包含在:
hao
2026-03-18 10:55:52 -07:00
父节点 1d5cb533e3
当前提交 1f9d9b1d16
修改 109 个文件,包含 10958 行新增1350 行删除

查看文件

@@ -43,6 +43,8 @@ const DOC_HUB_ITEMS = [
{ title: "仓库入口镜像", href: "/docs/root-readme.html", description: "根 README 的本地镜像,包含能力矩阵与主入口。", badge: "readme" },
{ title: "授权模型", href: "/docs/authorization-model.html", description: "目标范围、授权模型、最小化验证建议和记录要求。", badge: "scope" },
{ title: "source-map 镜像", href: "/docs/source-map.html", description: "系统覆盖、来源、输出目录和 secure-code 主题真值。", badge: "source-map" },
{ title: "source catalog audit", href: "/docs/source-catalog-audit.html", description: "active/retired source、replacement map 与覆盖摘要。", badge: "audit" },
{ title: "retired sources", href: "/docs/retired-sources.html", description: "退役源、退役原因和 replacement_sources 真值。", badge: "retired" },
{ title: "repro-map 镜像", href: "/docs/repro-map.html", description: "默认漏洞家族、浏览器要求和日志策略真值。", badge: "repro-map" },
{ title: "覆盖矩阵镜像", href: "/docs/coverage-matrix.html", description: "当前全库覆盖矩阵的本地镜像。", badge: "coverage" },
{ title: "安全编码索引", href: "/docs/secure-code-index.html", description: "secure-code 修复主题索引镜像。", badge: "secure-code" },
@@ -52,6 +54,10 @@ const DOC_HUB_ITEMS = [
const DATA_HUB_ITEMS = [
{ title: "summary.json", href: "/summary.json", description: "全局摘要、状态分布、最近失败与系统汇总。", badge: "json" },
{ title: "completeness.json", href: "/data/completeness.json", description: "最新 advisory 完整度、系统/family 进度与 ingest 健康度。", badge: "json" },
{ title: "source-health.json", href: "/data/source-health.json", description: "active source 健康度、失败分类与系统分布。", badge: "json" },
{ title: "alerts.json", href: "/data/alerts.json", description: "source 告警状态机、failure streak 与 resolved 记录。", badge: "json" },
{ title: "monitor-summary.json", href: "/data/monitor-summary.json", description: "每日监控摘要、open alerts 与最近全绿时间。", badge: "json" },
{ title: "source-catalog-audit.json", href: "/data/source-catalog-audit.json", description: "source catalog 审计真值与 retired/replacement 关系。", badge: "json" },
{ title: "runs.json", href: "/runs.json", description: "最近运行的结构化详情,可用于 UI 和调试。", badge: "json" },
{ title: "systems.json", href: "/systems.json", description: "系统级覆盖、分类、更新时间和浏览器证据统计。", badge: "json" },
{ title: "advisories.json", href: "/advisories.json", description: "漏洞条目元数据、来源和 secure-code 主题。", badge: "json" },
@@ -87,6 +93,9 @@ const state = {
profiles: {},
architecture: null,
completeness: null,
sourceHealth: null,
alerts: [],
monitorSummary: null,
selectedRunId: null,
selectedArtifact: null,
refreshHandle: null,
@@ -279,38 +288,41 @@ function familyOptions() {
function metricCards() {
const completeness = state.completeness || state.summary?.completeness || {};
const successCount = Number(completeness.verified_real || 0) + Number(completeness.verified_synthetic || 0);
const blockedCount = Number(completeness.blocked || 0);
const inProgressCount = Number(completeness.manual || 0);
const monitoring = state.monitorSummary || state.summary?.monitoring || {};
const advisoryTotal = Number(completeness.advisory_total || state.summary?.advisory_count || 0);
const advisorySuccess = Number(completeness.verified_real || 0);
const activeSources = Number(monitoring.active_source_count || state.sourceHealth?.active_source_count || 0);
const greenSources = Number(monitoring.green_source_count || state.sourceHealth?.green_source_count || 0);
const openAlerts = Number(monitoring.open_alert_count || state.sourceHealth?.open_alert_count || 0);
const lastFullyGreen = monitoring.last_fully_green_run || state.sourceHealth?.last_fully_green_run || "";
return [
{
label: "最新 advisory",
value: advisoryTotal,
label: "advisory 完整度",
value: `${advisorySuccess}/${advisoryTotal}`,
note: `历史运行 ${state.summary?.run_count || 0}`,
color: "var(--accent-purple)",
color: "var(--accent-green)",
iconName: "report"
},
{
label: "实证成功",
value: successCount,
note: "真实版本 + 合成靶场",
color: "var(--accent-green)",
label: "active sources",
value: activeSources,
note: `green ${greenSources}`,
color: "var(--accent-blue)",
iconName: "shield"
},
{
label: "当前阻塞",
value: blockedCount,
note: "latest advisory 状态里的 blocked-*",
label: "open alerts",
value: openAlerts,
note: "source-health 告警状态机",
color: "var(--accent-red)",
iconName: "failure"
},
{
label: "待处理 / 进行中",
value: inProgressCount,
note: "人工分诊或待补证据的 latest advisory",
color: "var(--accent-blue)",
label: "最近全绿",
value: lastFullyGreen ? formatDateTime(lastFullyGreen) : "-",
note: "active source 集合最近一次全绿",
color: "var(--accent-purple)",
iconName: "timeline"
}
];
@@ -762,6 +774,7 @@ function renderPanel(panelKey, title, meta, iconName, content) {
function renderCompletenessPanel(panelKey, compact = false) {
const completeness = state.completeness || state.summary?.completeness || {};
const sourceHealth = state.sourceHealth || completeness.source_health || {};
const systems = (state.completeness?.systems || []).map((system) => `
<article class="plan-card">
<span class="plan-label">${escapeHtml(system.system_id)}</span>
@@ -795,12 +808,21 @@ function renderCompletenessPanel(panelKey, compact = false) {
<strong>ingest failures</strong>
<span>${escapeHtml(state.completeness?.ingest_health?.failure_count || 0)}</span>
</article>
<article class="detail-stat">
<strong>active sources</strong>
<span>${escapeHtml(sourceHealth.active_source_count || 0)}</span>
</article>
<article class="detail-stat">
<strong>open alerts</strong>
<span>${escapeHtml(sourceHealth.open_alert_count || 0)}</span>
</article>
</div>
<div class="plan-grid" style="margin-top:16px;">${systems || `<div class="empty-state">暂无系统完整度数据。</div>`}</div>
${compact ? "" : `
<div class="detail-actions" style="margin-top:16px;">
<a class="button button-secondary" href="/docs/testing-completeness-report.html" target="_blank" rel="noreferrer">${icon("docs")}<span>打开中文报告</span></a>
<a class="button button-secondary" href="/data/completeness.json" target="_blank" rel="noreferrer">${icon("json")}<span>打开 completeness.json</span></a>
<a class="button button-secondary" href="/data/source-health.json" target="_blank" rel="noreferrer">${icon("json")}<span>打开 source-health.json</span></a>
</div>
${failures.length ? `<div class="callout" style="margin-top:16px;"><strong>Ingest 未清零</strong><div class="plan-copy">${escapeHtml(failures.join(" | "))}</div></div>` : ""}
`}
@@ -808,6 +830,66 @@ function renderCompletenessPanel(panelKey, compact = false) {
);
}
function renderSourceHealthPanel(panelKey, compact = false) {
const sourceHealth = state.sourceHealth || {};
const alerts = state.alerts || [];
const failures = (sourceHealth.failures || []).slice(0, 6);
const openAlertItems = alerts.filter((item) => item.status === "open");
const openAlerts = openAlertItems.slice(0, 6);
const failureCards = failures.length
? failures.map((item) => `
<article class="plan-card">
<span class="plan-label">${escapeHtml(item.system_id || "-")} · ${escapeHtml(item.source_name || "-")}</span>
<div class="plan-copy">${escapeHtml(item.category || "unknown")} · ${escapeHtml(item.message || item.summary || "-")}</div>
</article>
`).join("")
: `<div class="empty-state">当前 active source 集合全绿。</div>`;
const alertCards = openAlerts.length
? openAlerts.map((item) => `
<article class="plan-card">
<span class="plan-label">${escapeHtml(item.system_id || "-")} · ${escapeHtml(item.source_name || "-")}</span>
<div class="plan-copy">streak ${escapeHtml(item.failure_streak || 0)} · ${escapeHtml(item.last_category || "-")}</div>
</article>
`).join("")
: `<div class="empty-state">当前没有 open alert。</div>`;
return renderPanel(
panelKey,
"Source Health 与告警",
`${escapeHtml(sourceHealth.green_source_count || 0)}/${escapeHtml(sourceHealth.active_source_count || 0)}`,
"shield",
`
<div class="detail-stat-grid">
<article class="detail-stat">
<strong>green</strong>
<span>${escapeHtml(sourceHealth.green_source_count || 0)}</span>
</article>
<article class="detail-stat">
<strong>failures</strong>
<span>${escapeHtml(sourceHealth.failure_count || 0)}</span>
</article>
<article class="detail-stat">
<strong>open alerts</strong>
<span>${escapeHtml(openAlertItems.length)}</span>
</article>
<article class="detail-stat">
<strong>last fully green</strong>
<span>${escapeHtml(sourceHealth.last_fully_green_run ? formatDateTime(sourceHealth.last_fully_green_run) : "-")}</span>
</article>
</div>
${compact ? "" : `
<div class="detail-actions" style="margin-top:16px;">
<a class="button button-secondary" href="/data/source-health.json" target="_blank" rel="noreferrer">${icon("json")}<span>source-health.json</span></a>
<a class="button button-secondary" href="/data/alerts.json" target="_blank" rel="noreferrer">${icon("json")}<span>alerts.json</span></a>
<a class="button button-secondary" href="/data/monitor-summary.json" target="_blank" rel="noreferrer">${icon("json")}<span>monitor-summary.json</span></a>
<a class="button button-secondary" href="/docs/source-catalog-audit.html" target="_blank" rel="noreferrer">${icon("docs")}<span>source catalog audit</span></a>
</div>
`}
<div class="plan-grid" style="margin-top:16px;">${failureCards}</div>
<div class="plan-grid" style="margin-top:16px;">${alertCards}</div>
`
);
}
function renderArchitectureFields(fields = []) {
if (!fields.length) return "";
return `
@@ -1185,6 +1267,7 @@ function renderOverviewWorkspace() {
<div class="detail-subtitle">根入口保留为概览页,同时新增运行、系统、架构、文档和数据的独立 URL。顶部菜单负责分类切换,搜索与筛选会同步到地址栏。</div>
</section>
${renderCompletenessPanel("overview_completeness")}
${renderSourceHealthPanel("overview_source_health")}
${renderPanel("overview_runs", "最新运行", `${escapeHtml(runs.length)}`, "queue", renderRunList(runs, "暂无运行数据。"))}
${renderPanel("overview_systems", "系统覆盖概览", `${escapeHtml(systems.length)} 个系统`, "systems", `<div class="system-grid">${renderSystemCards(systems)}</div>`)}
${renderArchitecturePanel()}
@@ -1251,6 +1334,7 @@ function renderDocsWorkspace() {
<div class="detail-subtitle">不再把所有入口混在首页链接堆里。这里按说明、设计、真值镜像和 secure-code 索引集中展示。</div>
</section>
${renderCompletenessPanel("docs_completeness", true)}
${renderSourceHealthPanel("docs_source_health", true)}
${renderPanel("docs_hub", "文档与镜像页", `${escapeHtml(DOC_HUB_ITEMS.length)} 个入口`, "docs", renderHubCards(DOC_HUB_ITEMS))}
</div>
`;
@@ -1272,6 +1356,7 @@ function renderDataWorkspace() {
<div class="detail-subtitle">summary、runs、systems、advisories、profiles、architecture 已单独归入数据中心,避免和文档、运行详情混在一个地址里。</div>
</section>
${renderCompletenessPanel("data_completeness", true)}
${renderSourceHealthPanel("data_source_health")}
${renderPanel("data_hub", "JSON 与生成数据", `${escapeHtml(DATA_HUB_ITEMS.length)} 个入口`, "json", renderHubCards(DATA_HUB_ITEMS))}
</div>
`;
@@ -1473,14 +1558,17 @@ async function loadData(preserveSelection = true) {
renderSyncState("loading", "刷新中", `本地时间 ${new Date().toLocaleTimeString("zh-CN", { hour12: false })}`);
try {
const [summary, runs, systems, advisories, profiles, architecture, completeness] = await Promise.all([
const [summary, runs, systems, advisories, profiles, architecture, completeness, sourceHealth, alerts, monitorSummary] = await Promise.all([
fetchJson("/summary.json"),
fetchJson("/runs.json"),
fetchJson("/systems.json"),
fetchJson("/advisories.json"),
fetchJson("/profiles.json"),
fetchJson("/architecture.json"),
fetchJson("/data/completeness.json")
fetchJson("/data/completeness.json"),
fetchJson("/data/source-health.json"),
fetchJson("/data/alerts.json"),
fetchJson("/data/monitor-summary.json")
]);
state.summary = summary;
@@ -1490,6 +1578,9 @@ async function loadData(preserveSelection = true) {
state.profiles = profiles;
state.architecture = architecture;
state.completeness = completeness;
state.sourceHealth = sourceHealth;
state.alerts = alerts;
state.monitorSummary = monitorSummary;
const filtered = filteredRuns();
const candidate = preserveSelection ? (state.selectedRunId || previousRunId) : state.selectedRunId;