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:
@@ -9,8 +9,9 @@ entry points that later service implementations must follow.
|
||||
## MVP Freeze
|
||||
|
||||
- MVP scope is DEV only.
|
||||
- DEV endpoint is fixed at `http://74.48.78.17:6667`.
|
||||
- PROD endpoint `:6666` is reserved and is not an MVP acceptance target.
|
||||
- DEV browser/frontend endpoint is fixed at `http://74.48.78.17:16666/`.
|
||||
- DEV API/edge/live endpoint is fixed at `http://74.48.78.17:16667`.
|
||||
- PROD is not an MVP acceptance target.
|
||||
- UniDesk may be used only as an external scheduling, CI, or CD base.
|
||||
- HWLAB runtime services must not be replaced by UniDesk backend,
|
||||
provider-gateway, or microservice proxy implementations.
|
||||
|
||||
@@ -60,8 +60,8 @@ The preflight checks:
|
||||
`HWLAB_CLOUD_DB_SSL_MODE=require`.
|
||||
- The local cloud-api health payload reports DB env presence/missing status with
|
||||
redacted values only. This is a readiness gate, not live DB evidence.
|
||||
- `deploy/frp` and `deploy/master-edge` describe the D601-to-master DEV route
|
||||
on port `6667`.
|
||||
- `deploy/frp` and `deploy/master-edge` describe the D601-to-master DEV routes
|
||||
on public ports `16666`/`16667`.
|
||||
- The runner can perform read-only `kubectl` probes against `hwlab-dev`.
|
||||
- `reports/dev-gate/dev-edge-health.json`, when present, records read-only
|
||||
public edge, frps, tunnel-health, and k3s observability evidence.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
export const DEV_ENDPOINT = "http://74.48.78.17:16667";
|
||||
import { DEV_ENDPOINT } from "../protocol/index.mjs";
|
||||
|
||||
export { DEV_ENDPOINT };
|
||||
export const DEFAULT_GATE_REPORT_PATH = "reports/dev-gate/dev-mvp-gate-report.json";
|
||||
export const DEFAULT_M5_PLAN_PATH = "fixtures/mvp/m5-e2e/dry-run-plan.json";
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
"reportVersion": "v1",
|
||||
"issue": "pikasTech/HWLAB#36",
|
||||
"taskId": "dev-edge-health",
|
||||
"commitId": "cb35ada68606",
|
||||
"commitId": "86d769525caf",
|
||||
"acceptanceLevel": "dev_edge_health",
|
||||
"devOnly": true,
|
||||
"prodDisabled": true,
|
||||
"status": "blocked",
|
||||
"generatedAt": "2026-05-22T04:22:14.774Z",
|
||||
"generatedAt": "2026-05-22T04:30:36.613Z",
|
||||
"namespace": "hwlab-dev",
|
||||
"endpoint": "http://74.48.78.17:16667",
|
||||
"sourceContract": {
|
||||
@@ -69,7 +69,7 @@
|
||||
}
|
||||
],
|
||||
"edgeHealth": {
|
||||
"generatedAt": "2026-05-22T04:22:14.774Z",
|
||||
"generatedAt": "2026-05-22T04:30:36.613Z",
|
||||
"mode": "live-read-only",
|
||||
"endpoint": "http://74.48.78.17:16667",
|
||||
"safety": {
|
||||
@@ -189,19 +189,19 @@
|
||||
"host": "74.48.78.17",
|
||||
"port": 16667,
|
||||
"status": "connected",
|
||||
"durationMs": 212
|
||||
"durationMs": 228
|
||||
},
|
||||
{
|
||||
"host": "74.48.78.17",
|
||||
"port": 7000,
|
||||
"status": "connected",
|
||||
"durationMs": 1205
|
||||
"durationMs": 212
|
||||
},
|
||||
{
|
||||
"host": "74.48.78.17",
|
||||
"port": 7402,
|
||||
"status": "connected",
|
||||
"durationMs": 232
|
||||
"durationMs": 216
|
||||
}
|
||||
],
|
||||
"publicHttp": [
|
||||
@@ -214,7 +214,7 @@
|
||||
"connection": "keep-alive",
|
||||
"content-length": "661",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"date": "Fri, 22 May 2026 04:22:14 GMT",
|
||||
"date": "Fri, 22 May 2026 04:30:35 GMT",
|
||||
"keep-alive": "timeout=5"
|
||||
},
|
||||
"json": {
|
||||
@@ -237,14 +237,14 @@
|
||||
"digest": "unknown"
|
||||
},
|
||||
"endpoint": "http://74.48.78.17:16667",
|
||||
"observedAt": "2026-05-22T04:22:14.011Z",
|
||||
"observedAt": "2026-05-22T04:30:35.063Z",
|
||||
"details": {
|
||||
"upstream": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667",
|
||||
"mode": "dev-edge-proxy"
|
||||
}
|
||||
},
|
||||
"bodyPreview": "{\n \"serviceId\": \"hwlab-edge-proxy\",\n \"environment\": \"dev\",\n \"status\": \"ok\",\n \"service\": {\n \"id\": \"hwlab-edge-proxy\",\n \"role\": \"public-dev-ingress\",\n \"healthPath\": \"/health\",\n \"livePath\": \"/health/live\"\n },\n \"commit\": {\n \"id\": \"cb35ada6860653b27269b0a57991184118cbf4b1\",\n \"source\": \"runtime-env\"\n },\n \"image\": {\n \"reference\": \"ghcr.io/pikastech/hwlab-edge-proxy:cb35ada\",\n \"tag\": \"cb35ada\",\n \"digest\": \"unknown\"\n },\n \"endpoint\": \"http://74.48.78.17:16667\",\n \"obse",
|
||||
"durationMs": 821
|
||||
"durationMs": 2000
|
||||
},
|
||||
{
|
||||
"url": "http://74.48.78.17:16667/health/live",
|
||||
@@ -255,7 +255,7 @@
|
||||
"cache-control": "no-store",
|
||||
"connection": "keep-alive",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"date": "Fri, 22 May 2026 04:22:14 GMT",
|
||||
"date": "Fri, 22 May 2026 04:30:35 GMT",
|
||||
"keep-alive": "timeout=5",
|
||||
"transfer-encoding": "chunked"
|
||||
},
|
||||
@@ -279,7 +279,7 @@
|
||||
"digest": "unknown"
|
||||
},
|
||||
"endpoint": "http://74.48.78.17:16667",
|
||||
"observedAt": "2026-05-22T04:22:14.013Z",
|
||||
"observedAt": "2026-05-22T04:30:35.064Z",
|
||||
"db": {
|
||||
"contractVersion": "v1",
|
||||
"environment": "dev",
|
||||
@@ -339,8 +339,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"bodyPreview": "{\"serviceId\":\"hwlab-cloud-api\",\"environment\":\"dev\",\"status\":\"degraded\",\"service\":{\"id\":\"hwlab-cloud-api\",\"role\":\"cloud-api\",\"healthPath\":\"/health\",\"livePath\":\"/health/live\"},\"commit\":{\"id\":\"cb35ada\",\"source\":\"runtime-env\"},\"image\":{\"reference\":\"127.0.0.1:5000/hwlab/hwlab-cloud-api:cb35ada\",\"tag\":\"cb35ada\",\"digest\":\"unknown\"},\"endpoint\":\"http://74.48.78.17:16667\",\"observedAt\":\"2026-05-22T04:22:14.013Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"c",
|
||||
"durationMs": 793
|
||||
"bodyPreview": "{\"serviceId\":\"hwlab-cloud-api\",\"environment\":\"dev\",\"status\":\"degraded\",\"service\":{\"id\":\"hwlab-cloud-api\",\"role\":\"cloud-api\",\"healthPath\":\"/health\",\"livePath\":\"/health/live\"},\"commit\":{\"id\":\"cb35ada\",\"source\":\"runtime-env\"},\"image\":{\"reference\":\"127.0.0.1:5000/hwlab/hwlab-cloud-api:cb35ada\",\"tag\":\"cb35ada\",\"digest\":\"unknown\"},\"endpoint\":\"http://74.48.78.17:16667\",\"observedAt\":\"2026-05-22T04:30:35.064Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"c",
|
||||
"durationMs": 820
|
||||
}
|
||||
],
|
||||
"kubernetes": {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"reportVersion": "v1",
|
||||
"issue": "pikasTech/HWLAB#38",
|
||||
"taskId": "dev-m3-hardware-loop",
|
||||
"commitId": "70bb9168ead2",
|
||||
"commitId": "86d769525caf",
|
||||
"acceptanceLevel": "dev_m3_hardware_loop",
|
||||
"devOnly": true,
|
||||
"prodDisabled": true,
|
||||
@@ -64,20 +64,19 @@
|
||||
},
|
||||
{
|
||||
"id": "dev-ingress-health",
|
||||
"status": "blocked",
|
||||
"blockerClass": "network_blocker",
|
||||
"summary": "DEV ingress at http://74.48.78.17:16667 did not return reachable HWLAB DEV health.",
|
||||
"status": "pass",
|
||||
"summary": "DEV ingress returned HWLAB identity at /health/live.",
|
||||
"evidence": [
|
||||
"{\"url\":\"http://74.48.78.17:16667/health/live\",\"method\":\"GET\",\"startedAt\":\"2026-05-21T17:29:33.794Z\",\"observedAt\":\"2026-05-21T17:29:33.964Z\",\"reached\":false,\"ok\":false,\"error\":{\"name\":\"Error\",\"message\":\"connect ECONNREFUSED 74.48.78.17:16667\",\"code\":\"ECONNREFUSED\"}}",
|
||||
"{\"url\":\"http://74.48.78.17:16667/health\",\"method\":\"GET\",\"startedAt\":\"2026-05-21T17:29:33.964Z\",\"observedAt\":\"2026-05-21T17:29:34.132Z\",\"reached\":false,\"ok\":false,\"error\":{\"name\":\"Error\",\"message\":\"connect ECONNREFUSED 74.48.78.17:16667\",\"code\":\"ECONNREFUSED\"}}",
|
||||
"{\"url\":\"http://74.48.78.17:16667/live\",\"method\":\"GET\",\"startedAt\":\"2026-05-21T17:29:34.132Z\",\"observedAt\":\"2026-05-21T17:29:34.313Z\",\"reached\":false,\"ok\":false,\"error\":{\"name\":\"Error\",\"message\":\"connect ECONNREFUSED 74.48.78.17:16667\",\"code\":\"ECONNREFUSED\"}}",
|
||||
"{\"url\":\"http://74.48.78.17:16667/v1\",\"method\":\"GET\",\"startedAt\":\"2026-05-21T17:29:34.314Z\",\"observedAt\":\"2026-05-21T17:29:34.479Z\",\"reached\":false,\"ok\":false,\"error\":{\"name\":\"Error\",\"message\":\"connect ECONNREFUSED 74.48.78.17:16667\",\"code\":\"ECONNREFUSED\"}}"
|
||||
"{\"url\":\"http://74.48.78.17:16667/health/live\",\"method\":\"GET\",\"startedAt\":\"2026-05-22T04:30:50.824Z\",\"observedAt\":\"2026-05-22T04:30:51.649Z\",\"reached\":true,\"ok\":true,\"status\":200,\"statusText\":\"OK\",\"json\":{\"serviceId\":\"hwlab-cloud-api\",\"environment\":\"dev\",\"status\":\"degraded\",\"service\":{\"id\":\"hwlab-cloud-api\",\"role\":\"cloud-api\",\"healthPath\":\"/health\",\"livePath\":\"/health/live\"},\"commit\":{\"id\":\"cb35ada\",\"source\":\"runtime-env\"},\"image\":{\"reference\":\"127.0.0.1:5000/hwlab/hwlab-cloud-api:cb35ada\",\"tag\":\"cb35ada\",\"digest\":\"unknown\"},\"endpoint\":\"http://74.48.78.17:16667\",\"observedAt\":\"2026-05-22T04:30:51.463Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"configReady\":true,\"ready\":false,\"status\":\"degraded\",\"mode\":\"configured_without_live_connection\",\"fields\":[{\"name\":\"HWLAB_CLOUD_DB_URL\",\"present\":true,\"redacted\":true,\"source\":\"k8s-secret-ref\",\"required\":true},{\"name\":\"HWLAB_CLOUD_DB_SSL_MODE\",\"present\":true,\"redacted\":false,\"source\":\"runtime-env\",\"required\":true}],\"missingEnv\":[],\"secretRefs\":[{\"env\":\"HWLAB_CLOUD_DB_URL\",\"secretName\":\"hwlab-cloud-api-dev-db\",\"secretKey\":\"database-url\",\"present\":true,\"redacted\":true}],\"safety\":{\"devOnly\":true,\"prodAllowed\":false,\"secretsRead\":false,\"valuesRedacted\":true,\"liveDbEvidence\":false},\"evidence\":\"env_presence_only_no_live_db\"},\"runtime\":{\"adapter\":\"memory\",\"durable\":false,\"status\":\"degraded\",\"reason\":\"live DB persistence is not connected; L1 runtime writes are process-local only\",\"counts\":{\"gatewaySessions\":0,\"boxResources\":0,\"boxCapabilities\":0,\"hardwareOperations\":0,\"auditEvents\":0,\"evidenceRecords\":0}}}}",
|
||||
"{\"url\":\"http://74.48.78.17:16667/health\",\"method\":\"GET\",\"startedAt\":\"2026-05-22T04:30:51.650Z\",\"observedAt\":\"2026-05-22T04:30:52.025Z\",\"reached\":true,\"ok\":true,\"status\":200,\"statusText\":\"OK\",\"json\":{\"serviceId\":\"hwlab-edge-proxy\",\"environment\":\"dev\",\"status\":\"ok\",\"service\":{\"id\":\"hwlab-edge-proxy\",\"role\":\"public-dev-ingress\",\"healthPath\":\"/health\",\"livePath\":\"/health/live\"},\"commit\":{\"id\":\"cb35ada6860653b27269b0a57991184118cbf4b1\",\"source\":\"runtime-env\"},\"image\":{\"reference\":\"ghcr.io/pikastech/hwlab-edge-proxy:cb35ada\",\"tag\":\"cb35ada\",\"digest\":\"unknown\"},\"endpoint\":\"http://74.48.78.17:16667\",\"observedAt\":\"2026-05-22T04:30:51.840Z\",\"details\":{\"upstream\":\"http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667\",\"mode\":\"dev-edge-proxy\"}}}",
|
||||
"{\"url\":\"http://74.48.78.17:16667/live\",\"method\":\"GET\",\"startedAt\":\"2026-05-22T04:30:52.025Z\",\"observedAt\":\"2026-05-22T04:30:52.401Z\",\"reached\":true,\"ok\":true,\"status\":200,\"statusText\":\"OK\",\"json\":{\"serviceId\":\"hwlab-cloud-api\",\"status\":\"live\"}}",
|
||||
"{\"url\":\"http://74.48.78.17:16667/v1\",\"method\":\"GET\",\"startedAt\":\"2026-05-22T04:30:52.401Z\",\"observedAt\":\"2026-05-22T04:30:53.001Z\",\"reached\":true,\"ok\":true,\"status\":200,\"statusText\":\"OK\",\"json\":{\"serviceId\":\"hwlab-cloud-api\",\"adapter\":\"rest\",\"status\":\"degraded\",\"rpcBridge\":\"POST /v1/rpc/{method}\",\"methods\":[\"system.health\",\"cloud.adapter.describe\",\"gateway.session.register\",\"box.resource.register\",\"box.capability.report\",\"hardware.operation.request\",\"hardware.invoke.shell\",\"audit.event.write\",\"audit.event.query\",\"evidence.record.write\",\"evidence.record.query\"],\"auditFields\":[\"requestId\",\"actor\",\"source\",\"operation\",\"target\",\"result\",\"timestamp\"],\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"configReady\":true,\"ready\":false,\"status\":\"degraded\",\"mode\":\"configured_without_live_connection\",\"fields\":[{\"name\":\"HWLAB_CLOUD_DB_URL\",\"present\":true,\"redacted\":true,\"source\":\"k8s-secret-ref\",\"required\":true},{\"name\":\"HWLAB_CLOUD_DB_SSL_MODE\",\"present\":true,\"redacted\":false,\"source\":\"runtime-env\",\"required\":true}],\"missingEnv\":[],\"secretRefs\":[{\"env\":\"HWLAB_CLOUD_DB_URL\",\"secretName\":\"hwlab-cloud-api-dev-db\",\"secretKey\":\"database-url\",\"present\":true,\"redacted\":true}],\"safety\":{\"devOnly\":true,\"prodAllowed\":false,\"secretsRead\":false,\"valuesRedacted\":true,\"liveDbEvidence\":false},\"evidence\":\"env_presence_only_no_live_db\"},\"runtime\":{\"adapter\":\"memory\",\"durable\":false,\"status\":\"degraded\",\"reason\":\"live DB persistence is not connected; L1 runtime writes are process-local only\",\"counts\":{\"gatewaySessions\":0,\"boxResources\":0,\"boxCapabilities\":0,\"hardwareOperations\":0,\"auditEvents\":0,\"evidenceRecords\":0}}}}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "two-box-simu-online",
|
||||
"status": "not_run",
|
||||
"summary": "Stopped at DEV ingress per the DEV smoke matrix.",
|
||||
"summary": "A live DEV M3 runtime contract check failed before all checks passed.",
|
||||
"evidence": [
|
||||
"No live DEV evidence collected for this check."
|
||||
]
|
||||
@@ -85,7 +84,7 @@
|
||||
{
|
||||
"id": "two-gateway-simu-online",
|
||||
"status": "not_run",
|
||||
"summary": "Stopped at DEV ingress per the DEV smoke matrix.",
|
||||
"summary": "A live DEV M3 runtime contract check failed before all checks passed.",
|
||||
"evidence": [
|
||||
"No live DEV evidence collected for this check."
|
||||
]
|
||||
@@ -93,7 +92,7 @@
|
||||
{
|
||||
"id": "patch-panel-healthy",
|
||||
"status": "not_run",
|
||||
"summary": "Stopped at DEV ingress per the DEV smoke matrix.",
|
||||
"summary": "A live DEV M3 runtime contract check failed before all checks passed.",
|
||||
"evidence": [
|
||||
"No live DEV evidence collected for this check."
|
||||
]
|
||||
@@ -101,7 +100,7 @@
|
||||
{
|
||||
"id": "wiring-do1-di1-applied",
|
||||
"status": "not_run",
|
||||
"summary": "Stopped at DEV ingress per the DEV smoke matrix.",
|
||||
"summary": "A live DEV M3 runtime contract check failed before all checks passed.",
|
||||
"evidence": [
|
||||
"No live DEV evidence collected for this check."
|
||||
]
|
||||
@@ -109,7 +108,7 @@
|
||||
{
|
||||
"id": "direct-call-do-write-di-read",
|
||||
"status": "not_run",
|
||||
"summary": "Stopped at DEV ingress per the DEV smoke matrix.",
|
||||
"summary": "A live DEV M3 runtime contract check failed before all checks passed.",
|
||||
"evidence": [
|
||||
"No live DEV evidence collected for this check."
|
||||
]
|
||||
@@ -117,7 +116,7 @@
|
||||
{
|
||||
"id": "audit-evidence-traceable",
|
||||
"status": "not_run",
|
||||
"summary": "Stopped at DEV ingress per the DEV smoke matrix.",
|
||||
"summary": "A live DEV M3 runtime contract check failed before all checks passed.",
|
||||
"evidence": [
|
||||
"No live DEV evidence collected for this check."
|
||||
]
|
||||
@@ -169,9 +168,9 @@
|
||||
},
|
||||
{
|
||||
"id": "kubectl-hwlab-dev",
|
||||
"status": "unavailable",
|
||||
"command": "command -v kubectl",
|
||||
"summary": "kubectl is not available in this runner, so hwlab-dev namespace state was not observed."
|
||||
"status": "observed",
|
||||
"command": "kubectl get deploy,po,svc -n hwlab-dev -o wide",
|
||||
"summary": "NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/hwlab-agent-mgr 1/1 1 1 4h38m hwlab-agent-mgr 127.0.0.1:5000/hwlab/hwlab-agent-mgr:cb35ada app.kubernetes.io/name=hwlab-agent-mgr,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-agent-skills 1/1 1 1 66m hwlab-agent-skills 127.0.0.1:5000/hwlab/hwlab-agent-skills:cb35ada app.kubernetes.io/name=hwlab-agent-skills,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-box-simu 2/2 2 2 4h38m hwlab-box-simu 127.0.0.1:5000/hwlab/hwlab-box-simu:cb35ada app.kubernetes.io/name=hwlab-box-simu,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-cloud-api 1/1 1 1 4h38m hwlab-cloud-api 127.0.0.1:5000/hwlab/hwlab-cloud-api:cb35ada app.kubernetes.io/name=hwlab-cloud-api,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-cloud-web 1/1 1 1 4h38m hwlab-cloud-web 127.0.0.1:5000/hwlab/hwlab-cloud-web:cb35ada app.kubernetes.io/name=hwlab-cloud-web,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-edge-proxy 1/1 1 1 4h38m hwlab-edge-proxy 127.0.0.1:5000/hwlab/hwlab-edge-proxy:cb35ada app.kubernetes.io/name=hwlab-edge-proxy,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-frpc 1/1 1 1 4h33m frpc 127.0.0.1:5000/hwlab/frpc:v0.68.1 app.kubernetes.io/name=hwlab-frpc deployment.apps/hwlab-gateway 0/0 0 0 4h38m hwlab-gateway 127.0.0.1:5000/hwlab/hwlab-gateway:cb35ada app.kubernetes.io/name=hwlab-gateway,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-gateway-simu 2/2 2 2 4h38m hwlab-gateway-simu 127.0.0.1:5000/hwlab/hwlab-gateway-simu:cb35ada app.kubernetes.io/name=hwlab-gateway-simu,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/profile=dev deployment.apps/hwlab-patch-panel 1/1 1 1 4h38m hwlab-patch-panel 127.0.0.1:5000/hwlab/hwlab-patch-panel:cb35ada app.kubernetes.io/name=hwlab-patch-panel,app.kubernetes.io/part-of=hwlab,hwlab.pikastech.local/environment=dev,hwlab.pikastech.local/prof"
|
||||
}
|
||||
],
|
||||
"liveOperation": {
|
||||
@@ -180,19 +179,21 @@
|
||||
"traceId": "not_observed",
|
||||
"auditId": "not_observed",
|
||||
"evidenceId": "not_observed",
|
||||
"summary": "No live do.write -> di.read operation was attempted because DEV ingress is blocked."
|
||||
"summary": "No live DEV operation has run yet."
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-ingress-health",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"status": "open",
|
||||
"summary": "Blocked at the #33 DEV runtime readiness condition: public DEV ingress does not accept HWLAB health requests, so #36/M3 hardware-loop checks were not reached."
|
||||
"classification": "hardware loop",
|
||||
"summary": "patch-panel active DO1 -> DI1 connection missing"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"status": "blocked",
|
||||
"observedAt": "2026-05-21T17:29:33.789Z",
|
||||
"result": "No live DEV M3 evidence was produced; fixture-backed local evidence was not used as a substitute."
|
||||
"classification": "hardware loop",
|
||||
"observedAt": "2026-05-22T04:30:50.820Z",
|
||||
"result": "Live DEV M3 runtime was reachable but did not satisfy the M3 hardware-loop contract."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"reportVersion": "v1",
|
||||
"issue": "pikasTech/HWLAB#37",
|
||||
"taskId": "dev-m4-agent-loop",
|
||||
"commitId": "e9e71a7",
|
||||
"commitId": "a1c3cb5",
|
||||
"acceptanceLevel": "dev_m4_agent_loop",
|
||||
"devOnly": true,
|
||||
"prodDisabled": true,
|
||||
@@ -46,30 +46,34 @@
|
||||
},
|
||||
"devPreconditions": {
|
||||
"status": "blocked",
|
||||
"classification": "DB live",
|
||||
"requirements": [
|
||||
"DEV route remains frozen at http://74.48.78.17:16667",
|
||||
"No secret reads, real deployment, or long-running agent task is attempted",
|
||||
"Agent manager, worker, and skills are reachable only through the cloud API boundary"
|
||||
],
|
||||
"summary": "Blocked before agent scheduling because http://74.48.78.17:16667 is unreachable from this runner."
|
||||
"summary": "Blocked at DB live readiness before scheduling a DEV agent task."
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"status": "open",
|
||||
"summary": "connect ECONNREFUSED 74.48.78.17:16667"
|
||||
"summary": "cloud-api /health/live reports DB degraded; connected=false; ready=false.",
|
||||
"classification": "DB live"
|
||||
}
|
||||
],
|
||||
"livePreflight": {
|
||||
"status": "blocked",
|
||||
"classification": "DB live",
|
||||
"commands": [
|
||||
"node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"evidence": [
|
||||
"No live DEV observation was recorded."
|
||||
"health:hwlab-edge-proxy:dev:ok",
|
||||
"live:hwlab-cloud-api:degraded:db-blocked"
|
||||
],
|
||||
"summary": "Blocked before agent scheduling because http://74.48.78.17:16667 is unreachable from this runner."
|
||||
"summary": "Blocked at DB live readiness before scheduling a DEV agent task."
|
||||
},
|
||||
"notes": "DEV M4 agent loop live preflight report. No secret material is read."
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
"pikasTech/HWLAB#39",
|
||||
"pikasTech/HWLAB#46"
|
||||
],
|
||||
"generatedAt": "2026-05-21T18:27:07.237Z",
|
||||
"generatedFromCommit": "1e9591a6611e",
|
||||
"generatedAt": "2026-05-22T04:56:56.988Z",
|
||||
"generatedFromCommit": "d4fe2cf1bb8a",
|
||||
"environment": "dev",
|
||||
"endpoint": "http://74.48.78.17:16667",
|
||||
"devOnly": true,
|
||||
@@ -45,43 +45,43 @@
|
||||
"path": "reports/dev-gate/dev-deploy-report.json",
|
||||
"issue": "pikasTech/HWLAB#33",
|
||||
"taskId": "dev-deploy-apply",
|
||||
"status": "blocked",
|
||||
"commitId": "9b47ebe49f70"
|
||||
"status": "pass",
|
||||
"commitId": "73b379f4441d"
|
||||
},
|
||||
"devArtifacts": {
|
||||
"path": "reports/dev-gate/dev-artifacts.json",
|
||||
"issue": "pikasTech/HWLAB#35",
|
||||
"taskId": "dev-artifact-publish",
|
||||
"status": "blocked",
|
||||
"commitId": "7e0ccb0"
|
||||
"status": "published",
|
||||
"commitId": "73b379f"
|
||||
},
|
||||
"devEdgeHealth": {
|
||||
"path": "reports/dev-gate/dev-edge-health.json",
|
||||
"issue": "pikasTech/HWLAB#36",
|
||||
"taskId": "dev-edge-health",
|
||||
"status": "not_run",
|
||||
"commitId": "9b47ebe49f70"
|
||||
"status": "blocked",
|
||||
"commitId": "86d769525caf"
|
||||
},
|
||||
"devM3Hardware": {
|
||||
"path": "reports/dev-gate/dev-m3-hardware-loop.json",
|
||||
"issue": "pikasTech/HWLAB#38",
|
||||
"taskId": "dev-m3-hardware-loop",
|
||||
"status": "blocked",
|
||||
"commitId": "70bb9168ead2"
|
||||
"commitId": "86d769525caf"
|
||||
},
|
||||
"devM4Agent": {
|
||||
"path": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"issue": "pikasTech/HWLAB#37",
|
||||
"taskId": "dev-m4-agent-loop",
|
||||
"status": "blocked",
|
||||
"commitId": "e9e71a7"
|
||||
"commitId": "a1c3cb5"
|
||||
},
|
||||
"devM5Gate": {
|
||||
"path": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"status": "blocked",
|
||||
"commitId": "6eb4c199b0c6"
|
||||
"commitId": "86d769525caf"
|
||||
},
|
||||
"d601Observability": {
|
||||
"path": "reports/d601-k3s-readonly-observability.json",
|
||||
@@ -94,7 +94,7 @@
|
||||
"overall": {
|
||||
"status": "blocked",
|
||||
"green": false,
|
||||
"reason": "SOURCE, LOCAL, and DRY-RUN evidence exists, but DEV-LIVE acceptance is blocked by artifact, observability, DB, edge/frp, and loop evidence gaps."
|
||||
"reason": "SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is still blocked by artifact, observability, DB, and loop evidence gaps."
|
||||
},
|
||||
"dod": {
|
||||
"status": "blocked",
|
||||
@@ -125,10 +125,10 @@
|
||||
"summary": "D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev."
|
||||
},
|
||||
{
|
||||
"id": "dev-edge-frp-6667",
|
||||
"status": "blocked",
|
||||
"evidenceLevel": "BLOCKED",
|
||||
"summary": "No committed report proves live HTTP 200/JSON on http://74.48.78.17:16667."
|
||||
"id": "dev-edge-frp-16667",
|
||||
"status": "pass",
|
||||
"evidenceLevel": "DEV-LIVE",
|
||||
"summary": "Committed edge report proves read-only public HTTP on :16667 /health and /health/live; old preflight network probe blockers are stale."
|
||||
},
|
||||
{
|
||||
"id": "cloud-api-db-ready",
|
||||
@@ -166,11 +166,11 @@
|
||||
{
|
||||
"id": "M2",
|
||||
"status": "blocked",
|
||||
"highestVisibleLevel": "DRY-RUN",
|
||||
"highestVisibleLevel": "DEV-LIVE",
|
||||
"liveEvidence": "missing_or_blocked",
|
||||
"evidenceCount": 5,
|
||||
"blockerCount": 18,
|
||||
"summary": "deploy/runtime readiness is blocked before live DEV; highest visible level is DRY-RUN; status is blocked."
|
||||
"blockerCount": 9,
|
||||
"summary": "deploy/runtime readiness is blocked before live DEV; highest visible level is DEV-LIVE; status is blocked."
|
||||
},
|
||||
{
|
||||
"id": "M3",
|
||||
@@ -178,17 +178,17 @@
|
||||
"highestVisibleLevel": "LOCAL",
|
||||
"liveEvidence": "missing_or_blocked",
|
||||
"evidenceCount": 3,
|
||||
"blockerCount": 10,
|
||||
"blockerCount": 4,
|
||||
"summary": "hardware loop has source/local shape but no live operation; highest visible level is LOCAL; status is blocked."
|
||||
},
|
||||
{
|
||||
"id": "M4",
|
||||
"status": "blocked",
|
||||
"status": "not_run",
|
||||
"highestVisibleLevel": "LOCAL",
|
||||
"liveEvidence": "missing_or_blocked",
|
||||
"evidenceCount": 3,
|
||||
"blockerCount": 5,
|
||||
"summary": "agent loop has local smoke but live preflight is blocked; highest visible level is LOCAL; status is blocked."
|
||||
"blockerCount": 0,
|
||||
"summary": "agent loop has local smoke but live preflight is blocked; highest visible level is LOCAL; status is not_run."
|
||||
},
|
||||
{
|
||||
"id": "M5",
|
||||
@@ -196,7 +196,7 @@
|
||||
"highestVisibleLevel": "DRY-RUN",
|
||||
"liveEvidence": "missing_or_blocked",
|
||||
"evidenceCount": 2,
|
||||
"blockerCount": 12,
|
||||
"blockerCount": 9,
|
||||
"summary": "dry-run is green but live MVP gate is blocked; highest visible level is DRY-RUN; status is blocked."
|
||||
}
|
||||
],
|
||||
@@ -266,9 +266,9 @@
|
||||
"issue": "pikasTech/HWLAB#33",
|
||||
"taskId": "dev-deploy-apply",
|
||||
"reportPath": "reports/dev-gate/dev-deploy-report.json",
|
||||
"commitId": "9b47ebe49f70",
|
||||
"commitId": "73b379f4441d",
|
||||
"level": "DRY-RUN",
|
||||
"status": "blocked",
|
||||
"status": "pass",
|
||||
"category": "deploy-apply",
|
||||
"commands": [
|
||||
"node tools/hwlab-cli/bin/hwlab-cli.mjs test e2e --env dev --mvp --dry-run",
|
||||
@@ -276,25 +276,26 @@
|
||||
],
|
||||
"evidence": [
|
||||
"artifact services checked: 13",
|
||||
"expected artifact commit: 24eb3bf",
|
||||
"expected artifact commit: 73b379f",
|
||||
"namespace: hwlab-dev",
|
||||
"workloads planned: 13",
|
||||
"kubectl executor: missing",
|
||||
"live health: not_run"
|
||||
"kubectl executor: /usr/local/bin/kubectl",
|
||||
"live health: pass"
|
||||
],
|
||||
"summary": "DEV apply is blocked before mutation."
|
||||
"summary": "DEV dry-run preflight passed."
|
||||
},
|
||||
{
|
||||
"milestone": "M2",
|
||||
"issue": "pikasTech/HWLAB#35",
|
||||
"taskId": "dev-artifact-publish",
|
||||
"reportPath": "reports/dev-gate/dev-artifacts.json",
|
||||
"commitId": "7e0ccb0",
|
||||
"commitId": "73b379f",
|
||||
"level": "DRY-RUN",
|
||||
"status": "blocked",
|
||||
"status": "published",
|
||||
"category": "artifact-publish",
|
||||
"commands": [
|
||||
"node --check scripts/dev-artifact-publish.mjs",
|
||||
"node --check scripts/src/dev-artifact-services.mjs",
|
||||
"node --check scripts/preflight-dev-base-image.mjs",
|
||||
"node --check scripts/src/dev-base-image-preflight.mjs",
|
||||
"node scripts/preflight-dev-base-image.mjs",
|
||||
@@ -304,8 +305,8 @@
|
||||
],
|
||||
"evidence": [
|
||||
"services=13",
|
||||
"baseImagePreflight=blocked",
|
||||
"published=0/13"
|
||||
"baseImagePreflight=ready",
|
||||
"published=13/13"
|
||||
],
|
||||
"summary": "Artifact publish preflight exists but is blocked before any real image publish."
|
||||
},
|
||||
@@ -314,9 +315,9 @@
|
||||
"issue": "pikasTech/HWLAB#36",
|
||||
"taskId": "dev-edge-health",
|
||||
"reportPath": "reports/dev-gate/dev-edge-health.json",
|
||||
"commitId": "9b47ebe49f70",
|
||||
"level": "SOURCE",
|
||||
"status": "not_run",
|
||||
"commitId": "86d769525caf",
|
||||
"level": "DEV-LIVE",
|
||||
"status": "blocker",
|
||||
"category": "edge-frp-contract",
|
||||
"commands": [
|
||||
"node --check scripts/validate-dev-gate-report.mjs",
|
||||
@@ -326,11 +327,11 @@
|
||||
"node scripts/dev-edge-health-smoke.mjs --live --write-report"
|
||||
],
|
||||
"evidence": [
|
||||
"mode=contract-only",
|
||||
"classification=not_run",
|
||||
"cloudApiDb=ready"
|
||||
"mode=live-read-only",
|
||||
"classification=app_health_blocker",
|
||||
"cloudApiDb=degraded"
|
||||
],
|
||||
"summary": "Committed edge report is contract-only/not-run; it must not be counted as DEV-LIVE."
|
||||
"summary": "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."
|
||||
},
|
||||
{
|
||||
"milestone": "M2",
|
||||
@@ -358,7 +359,7 @@
|
||||
"issue": "pikasTech/HWLAB#38",
|
||||
"taskId": "dev-m3-hardware-loop",
|
||||
"reportPath": "reports/dev-gate/dev-m3-hardware-loop.json",
|
||||
"commitId": "70bb9168ead2",
|
||||
"commitId": "86d769525caf",
|
||||
"level": "SOURCE",
|
||||
"status": "manifest-ready",
|
||||
"category": "hardware-loop-cardinality",
|
||||
@@ -375,26 +376,27 @@
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"reportPath": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"commitId": "6eb4c199b0c6",
|
||||
"commitId": "86d769525caf",
|
||||
"level": "LOCAL",
|
||||
"status": "pass",
|
||||
"status": "blocked",
|
||||
"category": "hardware-loop-local",
|
||||
"commands": [
|
||||
"node scripts/m3-hardware-loop-smoke.mjs"
|
||||
"node scripts/m3-hardware-loop-smoke.mjs",
|
||||
"node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"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"
|
||||
"Local M3 hardware loop smoke passed",
|
||||
"Live DEV M3 smoke reached 16667 ingress and direct simulator/patch-panel Pod URLs",
|
||||
"Live DEV M3 blocked: patch-panel active DO1 -> DI1 connection missing"
|
||||
],
|
||||
"summary": "The local hardware trusted loop smoke passes."
|
||||
"summary": "Local M3 remains green, but active DEV-LIVE M3 is blocked by hardware loop topology."
|
||||
},
|
||||
{
|
||||
"milestone": "M3",
|
||||
"issue": "pikasTech/HWLAB#38",
|
||||
"taskId": "dev-m3-hardware-loop",
|
||||
"reportPath": "reports/dev-gate/dev-m3-hardware-loop.json",
|
||||
"commitId": "70bb9168ead2",
|
||||
"commitId": "86d769525caf",
|
||||
"level": "BLOCKED",
|
||||
"status": "not_run",
|
||||
"category": "hardware-loop-live",
|
||||
@@ -407,14 +409,14 @@
|
||||
"auditId=not_observed",
|
||||
"evidenceId=not_observed"
|
||||
],
|
||||
"summary": "No live do.write -> di.read operation was attempted because DEV ingress is blocked."
|
||||
"summary": "No live DEV operation has run yet."
|
||||
},
|
||||
{
|
||||
"milestone": "M4",
|
||||
"issue": "pikasTech/HWLAB#37",
|
||||
"taskId": "dev-m4-agent-loop",
|
||||
"reportPath": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"commitId": "e9e71a7",
|
||||
"commitId": "a1c3cb5",
|
||||
"level": "LOCAL",
|
||||
"status": "pass",
|
||||
"category": "agent-loop-local",
|
||||
@@ -432,7 +434,7 @@
|
||||
"issue": "pikasTech/HWLAB#37",
|
||||
"taskId": "dev-m4-agent-loop",
|
||||
"reportPath": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"commitId": "e9e71a7",
|
||||
"commitId": "a1c3cb5",
|
||||
"level": "DRY-RUN",
|
||||
"status": "not_run",
|
||||
"category": "agent-loop-dry-run",
|
||||
@@ -449,7 +451,7 @@
|
||||
"issue": "pikasTech/HWLAB#37",
|
||||
"taskId": "dev-m4-agent-loop",
|
||||
"reportPath": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"commitId": "e9e71a7",
|
||||
"commitId": "a1c3cb5",
|
||||
"level": "BLOCKED",
|
||||
"status": "blocked",
|
||||
"category": "agent-loop-live-preflight",
|
||||
@@ -457,16 +459,17 @@
|
||||
"node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"evidence": [
|
||||
"No live DEV observation was recorded."
|
||||
"health:hwlab-edge-proxy:dev:ok",
|
||||
"live:hwlab-cloud-api:degraded:db-blocked"
|
||||
],
|
||||
"summary": "Blocked before agent scheduling because http://74.48.78.17:16667 is unreachable from this runner."
|
||||
"summary": "Blocked at DB live readiness before scheduling a DEV agent task."
|
||||
},
|
||||
{
|
||||
"milestone": "M5",
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"reportPath": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"commitId": "6eb4c199b0c6",
|
||||
"commitId": "86d769525caf",
|
||||
"level": "DRY-RUN",
|
||||
"status": "pass",
|
||||
"category": "mvp-e2e-dry-run",
|
||||
@@ -487,19 +490,26 @@
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"reportPath": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"commitId": "6eb4c199b0c6",
|
||||
"commitId": "86d769525caf",
|
||||
"level": "BLOCKED",
|
||||
"status": "blocked",
|
||||
"category": "mvp-e2e-live",
|
||||
"commands": [
|
||||
"curl -fsS --max-time 5 http://74.48.78.17:16667/health",
|
||||
"curl -fsS --max-time 5 http://74.48.78.17:16667/live"
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16666/",
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16667/health/live",
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16667/health",
|
||||
"HWLAB_DEV_BOX_SIMU_1_URL=http://10.42.0.200:7201 HWLAB_DEV_BOX_SIMU_2_URL=http://10.42.0.208:7201 HWLAB_DEV_GATEWAY_SIMU_1_URL=http://10.42.0.209:7101 HWLAB_DEV_GATEWAY_SIMU_2_URL=http://10.42.0.204:7101 HWLAB_DEV_PATCH_PANEL_URL=http://10.42.0.205:7301 node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production",
|
||||
"node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"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"
|
||||
"http://74.48.78.17:16666/ -> HTTP 200 text/html, title=HWLAB DEV MVP Gate",
|
||||
"http://74.48.78.17:16667/health -> HTTP 200 serviceId=hwlab-edge-proxy status=ok commit=cb35ada6860653b27269b0a57991184118cbf4b1",
|
||||
"http://74.48.78.17:16667/health/live -> HTTP 200 serviceId=hwlab-cloud-api status=degraded db.ready=false db.connected=false db.connectionChecked=false",
|
||||
"dev-edge-health active report -> blocked by DB live readiness, while public 16667 TCP/HTTP and frp control/tunnel health are reachable",
|
||||
"dev-m3-hardware-loop active report -> blocked, classification=hardware loop, summary=patch-panel active DO1 -> DI1 connection missing",
|
||||
"dev-m4-agent-loop active report -> blocked, classification=DB live, summary=cloud-api /health/live reports DB degraded; connected=false; ready=false"
|
||||
],
|
||||
"summary": "The frozen DEV endpoint is not reachable from this runner, so no live DEV gate can be claimed yet."
|
||||
"summary": "Public DEV route/frp is reachable on 16666/16667, but live MVP remains blocked by DB live readiness and the M3 hardware loop topology; no historical 6667 failure is counted as active evidence."
|
||||
}
|
||||
],
|
||||
"levels": {
|
||||
@@ -520,15 +530,6 @@
|
||||
"reportPath": "reports/dev-gate/dev-preflight-report.json",
|
||||
"summary": "Deploy manifests, FRP/master-edge contracts, and safety boundary are source-readable and scoped to hwlab-dev."
|
||||
},
|
||||
{
|
||||
"milestone": "M2",
|
||||
"issue": "pikasTech/HWLAB#36",
|
||||
"taskId": "dev-edge-health",
|
||||
"status": "not_run",
|
||||
"category": "edge-frp-contract",
|
||||
"reportPath": "reports/dev-gate/dev-edge-health.json",
|
||||
"summary": "Committed edge report is contract-only/not-run; it must not be counted as DEV-LIVE."
|
||||
},
|
||||
{
|
||||
"milestone": "M3",
|
||||
"issue": "pikasTech/HWLAB#38",
|
||||
@@ -551,10 +552,10 @@
|
||||
"milestone": "M3",
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"status": "pass",
|
||||
"status": "blocked",
|
||||
"category": "hardware-loop-local",
|
||||
"reportPath": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"summary": "The local hardware trusted loop smoke passes."
|
||||
"summary": "Local M3 remains green, but active DEV-LIVE M3 is blocked by hardware loop topology."
|
||||
},
|
||||
{
|
||||
"milestone": "M4",
|
||||
@@ -571,16 +572,16 @@
|
||||
"milestone": "M2",
|
||||
"issue": "pikasTech/HWLAB#33",
|
||||
"taskId": "dev-deploy-apply",
|
||||
"status": "blocked",
|
||||
"status": "pass",
|
||||
"category": "deploy-apply",
|
||||
"reportPath": "reports/dev-gate/dev-deploy-report.json",
|
||||
"summary": "DEV apply is blocked before mutation."
|
||||
"summary": "DEV dry-run preflight passed."
|
||||
},
|
||||
{
|
||||
"milestone": "M2",
|
||||
"issue": "pikasTech/HWLAB#35",
|
||||
"taskId": "dev-artifact-publish",
|
||||
"status": "blocked",
|
||||
"status": "published",
|
||||
"category": "artifact-publish",
|
||||
"reportPath": "reports/dev-gate/dev-artifacts.json",
|
||||
"summary": "Artifact publish preflight exists but is blocked before any real image publish."
|
||||
@@ -604,7 +605,17 @@
|
||||
"summary": "The M5 orchestration dry-run is green, but it remains fixture-only and does not establish a live DEV gate."
|
||||
}
|
||||
],
|
||||
"DEV-LIVE": [],
|
||||
"DEV-LIVE": [
|
||||
{
|
||||
"milestone": "M2",
|
||||
"issue": "pikasTech/HWLAB#36",
|
||||
"taskId": "dev-edge-health",
|
||||
"status": "blocker",
|
||||
"category": "edge-frp-contract",
|
||||
"reportPath": "reports/dev-gate/dev-edge-health.json",
|
||||
"summary": "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."
|
||||
}
|
||||
],
|
||||
"BLOCKED": [
|
||||
{
|
||||
"milestone": "M2",
|
||||
@@ -622,7 +633,7 @@
|
||||
"status": "not_run",
|
||||
"category": "hardware-loop-live",
|
||||
"reportPath": "reports/dev-gate/dev-m3-hardware-loop.json",
|
||||
"summary": "No live do.write -> di.read operation was attempted because DEV ingress is blocked."
|
||||
"summary": "No live DEV operation has run yet."
|
||||
},
|
||||
{
|
||||
"milestone": "M4",
|
||||
@@ -631,7 +642,7 @@
|
||||
"status": "blocked",
|
||||
"category": "agent-loop-live-preflight",
|
||||
"reportPath": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"summary": "Blocked before agent scheduling because http://74.48.78.17:16667 is unreachable from this runner."
|
||||
"summary": "Blocked at DB live readiness before scheduling a DEV agent task."
|
||||
},
|
||||
{
|
||||
"milestone": "M5",
|
||||
@@ -640,37 +651,7 @@
|
||||
"status": "blocked",
|
||||
"category": "mvp-e2e-live",
|
||||
"reportPath": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"summary": "The frozen DEV endpoint is not reachable from this runner, so no live DEV gate can be claimed yet."
|
||||
},
|
||||
{
|
||||
"priority": "P0",
|
||||
"order": 1,
|
||||
"type": "environment_blocker",
|
||||
"scope": "base-image",
|
||||
"sourceIssue": "pikasTech/HWLAB#35",
|
||||
"source": "reports/dev-gate/dev-artifacts.json",
|
||||
"summary": "HWLAB_DEV_BASE_IMAGE is not set and no approved local DEV builder base image was found in the Docker image cache; expected node:20-bookworm-slim or 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim.",
|
||||
"nextTask": "Preload node:20-bookworm-slim into the D601 Docker cache, or tag it as 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim. Set HWLAB_DEV_BASE_IMAGE=node:20-bookworm-slim or HWLAB_DEV_BASE_IMAGE=127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim when invoking artifact publish. Rerun this preflight and require status=ready before #35 artifact publish. Do not use UniDesk runtime, Code Queue runner, backend-core, provider-gateway, or microservice-proxy images as substitutes."
|
||||
},
|
||||
{
|
||||
"priority": "P1",
|
||||
"order": 3,
|
||||
"type": "observability_blocker",
|
||||
"scope": "artifact-publish",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"summary": "DEV artifact catalog has no CI publish, registry verification, or registry digests",
|
||||
"nextTask": "Publish DEV images from the intended commit and update the catalog with registry digests and verification evidence."
|
||||
},
|
||||
{
|
||||
"priority": "P1",
|
||||
"order": 3,
|
||||
"type": "observability_blocker",
|
||||
"scope": "artifact-source-commit",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"summary": "deploy/catalog artifact commit 24eb3bf/24eb3bf does not match source 9b47ebe49f70",
|
||||
"nextTask": "Regenerate deploy/deploy.json and deploy/artifact-catalog.dev.json for the source commit that will be promoted."
|
||||
"summary": "Public DEV route/frp is reachable on 16666/16667, but live MVP remains blocked by DB live readiness and the M3 hardware loop topology; no historical 6667 failure is counted as active evidence."
|
||||
},
|
||||
{
|
||||
"priority": "P1",
|
||||
@@ -732,16 +713,6 @@
|
||||
"summary": "No SSH maintenance bridge was detected from ssh binary plus known environment variables or ~/.ssh/config metadata.",
|
||||
"nextTask": "Provide a documented read-only maintenance bridge variable or config path if kubectl cannot be mounted directly in the runner."
|
||||
},
|
||||
{
|
||||
"priority": "P1",
|
||||
"order": 4,
|
||||
"type": "environment_blocker",
|
||||
"scope": "kubectl",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"summary": "kubectl is not installed in the runner",
|
||||
"nextTask": "Provide a kubectl client configured for the D601 DEV k3s context without exposing token or secret values."
|
||||
},
|
||||
{
|
||||
"priority": "P1",
|
||||
"order": 4,
|
||||
@@ -757,10 +728,9 @@
|
||||
"order": 5,
|
||||
"type": "runtime_blocker",
|
||||
"scope": "cloud-api-db",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"summary": "cloud-api health reports DB config blocked; missing HWLAB_CLOUD_DB_URL, HWLAB_CLOUD_DB_SSL_MODE",
|
||||
"nextTask": "Configure and verify the DEV cloud-api DB env readiness through health output, without reading secret values."
|
||||
"sourceIssue": "pikasTech/HWLAB#36",
|
||||
"source": "reports/dev-gate/dev-edge-health.json",
|
||||
"summary": "cloud-api DB env is injected, but runtime health has not attempted a live DB connection"
|
||||
},
|
||||
{
|
||||
"priority": "P1",
|
||||
@@ -773,108 +743,44 @@
|
||||
"nextTask": "Configure DEV hwlab-cloud-api with Secret hwlab-cloud-api-dev-db/database-url and HWLAB_CLOUD_DB_SSL_MODE=require, then rerun health/preflight without printing the secret value."
|
||||
},
|
||||
{
|
||||
"priority": "P2",
|
||||
"order": 6,
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-edge",
|
||||
"sourceIssue": "pikasTech/HWLAB#34",
|
||||
"source": "reports/dev-gate/dev-preflight-report.json",
|
||||
"summary": "http://74.48.78.17:16667/health/live is not reachable from this runner.",
|
||||
"nextTask": "Bring up or repair the D601-to-master frp route and hwlab-edge-proxy, then rerun the health probe."
|
||||
},
|
||||
{
|
||||
"priority": "P2",
|
||||
"order": 6,
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-edge-health",
|
||||
"sourceIssue": "pikasTech/HWLAB#34",
|
||||
"source": "reports/dev-gate/dev-preflight-report.json",
|
||||
"summary": "live network probes require --live",
|
||||
"nextTask": "Repair the master frps/public DEV edge route and rerun the read-only DEV edge health smoke before real deployment."
|
||||
},
|
||||
{
|
||||
"priority": "P2",
|
||||
"order": 6,
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-ingress-health",
|
||||
"priority": "P3",
|
||||
"order": 99,
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"sourceIssue": "pikasTech/HWLAB#38",
|
||||
"source": "reports/dev-gate/dev-m3-hardware-loop.json",
|
||||
"summary": "Blocked at the #33 DEV runtime readiness condition: public DEV ingress does not accept HWLAB health requests, so #36/M3 hardware-loop checks were not reached."
|
||||
"summary": "patch-panel active DO1 -> DI1 connection missing"
|
||||
},
|
||||
{
|
||||
"priority": "P2",
|
||||
"order": 6,
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"priority": "P3",
|
||||
"order": 99,
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"sourceIssue": "pikasTech/HWLAB#37",
|
||||
"source": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"summary": "connect ECONNREFUSED 74.48.78.17:16667"
|
||||
"summary": "cloud-api /health/live reports DB degraded; connected=false; ready=false."
|
||||
},
|
||||
{
|
||||
"priority": "P2",
|
||||
"order": 6,
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"priority": "P3",
|
||||
"order": 99,
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"sourceIssue": "pikasTech/HWLAB#39",
|
||||
"source": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"summary": "http://74.48.78.17:16667/health and /live both fail with curl exit 7; live DEV ingress evidence is missing."
|
||||
"summary": "cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established."
|
||||
},
|
||||
{
|
||||
"priority": "P3",
|
||||
"order": 99,
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"sourceIssue": "pikasTech/HWLAB#39",
|
||||
"source": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"summary": "Live M3 smoke reached DEV simulators, but patch-panel active DO1 -> DI1 connection is missing."
|
||||
}
|
||||
]
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"id": "dev-artifact-publish:base-image",
|
||||
"priority": "P0",
|
||||
"type": "environment_blocker",
|
||||
"scope": "base-image",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-artifacts.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#35",
|
||||
"summary": "HWLAB_DEV_BASE_IMAGE is not set and no approved local DEV builder base image was found in the Docker image cache; expected node:20-bookworm-slim or 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim.",
|
||||
"nextTask": "Preload node:20-bookworm-slim into the D601 Docker cache, or tag it as 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim. Set HWLAB_DEV_BASE_IMAGE=node:20-bookworm-slim or HWLAB_DEV_BASE_IMAGE=127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim when invoking artifact publish. Rerun this preflight and require status=ready before #35 artifact publish. Do not use UniDesk runtime, Code Queue runner, backend-core, provider-gateway, or microservice-proxy images as substitutes.",
|
||||
"unblockOrder": 1,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#35",
|
||||
"pikasTech/HWLAB#33"
|
||||
],
|
||||
"rationale": "Artifact publishing cannot start until an approved Node 20 DEV builder base image is available."
|
||||
},
|
||||
{
|
||||
"id": "dev-deploy-apply:artifact-publish",
|
||||
"priority": "P1",
|
||||
"type": "observability_blocker",
|
||||
"scope": "artifact-publish",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"summary": "DEV artifact catalog has no CI publish, registry verification, or registry digests",
|
||||
"nextTask": "Publish DEV images from the intended commit and update the catalog with registry digests and verification evidence.",
|
||||
"unblockOrder": 3,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#35",
|
||||
"pikasTech/HWLAB#33",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The gate cannot promote deploy or runtime observations without immutable image provenance and digests."
|
||||
},
|
||||
{
|
||||
"id": "dev-deploy-apply:artifact-source-commit",
|
||||
"priority": "P1",
|
||||
"type": "observability_blocker",
|
||||
"scope": "artifact-source-commit",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"summary": "deploy/catalog artifact commit 24eb3bf/24eb3bf does not match source 9b47ebe49f70",
|
||||
"nextTask": "Regenerate deploy/deploy.json and deploy/artifact-catalog.dev.json for the source commit that will be promoted.",
|
||||
"unblockOrder": 3,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#35",
|
||||
"pikasTech/HWLAB#33",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The gate cannot promote deploy or runtime observations without immutable image provenance and digests."
|
||||
},
|
||||
{
|
||||
"id": "dev-gate-preflight:artifact-catalog",
|
||||
"priority": "P1",
|
||||
@@ -986,25 +892,6 @@
|
||||
],
|
||||
"rationale": "D601 hwlab-dev cluster state must be observable read-only before any live apply or M3/M4/M5 acceptance."
|
||||
},
|
||||
{
|
||||
"id": "dev-deploy-apply:kubectl",
|
||||
"priority": "P1",
|
||||
"type": "environment_blocker",
|
||||
"scope": "kubectl",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"summary": "kubectl is not installed in the runner",
|
||||
"nextTask": "Provide a kubectl client configured for the D601 DEV k3s context without exposing token or secret values.",
|
||||
"unblockOrder": 4,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#34",
|
||||
"pikasTech/HWLAB#33",
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#38"
|
||||
],
|
||||
"rationale": "D601 hwlab-dev cluster state must be observable read-only before any live apply or M3/M4/M5 acceptance."
|
||||
},
|
||||
{
|
||||
"id": "dev-gate-preflight:d601-k3s",
|
||||
"priority": "P1",
|
||||
@@ -1025,15 +912,14 @@
|
||||
"rationale": "D601 hwlab-dev cluster state must be observable read-only before any live apply or M3/M4/M5 acceptance."
|
||||
},
|
||||
{
|
||||
"id": "dev-deploy-apply:cloud-api-db",
|
||||
"id": "dev-edge-health:cloud-api-db",
|
||||
"priority": "P1",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "cloud-api-db",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-deploy-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#33",
|
||||
"summary": "cloud-api health reports DB config blocked; missing HWLAB_CLOUD_DB_URL, HWLAB_CLOUD_DB_SSL_MODE",
|
||||
"nextTask": "Configure and verify the DEV cloud-api DB env readiness through health output, without reading secret values.",
|
||||
"source": "reports/dev-gate/dev-edge-health.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#36",
|
||||
"summary": "cloud-api DB env is injected, but runtime health has not attempted a live DB connection",
|
||||
"unblockOrder": 5,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#34",
|
||||
@@ -1061,121 +947,72 @@
|
||||
"rationale": "Cloud API DB env and health readiness block runtime health and MVP evidence even if ingress starts responding."
|
||||
},
|
||||
{
|
||||
"id": "dev-gate-preflight:dev-edge",
|
||||
"priority": "P2",
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-edge",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-preflight-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#34",
|
||||
"summary": "http://74.48.78.17:16667/health/live is not reachable from this runner.",
|
||||
"nextTask": "Bring up or repair the D601-to-master frp route and hwlab-edge-proxy, then rerun the health probe.",
|
||||
"unblockOrder": 6,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#38",
|
||||
"pikasTech/HWLAB#37",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The :6667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected."
|
||||
},
|
||||
{
|
||||
"id": "dev-gate-preflight:dev-edge-health",
|
||||
"priority": "P2",
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-edge-health",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-preflight-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#34",
|
||||
"summary": "live network probes require --live",
|
||||
"nextTask": "Repair the master frps/public DEV edge route and rerun the read-only DEV edge health smoke before real deployment.",
|
||||
"unblockOrder": 6,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#38",
|
||||
"pikasTech/HWLAB#37",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The :6667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected."
|
||||
},
|
||||
{
|
||||
"id": "dev-m3-hardware-loop:dev-ingress-health",
|
||||
"priority": "P2",
|
||||
"type": "network_blocker",
|
||||
"scope": "dev-ingress-health",
|
||||
"id": "dev-m3-hardware-loop:m3-hardware-loop-runtime",
|
||||
"priority": "P3",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-m3-hardware-loop.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#38",
|
||||
"summary": "Blocked at the #33 DEV runtime readiness condition: public DEV ingress does not accept HWLAB health requests, so #36/M3 hardware-loop checks were not reached.",
|
||||
"unblockOrder": 6,
|
||||
"summary": "patch-panel active DO1 -> DI1 connection missing",
|
||||
"unblockOrder": 99,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#38",
|
||||
"pikasTech/HWLAB#37",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The :6667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected."
|
||||
"rationale": "Residual blocker that must be classified before claiming a green DEV gate."
|
||||
},
|
||||
{
|
||||
"id": "dev-m4-agent-loop:devPreconditions",
|
||||
"priority": "P2",
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"id": "dev-m4-agent-loop:db-live",
|
||||
"priority": "P3",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-m4-agent-loop.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#37",
|
||||
"summary": "connect ECONNREFUSED 74.48.78.17:16667",
|
||||
"unblockOrder": 6,
|
||||
"summary": "cloud-api /health/live reports DB degraded; connected=false; ready=false.",
|
||||
"unblockOrder": 99,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#38",
|
||||
"pikasTech/HWLAB#37",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The :6667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected."
|
||||
"rationale": "Residual blocker that must be classified before claiming a green DEV gate."
|
||||
},
|
||||
{
|
||||
"id": "dev-mvp-gate-report:devPreconditions",
|
||||
"priority": "P2",
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"id": "dev-mvp-gate-report:db-live",
|
||||
"priority": "P3",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#39",
|
||||
"summary": "http://74.48.78.17:16667/health and /live both fail with curl exit 7; live DEV ingress evidence is missing.",
|
||||
"unblockOrder": 6,
|
||||
"summary": "cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established.",
|
||||
"unblockOrder": 99,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#38",
|
||||
"pikasTech/HWLAB#37",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The :6667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected."
|
||||
"rationale": "Residual blocker that must be classified before claiming a green DEV gate."
|
||||
},
|
||||
{
|
||||
"id": "dev-mvp-gate-report:m3-hardware-loop-runtime",
|
||||
"priority": "P3",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"status": "open",
|
||||
"source": "reports/dev-gate/dev-mvp-gate-report.json",
|
||||
"sourceIssue": "pikasTech/HWLAB#39",
|
||||
"summary": "Live M3 smoke reached DEV simulators, but patch-panel active DO1 -> DI1 connection is missing.",
|
||||
"unblockOrder": 99,
|
||||
"unblocks": [
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "Residual blocker that must be classified before claiming a green DEV gate."
|
||||
}
|
||||
],
|
||||
"nextSteps": [
|
||||
{
|
||||
"order": 1,
|
||||
"blockerOrder": 1,
|
||||
"priority": "P0",
|
||||
"scopes": [
|
||||
"base-image"
|
||||
],
|
||||
"sourceIssues": [
|
||||
"pikasTech/HWLAB#33",
|
||||
"pikasTech/HWLAB#35"
|
||||
],
|
||||
"rationale": "Artifact publishing cannot start until an approved Node 20 DEV builder base image is available.",
|
||||
"action": "Preload node:20-bookworm-slim into the D601 Docker cache, or tag it as 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim. Set HWLAB_DEV_BASE_IMAGE=node:20-bookworm-slim or HWLAB_DEV_BASE_IMAGE=127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim when invoking artifact publish. Rerun this preflight and require status=ready before #35 artifact publish. Do not use UniDesk runtime, Code Queue runner, backend-core, provider-gateway, or microservice-proxy images as substitutes.",
|
||||
"evidenceRequired": "Base-image preflight status=ready with approved Node 20 builder base and no UniDesk/runtime substitute."
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
"blockerOrder": 3,
|
||||
"priority": "P1",
|
||||
"scopes": [
|
||||
"artifact-publish",
|
||||
"artifact-source-commit",
|
||||
"artifact-catalog",
|
||||
"dev-artifact-publish",
|
||||
"ghcr"
|
||||
@@ -1187,18 +1024,17 @@
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The gate cannot promote deploy or runtime observations without immutable image provenance and digests.",
|
||||
"action": "Publish DEV images from the intended commit and update the catalog with registry digests and verification evidence.",
|
||||
"action": "Run the DEV artifact publish workflow, then record only real sha256 digests with `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json`; if publish is still blocked, keep not_published via `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked`.",
|
||||
"evidenceRequired": "Artifact publish report with ciPublished=true, registryVerified=true, and sha256 digest for each frozen service ID."
|
||||
},
|
||||
{
|
||||
"order": 3,
|
||||
"order": 2,
|
||||
"blockerOrder": 4,
|
||||
"priority": "P1",
|
||||
"scopes": [
|
||||
"d601-k3s-client-binary",
|
||||
"d601-kubeconfig-path",
|
||||
"d601-maintenance-ssh-bridge",
|
||||
"kubectl",
|
||||
"d601-k3s"
|
||||
],
|
||||
"sourceIssues": [
|
||||
@@ -1213,7 +1049,7 @@
|
||||
"evidenceRequired": "Read-only kubectl/k3s report proving pods/services/configmaps are observable in hwlab-dev without reading Secrets."
|
||||
},
|
||||
{
|
||||
"order": 4,
|
||||
"order": 3,
|
||||
"blockerOrder": 5,
|
||||
"priority": "P1",
|
||||
"scopes": [
|
||||
@@ -1223,32 +1059,29 @@
|
||||
"sourceIssues": [
|
||||
"pikasTech/HWLAB#33",
|
||||
"pikasTech/HWLAB#34",
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "Cloud API DB env and health readiness block runtime health and MVP evidence even if ingress starts responding.",
|
||||
"action": "Configure and verify the DEV cloud-api DB env readiness through health output, without reading secret values.",
|
||||
"action": "Configure DEV hwlab-cloud-api with Secret hwlab-cloud-api-dev-db/database-url and HWLAB_CLOUD_DB_SSL_MODE=require, then rerun health/preflight without printing the secret value.",
|
||||
"evidenceRequired": "Cloud API health/live output showing DB env ready and redacted secret references, without secret material."
|
||||
},
|
||||
{
|
||||
"order": 5,
|
||||
"blockerOrder": 6,
|
||||
"priority": "P2",
|
||||
"order": 4,
|
||||
"blockerOrder": 99,
|
||||
"priority": "P3",
|
||||
"scopes": [
|
||||
"dev-edge",
|
||||
"dev-edge-health",
|
||||
"dev-ingress-health",
|
||||
"devPreconditions"
|
||||
"m3-hardware-loop-runtime",
|
||||
"db-live"
|
||||
],
|
||||
"sourceIssues": [
|
||||
"pikasTech/HWLAB#34",
|
||||
"pikasTech/HWLAB#36",
|
||||
"pikasTech/HWLAB#37",
|
||||
"pikasTech/HWLAB#38",
|
||||
"pikasTech/HWLAB#39"
|
||||
],
|
||||
"rationale": "The :6667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected.",
|
||||
"action": "Bring up or repair the D601-to-master frp route and hwlab-edge-proxy, then rerun the health probe.",
|
||||
"evidenceRequired": "Read-only DEV route observation for :6667/frp/edge/router with HWLAB service identity and artifact identity."
|
||||
"rationale": "Residual blocker that must be classified before claiming a green DEV gate.",
|
||||
"action": "Resolve the blocker and attach source/local/dry-run/DEV-live evidence at the correct level.",
|
||||
"evidenceRequired": "A committed report with the exact evidence level and command used."
|
||||
}
|
||||
],
|
||||
"validationCommands": [
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# HWLAB M5 DEV Gate Aggregator v2
|
||||
|
||||
Status: blocked
|
||||
Generated from: `1e9591a6611e`
|
||||
Generated from: `d4fe2cf1bb8a`
|
||||
Scope: DEV only, report-only
|
||||
|
||||
## Summary
|
||||
|
||||
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.
|
||||
|
||||
## Milestones
|
||||
|
||||
@@ -14,9 +14,9 @@ SOURCE, LOCAL, and DRY-RUN evidence exists, but DEV-LIVE acceptance is blocked b
|
||||
| --- | --- | --- | --- | --- |
|
||||
| M0 | pass | SOURCE | missing_or_blocked | contract source is available; highest visible level is SOURCE; status is pass. |
|
||||
| M1 | pass | LOCAL | missing_or_blocked | local smoke is available; highest visible level is LOCAL; status is pass. |
|
||||
| M2 | blocked | DRY-RUN | missing_or_blocked | deploy/runtime readiness is blocked before live DEV; highest visible level is DRY-RUN; status is blocked. |
|
||||
| M2 | blocked | DEV-LIVE | missing_or_blocked | deploy/runtime readiness is blocked before live DEV; highest visible level is DEV-LIVE; status is blocked. |
|
||||
| M3 | blocked | LOCAL | missing_or_blocked | hardware loop has source/local shape but no live operation; highest visible level is LOCAL; status is blocked. |
|
||||
| M4 | blocked | LOCAL | missing_or_blocked | agent loop has local smoke but live preflight is blocked; highest visible level is LOCAL; status is blocked. |
|
||||
| M4 | not_run | LOCAL | missing_or_blocked | agent loop has local smoke but live preflight is blocked; highest visible level is LOCAL; status is not_run. |
|
||||
| M5 | blocked | DRY-RUN | missing_or_blocked | dry-run is green but live MVP gate is blocked; highest visible level is DRY-RUN; status is blocked. |
|
||||
|
||||
## #9 DoD Checks
|
||||
@@ -27,7 +27,7 @@ SOURCE, LOCAL, and DRY-RUN evidence exists, but DEV-LIVE acceptance is blocked b
|
||||
| m1-local-smoke | pass | LOCAL | M1 local smoke is not a live DEV substitute. |
|
||||
| artifact-publish-digests | blocked | BLOCKED | artifactState=contract-skeleton, ciPublished=false, registryVerified=false, sha256=0, not_published=13 |
|
||||
| d601-k3s-observability | blocked | BLOCKED | D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev. |
|
||||
| dev-edge-frp-6667 | blocked | BLOCKED | No committed report proves live HTTP 200/JSON on http://74.48.78.17:16667. |
|
||||
| dev-edge-frp-16667 | pass | DEV-LIVE | Committed edge report proves read-only public HTTP on :16667 /health and /health/live; old preflight network probe blockers are stale. |
|
||||
| cloud-api-db-ready | blocked | BLOCKED | Manifest-level DB env exists, but live DB health readiness is still blocked/missing. |
|
||||
| m5-mvp-dev-live | blocked | BLOCKED | M5 dry-run passed; bounded DEV-LIVE MVP e2e has not passed. |
|
||||
|
||||
@@ -35,37 +35,30 @@ SOURCE, LOCAL, and DRY-RUN evidence exists, but DEV-LIVE acceptance is blocked b
|
||||
|
||||
| Priority | Order | Type | Scope | Summary |
|
||||
| --- | ---: | --- | --- | --- |
|
||||
| P0 | 1 | environment_blocker | base-image | HWLAB_DEV_BASE_IMAGE is not set and no approved local DEV builder base image was found in the Docker image cache; expected node:20-bookworm-slim or 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim. |
|
||||
| P1 | 3 | observability_blocker | artifact-publish | DEV artifact catalog has no CI publish, registry verification, or registry digests |
|
||||
| P1 | 3 | observability_blocker | artifact-source-commit | deploy/catalog artifact commit 24eb3bf/24eb3bf does not match source 9b47ebe49f70 |
|
||||
| P1 | 3 | runtime_blocker | artifact-catalog | deploy/artifact-catalog.dev.json does not prove published artifacts for origin/main 1a2efd4; ciPublished=false, registryVerified=false, not_published=13. |
|
||||
| P1 | 3 | runtime_blocker | dev-artifact-publish | reports/dev-gate/dev-artifacts.json does not prove all HWLAB service artifacts for origin/main 1a2efd4; current status is blocked with 0/13 published. |
|
||||
| P1 | 3 | runtime_blocker | ghcr | This preflight could not verify GHCR manifests for the DEV catalog images without reading credentials. |
|
||||
| P1 | 4 | environment_blocker | d601-k3s-client-binary | Neither kubectl nor k3s is installed in this runner PATH. |
|
||||
| P1 | 4 | environment_blocker | d601-kubeconfig-path | No readable KUBECONFIG/default k3s kubeconfig path was found by metadata checks. |
|
||||
| P1 | 4 | environment_blocker | d601-maintenance-ssh-bridge | No SSH maintenance bridge was detected from ssh binary plus known environment variables or ~/.ssh/config metadata. |
|
||||
| P1 | 4 | environment_blocker | kubectl | kubectl is not installed in the runner |
|
||||
| P1 | 4 | environment_blocker | d601-k3s | D601 runner lacks kubectl and no default kubeconfig was used by this preflight. |
|
||||
| P1 | 5 | runtime_blocker | cloud-api-db | cloud-api health reports DB config blocked; missing HWLAB_CLOUD_DB_URL, HWLAB_CLOUD_DB_SSL_MODE |
|
||||
| P1 | 5 | runtime_blocker | cloud-api-db | cloud-api DB env is injected, but runtime health has not attempted a live DB connection |
|
||||
| P1 | 5 | runtime_blocker | cloud-api-db-health-gate | cloud-api DB runtime env is not ready; missing HWLAB_CLOUD_DB_URL, HWLAB_CLOUD_DB_SSL_MODE. |
|
||||
| P2 | 6 | network_blocker | dev-edge | http://74.48.78.17:16667/health/live is not reachable from this runner. |
|
||||
| P2 | 6 | network_blocker | dev-edge-health | live network probes require --live |
|
||||
| P2 | 6 | network_blocker | dev-ingress-health | Blocked at the #33 DEV runtime readiness condition: public DEV ingress does not accept HWLAB health requests, so #36/M3 hardware-loop checks were not reached. |
|
||||
| P2 | 6 | network_blocker | devPreconditions | connect ECONNREFUSED 74.48.78.17:16667 |
|
||||
| P2 | 6 | network_blocker | devPreconditions | http://74.48.78.17:16667/health and /live both fail with curl exit 7; live DEV ingress evidence is missing. |
|
||||
| P3 | 99 | runtime_blocker | m3-hardware-loop-runtime | patch-panel active DO1 -> DI1 connection missing |
|
||||
| P3 | 99 | runtime_blocker | db-live | cloud-api /health/live reports DB degraded; connected=false; ready=false. |
|
||||
| P3 | 99 | runtime_blocker | db-live | cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established. |
|
||||
| P3 | 99 | runtime_blocker | m3-hardware-loop-runtime | Live M3 smoke reached DEV simulators, but patch-panel active DO1 -> DI1 connection is missing. |
|
||||
|
||||
## Next Unblock Order
|
||||
|
||||
1. Preload node:20-bookworm-slim into the D601 Docker cache, or tag it as 127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim. Set HWLAB_DEV_BASE_IMAGE=node:20-bookworm-slim or HWLAB_DEV_BASE_IMAGE=127.0.0.1:5000/hwlab/hwlab-dev-base:node20-bookworm-slim when invoking artifact publish. Rerun this preflight and require status=ready before #35 artifact publish. Do not use UniDesk runtime, Code Queue runner, backend-core, provider-gateway, or microservice-proxy images as substitutes.
|
||||
Evidence required: Base-image preflight status=ready with approved Node 20 builder base and no UniDesk/runtime substitute.
|
||||
2. Publish DEV images from the intended commit and update the catalog with registry digests and verification evidence.
|
||||
1. Run the DEV artifact publish workflow, then record only real sha256 digests with `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json`; if publish is still blocked, keep not_published via `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked`.
|
||||
Evidence required: Artifact publish report with ciPublished=true, registryVerified=true, and sha256 digest for each frozen service ID.
|
||||
3. Install kubectl in the D601 Code Queue runner image, or mount an approved k3s kubectl client path for read-only hwlab-dev observation.
|
||||
2. Install kubectl in the D601 Code Queue runner image, or mount an approved k3s kubectl client path for read-only hwlab-dev observation.
|
||||
Evidence required: Read-only kubectl/k3s report proving pods/services/configmaps are observable in hwlab-dev without reading Secrets.
|
||||
4. Configure and verify the DEV cloud-api DB env readiness through health output, without reading secret values.
|
||||
3. Configure DEV hwlab-cloud-api with Secret hwlab-cloud-api-dev-db/database-url and HWLAB_CLOUD_DB_SSL_MODE=require, then rerun health/preflight without printing the secret value.
|
||||
Evidence required: Cloud API health/live output showing DB env ready and redacted secret references, without secret material.
|
||||
5. Bring up or repair the D601-to-master frp route and hwlab-edge-proxy, then rerun the health probe.
|
||||
Evidence required: Read-only DEV route observation for :6667/frp/edge/router with HWLAB service identity and artifact identity.
|
||||
4. Resolve the blocker and attach source/local/dry-run/DEV-live evidence at the correct level.
|
||||
Evidence required: A committed report with the exact evidence level and command used.
|
||||
|
||||
## Validation
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"reportVersion": "v1",
|
||||
"issue": "pikasTech/HWLAB#39",
|
||||
"taskId": "dev-mvp-gate-report",
|
||||
"commitId": "6eb4c199b0c63cca7fd68fc3306f7a9cbe4323ea",
|
||||
"commitId": "86d769525caf1db513b93cb67c2c8ee8863dd4b1",
|
||||
"acceptanceLevel": "dev_mvp_gate",
|
||||
"devOnly": true,
|
||||
"prodDisabled": true,
|
||||
@@ -81,27 +81,46 @@
|
||||
},
|
||||
"devPreconditions": {
|
||||
"status": "blocked",
|
||||
"classification": "DB live; hardware loop",
|
||||
"requirements": [
|
||||
"Obtain a live HTTP 200/JSON health observation from http://74.48.78.17:16667/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",
|
||||
"http://74.48.78.17:16666/ returns the DEV browser entry",
|
||||
"http://74.48.78.17:16667/health returns HWLAB DEV edge JSON",
|
||||
"http://74.48.78.17:16667/health/live returns HWLAB cloud-api JSON with DB live readiness",
|
||||
"M3 hardware loop proves box-simu-1 DO1 -> box-simu-2 DI1 via patch-panel",
|
||||
"M4 agent runtime/evidence path is only attempted after DB live and M3 readiness are not blocked",
|
||||
"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:16667/health",
|
||||
"curl -fsS --max-time 5 http://74.48.78.17:16667/live"
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16666/",
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16667/health/live",
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16667/health",
|
||||
"HWLAB_DEV_BOX_SIMU_1_URL=http://10.42.0.200:7201 HWLAB_DEV_BOX_SIMU_2_URL=http://10.42.0.208:7201 HWLAB_DEV_GATEWAY_SIMU_1_URL=http://10.42.0.209:7101 HWLAB_DEV_GATEWAY_SIMU_2_URL=http://10.42.0.204:7101 HWLAB_DEV_PATCH_PANEL_URL=http://10.42.0.205:7301 node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production",
|
||||
"node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"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"
|
||||
"http://74.48.78.17:16666/ -> HTTP 200 text/html, title=HWLAB DEV MVP Gate",
|
||||
"http://74.48.78.17:16667/health -> HTTP 200 serviceId=hwlab-edge-proxy status=ok commit=cb35ada6860653b27269b0a57991184118cbf4b1",
|
||||
"http://74.48.78.17:16667/health/live -> HTTP 200 serviceId=hwlab-cloud-api status=degraded db.ready=false db.connected=false db.connectionChecked=false",
|
||||
"dev-edge-health active report -> blocked by DB live readiness, while public 16667 TCP/HTTP and frp control/tunnel health are reachable",
|
||||
"dev-m3-hardware-loop active report -> blocked, classification=hardware loop, summary=patch-panel active DO1 -> DI1 connection missing",
|
||||
"dev-m4-agent-loop active report -> blocked, classification=DB live, summary=cloud-api /health/live reports DB degraded; connected=false; ready=false"
|
||||
],
|
||||
"summary": "The frozen DEV endpoint is not reachable from this runner, so no live DEV gate can be claimed yet."
|
||||
"summary": "Public DEV route/frp is reachable on 16666/16667, but live MVP remains blocked by DB live readiness and the M3 hardware loop topology; no historical 6667 failure is counted as active evidence."
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"status": "open",
|
||||
"summary": "http://74.48.78.17:16667/health and /live both fail with curl exit 7; live DEV ingress evidence is missing."
|
||||
"classification": "DB live",
|
||||
"summary": "cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established."
|
||||
},
|
||||
{
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"status": "open",
|
||||
"classification": "hardware loop",
|
||||
"summary": "Live M3 smoke reached DEV simulators, but patch-panel active DO1 -> DI1 connection is missing."
|
||||
}
|
||||
],
|
||||
"milestones": [
|
||||
@@ -155,43 +174,87 @@
|
||||
},
|
||||
{
|
||||
"id": "M3",
|
||||
"status": "pass",
|
||||
"status": "blocked",
|
||||
"commands": [
|
||||
"node scripts/m3-hardware-loop-smoke.mjs"
|
||||
"node scripts/m3-hardware-loop-smoke.mjs",
|
||||
"node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"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"
|
||||
"Local M3 hardware loop smoke passed",
|
||||
"Live DEV M3 smoke reached 16667 ingress and direct simulator/patch-panel Pod URLs",
|
||||
"Live DEV M3 blocked: patch-panel active DO1 -> DI1 connection missing"
|
||||
],
|
||||
"summary": "The local hardware trusted loop smoke passes."
|
||||
"summary": "Local M3 remains green, but active DEV-LIVE M3 is blocked by hardware loop topology.",
|
||||
"blocker": "hardware loop"
|
||||
},
|
||||
{
|
||||
"id": "M4",
|
||||
"status": "pass",
|
||||
"status": "blocked",
|
||||
"commands": [
|
||||
"node scripts/m4-agent-loop-smoke.mjs"
|
||||
"node scripts/m4-agent-loop-smoke.mjs",
|
||||
"node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"evidence": [
|
||||
"[m4-smoke] ok m4-agent-automation-loop-local-contract-smoke"
|
||||
"[m4-smoke] ok m4-agent-automation-loop-local-contract-smoke",
|
||||
"Live DEV M4 preflight blocked before agent scheduling: cloud-api /health/live DB degraded, ready=false, connected=false"
|
||||
],
|
||||
"summary": "The local agent automation loop smoke passes."
|
||||
"summary": "Local M4 remains green, but active DEV-LIVE M4 is blocked at DB live readiness before agent runtime scheduling.",
|
||||
"blocker": "DB live"
|
||||
},
|
||||
{
|
||||
"id": "M5",
|
||||
"status": "pass",
|
||||
"status": "blocked",
|
||||
"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:16667, projects: 2",
|
||||
"hwlab-cli health -> status: ok, environment: dev, endpoint: http://74.48.78.17:16667, gateStatus: blocked",
|
||||
"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"
|
||||
"M5 MVP E2E dry-run passed: 9 steps, 13 artifacts, 14 health contracts, 2 hardware operations, 2 evidence records, 0 network calls",
|
||||
"Live MVP remains blocked by DB live and M3 hardware loop active reports"
|
||||
],
|
||||
"summary": "The M5 orchestration is green in dry-run mode, but it stays fixture-only and does not claim live DEV readiness."
|
||||
"summary": "The M5 orchestration is green in dry-run mode, but active DEV-LIVE acceptance is blocked by DB live and hardware loop evidence.",
|
||||
"blocker": "DB live; hardware loop"
|
||||
}
|
||||
],
|
||||
"notes": "Blocked gate report. Local contract, smoke, and dry-run checks pass on origin/main, but live DEV ingress is unreachable from this runner."
|
||||
"notes": "Active #64 DEV retest report. Public 16666/16667 route is reachable; live MVP remains blocked. No PROD, secret read, runtime restart, long-running agent task, or UniDesk runtime substitution was used.",
|
||||
"blockedClassification": [
|
||||
{
|
||||
"category": "DB live",
|
||||
"status": "blocked",
|
||||
"evidence": "16667/health/live serviceId=hwlab-cloud-api status=degraded db.ready=false db.connected=false"
|
||||
},
|
||||
{
|
||||
"category": "agent runtime",
|
||||
"status": "not_run",
|
||||
"evidence": "M4 stopped before agent scheduling because DB live is blocked"
|
||||
},
|
||||
{
|
||||
"category": "hardware loop",
|
||||
"status": "blocked",
|
||||
"evidence": "M3 stopped on missing patch-panel DO1 -> DI1 active connection"
|
||||
},
|
||||
{
|
||||
"category": "evidence/audit",
|
||||
"status": "not_run",
|
||||
"evidence": "M3/M4 did not reach accepted hardware operations requiring audit/evidence closure"
|
||||
},
|
||||
{
|
||||
"category": "CD apply",
|
||||
"status": "not_run",
|
||||
"evidence": "No deploy/apply command was run in this #64 retest"
|
||||
},
|
||||
{
|
||||
"category": "frp",
|
||||
"status": "pass",
|
||||
"evidence": "16666 browser, 16667/health, 16667/health/live, frps 7000, and tunnel health 7402 are reachable"
|
||||
},
|
||||
{
|
||||
"category": "other",
|
||||
"status": "not_observed",
|
||||
"evidence": "No additional blocker class observed in the short DEV-only retest"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
Status: blocked
|
||||
|
||||
Baseline: `6eb4c199b0c63cca7fd68fc3306f7a9cbe4323ea`
|
||||
Baseline: `86d769525caf1db513b93cb67c2c8ee8863dd4b1`
|
||||
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:16667` is not reachable from this runner.
|
||||
Public DEV route/frp is reachable on 16666/16667, but live MVP remains blocked by DB live readiness and the M3 hardware loop topology; no historical 6667 failure is counted as active evidence.
|
||||
|
||||
## Evidence
|
||||
## Commands
|
||||
|
||||
- `node scripts/validate-contract.mjs`
|
||||
- `node scripts/validate-m0-contract.mjs`
|
||||
@@ -24,23 +24,38 @@ M0-M5 local contract, smoke, and dry-run checks pass on the frozen `origin/main`
|
||||
- `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:16667/health`
|
||||
- `curl -fsS --max-time 5 http://74.48.78.17:16667/live`
|
||||
- `curl -fsS --max-time 8 http://74.48.78.17:16666/`
|
||||
- `curl -fsS --max-time 8 http://74.48.78.17:16667/health/live`
|
||||
- `curl -fsS --max-time 8 http://74.48.78.17:16667/health`
|
||||
- `HWLAB_DEV_BOX_SIMU_1_URL=http://10.42.0.200:7201 HWLAB_DEV_BOX_SIMU_2_URL=http://10.42.0.208:7201 HWLAB_DEV_GATEWAY_SIMU_1_URL=http://10.42.0.209:7101 HWLAB_DEV_GATEWAY_SIMU_2_URL=http://10.42.0.204:7101 HWLAB_DEV_PATCH_PANEL_URL=http://10.42.0.205:7301 node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production`
|
||||
- `node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production`
|
||||
|
||||
## Result
|
||||
## Milestones
|
||||
|
||||
- `M0`: pass
|
||||
- `M1`: pass
|
||||
- `M2`: pass
|
||||
- `M3`: pass
|
||||
- `M4`: pass
|
||||
- `M5`: pass
|
||||
- `overall`: blocked
|
||||
- `M0`: pass - Frozen contract, artifact, boundary, drift, and evidence fixtures are parseable and aligned to the DEV boundary.
|
||||
- `M1`: pass - The local M1 contract smoke passes.
|
||||
- `M2`: pass - The deploy smoke remains fixture-only and validates the frozen route phases and artifact metadata.
|
||||
- `M3`: blocked - Local M3 remains green, but active DEV-LIVE M3 is blocked by hardware loop topology.
|
||||
- `M4`: blocked - Local M4 remains green, but active DEV-LIVE M4 is blocked at DB live readiness before agent runtime scheduling.
|
||||
- `M5`: blocked - The M5 orchestration is green in dry-run mode, but active DEV-LIVE acceptance is blocked by DB live and hardware loop evidence.
|
||||
|
||||
## Minimal Next Step
|
||||
## Blocked Classification
|
||||
|
||||
Obtain live `200`/JSON health observations from `http://74.48.78.17:16667/health` and `/live`, then capture the live route observations for the DEV ingress chain without switching to PROD or heavy e2e.
|
||||
| Category | Status | Evidence |
|
||||
| --- | --- | --- |
|
||||
| DB live | blocked | 16667/health/live serviceId=hwlab-cloud-api status=degraded db.ready=false db.connected=false |
|
||||
| agent runtime | not_run | M4 stopped before agent scheduling because DB live is blocked |
|
||||
| hardware loop | blocked | M3 stopped on missing patch-panel DO1 -> DI1 active connection |
|
||||
| evidence/audit | not_run | M3/M4 did not reach accepted hardware operations requiring audit/evidence closure |
|
||||
| CD apply | not_run | No deploy/apply command was run in this #64 retest |
|
||||
| frp | pass | 16666 browser, 16667/health, 16667/health/live, frps 7000, and tunnel health 7402 are reachable |
|
||||
| other | not_observed | No additional blocker class observed in the short DEV-only retest |
|
||||
|
||||
## Blocker
|
||||
## Blockers
|
||||
|
||||
The frozen DEV endpoint returns connection failures from this runner, so no live DEV ingress evidence can be claimed yet.
|
||||
- DB live: cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established.
|
||||
- hardware loop: Live M3 smoke reached DEV simulators, but patch-panel active DO1 -> DI1 connection is missing.
|
||||
|
||||
## Boundary
|
||||
|
||||
Active #64 DEV retest report. Public 16666/16667 route is reachable; live MVP remains blocked. No PROD, secret read, runtime restart, long-running agent task, or UniDesk runtime substitution was used.
|
||||
|
||||
@@ -704,12 +704,14 @@ async function main() {
|
||||
};
|
||||
report.blockers.push({
|
||||
type: "network_blocker",
|
||||
scope: "dev-ingress-health",
|
||||
scope: "frp",
|
||||
status: "open",
|
||||
classification: "frp",
|
||||
summary: "Blocked at the #33 DEV runtime readiness condition: public DEV ingress does not accept HWLAB health requests, so #36/M3 hardware-loop checks were not reached."
|
||||
});
|
||||
report.summary = {
|
||||
status: "blocked",
|
||||
classification: "frp",
|
||||
observedAt,
|
||||
result: "No live DEV M3 evidence was produced; fixture-backed local evidence was not used as a substitute."
|
||||
};
|
||||
@@ -726,10 +728,12 @@ async function main() {
|
||||
type: "runtime_blocker",
|
||||
scope: "m3-service-discovery",
|
||||
status: "open",
|
||||
classification: "hardware loop",
|
||||
summary: `DEV ingress is reachable, but M3 smoke lacks direct DEV service URLs: ${missing.join(", ")}.`
|
||||
});
|
||||
report.summary = {
|
||||
status: "blocked",
|
||||
classification: "hardware loop",
|
||||
observedAt,
|
||||
result: "DEV ingress was reachable, but live M3 simulator and patch-panel targets were not discoverable."
|
||||
};
|
||||
@@ -804,10 +808,12 @@ async function main() {
|
||||
type: "runtime_blocker",
|
||||
scope: "m3-hardware-loop-runtime",
|
||||
status: "open",
|
||||
classification: "hardware loop",
|
||||
summary: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
report.summary = {
|
||||
status: "blocked",
|
||||
classification: "hardware loop",
|
||||
observedAt,
|
||||
result: "Live DEV M3 runtime was reachable but did not satisfy the M3 hardware-loop contract."
|
||||
};
|
||||
|
||||
@@ -7,9 +7,10 @@ import { readFile, writeFile, mkdir } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { DEV_ENDPOINT, ENVIRONMENT_DEV } from "../internal/protocol/index.mjs";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const fixedNow = () => "2026-05-21T00:00:00.000Z";
|
||||
const DEV_ENDPOINT = "http://74.48.78.17:16667";
|
||||
const requiredDocs = ["docs/dev-acceptance-matrix.md", "docs/dev-m4-agent-loop.md"];
|
||||
const reportPath = "reports/dev-gate/dev-m4-agent-loop.json";
|
||||
const preflightCommand = "node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production";
|
||||
@@ -116,9 +117,10 @@ function blockerForResult(result) {
|
||||
? [
|
||||
{
|
||||
type: result.blockerType,
|
||||
scope: "devPreconditions",
|
||||
scope: result.blockerScope ?? "devPreconditions",
|
||||
status: "open",
|
||||
summary: result.blockerSummary
|
||||
summary: result.blockerSummary,
|
||||
classification: result.blockedClassification ?? "other"
|
||||
}
|
||||
]
|
||||
: [];
|
||||
@@ -170,8 +172,9 @@ function buildReport(fixture, evidence, result) {
|
||||
},
|
||||
devPreconditions: {
|
||||
status: statusForResult(result),
|
||||
classification: result.blockedClassification ?? "none",
|
||||
requirements: [
|
||||
"DEV route remains frozen at http://74.48.78.17:16667",
|
||||
`DEV route remains frozen at ${DEV_ENDPOINT}`,
|
||||
"No secret reads, real deployment, or long-running agent task is attempted",
|
||||
"Agent manager, worker, and skills are reachable only through the cloud API boundary"
|
||||
],
|
||||
@@ -180,6 +183,7 @@ function buildReport(fixture, evidence, result) {
|
||||
blockers: blockerForResult(result),
|
||||
livePreflight: {
|
||||
status: result.blocked ? "blocked" : "pass",
|
||||
classification: result.blockedClassification ?? "none",
|
||||
commands: [preflightCommand],
|
||||
evidence: evidence.length ? evidence : ["No live DEV observation was recorded."],
|
||||
summary: result.summary
|
||||
@@ -204,6 +208,8 @@ async function main() {
|
||||
let result = {
|
||||
blocked: true,
|
||||
blockerType: "network_blocker",
|
||||
blockerScope: "frp",
|
||||
blockedClassification: "frp",
|
||||
blockerSummary: "The fixed DEV endpoint did not accept a live connection from this runner.",
|
||||
summary: `Blocked before agent scheduling because ${DEV_ENDPOINT} is not reachable from this D601 runner.`
|
||||
};
|
||||
@@ -214,6 +220,8 @@ async function main() {
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "network_blocker",
|
||||
blockerScope: "frp",
|
||||
blockedClassification: "frp",
|
||||
blockerSummary: `DEV health returned HTTP ${health.statusCode}.`,
|
||||
summary: `Blocked on DEV ingress health because ${DEV_ENDPOINT}/health did not return success.`
|
||||
};
|
||||
@@ -221,15 +229,27 @@ async function main() {
|
||||
const body = health.body || {};
|
||||
evidence.push(`health:${body.serviceId}:${body.environment}:${body.status}`);
|
||||
|
||||
const live = await requestJson(`${DEV_ENDPOINT}/live`);
|
||||
const live = await requestJson(`${DEV_ENDPOINT}/health/live`);
|
||||
const liveBody = live.body || {};
|
||||
if (live.statusCode < 200 || live.statusCode >= 300 || liveBody?.serviceId !== "hwlab-cloud-api") {
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "runtime_blocker",
|
||||
blockerType: "network_blocker",
|
||||
blockerScope: "frp",
|
||||
blockedClassification: "frp",
|
||||
blockerSummary: "DEV live probe did not present the expected HWLAB cloud API identity.",
|
||||
summary: "Blocked because the live DEV boundary did not expose the expected cloud API identity."
|
||||
};
|
||||
} else if (isDbLiveBlocked(liveBody)) {
|
||||
evidence.push(`live:${liveBody.serviceId}:${liveBody.status}:db-blocked`);
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "runtime_blocker",
|
||||
blockerScope: "db-live",
|
||||
blockedClassification: "DB live",
|
||||
blockerSummary: summarizeDbBlocker(liveBody),
|
||||
summary: "Blocked at DB live readiness before scheduling a DEV agent task."
|
||||
};
|
||||
} else {
|
||||
evidence.push(`live:${liveBody.serviceId}:${liveBody.status}`);
|
||||
|
||||
@@ -246,51 +266,75 @@ async function main() {
|
||||
meta: {
|
||||
traceId: "trc_dev_m4_health",
|
||||
serviceId: "hwlab-cli",
|
||||
environment: "dev"
|
||||
environment: ENVIRONMENT_DEV
|
||||
}
|
||||
})
|
||||
});
|
||||
const rpcHealthBody = rpcHealth.body || {};
|
||||
evidence.push(`rpc-health:${rpcHealthBody.result?.serviceId ?? "unknown"}`);
|
||||
|
||||
const rpcHardware = await requestJson(`${DEV_ENDPOINT}/rpc`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "req_dev_m4_hw",
|
||||
method: "hardware.operation.request",
|
||||
params: {
|
||||
projectId: fixture.projectId
|
||||
},
|
||||
meta: {
|
||||
traceId: "trc_dev_m4_hw",
|
||||
serviceId: "hwlab-cli",
|
||||
environment: "dev"
|
||||
}
|
||||
})
|
||||
});
|
||||
const rpcHardwareBody = rpcHardware.body || {};
|
||||
const accepted = rpcHardwareBody.result?.accepted === true;
|
||||
const status = rpcHardwareBody.result?.status || rpcHardwareBody.error?.message || "unknown";
|
||||
evidence.push(`rpc-hardware:${status}`);
|
||||
|
||||
if (!accepted) {
|
||||
if (rpcHealth.statusCode < 200 || rpcHealth.statusCode >= 300 || rpcHealthBody.error) {
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "agent_blocker",
|
||||
blockerSummary: "hardware.operation.request remains a skeleton response in the current DEV runtime.",
|
||||
summary: "Blocked by M3 readiness because the agent hardware dispatch path is still skeleton-only."
|
||||
blockerScope: "agent-runtime",
|
||||
blockedClassification: "agent runtime",
|
||||
blockerSummary: rpcHealthBody.error?.message ?? `system.health returned HTTP ${rpcHealth.statusCode}.`,
|
||||
summary: "Blocked at agent runtime health before attempting hardware dispatch."
|
||||
};
|
||||
} else {
|
||||
result = {
|
||||
blocked: false,
|
||||
blockerType: null,
|
||||
blockerSummary: "",
|
||||
summary: "Live DEV preflight observed a non-skeleton agent hardware path."
|
||||
};
|
||||
|
||||
const rpcHardware = await requestJson(`${DEV_ENDPOINT}/rpc`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "req_dev_m4_hw",
|
||||
method: "hardware.operation.request",
|
||||
params: {
|
||||
projectId: fixture.projectId
|
||||
},
|
||||
meta: {
|
||||
traceId: "trc_dev_m4_hw",
|
||||
serviceId: "hwlab-cli",
|
||||
environment: ENVIRONMENT_DEV
|
||||
}
|
||||
})
|
||||
});
|
||||
const rpcHardwareBody = rpcHardware.body || {};
|
||||
const accepted = rpcHardwareBody.result?.accepted === true;
|
||||
const status = rpcHardwareBody.result?.status || rpcHardwareBody.error?.message || "unknown";
|
||||
evidence.push(`rpc-hardware:${status}`);
|
||||
|
||||
if (!accepted) {
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "agent_blocker",
|
||||
blockerScope: "hardware-loop",
|
||||
blockedClassification: "hardware loop",
|
||||
blockerSummary: "hardware.operation.request remains a skeleton response in the current DEV runtime.",
|
||||
summary: "Blocked by M3 readiness because the agent hardware dispatch path is still skeleton-only."
|
||||
};
|
||||
} else if (!rpcHardwareBody.result?.auditId || !rpcHardwareBody.result?.evidenceId) {
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "observability_blocker",
|
||||
blockerScope: "evidence-audit",
|
||||
blockedClassification: "evidence/audit",
|
||||
blockerSummary: "hardware.operation.request accepted but did not return audit/evidence identifiers.",
|
||||
summary: "Blocked because accepted DEV agent hardware dispatch lacks audit/evidence closure."
|
||||
};
|
||||
} else {
|
||||
result = {
|
||||
blocked: false,
|
||||
blockerType: null,
|
||||
blockerScope: null,
|
||||
blockedClassification: "none",
|
||||
blockerSummary: "",
|
||||
summary: "Live DEV preflight observed a non-skeleton agent hardware path."
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,6 +342,8 @@ async function main() {
|
||||
result = {
|
||||
blocked: true,
|
||||
blockerType: "network_blocker",
|
||||
blockerScope: "frp",
|
||||
blockedClassification: "frp",
|
||||
blockerSummary: error instanceof Error ? error.message : String(error),
|
||||
summary: `Blocked before agent scheduling because ${DEV_ENDPOINT} is unreachable from this runner.`
|
||||
};
|
||||
@@ -310,6 +356,7 @@ async function main() {
|
||||
reportPath,
|
||||
status: report.devPreconditions.status,
|
||||
blocker: report.blockers[0] ?? null,
|
||||
classification: report.devPreconditions.classification,
|
||||
evidence: report.livePreflight.evidence,
|
||||
summary: report.livePreflight.summary,
|
||||
observedAt: fixedNow()
|
||||
@@ -317,4 +364,20 @@ async function main() {
|
||||
process.stdout.write("\n");
|
||||
}
|
||||
|
||||
function isDbLiveBlocked(body) {
|
||||
const db = body?.db;
|
||||
if (!db || typeof db !== "object") {
|
||||
return false;
|
||||
}
|
||||
return db.connected === false || db.ready === false || ["blocked", "degraded"].includes(db.status);
|
||||
}
|
||||
|
||||
function summarizeDbBlocker(body) {
|
||||
const db = body?.db ?? {};
|
||||
const missing = Array.isArray(db.missingEnv) && db.missingEnv.length > 0
|
||||
? ` missing ${db.missingEnv.join(", ")}`
|
||||
: "";
|
||||
return `cloud-api /health/live reports DB ${db.status ?? "not ready"}; connected=${db.connected ?? "unknown"}; ready=${db.ready ?? "unknown"}.${missing}`;
|
||||
}
|
||||
|
||||
await main();
|
||||
|
||||
@@ -66,7 +66,9 @@ const liveBlocked = await captureCli([
|
||||
assert.equal(liveBlocked.exitCode, 2);
|
||||
const liveBlockedJson = JSON.parse(liveBlocked.stderr);
|
||||
assert.equal(liveBlockedJson.code, "BLOCKED");
|
||||
assert.equal(liveBlockedJson.blockers[0].type, "network_blocker");
|
||||
assert.equal(liveBlockedJson.blockers[0].type, "runtime_blocker");
|
||||
assert.equal(liveBlockedJson.blockers[0].scope, "db-live");
|
||||
assert.ok(liveBlockedJson.blockers.some((blocker) => blocker.scope === "m3-hardware-loop-runtime"));
|
||||
|
||||
assert.equal(gateSummary.endpoint, summary.endpoint);
|
||||
assert.equal(gateSummary.gateStatus, "blocked");
|
||||
|
||||
@@ -5,6 +5,8 @@ import { readFile, stat } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { DEV_ENDPOINT, ENVIRONMENT_DEV } from "../internal/protocol/index.mjs";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const planPath = "fixtures/mvp/m5-e2e/dry-run-plan.json";
|
||||
const checklistPath = "docs/dev-acceptance-checklist.json";
|
||||
@@ -12,8 +14,6 @@ const matrixPath = "docs/dev-acceptance-matrix.md";
|
||||
const runtimePath = "fixtures/mvp/runtime.json";
|
||||
const contractPath = "protocol/mvp-e2e-contract.md";
|
||||
const commonSchemaPath = "protocol/schemas/common.json";
|
||||
const DEV_ENDPOINT = "http://74.48.78.17:16667";
|
||||
const ENVIRONMENT_DEV = "dev";
|
||||
const JSON_RPC_VERSION = "2.0";
|
||||
let serviceIds = [];
|
||||
let serviceIdSet = new Set();
|
||||
|
||||
@@ -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])
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1433,7 +1433,12 @@ async function validateAggregatorV2Report(relativePath, report) {
|
||||
}
|
||||
|
||||
assertArray(report.nextSteps, `${label}.nextSteps`);
|
||||
assert.ok(report.nextSteps.length >= 5, `${label}.nextSteps must contain blocker order`);
|
||||
assert.ok(report.nextSteps.length >= 1, `${label}.nextSteps must contain blocker order`);
|
||||
assert.deepEqual(
|
||||
report.nextSteps.map((step) => step.blockerOrder).sort((a, b) => a - b),
|
||||
[...new Set(report.blockers.map((blocker) => blocker.unblockOrder))].sort((a, b) => a - b),
|
||||
`${label}.nextSteps must cover active blocker orders`
|
||||
);
|
||||
assert.deepEqual(
|
||||
report.nextSteps.map((step) => step.order),
|
||||
[...report.nextSteps].map((step) => step.order).sort((a, b) => a - b),
|
||||
|
||||
@@ -13,7 +13,7 @@ export const gateSummary = {
|
||||
"gateStatus": "blocked",
|
||||
"blocked": true,
|
||||
"acceptanceLevel": "dev_mvp_gate",
|
||||
"reportCommitId": "6eb4c199b0c63cca7fd68fc3306f7a9cbe4323ea",
|
||||
"reportCommitId": "86d769525caf1db513b93cb67c2c8ee8863dd4b1",
|
||||
"dryRunOnly": true,
|
||||
"devOnly": true,
|
||||
"prodDisabled": true,
|
||||
@@ -67,27 +67,44 @@ export const gateSummary = {
|
||||
},
|
||||
"devPreconditions": {
|
||||
"status": "blocked",
|
||||
"classification": "DB live; hardware loop",
|
||||
"requirements": [
|
||||
"Obtain a live HTTP 200/JSON health observation from http://74.48.78.17:16667/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",
|
||||
"http://74.48.78.17:16666/ returns the DEV browser entry",
|
||||
"http://74.48.78.17:16667/health returns HWLAB DEV edge JSON",
|
||||
"http://74.48.78.17:16667/health/live returns HWLAB cloud-api JSON with DB live readiness",
|
||||
"M3 hardware loop proves box-simu-1 DO1 -> box-simu-2 DI1 via patch-panel",
|
||||
"M4 agent runtime/evidence path is only attempted after DB live and M3 readiness are not blocked",
|
||||
"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:16667/health",
|
||||
"curl -fsS --max-time 5 http://74.48.78.17:16667/live"
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16666/",
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16667/health/live",
|
||||
"curl -fsS --max-time 8 http://74.48.78.17:16667/health",
|
||||
"HWLAB_DEV_BOX_SIMU_1_URL=http://10.42.0.200:7201 HWLAB_DEV_BOX_SIMU_2_URL=http://10.42.0.208:7201 HWLAB_DEV_GATEWAY_SIMU_1_URL=http://10.42.0.209:7101 HWLAB_DEV_GATEWAY_SIMU_2_URL=http://10.42.0.204:7101 HWLAB_DEV_PATCH_PANEL_URL=http://10.42.0.205:7301 node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production",
|
||||
"node scripts/dev-m4-agent-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"
|
||||
],
|
||||
"evidence": [
|
||||
"curl exit 7 for /health: could not connect to 74.48.78.17 port 16667",
|
||||
"curl exit 7 for /live: could not connect to 74.48.78.17 port 16667"
|
||||
"http://74.48.78.17:16666/ -> HTTP 200 text/html, title=HWLAB DEV MVP Gate",
|
||||
"http://74.48.78.17:16667/health -> HTTP 200 serviceId=hwlab-edge-proxy status=ok commit=cb35ada6860653b27269b0a57991184118cbf4b1",
|
||||
"http://74.48.78.17:16667/health/live -> HTTP 200 serviceId=hwlab-cloud-api status=degraded db.ready=false db.connected=false db.connectionChecked=false",
|
||||
"dev-edge-health active report -> blocked by DB live readiness, while public 16667 TCP/HTTP and frp control/tunnel health are reachable",
|
||||
"dev-m3-hardware-loop active report -> blocked, classification=hardware loop, summary=patch-panel active DO1 -> DI1 connection missing",
|
||||
"dev-m4-agent-loop active report -> blocked, classification=DB live, summary=cloud-api /health/live reports DB degraded; connected=false; ready=false"
|
||||
],
|
||||
"summary": "The frozen DEV endpoint is not reachable from this runner, so no live DEV gate can be claimed yet."
|
||||
"summary": "Public DEV route/frp is reachable on 16666/16667, but live MVP remains blocked by DB live readiness and the M3 hardware loop topology; no historical 6667 failure is counted as active evidence."
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"type": "network_blocker",
|
||||
"scope": "devPreconditions",
|
||||
"type": "runtime_blocker",
|
||||
"scope": "db-live",
|
||||
"status": "open",
|
||||
"summary": "http://74.48.78.17:16667/health and /live both fail with curl exit 7; live DEV ingress evidence is missing."
|
||||
"summary": "cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established."
|
||||
},
|
||||
{
|
||||
"type": "runtime_blocker",
|
||||
"scope": "m3-hardware-loop-runtime",
|
||||
"status": "open",
|
||||
"summary": "Live M3 smoke reached DEV simulators, but patch-panel active DO1 -> DI1 connection is missing."
|
||||
}
|
||||
],
|
||||
"milestones": [
|
||||
@@ -114,24 +131,24 @@ export const gateSummary = {
|
||||
},
|
||||
{
|
||||
"id": "M3",
|
||||
"status": "pass",
|
||||
"commandCount": 1,
|
||||
"status": "blocked",
|
||||
"commandCount": 2,
|
||||
"evidenceCount": 3,
|
||||
"summary": "The local hardware trusted loop smoke passes."
|
||||
"summary": "Local M3 remains green, but active DEV-LIVE M3 is blocked by hardware loop topology."
|
||||
},
|
||||
{
|
||||
"id": "M4",
|
||||
"status": "pass",
|
||||
"commandCount": 1,
|
||||
"evidenceCount": 1,
|
||||
"summary": "The local agent automation loop smoke passes."
|
||||
"status": "blocked",
|
||||
"commandCount": 2,
|
||||
"evidenceCount": 2,
|
||||
"summary": "Local M4 remains green, but active DEV-LIVE M4 is blocked at DB live readiness before agent runtime scheduling."
|
||||
},
|
||||
{
|
||||
"id": "M5",
|
||||
"status": "pass",
|
||||
"status": "blocked",
|
||||
"commandCount": 3,
|
||||
"evidenceCount": 3,
|
||||
"summary": "The M5 orchestration is green in dry-run mode, but it stays fixture-only and does not claim live DEV readiness."
|
||||
"evidenceCount": 4,
|
||||
"summary": "The M5 orchestration is green in dry-run mode, but active DEV-LIVE acceptance is blocked by DB live and hardware loop evidence."
|
||||
}
|
||||
],
|
||||
"artifactCount": 13,
|
||||
|
||||
Reference in New Issue
Block a user