docs: add dev m5 gate report
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"$schema": "https://hwlab.pikastech.local/schemas/dev-gate-report.schema.json",
|
||||
"$id": "https://hwlab.pikastech.local/reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"reportVersion": "v1",
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"commitId": "6eb4c199b0c63cca7fd68fc3306f7a9cbe4323ea",
|
||||
"acceptanceLevel": "dev_mvp_gate",
|
||||
"devOnly": true,
|
||||
"prodDisabled": true,
|
||||
"gateStatus": "blocked",
|
||||
"sourceContract": {
|
||||
"status": "pass",
|
||||
"documents": [
|
||||
"docs/dev-gate-report.md",
|
||||
"docs/dev-acceptance-matrix.md",
|
||||
"docs/m0-contract-audit.md",
|
||||
"docs/m1-local-smoke.md",
|
||||
"docs/m2-dev-deploy-smoke.md",
|
||||
"docs/m3-hardware-loop.md",
|
||||
"docs/m4-agent-loop.md",
|
||||
"docs/m5-mvp-e2e.md",
|
||||
"docs/runtime-boundary-guard.md",
|
||||
"docs/topology-constraints.md",
|
||||
"docs/artifact-catalog.md",
|
||||
"docs/schema-drift-map.md",
|
||||
"protocol/README.md",
|
||||
"protocol/audit.md",
|
||||
"protocol/evidence-chain.md",
|
||||
"protocol/mvp-e2e-contract.md"
|
||||
],
|
||||
"summary": "The DEV gate is anchored to the frozen matrix, gate contract, and M0-M5 milestone docs on origin/main."
|
||||
},
|
||||
"validationCommands": [
|
||||
"node --check scripts/validate-dev-gate-report.mjs",
|
||||
"node scripts/validate-dev-gate-report.mjs"
|
||||
],
|
||||
"localSmoke": {
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node scripts/validate-contract.mjs",
|
||||
"node scripts/validate-m0-contract.mjs",
|
||||
"node scripts/validate-artifact-catalog.mjs",
|
||||
"node scripts/validate-runtime-boundary.mjs",
|
||||
"node scripts/validate-schema-drift-map.mjs",
|
||||
"node scripts/validate-evidence-chain.mjs",
|
||||
"node scripts/m1-contract-smoke.mjs",
|
||||
"node scripts/m2-dev-deploy-smoke.mjs --dry-run",
|
||||
"node scripts/m3-hardware-loop-smoke.mjs",
|
||||
"node scripts/m4-agent-loop-smoke.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"validated 15 JSON files and 13 service ids",
|
||||
"validated M0 contract examples: 7 JSON files, 13 service ids",
|
||||
"validated 13 DEV artifact catalog services at 24eb3bf",
|
||||
"validated HWLAB runtime boundary guard for 13 services; forbidden substitutes: unidesk-backend, provider-gateway, microservice-proxy",
|
||||
"validated schema drift map with 59 aligned fields and 12 gaps",
|
||||
"validated 2 evidence chain fixtures and 2 evidence records",
|
||||
"[m1-smoke] passed",
|
||||
"[m2-smoke] validated 11 service contracts",
|
||||
"[m2-smoke] mode=dry-run endpoint=http://74.48.78.17:6667",
|
||||
"[m2-smoke] no real DEV/PROD request was made",
|
||||
"M3 hardware loop smoke passed",
|
||||
"[m4-smoke] ok m4-agent-automation-loop-local-contract-smoke"
|
||||
],
|
||||
"summary": "M0-M4 contract and smoke checks pass locally without contacting the live DEV ingress."
|
||||
},
|
||||
"dryRun": {
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node tools/hwlab-cli/bin/hwlab-cli.mjs health",
|
||||
"node tools/hwlab-cli/bin/hwlab-cli.mjs test e2e --env dev --mvp --dry-run",
|
||||
"node scripts/m5-mvp-e2e-dry-run.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"hwlab-cli health -> status: ok, environment: dev, endpoint: http://74.48.78.17:6667, projects: 2",
|
||||
"hwlab-cli dry-run -> 9 steps, 13 artifacts, 14 health contracts, 2 hardware operations, 2 evidence records, 0 network calls",
|
||||
"M5 MVP E2E dry-run passed: 9 steps, 13 artifacts, 14 health contracts, 2 hardware operations, 2 evidence records, 0 network calls"
|
||||
],
|
||||
"summary": "The M5 orchestration dry-run is green, but it remains fixture-only and does not establish a live DEV gate."
|
||||
},
|
||||
"devPreconditions": {
|
||||
"status": "blocked",
|
||||
"requirements": [
|
||||
"Obtain a live HTTP 200/JSON health observation from http://74.48.78.17:6667/health and /live",
|
||||
"Record live route observations for hwlab-edge-proxy, hwlab-tunnel-client, hwlab-router, hwlab-cloud-api/web, hwlab-gateway, hwlab-gateway-simu, hwlab-box-simu, hwlab-patch-panel, hwlab-agent-mgr, hwlab-agent-worker, and hwlab-agent-skills",
|
||||
"Keep the run DEV-only and avoid PROD, heavy e2e, secrets, restarts, or UniDesk substitution"
|
||||
],
|
||||
"commands": [
|
||||
"curl -fsS --max-time 5 http://74.48.78.17:6667/health",
|
||||
"curl -fsS --max-time 5 http://74.48.78.17:6667/live"
|
||||
],
|
||||
"evidence": [
|
||||
"curl exit 7 for /health: could not connect to 74.48.78.17 port 6667",
|
||||
"curl exit 7 for /live: could not connect to 74.48.78.17 port 6667"
|
||||
],
|
||||
"summary": "The frozen DEV endpoint is not reachable from this runner, so no live DEV gate can be claimed yet."
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"status": "open",
|
||||
"summary": "http://74.48.78.17:6667/health and /live both fail with curl exit 7; live DEV ingress evidence is missing."
|
||||
}
|
||||
],
|
||||
"milestones": [
|
||||
{
|
||||
"id": "M0",
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node scripts/validate-contract.mjs",
|
||||
"node scripts/validate-m0-contract.mjs",
|
||||
"node scripts/validate-artifact-catalog.mjs",
|
||||
"node scripts/validate-runtime-boundary.mjs",
|
||||
"node scripts/validate-schema-drift-map.mjs",
|
||||
"node scripts/validate-evidence-chain.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"validated 15 JSON files and 13 service ids",
|
||||
"validated M0 contract examples: 7 JSON files, 13 service ids",
|
||||
"validated 13 DEV artifact catalog services at 24eb3bf",
|
||||
"validated HWLAB runtime boundary guard for 13 services; forbidden substitutes: unidesk-backend, provider-gateway, microservice-proxy",
|
||||
"validated schema drift map with 59 aligned fields and 12 gaps",
|
||||
"validated 2 evidence chain fixtures and 2 evidence records"
|
||||
],
|
||||
"summary": "Frozen contract, artifact, boundary, drift, and evidence fixtures are parseable and aligned to the DEV boundary."
|
||||
},
|
||||
{
|
||||
"id": "M1",
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node scripts/m1-contract-smoke.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"[m1-smoke] ok cloud-api health/live/rpc skeleton",
|
||||
"[m1-smoke] ok patch-panel/sim status and route skeleton",
|
||||
"[m1-smoke] ok CLI dry-run fixture parse",
|
||||
"[m1-smoke] passed"
|
||||
],
|
||||
"summary": "The local M1 contract smoke passes."
|
||||
},
|
||||
{
|
||||
"id": "M2",
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node scripts/m2-dev-deploy-smoke.mjs --dry-run"
|
||||
],
|
||||
"evidence": [
|
||||
"[m2-smoke] validated 11 service contracts",
|
||||
"[m2-smoke] mode=dry-run endpoint=http://74.48.78.17:6667",
|
||||
"[m2-smoke] no real DEV/PROD request was made"
|
||||
],
|
||||
"summary": "The deploy smoke remains fixture-only and validates the frozen route phases and artifact metadata."
|
||||
},
|
||||
{
|
||||
"id": "M3",
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node scripts/m3-hardware-loop-smoke.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"M3 hardware loop smoke passed",
|
||||
"topology: 2 box simulators, 2 gateway simulators, 1 patch panel",
|
||||
"wiring: box-simu-1 DO1 -> box-simu-2 DI1 via hwlab-patch-panel"
|
||||
],
|
||||
"summary": "The local hardware trusted loop smoke passes."
|
||||
},
|
||||
{
|
||||
"id": "M4",
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node scripts/m4-agent-loop-smoke.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"[m4-smoke] ok m4-agent-automation-loop-local-contract-smoke"
|
||||
],
|
||||
"summary": "The local agent automation loop smoke passes."
|
||||
},
|
||||
{
|
||||
"id": "M5",
|
||||
"status": "pass",
|
||||
"commands": [
|
||||
"node tools/hwlab-cli/bin/hwlab-cli.mjs health",
|
||||
"node tools/hwlab-cli/bin/hwlab-cli.mjs test e2e --env dev --mvp --dry-run",
|
||||
"node scripts/m5-mvp-e2e-dry-run.mjs"
|
||||
],
|
||||
"evidence": [
|
||||
"hwlab-cli health -> status: ok, environment: dev, endpoint: http://74.48.78.17:6667, projects: 2",
|
||||
"hwlab-cli dry-run -> 9 steps, 13 artifacts, 14 health contracts, 2 hardware operations, 2 evidence records, 0 network calls",
|
||||
"M5 MVP E2E dry-run passed: 9 steps, 13 artifacts, 14 health contracts, 2 hardware operations, 2 evidence records, 0 network calls"
|
||||
],
|
||||
"summary": "The M5 orchestration is green in dry-run mode, but it stays fixture-only and does not claim live DEV readiness."
|
||||
}
|
||||
],
|
||||
"notes": "Blocked gate report. Local contract, smoke, and dry-run checks pass on origin/main, but live DEV ingress is unreachable from this runner."
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
# HWLAB DEV M5 Gate Report
|
||||
|
||||
Status: blocked
|
||||
|
||||
Baseline: `6eb4c199b0c63cca7fd68fc3306f7a9cbe4323ea`
|
||||
Scope: DEV only
|
||||
|
||||
## Summary
|
||||
|
||||
M0-M5 local contract, smoke, and dry-run checks pass on the frozen `origin/main` baseline. The live DEV gate is still blocked because `http://74.48.78.17:6667` is not reachable from this runner.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node scripts/validate-contract.mjs`
|
||||
- `node scripts/validate-m0-contract.mjs`
|
||||
- `node scripts/validate-artifact-catalog.mjs`
|
||||
- `node scripts/validate-runtime-boundary.mjs`
|
||||
- `node scripts/validate-schema-drift-map.mjs`
|
||||
- `node scripts/validate-evidence-chain.mjs`
|
||||
- `node scripts/m1-contract-smoke.mjs`
|
||||
- `node scripts/m2-dev-deploy-smoke.mjs --dry-run`
|
||||
- `node scripts/m3-hardware-loop-smoke.mjs`
|
||||
- `node scripts/m4-agent-loop-smoke.mjs`
|
||||
- `node tools/hwlab-cli/bin/hwlab-cli.mjs health`
|
||||
- `node tools/hwlab-cli/bin/hwlab-cli.mjs test e2e --env dev --mvp --dry-run`
|
||||
- `node scripts/m5-mvp-e2e-dry-run.mjs`
|
||||
- `curl -fsS --max-time 5 http://74.48.78.17:6667/health`
|
||||
- `curl -fsS --max-time 5 http://74.48.78.17:6667/live`
|
||||
|
||||
## Result
|
||||
|
||||
- `M0`: pass
|
||||
- `M1`: pass
|
||||
- `M2`: pass
|
||||
- `M3`: pass
|
||||
- `M4`: pass
|
||||
- `M5`: pass
|
||||
- `overall`: blocked
|
||||
|
||||
## Minimal Next Step
|
||||
|
||||
Obtain live `200`/JSON health observations from `http://74.48.78.17:6667/health` and `/live`, then capture the live route observations for the DEV ingress chain without switching to PROD or heavy e2e.
|
||||
|
||||
## Blocker
|
||||
|
||||
The frozen DEV endpoint returns connection failures from this runner, so no live DEV ingress evidence can be claimed yet.
|
||||
@@ -8,8 +8,24 @@ import { fileURLToPath } from "node:url";
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const reportsDir = path.join(repoRoot, "reports/dev-gate");
|
||||
|
||||
const allowedIssues = new Set(["pikasTech/HWLAB#31", "pikasTech/HWLAB#33", "pikasTech/HWLAB#36"]);
|
||||
const requiredPreflightIssue = "pikasTech/HWLAB#34";
|
||||
const contractIssue = "pikasTech/HWLAB#31";
|
||||
const issueFamily = Object.freeze({
|
||||
DEV_DEPLOY_APPLY: "pikasTech/HWLAB#33",
|
||||
DEV_GATE_PREFLIGHT: "pikasTech/HWLAB#34",
|
||||
DEV_ARTIFACT_PUBLISH: "pikasTech/HWLAB#35",
|
||||
DEV_EDGE_HEALTH: "pikasTech/HWLAB#36",
|
||||
DEV_M4_AGENT_LOOP: "pikasTech/HWLAB#37",
|
||||
DEV_M3_HARDWARE_LOOP: "pikasTech/HWLAB#38",
|
||||
DEV_M5_GATE_REPORT: "pikasTech/HWLAB#39",
|
||||
DEV_BASE_IMAGE_PREFLIGHT: "pikasTech/HWLAB#40",
|
||||
DEV_EVIDENCE_BLOCKER_AGGREGATOR: "pikasTech/HWLAB#41"
|
||||
});
|
||||
const allowedIssues = new Set([
|
||||
contractIssue,
|
||||
...Object.values(issueFamily)
|
||||
]);
|
||||
const requiredPreflightIssue = issueFamily.DEV_GATE_PREFLIGHT;
|
||||
const requiredMilestoneIds = ["M0", "M1", "M2", "M3", "M4", "M5"];
|
||||
const requiredValidationCommands = [
|
||||
"node --check scripts/validate-dev-gate-report.mjs",
|
||||
"node scripts/validate-dev-gate-report.mjs"
|
||||
@@ -26,7 +42,7 @@ const requiredDocs = [
|
||||
"docs/dev-acceptance-matrix.md",
|
||||
"docs/m0-contract-audit.md"
|
||||
];
|
||||
const requiredDevM3Issue = "pikasTech/HWLAB#38";
|
||||
const requiredDevM3Issue = issueFamily.DEV_M3_HARDWARE_LOOP;
|
||||
const requiredDevM3ValidationCommands = [
|
||||
"node --check scripts/dev-m3-hardware-loop-smoke.mjs",
|
||||
"node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
@@ -35,7 +51,7 @@ const requiredDevM3Docs = [
|
||||
"docs/dev-acceptance-matrix.md",
|
||||
"docs/m3-hardware-loop.md"
|
||||
];
|
||||
const requiredDevEdgeIssue = "pikasTech/HWLAB#36";
|
||||
const requiredDevEdgeIssue = issueFamily.DEV_EDGE_HEALTH;
|
||||
const requiredDevEdgeValidationCommands = [
|
||||
"node --check scripts/dev-edge-health-smoke.mjs",
|
||||
"node --check scripts/src/dev-edge-health-smoke-lib.mjs",
|
||||
@@ -259,6 +275,55 @@ async function validateReport(relativePath) {
|
||||
if (Object.hasOwn(report, "notes")) {
|
||||
assertString(report.notes, `${label}.notes`);
|
||||
}
|
||||
|
||||
if (Object.hasOwn(report, "gateStatus")) {
|
||||
assertStatus(report.gateStatus, `${label}.gateStatus`);
|
||||
}
|
||||
|
||||
if (Object.hasOwn(report, "milestones")) {
|
||||
assertArray(report.milestones, `${label}.milestones`);
|
||||
assert.deepEqual(
|
||||
report.milestones.map((milestone) => milestone.id),
|
||||
requiredMilestoneIds,
|
||||
`${label}.milestones must cover M0-M5 in order`
|
||||
);
|
||||
assertUnique(
|
||||
report.milestones.map((milestone) => milestone.id),
|
||||
`${label}.milestones`
|
||||
);
|
||||
|
||||
for (const [index, milestone] of report.milestones.entries()) {
|
||||
const milestoneLabel = `${label}.milestones[${index}]`;
|
||||
assertObject(milestone, milestoneLabel);
|
||||
for (const field of ["id", "status", "commands", "evidence", "summary"]) {
|
||||
assert.ok(Object.hasOwn(milestone, field), `${milestoneLabel} missing ${field}`);
|
||||
}
|
||||
assert.match(milestone.id, /^M[0-5]$/, `${milestoneLabel}.id`);
|
||||
assertStatus(milestone.status, `${milestoneLabel}.status`);
|
||||
assertStringArray(milestone.commands, `${milestoneLabel}.commands`, { minLength: 1 });
|
||||
assertUnique(milestone.commands, `${milestoneLabel}.commands`);
|
||||
assertStringArray(milestone.evidence, `${milestoneLabel}.evidence`, { minLength: 1 });
|
||||
assertUnique(milestone.evidence, `${milestoneLabel}.evidence`);
|
||||
assertString(milestone.summary, `${milestoneLabel}.summary`);
|
||||
if (Object.hasOwn(milestone, "blocker")) {
|
||||
assertString(milestone.blocker, `${milestoneLabel}.blocker`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.hasOwn(report.devPreconditions, "commands")) {
|
||||
assertStringArray(report.devPreconditions.commands, `${label}.devPreconditions.commands`, {
|
||||
minLength: 1
|
||||
});
|
||||
assertUnique(report.devPreconditions.commands, `${label}.devPreconditions.commands`);
|
||||
}
|
||||
|
||||
if (Object.hasOwn(report.devPreconditions, "evidence")) {
|
||||
assertStringArray(report.devPreconditions.evidence, `${label}.devPreconditions.evidence`, {
|
||||
minLength: 1
|
||||
});
|
||||
assertUnique(report.devPreconditions.evidence, `${label}.devPreconditions.evidence`);
|
||||
}
|
||||
}
|
||||
|
||||
async function assertDocumentSet(documentsValue, label, requiredDocs) {
|
||||
|
||||
Reference in New Issue
Block a user