test: refresh HWLAB DEV live evidence

Merge PR #71 after commander review. Rebaselines DEV live evidence to 16666/16667, removes stale edge/frp blocker classification, keeps DB live and M3 patch-panel runtime as real blockers. Complies with HWLAB #78 / DC-DCSN-P0-2026-003 by preserving DEV-LIVE evidence boundaries and not treating Gate/UI as MVP success.
This commit is contained in:
Lyon
2026-05-22 13:15:31 +08:00
committed by GitHub
parent 7e29522b65
commit ab11565640
17 changed files with 590 additions and 530 deletions
+66 -11
View File
@@ -239,7 +239,7 @@ function applyPriority(blocker) {
};
}
if (blocker.scope.includes("edge") || blocker.scope.includes("ingress") || blocker.summary.includes("6667")) {
if (isEdgeOrFrpBlocker(blocker)) {
return {
...blocker,
priority: "P2",
@@ -258,6 +258,16 @@ function applyPriority(blocker) {
};
}
function isEdgeOrFrpBlocker(blocker) {
return blocker.scope.includes("edge") ||
blocker.scope.includes("ingress") ||
blocker.scope.includes("frp") ||
blocker.summary.includes(":16667") ||
blocker.summary.includes("16667") ||
blocker.summary.includes(":6667") ||
blocker.summary.includes("6667");
}
function sourceEntry(entry) {
return {
milestone: entry.milestone,
@@ -294,6 +304,7 @@ function collectM2Evidence(reports) {
const edge = reports.devEdgeHealth;
const d601 = reports.d601Observability;
const artifactIdentity = preflight.artifactIdentity;
const edgeLive = hasCurrentLiveEdgeEvidence(edge);
return [
reportEvidence({
@@ -336,7 +347,7 @@ function collectM2Evidence(reports) {
}),
reportEvidence({
milestone: "M2",
level: "SOURCE",
level: edgeLive ? "DEV-LIVE" : "SOURCE",
report: edge,
status: edge.edgeHealth?.status ?? primaryStatus(edge),
category: "edge-frp-contract",
@@ -346,7 +357,9 @@ function collectM2Evidence(reports) {
`cloudApiDb=${edge.edgeHealth?.contracts?.deploy?.cloudApiDb?.status ?? "unknown"}`
],
commands: edge.validationCommands,
summary: "Committed edge report is contract-only/not-run; it must not be counted as DEV-LIVE."
summary: edgeLive
? "Committed edge report proves read-only public HTTP on :16667 /health and /health/live; remaining edge report blocker is DB readiness, not route/frp reachability."
: "Committed edge report is contract-only/not-run; it must not be counted as DEV-LIVE."
}),
reportEvidence({
milestone: "M2",
@@ -473,12 +486,21 @@ function collectBlockers(reports) {
const blockers = [];
for (const report of Object.values(reports)) {
for (const blocker of report.blockers ?? []) {
if (isStaleLegacyIngressBlocker(blocker, report, reports)) {
continue;
}
blockers.push(normalizeBlocker(blocker, report));
}
for (const blocker of report.artifactPublish?.blockers ?? []) {
if (isStaleLegacyIngressBlocker(blocker, report, reports)) {
continue;
}
blockers.push(normalizeBlocker(blocker, report));
}
for (const blocker of report.devDeployApply?.remainingBlockers ?? []) {
if (isStaleLegacyIngressBlocker(blocker, report, reports)) {
continue;
}
blockers.push(normalizeBlocker(blocker, report));
}
}
@@ -487,6 +509,34 @@ function collectBlockers(reports) {
return normalized.sort((a, b) => a.unblockOrder - b.unblockOrder || a.id.localeCompare(b.id));
}
function hasCurrentLiveEdgeEvidence(edgeReport) {
const publicHttp = edgeReport?.edgeHealth?.publicHttp ?? [];
return edgeReport?.edgeHealth?.endpoint === DEV_ENDPOINT &&
edgeReport?.edgeHealth?.mode === "live-read-only" &&
publicHttp.some((probe) => probe.url === `${DEV_ENDPOINT}/health` && probe.ok === true && probe.status === 200) &&
publicHttp.some((probe) => probe.url === `${DEV_ENDPOINT}/health/live` && probe.ok === true && probe.status === 200);
}
function isStaleLegacyIngressBlocker(blocker, sourceReport, reports) {
const text = `${blocker.scope ?? ""} ${blocker.summary ?? ""}`;
const staleLegacyPort = text.includes("74.48.78.17:6667");
const stalePreflightEdgeProbe = sourceReport.path === reportPaths.devPreflight &&
blocker.type === "network_blocker" &&
(blocker.scope === "dev-edge" || blocker.scope === "dev-edge-health") &&
(
text.includes(`${DEV_ENDPOINT}/health/live is not reachable`) ||
text.includes("live network probes require --live")
);
if (!staleLegacyPort && !stalePreflightEdgeProbe) {
return false;
}
const currentEdgeReachable = hasCurrentLiveEdgeEvidence(reports.devEdgeHealth);
return currentEdgeReachable && sourceReport.path !== reportPaths.devM3Hardware &&
sourceReport.path !== reportPaths.devM4Agent &&
sourceReport.path !== reportPaths.devM5Gate;
}
function deriveMilestones(evidence, blockers) {
const evidenceByMilestone = new Map();
for (const item of evidence) {
@@ -571,6 +621,7 @@ function buildDoD(reports, milestones, blockers) {
const preflight = reports.devPreflight;
const artifactIdentity = preflight.artifactIdentity;
const d601 = reports.d601Observability;
const edgeLive = hasCurrentLiveEdgeEvidence(reports.devEdgeHealth);
return {
status: blockers.length === 0 && milestones.every((item) => item.status === "pass") ? "green" : "blocked",
@@ -603,10 +654,12 @@ function buildDoD(reports, milestones, blockers) {
: "D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev."
},
{
id: "dev-edge-frp-6667",
status: hasBlocker(blockers, (blocker) => blocker.scope.includes("edge") || blocker.scope.includes("ingress") || blocker.summary.includes("6667")) ? "blocked" : "pass",
evidenceLevel: "BLOCKED",
summary: "No committed report proves live HTTP 200/JSON on http://74.48.78.17:16667."
id: "dev-edge-frp-16667",
status: edgeLive && !hasBlocker(blockers, isEdgeOrFrpBlocker) ? "pass" : "blocked",
evidenceLevel: edgeLive && !hasBlocker(blockers, isEdgeOrFrpBlocker) ? "DEV-LIVE" : "BLOCKED",
summary: edgeLive
? "Committed edge report proves read-only public HTTP on :16667 /health and /health/live; old preflight network probe blockers are stale."
: "No committed report proves live HTTP 200/JSON on http://74.48.78.17:16667."
},
{
id: "cloud-api-db-ready",
@@ -661,7 +714,7 @@ function actionForBlockerOrder(blockerOrder, items) {
function fallbackAction(scope) {
if (scope === "base-image") return "Preload or tag node:20-bookworm-slim and rerun the base-image and artifact publish preflights.";
if (scope.includes("artifact")) return "Publish DEV artifacts for every frozen HWLAB service and record immutable registry digests.";
if (scope.includes("edge") || scope.includes("ingress")) return "Repair frp/master-edge/D601 router path and rerun read-only DEV edge health.";
if (scope.includes("edge") || scope.includes("ingress") || scope.includes("frp")) return "Repair frp/master-edge/D601 router path and rerun read-only DEV edge health.";
if (scope.includes("cloud-api-db")) return "Configure DEV cloud-api DB env readiness and rerun health/preflight without exposing secrets.";
if (scope.includes("kubectl") || scope.includes("k3s")) return "Provide read-only kubectl/kubeconfig observability for hwlab-dev.";
return "Resolve the blocker and attach source/local/dry-run/DEV-live evidence at the correct level.";
@@ -673,7 +726,7 @@ function evidenceRequiredFor(scope) {
if (scope.includes("artifact") || scope === "ghcr") return "Artifact publish report with ciPublished=true, registryVerified=true, and sha256 digest for each frozen service ID.";
if (scope.includes("kubectl") || scope.includes("k3s")) return "Read-only kubectl/k3s report proving pods/services/configmaps are observable in hwlab-dev without reading Secrets.";
if (scope.includes("cloud-api-db")) return "Cloud API health/live output showing DB env ready and redacted secret references, without secret material.";
if (scope.includes("edge") || scope.includes("ingress")) return "Read-only DEV route observation for :16667/frp/edge/router with HWLAB service identity and artifact identity.";
if (scope.includes("edge") || scope.includes("ingress") || scope.includes("frp")) return "Read-only DEV route observation for :16667/frp/edge/router with HWLAB service identity and artifact identity.";
return "A committed report with the exact evidence level and command used.";
}
@@ -754,7 +807,7 @@ export async function buildReport() {
green: dod.green,
reason: dod.green
? "All #9 DEV DoD checks are green."
: "SOURCE, LOCAL, and DRY-RUN evidence exists, but DEV-LIVE acceptance is blocked by artifact, observability, DB, edge/frp, and loop evidence gaps."
: "SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is still blocked by artifact, observability, DB, and loop evidence gaps."
},
dod,
milestones,
@@ -777,7 +830,9 @@ export function formatCheckSummary(report) {
green: report.overall.green,
blockers: report.blockers.length,
nextStep: report.nextSteps[0]?.action ?? null,
levels
levels: Object.fromEntries(
Object.entries(report.levels).map(([level, entries]) => [level, entries.length])
)
};
}