Files
pikasTech-HWLAB/internal/mvp-gate/summary.mjs
T
2026-05-30 12:31:07 +08:00

185 lines
6.7 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
import { DEV_ENDPOINT } from "../protocol/index.mjs";
export { DEV_ENDPOINT };
export const DEFAULT_GATE_REPORT_SOURCE = "source:v02-live-api-summary";
export const V02_CLI_LIVE_CHECKS = Object.freeze([
"node scripts/run-bun.mjs tools/hwlab-cli/bin/hwlab-cli.ts client auth session --base-url http://74.48.78.17:19666 --no-session",
"node scripts/run-bun.mjs tools/hwlab-cli/bin/hwlab-cli.ts client auth login --base-url http://74.48.78.17:19666 --username admin --password-env HWLAB_PASSWORD",
"node scripts/run-bun.mjs tools/hwlab-cli/bin/hwlab-cli.ts client device-pods list --base-url http://74.48.78.17:19666",
"node scripts/run-bun.mjs tools/hwlab-cli/bin/hwlab-cli.ts client device-pods status device-pod-71-freq --base-url http://74.48.78.17:19666",
"node scripts/run-bun.mjs tools/hwlab-cli/bin/hwlab-cli.ts client workbench summary --base-url http://74.48.78.17:19666 --pod-id device-pod-71-freq"
]);
export const M3_WORKBENCH_TOPOLOGY = Object.freeze({
projectId: "retired_legacy_mvp_fixture",
projectStatus: "retired",
gateways: Object.freeze([]),
boxResources: Object.freeze([]),
patchPanel: null
});
function readJsonFile(repoRoot, relativePath) {
const absolutePath = path.resolve(repoRoot, relativePath);
return JSON.parse(fs.readFileSync(absolutePath, "utf8"));
}
function defaultMvpGateReport() {
return {
reportVersion: "v2",
issue: "pikasTech/HWLAB#7",
taskId: "v02-live-api-summary",
acceptanceLevel: "v02_live_api_observation",
devOnly: true,
prodDisabled: true,
gateStatus: "retired",
sourceContract: {
status: "pass",
documents: [
"docs/reference/spec-v02-hwlab-cli.md",
"docs/reference/spec-v02-services.md",
"docs/reference/spec-device-pod.md",
"docs/reference/g14-gitops-cicd.md"
],
summary: "Legacy M5 fixture gate is retired. v0.2 validation uses short-connection hwlab-cli client commands against the same Cloud Web APIs used by the browser."
},
validationCommands: V02_CLI_LIVE_CHECKS,
localSmoke: {
status: "pass",
commands: ["node scripts/run-bun.mjs test tools/hwlab-cli/client.test.ts"],
evidence: [
"hwlab-cli stores only cookie session metadata.",
"device-pods and workbench commands use Cloud Web API paths, not fixtures."
],
summary: "Short-connection CLI unit coverage replaces the old fixture dry-run gate."
},
liveChecks: {
status: "manual",
commands: V02_CLI_LIVE_CHECKS,
evidence: [
"Unauthenticated requests must return explicit auth state or HTTP auth errors with JSON output.",
"Authenticated requests must exercise /auth, /v1/device-pods, /v1/live-builds, and health endpoints through 19666."
],
summary: "Live non-visual workbench checks are performed through hwlab-cli client, not a service, image, Job, or CI gate."
},
blockers: [
{
type: "runtime_observation",
scope: "v02-live-api",
status: "manual",
summary: "Run the current short-connection CLI against Cloud Web when live evidence is needed."
}
],
milestones: [
{
id: "v0.2-cli",
status: "active",
commands: V02_CLI_LIVE_CHECKS,
evidence: ["WEB-equivalent non-visual APIs are tested through hwlab-cli client."],
summary: "The current validation path is short-connection live API probing."
},
{
id: "legacy-m5-fixture",
status: "retired",
commands: [],
evidence: ["Old hwlab-cli artifact/test fixture is removed from active checks."],
summary: "Do not restore the former M5 fixture gate or hwlab-cli image/job path."
}
]
};
}
function clone(value) {
return JSON.parse(JSON.stringify(value));
}
function summarizeMilestone(milestone) {
return {
id: milestone.id,
status: milestone.status,
commandCount: milestone.commands?.length ?? 0,
evidenceCount: milestone.evidence?.length ?? 0,
summary: milestone.summary
};
}
function summarizeBlocker(blocker) {
return {
type: blocker.type,
scope: blocker.scope,
status: blocker.status,
summary: blocker.summary
};
}
export function buildMvpGateSummary({ report = defaultMvpGateReport() } = {}) {
const blockers = Array.isArray(report.blockers) ? report.blockers.map(summarizeBlocker) : [];
const milestones = Array.isArray(report.milestones) ? report.milestones.map(summarizeMilestone) : [];
return {
generatedFrom: {
gateReport: DEFAULT_GATE_REPORT_SOURCE,
m5Plan: "retired"
},
issue: report.issue ?? "pikasTech/HWLAB#7",
supports: ["pikasTech/HWLAB#7"],
gateStatus: report.gateStatus ?? "retired",
activeGate: false,
legacyFixtureGateRetired: true,
acceptanceLevel: report.acceptanceLevel ?? "v02_live_api_observation",
reportCommitId: report.commitId ?? "source-summary",
dryRunOnly: false,
devOnly: report.devOnly === true,
prodDisabled: report.prodDisabled === true,
environment: "v02",
endpoint: "http://74.48.78.17:19666",
namespace: "hwlab-v02",
sourceSummary: report.sourceContract?.summary ?? "Legacy fixture gate retired.",
localSmoke: report.localSmoke ?? null,
liveChecks: report.liveChecks ?? null,
blockers,
milestones,
topology: clone(M3_WORKBENCH_TOPOLOGY),
serviceModel: {
"hwlab-cli": {
runtimeService: false,
image: false,
kubernetesJob: false,
gitopsDesiredState: false,
invocation: "short-connection client from G14:/root/hwlab-v02"
}
},
validationCommands: report.validationCommands ?? V02_CLI_LIVE_CHECKS,
realDevGate: {
sourcePlanCommand: "retired",
command: "use hwlab-cli client live commands from docs/reference/spec-v02-hwlab-cli.md",
requiresAllBlockersClear: false,
requiresDryRunPass: false,
requiresArtifactObservability: false,
requiresD601RouteObservation: false,
requiresHumanApprovalForRealDev: false
},
safety: {
mode: "short-connection-live-api",
allowNetwork: true,
allowDeploy: false,
allowBrowserE2E: false,
allowSecrets: false,
prohibitedActions: ["create hwlab-cli image", "create hwlab-cli service", "create hwlab-cli job", "restore legacy M5 fixture gate"]
}
};
}
export function loadMvpGateSummary(repoRoot, options = {}) {
const reportPath = options.reportPath ?? null;
const report = reportPath ? readJsonFile(repoRoot, reportPath) : defaultMvpGateReport();
const summary = buildMvpGateSummary({ report });
summary.generatedFrom = {
gateReport: reportPath ?? DEFAULT_GATE_REPORT_SOURCE,
m5Plan: "retired"
};
return summary;
}