fix: derive workbench smoke report identity

This commit is contained in:
Code Queue Review
2026-05-22 18:23:21 +00:00
parent ee9d60f00b
commit b6d5ef900f
3 changed files with 230 additions and 7 deletions
+143 -2
View File
@@ -1,4 +1,5 @@
import fs from "node:fs";
import { execFileSync } from "node:child_process";
import http from "node:http";
import path from "node:path";
import { fileURLToPath } from "node:url";
@@ -328,6 +329,7 @@ function runStaticSmoke() {
async function runLiveSmoke(args) {
const checks = [];
const blockers = [];
const runtimeIdentity = await observeLiveRuntimeIdentity(runtime.endpoints.api);
const http = await fetchText(args.url);
addCheck(checks, blockers, "live-http-html", http.ok && http.status === 200 && /text\/html/u.test(http.contentType) && liveHtmlLooksLikeWorkbench(http.body), "Live URL serves the Cloud Workbench HTML.", {
blocker: "runtime_blocker",
@@ -375,6 +377,7 @@ async function runLiveSmoke(args) {
blockers,
evidenceLevel: status === "pass" ? "DEV-LIVE-BROWSER" : "BLOCKED",
devLive: status === "pass",
runtimeIdentity,
safety: {
prodTouched: false,
servicesRestarted: false,
@@ -388,7 +391,8 @@ async function runLiveSmoke(args) {
});
}
function baseReport({ mode, status, checks, blockers, evidenceLevel, devLive, help = undefined, safety, url = null }) {
function baseReport({ mode, status, checks, blockers, evidenceLevel, devLive, help = undefined, safety, url = null, runtimeIdentity = null }) {
const sourceIdentity = observeSourceIdentity();
return {
$schema: "https://hwlab.pikastech.local/schemas/dev-gate-report.schema.json",
$id: "https://hwlab.pikastech.local/reports/dev-gate/dev-cloud-workbench-live.json",
@@ -396,7 +400,7 @@ function baseReport({ mode, status, checks, blockers, evidenceLevel, devLive, he
status,
issue: "pikasTech/HWLAB#7",
taskId: "dev-cloud-workbench-live",
commitId: "ab252f5",
commitId: sourceIdentity.reportCommitId,
acceptanceLevel: "dev_cloud_workbench_live",
devOnly: true,
prodDisabled: true,
@@ -426,6 +430,8 @@ function baseReport({ mode, status, checks, blockers, evidenceLevel, devLive, he
generatedAt: new Date().toISOString(),
evidenceLevel,
devLive,
sourceIdentity,
runtimeIdentity: runtimeIdentity ?? notObservedRuntimeIdentity("live runtime identity was not observed in this smoke mode"),
sourceContract: {
status: "pass",
documents: [
@@ -518,6 +524,65 @@ function readText(relativePath) {
return fs.readFileSync(path.join(repoRoot, relativePath), "utf8");
}
function observeSourceIdentity() {
const head = runGit(["rev-parse", "--verify", "HEAD"]);
const shortHead = head ? runGit(["rev-parse", "--short=12", "HEAD"]) : null;
const ref = runGit(["rev-parse", "--abbrev-ref", "HEAD"]) ?? process.env.GITHUB_HEAD_REF ?? process.env.GITHUB_REF_NAME ?? "unknown";
const statusOutput = runGit(["status", "--porcelain"]);
const envIdentity = head ? null : environmentCommitIdentity();
const commitId = head ?? envIdentity?.commitId ?? "unknown";
const shortCommitId = shortHead ?? envIdentity?.commitId.slice(0, 12) ?? "unknown";
const dirty = statusOutput === null ? null : statusOutput.length > 0;
const worktreeState = dirty === null ? "unknown" : dirty ? "dirty" : "clean";
const source = head ? "git-head" : envIdentity ? "environment" : "unknown";
const reportCommitId = commitId !== "unknown" && worktreeState === "clean" ? shortCommitId : "unknown";
return {
status: commitId === "unknown" ? "unknown" : "observed",
source,
...(envIdentity ? { environmentKey: envIdentity.key } : {}),
commitId,
shortCommitId,
ref,
worktreeState,
dirty,
reportCommitId,
summary: worktreeState !== "clean"
? "Source HEAD was observed, but the worktree was not cleanly attributable when the report was generated; top-level commitId is unknown rather than pretending to identify uncommitted source."
: "Source identity was derived from the current worktree or source environment and is separate from the live runtime identity."
};
}
function environmentCommitIdentity() {
for (const key of [
"GITHUB_SHA",
"CI_COMMIT_SHA",
"BUILDKITE_COMMIT",
"CODEBUILD_RESOLVED_SOURCE_VERSION",
"SOURCE_COMMIT",
"HWLAB_SOURCE_COMMIT_ID"
]) {
const value = process.env[key];
if (typeof value === "string" && /^[a-f0-9]{7,40}$/iu.test(value.trim())) {
return { key, commitId: value.trim().toLowerCase() };
}
}
return null;
}
function runGit(args) {
try {
return execFileSync("git", args, {
cwd: repoRoot,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
timeout: 5000
}).trim();
} catch {
return null;
}
}
function assetsExist() {
return requiredWebAssets.every((file) => fs.existsSync(path.join(webRoot, file)));
}
@@ -907,6 +972,82 @@ function staticSafety() {
};
}
async function observeLiveRuntimeIdentity(apiEndpoint) {
const endpoint = new URL("/health/live", apiEndpoint).toString();
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 6000);
try {
const response = await fetch(endpoint, {
signal: controller.signal,
headers: { Accept: "application/json" }
});
let body = null;
try {
body = await response.json();
} catch {
body = null;
}
if (!response.ok || !body || typeof body !== "object") {
return notObservedRuntimeIdentity(`health-live returned HTTP ${response.status}`, endpoint);
}
return {
status: "observed",
source: "health-live",
endpoint,
serviceId: sanitizeRuntimeString(body.serviceId),
environment: sanitizeRuntimeString(body.environment),
healthStatus: sanitizeRuntimeString(body.status),
commitId: sanitizeRevision(body.commit?.id ?? body.commitId),
commitSource: sanitizeRuntimeString(body.commit?.source),
imageTag: sanitizeRuntimeString(body.image?.tag),
observedAt: sanitizeTimestamp(body.observedAt),
summary: "Live runtime identity was observed through the existing read-only health endpoint and is not inferred from source git HEAD."
};
} catch (error) {
return notObservedRuntimeIdentity(
error.name === "AbortError" ? "health-live request timed out" : `health-live request failed: ${oneLine(error.message)}`,
endpoint
);
} finally {
clearTimeout(timer);
}
}
function notObservedRuntimeIdentity(reason, endpoint = new URL("/health/live", runtime.endpoints.api).toString()) {
return {
status: "not_observed",
source: "health-live",
endpoint,
serviceId: "not_observed",
environment: "not_observed",
healthStatus: "not_observed",
commitId: "not_observed",
commitSource: "not_observed",
imageTag: "not_observed",
observedAt: new Date().toISOString(),
reason: oneLine(reason),
summary: "Live runtime identity is recorded as not_observed; source identity must not be treated as the deployed runtime revision."
};
}
function sanitizeRevision(value) {
if (typeof value !== "string") return "unknown";
const trimmed = value.trim().toLowerCase();
return /^[a-f0-9]{7,40}$/u.test(trimmed) ? trimmed : "unknown";
}
function sanitizeTimestamp(value) {
return typeof value === "string" && !Number.isNaN(Date.parse(value)) ? value : new Date().toISOString();
}
function sanitizeRuntimeString(value) {
return typeof value === "string" && value.trim().length > 0 ? oneLine(value) : "unknown";
}
function oneLine(value) {
return String(value ?? "unknown").replace(/\s+/gu, " ").trim().slice(0, 240) || "unknown";
}
async function fetchText(url) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 6000);