From e7cc38147ecdac3bb284a5b4dce36b5b3330620a Mon Sep 17 00:00:00 2001 From: HWLAB Code Queue Date: Fri, 22 May 2026 07:26:40 +0000 Subject: [PATCH] docs: refresh DEV gate evidence layering --- docs/dev-evidence-blocker-aggregator.md | 26 +- docs/dev-gate-report.md | 5 + reports/d601-k3s-readonly-observability.json | 513 +++++++++++++++-- .../dev-gate/dev-m2-deploy-smoke-active.json | 42 +- .../dev-gate/dev-m5-gate-aggregator-v2.json | 519 +++++++++--------- reports/dev-gate/dev-m5-gate-aggregator-v2.md | 52 +- reports/dev-gate/dev-preflight-report.json | 74 +-- scripts/m2-dev-deploy-smoke.mjs | 4 + .../src/d601-k3s-readonly-observability.mjs | 21 +- .../src/dev-evidence-blocker-aggregator.mjs | 259 ++++++++- 10 files changed, 1116 insertions(+), 399 deletions(-) diff --git a/docs/dev-evidence-blocker-aggregator.md b/docs/dev-evidence-blocker-aggregator.md index 8ec9c8e5..7f306276 100644 --- a/docs/dev-evidence-blocker-aggregator.md +++ b/docs/dev-evidence-blocker-aggregator.md @@ -38,16 +38,29 @@ promoted to live DEV evidence: | `SOURCE` | Repository contracts, schemas, docs, manifests, or examples. | | `LOCAL` | Localhost or in-process smoke results only. | | `DRY-RUN` | Fixture-backed or no-mutation dry-run readiness evidence. | -| `DEV-LIVE` | Read-only evidence observed from the real DEV route. | +| `DEV-LIVE` | Read-only evidence observed from the real DEV route; this may prove entrypoint reachability without proving downstream DB, M3, M4, or M5 acceptance. | | `BLOCKED` | Missing issue reads, missing DEV evidence, missing artifacts, or other open blockers. | +## Current DEV Layering + +The v2 report exposes `currentDevLayering` so the public route can be green +without promoting the full gate: + +| Layer | Meaning | +| --- | --- | +| `EDGE/ROUTE live` | `16666` browser and `16667` health route evidence from read-only probes. | +| `DB live/degraded` | Cloud API DB readiness from redacted health evidence; route success does not imply DB live. | +| `M3 hardware trusted loop` | Real DEV `res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1` plus operation, trace, audit, and evidence identifiers. | +| `M4 agent loop` | Agent loop live preflight and scheduling/evidence closure, gated by DB and runtime readiness. | +| `artifact/desired-state source` | Artifact source coverage for the current target ref plus desired-state dry-run/apply status. | + ## Current Contract Map | Milestone | Current visible level | Contract entry | | --- | --- | --- | | M0 | `SOURCE` | `docs/m0-contract-audit.md`, protocol schemas, evidence chain examples, M0 validator. | | M1 | `LOCAL` | `docs/m1-local-smoke.md`, `fixtures/mvp/runtime.json`, `scripts/m1-contract-smoke.mjs`. | -| M2 | `DRY-RUN` | DEV deploy smoke fixture, artifact catalog, runtime boundary, and M2 dry-run validator. | +| M2 | `DEV-LIVE` for route only | DEV deploy smoke fixture plus active read-only `16666`/`16667` endpoint smoke. | | M3 | `LOCAL` | Hardware trusted loop topology fixture and local patch-panel smoke. | | M4 | `LOCAL` | Agent automation loop fixture, local runtime skeleton, skills commit, evidence, and cleanup smoke. | | M5 | `DRY-RUN` | MVP e2e dry-run plan and orchestration validator. | @@ -60,14 +73,17 @@ The v2 report reads committed report fixtures only: - `reports/dev-gate/dev-deploy-report.json` - `reports/dev-gate/dev-artifacts.json` - `reports/dev-gate/dev-edge-health.json` +- `reports/dev-gate/dev-m2-deploy-smoke-active.json` - `reports/dev-gate/dev-m3-hardware-loop.json` - `reports/dev-gate/dev-m4-agent-loop.json` - `reports/dev-gate/dev-mvp-gate-report.json` - `reports/d601-k3s-readonly-observability.json` -The report is blocked until real DEV-LIVE evidence is attached for the DEV -route and downstream HWLAB runtime services. Current source, local, and dry-run -contracts are useful readiness signals, but they are not live DEV proof. +The report remains blocked until real DEV-LIVE evidence is attached for the +required downstream HWLAB runtime services. Public route evidence on +`16666/16667` is necessary but not sufficient: DB live readiness, M3 trusted +loop evidence, M4 agent-loop evidence, and artifact/desired-state source +coverage stay separate. The legacy base-image blocker is not current when the committed reports show an approved Node 20 builder base. Artifact/current remains stricter: a target ref diff --git a/docs/dev-gate-report.md b/docs/dev-gate-report.md index 31141cad..35f4cb25 100644 --- a/docs/dev-gate-report.md +++ b/docs/dev-gate-report.md @@ -29,6 +29,11 @@ Each committed DEV gate report must carry `reportLifecycle`: `res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1` in real DEV plus operation, audit, and evidence identifiers. SOURCE, LOCAL, DRY-RUN, fixture, and historical report evidence are support/diagnostics only. +- M5 DEV-LIVE cannot be inferred from public entrypoint reachability. Reports + must keep EDGE/ROUTE live, DB live/degraded, M3 hardware trusted loop, + M4 agent loop, and artifact/desired-state source status as separate layers. + If the only read-only evidence is `16666/16667` reachability, M5 must remain + blocked/non-green. ## Files diff --git a/reports/d601-k3s-readonly-observability.json b/reports/d601-k3s-readonly-observability.json index 9d30df7e..9756c263 100644 --- a/reports/d601-k3s-readonly-observability.json +++ b/reports/d601-k3s-readonly-observability.json @@ -12,7 +12,7 @@ "pikasTech/HWLAB#39", "pikasTech/HWLAB#42" ], - "generatedAt": "2026-05-21T17:34:15.046Z", + "generatedAt": "2026-05-22T07:21:35.915Z", "mode": "read-only", "devOnly": true, "prodDisabled": true, @@ -48,18 +48,28 @@ "node --check scripts/src/d601-k3s-readonly-observability.mjs", "node scripts/d601-k3s-readonly-observability.mjs" ], - "conclusion": "blocked", + "conclusion": "ready", "environment": { "binaries": { "kubectl": { "name": "kubectl", - "available": false, - "path": null + "available": true, + "path": "/usr/local/bin/kubectl", + "version": { + "ok": true, + "command": "kubectl version --client=true", + "output": "Client Version: v1.36.1 Kustomize Version: v5.8.1" + } }, "k3s": { "name": "k3s", - "available": false, - "path": null + "available": true, + "path": "/usr/local/bin/k3s", + "version": { + "ok": true, + "command": "k3s --version", + "output": "k3s version v1.34.1+k3s1 (24fc436e) go version go1.24.6" + } }, "k3sctl": { "name": "k3sctl", @@ -73,11 +83,19 @@ "version": { "ok": true, "command": "ssh -V", - "output": "OpenSSH_10.0p2 Debian-7+deb13u2, OpenSSL 3.5.5 27 Jan 2026" + "output": "OpenSSH_10.0p2 Debian-7+deb13u4, OpenSSL 3.5.6 7 Apr 2026" } } }, "kubeconfig": [ + { + "source": "KUBECONFIG", + "path": "/var/lib/unidesk/code-queue/kubeconfig", + "exists": true, + "readable": true, + "type": "file", + "sizeBytes": 410 + }, { "source": "default", "path": "~/.kube/config", @@ -147,7 +165,7 @@ "exists": true, "readable": true, "type": "file", - "sizeBytes": 4208 + "sizeBytes": 5186 } ], "configured": false, @@ -156,36 +174,459 @@ }, "cluster": { "namespace": "hwlab-dev", - "attemptedExecutors": [], - "readable": false, - "executors": [] + "attemptedExecutors": [ + "kubectl", + "k3s-kubectl" + ], + "readable": true, + "executors": [ + { + "executor": "kubectl", + "ready": true, + "probes": { + "clientVersion": { + "ok": true, + "command": "kubectl version --client=true", + "exitCode": 0, + "stdout": "Client Version: v1.36.1\nKustomize Version: v5.8.1" + }, + "currentContext": { + "ok": true, + "command": "kubectl config current-context", + "exitCode": 0, + "stdout": "in-cluster" + }, + "namespace": { + "ok": true, + "command": "kubectl get namespace hwlab-dev -o json", + "exitCode": 0 + }, + "auth": { + "pods": { + "allowed": true, + "ok": true, + "command": "kubectl auth can-i get pods -n hwlab-dev", + "exitCode": 0, + "stdout": "yes" + }, + "services": { + "allowed": true, + "ok": true, + "command": "kubectl auth can-i get services -n hwlab-dev", + "exitCode": 0, + "stdout": "yes" + }, + "configmaps": { + "allowed": true, + "ok": true, + "command": "kubectl auth can-i get configmaps -n hwlab-dev", + "exitCode": 0, + "stdout": "yes" + } + }, + "pods": { + "ok": true, + "command": "kubectl -n hwlab-dev get pods -o json", + "exitCode": 0 + }, + "services": { + "ok": true, + "command": "kubectl -n hwlab-dev get services -o json", + "exitCode": 0 + }, + "configMaps": { + "ok": true, + "command": "kubectl -n hwlab-dev get configmaps -o json", + "exitCode": 0 + } + }, + "summaries": { + "pods": { + "count": 13, + "items": [ + { + "name": "hwlab-agent-mgr-75544c7747-5dzt9", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-agent-skills-849d9976f4-2nsmw", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-box-simu-55688cbcc7-pftxc", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-box-simu-55688cbcc7-sq5fx", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-cloud-api-f48dcdfb-9n6zh", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-cloud-web-cd9655b98-gxtmc", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-edge-proxy-567f978cdd-8fwc8", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-frpc-59f57d479c-wm5l2", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-gateway-simu-699fd486b-j9pk7", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-gateway-simu-699fd486b-phcgp", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-patch-panel-757f9f44d5-7np8r", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-router-5d9cbdf89b-p7r94", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + }, + { + "name": "hwlab-tunnel-client-65c7858c8-wjqsh", + "phase": "Running", + "readyContainers": 1, + "totalContainers": 1, + "restartCount": 0, + "nodeName": "d601" + } + ] + }, + "services": { + "count": 12, + "items": [ + { + "name": "hwlab-agent-mgr", + "type": "ClusterIP", + "clusterIP": "10.43.175.43", + "ports": [ + { + "name": "http", + "port": 7410, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-agent-skills", + "type": "ClusterIP", + "clusterIP": "10.43.218.243", + "ports": [ + { + "name": "http", + "port": 7430, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-box-simu", + "type": "ClusterIP", + "clusterIP": "10.43.192.161", + "ports": [ + { + "name": "http", + "port": 7201, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-cli", + "type": "ClusterIP", + "clusterIP": "10.43.94.68", + "ports": [ + { + "name": "http", + "port": 7501, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-cloud-api", + "type": "ClusterIP", + "clusterIP": "10.43.88.144", + "ports": [ + { + "name": "http", + "port": 6667, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-cloud-web", + "type": "ClusterIP", + "clusterIP": "10.43.112.75", + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-edge-proxy", + "type": "ClusterIP", + "clusterIP": "10.43.104.107", + "ports": [ + { + "name": "http", + "port": 6667, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-gateway", + "type": "ClusterIP", + "clusterIP": "10.43.70.176", + "ports": [ + { + "name": "http", + "port": 7001, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-gateway-simu", + "type": "ClusterIP", + "clusterIP": "10.43.70.14", + "ports": [ + { + "name": "http", + "port": 7101, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-patch-panel", + "type": "ClusterIP", + "clusterIP": "10.43.7.35", + "ports": [ + { + "name": "http", + "port": 7301, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-router", + "type": "ClusterIP", + "clusterIP": "10.43.6.240", + "ports": [ + { + "name": "http", + "port": 7401, + "targetPort": "http", + "protocol": "TCP" + } + ] + }, + { + "name": "hwlab-tunnel-client", + "type": "ClusterIP", + "clusterIP": "10.43.129.225", + "ports": [ + { + "name": "http", + "port": 7402, + "targetPort": "http", + "protocol": "TCP" + } + ] + } + ] + }, + "configMaps": { + "count": 3, + "items": [ + { + "name": "hwlab-dev-health-contract", + "keys": [ + "agent", + "cloud-api", + "cloud-api-db", + "cloud-web", + "edge-proxy", + "endpoint", + "patch-panel", + "router", + "runtime-substitute-policy", + "sim", + "tunnel-client" + ] + }, + { + "name": "hwlab-frpc-config", + "keys": [ + "frpc.toml" + ] + }, + { + "name": "kube-root-ca.crt", + "keys": [ + "ca.crt" + ] + } + ] + } + } + }, + { + "executor": "k3s-kubectl", + "ready": false, + "probes": { + "clientVersion": { + "ok": false, + "command": "k3s kubectl version --client=true", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl version --client=true error: unknown command \"kubectl\" for \"kubectl\"" + }, + "currentContext": { + "ok": false, + "command": "k3s kubectl config current-context", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl config current-context error: unknown command \"kubectl\" for \"kubectl\"" + }, + "namespace": { + "ok": false, + "command": "k3s kubectl get namespace hwlab-dev -o json", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl get namespace hwlab-dev -o json error: unknown command \"kubectl\" for \"kubectl\"" + }, + "auth": { + "pods": { + "allowed": false, + "ok": false, + "command": "k3s kubectl auth can-i get pods -n hwlab-dev", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl auth can-i get pods -n hwlab-dev error: unknown command \"kubectl\" for \"kubectl\"" + }, + "services": { + "allowed": false, + "ok": false, + "command": "k3s kubectl auth can-i get services -n hwlab-dev", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl auth can-i get services -n hwlab-dev error: unknown command \"kubectl\" for \"kubectl\"" + }, + "configmaps": { + "allowed": false, + "ok": false, + "command": "k3s kubectl auth can-i get configmaps -n hwlab-dev", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl auth can-i get configmaps -n hwlab-dev error: unknown command \"kubectl\" for \"kubectl\"" + } + }, + "pods": { + "ok": false, + "command": "k3s kubectl -n hwlab-dev get pods -o json", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl -n hwlab-dev get pods -o json error: unknown command \"kubectl\" for \"kubectl\"" + }, + "services": { + "ok": false, + "command": "k3s kubectl -n hwlab-dev get services -o json", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl -n hwlab-dev get services -o json error: unknown command \"kubectl\" for \"kubectl\"" + }, + "configMaps": { + "ok": false, + "command": "k3s kubectl -n hwlab-dev get configmaps -o json", + "exitCode": 1, + "stderr": "error: unknown command \"kubectl\" for \"kubectl\"", + "error": "Command failed: k3s kubectl -n hwlab-dev get configmaps -o json error: unknown command \"kubectl\" for \"kubectl\"" + } + }, + "summaries": null + } + ] }, - "blockers": [ - { - "status": "open", - "type": "environment_blocker", - "scope": "d601-k3s-client-binary", - "summary": "Neither kubectl nor k3s is installed in this runner PATH.", - "nextTask": "Install kubectl in the D601 Code Queue runner image, or mount an approved k3s kubectl client path for read-only hwlab-dev observation." - }, - { - "status": "open", - "type": "environment_blocker", - "scope": "d601-kubeconfig-path", - "summary": "No readable KUBECONFIG/default k3s kubeconfig path was found by metadata checks.", - "nextTask": "Mount a read-only kubeconfig for hwlab-dev, or document the approved k3s local kubeconfig path without exposing token material." - }, - { - "status": "open", - "type": "environment_blocker", - "scope": "d601-maintenance-ssh-bridge", - "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." - } - ], + "blockers": [], "runnerImageFollowUp": { - "needed": true, - "suggestedUniDeskIssue": "Code Queue runner image should include kubectl and a documented read-only hwlab-dev kubeconfig mount/permission path; keep Secret resources and token material inaccessible to reports." + "needed": false, + "suggestedUniDeskIssue": null }, "notes": "This report uses command availability checks, file metadata checks, kubectl/k3s kubectl read-only get probes, and auth can-i checks only. It does not print kubeconfig contents, token material, Secret resources, ConfigMap values, SSH config contents, or private keys." } diff --git a/reports/dev-gate/dev-m2-deploy-smoke-active.json b/reports/dev-gate/dev-m2-deploy-smoke-active.json index c06c3019..1ac5dad6 100644 --- a/reports/dev-gate/dev-m2-deploy-smoke-active.json +++ b/reports/dev-gate/dev-m2-deploy-smoke-active.json @@ -4,12 +4,20 @@ "reportVersion": "v1", "issue": "pikasTech/HWLAB#23", "taskId": "m2-dev-deploy-smoke", - "commitId": "54f927b02bc1", + "commitId": "8e89409dda5d", "acceptanceLevel": "dev_m2_deploy_smoke", "devOnly": true, "prodDisabled": true, + "reportLifecycle": { + "version": "v1", + "state": "active", + "activeEndpoint": "http://74.48.78.17:16667", + "activeBrowserEndpoint": "http://74.48.78.17:16666", + "deprecatedEndpoint": null, + "summary": "Active M2 read-only public endpoint smoke; route reachability is not M5 DEV-LIVE acceptance." + }, "status": "pass", - "generatedAt": "2026-05-22T04:53:00.375Z", + "generatedAt": "2026-05-22T07:18:45.192Z", "endpoint": "http://74.48.78.17:16667", "frontendEndpoint": "http://74.48.78.17:16666", "sourceContract": { @@ -76,7 +84,7 @@ "runtimeSmoke": { "mode": "live-read-only", "status": "pass", - "generatedAt": "2026-05-22T04:53:00.375Z", + "generatedAt": "2026-05-22T07:18:45.192Z", "apiEndpoint": "http://74.48.78.17:16667", "frontendEndpoint": "http://74.48.78.17:16666", "safety": { @@ -95,12 +103,12 @@ "ok": true, "status": 200, "statusText": "OK", - "durationMs": 939, + "durationMs": 3916, "contentType": "application/json; charset=utf-8", "headers": { "content-type": "application/json; charset=utf-8", "content-length": "661", - "date": "Fri, 22 May 2026 04:53:00 GMT" + "date": "Fri, 22 May 2026 07:18:43 GMT" }, "json": { "serviceId": "hwlab-edge-proxy", @@ -122,7 +130,7 @@ "digest": "unknown" }, "endpoint": "http://74.48.78.17:16667", - "observedAt": "2026-05-22T04:53:00.143Z", + "observedAt": "2026-05-22T07:18:43.527Z", "details": { "upstream": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667", "mode": "dev-edge-proxy" @@ -137,12 +145,12 @@ "ok": true, "status": 200, "statusText": "OK", - "durationMs": 936, + "durationMs": 3510, "contentType": "application/json; charset=utf-8", "headers": { "content-type": "application/json; charset=utf-8", "cache-control": "no-store", - "date": "Fri, 22 May 2026 04:53:00 GMT" + "date": "Fri, 22 May 2026 07:18:44 GMT" }, "json": { "serviceId": "hwlab-cloud-api", @@ -164,7 +172,7 @@ "digest": "unknown" }, "endpoint": "http://74.48.78.17:16667", - "observedAt": "2026-05-22T04:53:00.145Z", + "observedAt": "2026-05-22T07:18:44.622Z", "db": { "contractVersion": "v1", "environment": "dev", @@ -225,7 +233,7 @@ } }, "title": null, - "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:53:00.145Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"configReady\":" + "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-22T07:18:44.622Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"configReady\":" }, { "id": "frontend-root", @@ -233,12 +241,12 @@ "ok": true, "status": 200, "statusText": "OK", - "durationMs": 923, + "durationMs": 1027, "contentType": "text/html; charset=utf-8", "headers": { "content-type": "text/html; charset=utf-8", "content-length": "4230", - "date": "Fri, 22 May 2026 04:53:00 GMT" + "date": "Fri, 22 May 2026 07:18:42 GMT" }, "json": null, "title": "HWLAB DEV MVP Gate", @@ -252,13 +260,5 @@ "summary": "Legacy public :6667 observations are retained only as historical blockers and are not accepted as active green evidence." } }, - "notes": "M2 active report uses read-only GET probes only; PROD, service restarts, deployments, and script-driven apply flows were not touched.", - "reportLifecycle": { - "version": "v1", - "state": "active", - "activeEndpoint": "http://74.48.78.17:16667", - "activeBrowserEndpoint": "http://74.48.78.17:16666", - "deprecatedEndpoint": null, - "summary": "Current M2 DEV deploy smoke report; legacy public endpoints are deprecated and not active green evidence." - } + "notes": "M2 active report uses read-only GET probes only; PROD, service restarts, deployments, and script-driven apply flows were not touched." } diff --git a/reports/dev-gate/dev-m5-gate-aggregator-v2.json b/reports/dev-gate/dev-m5-gate-aggregator-v2.json index 8d021645..9af7f926 100644 --- a/reports/dev-gate/dev-m5-gate-aggregator-v2.json +++ b/reports/dev-gate/dev-m5-gate-aggregator-v2.json @@ -7,6 +7,8 @@ "supports": [ "pikasTech/HWLAB#7", "pikasTech/HWLAB#9", + "pikasTech/HWLAB#23", + "pikasTech/HWLAB#26", "pikasTech/HWLAB#31", "pikasTech/HWLAB#33", "pikasTech/HWLAB#34", @@ -15,14 +17,23 @@ "pikasTech/HWLAB#37", "pikasTech/HWLAB#38", "pikasTech/HWLAB#39", - "pikasTech/HWLAB#46" + "pikasTech/HWLAB#46", + "pikasTech/HWLAB#64" ], - "generatedAt": "2026-05-22T05:38:03.366Z", - "generatedFromCommit": "721bc37c084e", + "generatedAt": "2026-05-22T07:23:47.479Z", + "generatedFromCommit": "8e89409dda5d", "environment": "dev", "endpoint": "http://74.48.78.17:16667", "devOnly": true, "prodDisabled": true, + "reportLifecycle": { + "version": "v1", + "state": "active", + "activeEndpoint": "http://74.48.78.17:16667", + "activeBrowserEndpoint": "http://74.48.78.17:16666", + "deprecatedEndpoint": null, + "summary": "Current M5 evidence aggregator report; source, local, and dry-run evidence are not DEV-LIVE acceptance." + }, "safety": { "reportOnly": true, "noDeploy": true, @@ -38,20 +49,23 @@ "path": "reports/dev-gate/dev-preflight-report.json", "issue": "pikasTech/HWLAB#34", "taskId": "dev-gate-preflight", + "lifecycleState": "active", "status": "blocked", - "commitId": "82ad96c5c67c" + "commitId": "8e89409dda5d" }, "devDeploy": { "path": "reports/dev-gate/dev-deploy-report.json", "issue": "pikasTech/HWLAB#33", "taskId": "dev-deploy-apply", - "status": "blocked", - "commitId": "7e29522b65c8" + "lifecycleState": "active", + "status": "pass", + "commitId": "7e29522" }, "devArtifacts": { "path": "reports/dev-gate/dev-artifacts.json", "issue": "pikasTech/HWLAB#35", "taskId": "dev-artifact-publish", + "lifecycleState": "active", "status": "published", "commitId": "7e29522" }, @@ -59,13 +73,23 @@ "path": "reports/dev-gate/dev-edge-health.json", "issue": "pikasTech/HWLAB#36", "taskId": "dev-edge-health", + "lifecycleState": "active", "status": "blocked", "commitId": "86d769525caf" }, + "devM2Smoke": { + "path": "reports/dev-gate/dev-m2-deploy-smoke-active.json", + "issue": "pikasTech/HWLAB#23", + "taskId": "m2-dev-deploy-smoke", + "lifecycleState": "active", + "status": "pass", + "commitId": "8e89409dda5d" + }, "devM3Hardware": { "path": "reports/dev-gate/dev-m3-hardware-loop.json", "issue": "pikasTech/HWLAB#38", "taskId": "dev-m3-hardware-loop", + "lifecycleState": "active", "status": "blocked", "commitId": "86d769525caf" }, @@ -73,6 +97,7 @@ "path": "reports/dev-gate/dev-m4-agent-loop.json", "issue": "pikasTech/HWLAB#37", "taskId": "dev-m4-agent-loop", + "lifecycleState": "active", "status": "blocked", "commitId": "a1c3cb5" }, @@ -80,6 +105,7 @@ "path": "reports/dev-gate/dev-mvp-gate-report.json", "issue": "pikasTech/HWLAB#39", "taskId": "dev-mvp-gate-report", + "lifecycleState": "active", "status": "blocked", "commitId": "86d769525caf" }, @@ -87,14 +113,15 @@ "path": "reports/d601-k3s-readonly-observability.json", "issue": "pikasTech/HWLAB#46", "taskId": "d601-k3s-readonly-observability", - "status": "blocked", + "lifecycleState": "active", + "status": "ready", "commitId": "unknown" } }, "overall": { "status": "blocked", "green": false, - "reason": "SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is still blocked by artifact, observability, DB, and loop evidence gaps." + "reason": "EDGE/ROUTE DEV-LIVE evidence exists on :16666/:16667, but M5 remains blocked by artifact source drift, DB live degradation, missing M3 trusted loop operation evidence, and blocked M4 agent-loop preflight." }, "dod": { "status": "blocked", @@ -114,27 +141,39 @@ }, { "id": "artifact-publish-digests", - "status": "pass", - "evidenceLevel": "DEV-LIVE", - "summary": "artifactState=published, ciPublished=true, registryVerified=true, sha256=13, not_published=0" + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "artifactState=published, ciPublished=true, registryVerified=true, sha256=13, not_published=0, targetCovered=false" }, { "id": "d601-k3s-observability", - "status": "blocked", - "evidenceLevel": "BLOCKED", - "summary": "D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev." + "status": "pass", + "evidenceLevel": "DEV-LIVE", + "summary": "D601 hwlab-dev cluster was readable." }, { "id": "dev-edge-frp-16667", - "status": "blocked", - "evidenceLevel": "BLOCKED", - "summary": "Committed edge report proves read-only public HTTP on :16667 /health and /health/live; old preflight network probe blockers are stale." + "status": "pass", + "evidenceLevel": "DEV-LIVE", + "summary": "Committed edge report proves read-only public HTTP on :16667 /health and /health/live; this is route evidence, not DB/M3/M4/M5 acceptance." }, { "id": "cloud-api-db-ready", "status": "blocked", "evidenceLevel": "BLOCKED", - "summary": "Manifest-level DB env exists, but live DB health readiness is still blocked/missing." + "summary": "cloud-api DB status=degraded; ready=false; connected=false; liveDbEvidence=false." + }, + { + "id": "m3-hardware-trusted-loop", + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "M3 trusted loop is blocked until res_boxsimu_1:DO1 -> patch-panel -> res_boxsimu_2:DI1 is proven with operation/trace/audit/evidence." + }, + { + "id": "m4-agent-loop-live", + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "M4 agent loop live path is blocked before accepted agent scheduling/evidence closure." }, { "id": "m5-mvp-dev-live", @@ -144,6 +183,68 @@ } ] }, + "currentDevLayering": { + "edgeRoute": { + "label": "EDGE/ROUTE live", + "status": "pass", + "evidenceLevel": "DEV-LIVE", + "summary": "16666 browser, 16667 /health, and 16667 /health/live returned accepted HWLAB DEV responses in the active M2 read-only smoke.", + "evidence": [ + "http://74.48.78.17:16667/health -> HTTP 200 identity=hwlab-edge-proxy status=ok", + "http://74.48.78.17:16667/health/live -> HTTP 200 identity=hwlab-cloud-api status=degraded", + "http://74.48.78.17:16666/ -> HTTP 200 identity=HWLAB DEV MVP Gate status=ok" + ], + "nextRequired": "Keep this separated from DB readiness, M3/M4 loop evidence, and M5 acceptance." + }, + "dbLive": { + "label": "DB live/degraded", + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "cloud-api DB status=degraded; configReady=true; ready=false; connected=false; liveDbEvidence=false.", + "evidence": [ + "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-m4-agent-loop active report -> blocked, classification=DB live, summary=cloud-api /health/live reports DB degraded; connected=false; ready=false" + ], + "nextRequired": "Provide live DB connection evidence through redacted health output; route reachability alone is insufficient." + }, + "m3HardwareTrustedLoop": { + "label": "M3 hardware trusted loop", + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "No live DEV operation has run yet. Blocker: patch-panel active DO1 -> DI1 connection missing.", + "evidence": [ + "operationId=not_observed", + "traceId=not_observed", + "auditId=not_observed", + "evidenceId=not_observed" + ], + "nextRequired": "Only a real DEV res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1 observation with operation/trace/audit/evidence can clear M3." + }, + "m4AgentLoop": { + "label": "M4 agent loop", + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "Blocked at DB live readiness before scheduling a DEV agent task.", + "evidence": [ + "health:hwlab-edge-proxy:dev:ok", + "live:hwlab-cloud-api:degraded:db-blocked" + ], + "nextRequired": "Do not schedule or claim the agent loop as live until DB live and required runtime/evidence preconditions pass." + }, + "artifactDesiredStateSource": { + "label": "artifact/desired-state source", + "status": "blocked", + "evidenceLevel": "BLOCKED", + "summary": "artifact targetCovered=false; artifactSource=7e29522b65c8; target=8e89409dda5d; desiredApplyMode=dry-run; mutationAttempted=false.", + "evidence": [ + "artifactState=published", + "sourceStates=13 source-present, 0 intentionally-disabled", + "desiredState=ready dry-run-only" + ], + "nextRequired": "Refresh artifact/source coverage for current origin/main and keep desired-state apply separate from read-only route proof." + } + }, "milestones": [ { "id": "M0", @@ -167,9 +268,9 @@ "id": "M2", "status": "blocked", "highestVisibleLevel": "DEV-LIVE", - "liveEvidence": "missing_or_blocked", - "evidenceCount": 5, - "blockerCount": 9, + "liveEvidence": "pass", + "evidenceCount": 6, + "blockerCount": 5, "summary": "deploy/runtime readiness is blocked before live DEV; highest visible level is DEV-LIVE; status is blocked." }, { @@ -178,7 +279,7 @@ "highestVisibleLevel": "LOCAL", "liveEvidence": "missing_or_blocked", "evidenceCount": 3, - "blockerCount": 4, + "blockerCount": 2, "summary": "hardware loop has source/local shape but no live operation; highest visible level is LOCAL; status is blocked." }, { @@ -187,7 +288,7 @@ "highestVisibleLevel": "LOCAL", "liveEvidence": "missing_or_blocked", "evidenceCount": 3, - "blockerCount": 1, + "blockerCount": 2, "summary": "agent loop has local smoke but live preflight is blocked; highest visible level is LOCAL; status is blocked." }, { @@ -196,7 +297,7 @@ "highestVisibleLevel": "DRY-RUN", "liveEvidence": "missing_or_blocked", "evidenceCount": 2, - "blockerCount": 10, + "blockerCount": 9, "summary": "dry-run is green but live MVP gate is blocked; highest visible level is DRY-RUN; status is blocked." } ], @@ -207,6 +308,7 @@ "level": "SOURCE", "status": "pass", "category": "contract", + "lifecycleState": "active", "sources": [ "docs/m0-contract-audit.md", "protocol/README.md", @@ -227,6 +329,7 @@ "level": "LOCAL", "status": "pass", "category": "local-smoke", + "lifecycleState": "active", "sources": [ "docs/m1-local-smoke.md", "fixtures/mvp/runtime.json", @@ -242,7 +345,8 @@ "issue": "pikasTech/HWLAB#34", "taskId": "dev-gate-preflight", "reportPath": "reports/dev-gate/dev-preflight-report.json", - "commitId": "82ad96c5c67c", + "commitId": "8e89409dda5d", + "lifecycleState": "active", "level": "SOURCE", "status": "pass", "category": "deploy-manifest", @@ -267,9 +371,10 @@ "issue": "pikasTech/HWLAB#33", "taskId": "dev-deploy-apply", "reportPath": "reports/dev-gate/dev-deploy-report.json", - "commitId": "7e29522b65c8", + "commitId": "7e29522", + "lifecycleState": "active", "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", @@ -281,9 +386,10 @@ "namespace: hwlab-dev", "workloads planned: 13", "kubectl executor: /usr/local/bin/kubectl", - "live health: pass" + "live health: pass", + "template job replacements: 2" ], - "summary": "DEV apply is blocked before mutation." + "summary": "DEV dry-run preflight passed." }, { "milestone": "M2", @@ -291,6 +397,7 @@ "taskId": "dev-artifact-publish", "reportPath": "reports/dev-gate/dev-artifacts.json", "commitId": "7e29522", + "lifecycleState": "active", "level": "DRY-RUN", "status": "published", "category": "artifact-publish", @@ -312,12 +419,35 @@ ], "summary": "Artifact publish preflight exists but is blocked before any real image publish." }, + { + "milestone": "M2", + "issue": "pikasTech/HWLAB#23", + "taskId": "m2-dev-deploy-smoke", + "reportPath": "reports/dev-gate/dev-m2-deploy-smoke-active.json", + "commitId": "8e89409dda5d", + "lifecycleState": "active", + "level": "DEV-LIVE", + "status": "pass", + "category": "public-entrypoints-read-only", + "commands": [ + "curl -fsS --max-time 10 http://74.48.78.17:16667/health", + "curl -fsS --max-time 10 http://74.48.78.17:16667/health/live", + "curl -fsS --max-time 10 http://74.48.78.17:16666/" + ], + "evidence": [ + "http://74.48.78.17:16667/health -> HTTP 200 identity=hwlab-edge-proxy status=ok", + "http://74.48.78.17:16667/health/live -> HTTP 200 identity=hwlab-cloud-api status=degraded", + "http://74.48.78.17:16666/ -> HTTP 200 identity=HWLAB DEV MVP Gate status=ok" + ], + "summary": "Read-only probes prove the frozen public DEV entrypoints on :16666/:16667 are reachable; this is EDGE/ROUTE evidence only." + }, { "milestone": "M2", "issue": "pikasTech/HWLAB#36", "taskId": "dev-edge-health", "reportPath": "reports/dev-gate/dev-edge-health.json", "commitId": "86d769525caf", + "lifecycleState": "active", "level": "DEV-LIVE", "status": "blocker", "category": "edge-frp-contract", @@ -341,8 +471,9 @@ "taskId": "d601-k3s-readonly-observability", "reportPath": "reports/d601-k3s-readonly-observability.json", "commitId": "unknown", + "lifecycleState": "active", "level": "BLOCKED", - "status": "blocked", + "status": "ready", "category": "d601-observability", "commands": [ "node --check scripts/d601-k3s-readonly-observability.mjs", @@ -350,9 +481,9 @@ "node scripts/d601-k3s-readonly-observability.mjs" ], "evidence": [ - "kubectl=missing", - "k3s=missing", - "clusterReadable=no" + "kubectl=available", + "k3s=available", + "clusterReadable=yes" ], "summary": "D601 k3s observability is blocked; cluster state has not been read." }, @@ -362,6 +493,7 @@ "taskId": "dev-m3-hardware-loop", "reportPath": "reports/dev-gate/dev-m3-hardware-loop.json", "commitId": "86d769525caf", + "lifecycleState": "active", "level": "SOURCE", "status": "manifest-ready", "category": "hardware-loop-cardinality", @@ -379,6 +511,7 @@ "taskId": "dev-mvp-gate-report", "reportPath": "reports/dev-gate/dev-mvp-gate-report.json", "commitId": "86d769525caf", + "lifecycleState": "active", "level": "LOCAL", "status": "blocked", "category": "hardware-loop-local", @@ -399,6 +532,7 @@ "taskId": "dev-m3-hardware-loop", "reportPath": "reports/dev-gate/dev-m3-hardware-loop.json", "commitId": "86d769525caf", + "lifecycleState": "active", "level": "BLOCKED", "status": "not_run", "category": "hardware-loop-live", @@ -411,7 +545,7 @@ "auditId=not_observed", "evidenceId=not_observed" ], - "summary": "No live DEV operation has run yet." + "summary": "No live DEV operation has run yet. Blocker: patch-panel active DO1 -> DI1 connection missing." }, { "milestone": "M4", @@ -419,6 +553,7 @@ "taskId": "dev-m4-agent-loop", "reportPath": "reports/dev-gate/dev-m4-agent-loop.json", "commitId": "a1c3cb5", + "lifecycleState": "active", "level": "LOCAL", "status": "pass", "category": "agent-loop-local", @@ -437,6 +572,7 @@ "taskId": "dev-m4-agent-loop", "reportPath": "reports/dev-gate/dev-m4-agent-loop.json", "commitId": "a1c3cb5", + "lifecycleState": "active", "level": "DRY-RUN", "status": "not_run", "category": "agent-loop-dry-run", @@ -454,6 +590,7 @@ "taskId": "dev-m4-agent-loop", "reportPath": "reports/dev-gate/dev-m4-agent-loop.json", "commitId": "a1c3cb5", + "lifecycleState": "active", "level": "BLOCKED", "status": "blocked", "category": "agent-loop-live-preflight", @@ -472,6 +609,7 @@ "taskId": "dev-mvp-gate-report", "reportPath": "reports/dev-gate/dev-mvp-gate-report.json", "commitId": "86d769525caf", + "lifecycleState": "active", "level": "DRY-RUN", "status": "pass", "category": "mvp-e2e-dry-run", @@ -493,6 +631,7 @@ "taskId": "dev-mvp-gate-report", "reportPath": "reports/dev-gate/dev-mvp-gate-report.json", "commitId": "86d769525caf", + "lifecycleState": "active", "level": "BLOCKED", "status": "blocked", "category": "mvp-e2e-live", @@ -519,6 +658,7 @@ { "milestone": "M0", "issue": "pikasTech/HWLAB#31", + "lifecycleState": "active", "status": "pass", "category": "contract", "summary": "Frozen service IDs, JSON-RPC, audit, topology, evidence, and DEV-only deploy contracts are source-ready." @@ -527,6 +667,7 @@ "milestone": "M2", "issue": "pikasTech/HWLAB#34", "taskId": "dev-gate-preflight", + "lifecycleState": "active", "status": "pass", "category": "deploy-manifest", "reportPath": "reports/dev-gate/dev-preflight-report.json", @@ -536,6 +677,7 @@ "milestone": "M3", "issue": "pikasTech/HWLAB#38", "taskId": "dev-m3-hardware-loop", + "lifecycleState": "active", "status": "manifest-ready", "category": "hardware-loop-cardinality", "reportPath": "reports/dev-gate/dev-m3-hardware-loop.json", @@ -546,6 +688,7 @@ { "milestone": "M1", "issue": "pikasTech/HWLAB#7", + "lifecycleState": "active", "status": "pass", "category": "local-smoke", "summary": "Local skeleton smoke covers cloud API, simulators, patch-panel routing, CLI dry-run boundary, and no DEV/PROD mutation." @@ -554,6 +697,7 @@ "milestone": "M3", "issue": "pikasTech/HWLAB#39", "taskId": "dev-mvp-gate-report", + "lifecycleState": "active", "status": "blocked", "category": "hardware-loop-local", "reportPath": "reports/dev-gate/dev-mvp-gate-report.json", @@ -563,6 +707,7 @@ "milestone": "M4", "issue": "pikasTech/HWLAB#37", "taskId": "dev-m4-agent-loop", + "lifecycleState": "active", "status": "pass", "category": "agent-loop-local", "reportPath": "reports/dev-gate/dev-m4-agent-loop.json", @@ -574,15 +719,17 @@ "milestone": "M2", "issue": "pikasTech/HWLAB#33", "taskId": "dev-deploy-apply", - "status": "blocked", + "lifecycleState": "active", + "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", + "lifecycleState": "active", "status": "published", "category": "artifact-publish", "reportPath": "reports/dev-gate/dev-artifacts.json", @@ -592,6 +739,7 @@ "milestone": "M4", "issue": "pikasTech/HWLAB#37", "taskId": "dev-m4-agent-loop", + "lifecycleState": "active", "status": "not_run", "category": "agent-loop-dry-run", "reportPath": "reports/dev-gate/dev-m4-agent-loop.json", @@ -601,6 +749,7 @@ "milestone": "M5", "issue": "pikasTech/HWLAB#39", "taskId": "dev-mvp-gate-report", + "lifecycleState": "active", "status": "pass", "category": "mvp-e2e-dry-run", "reportPath": "reports/dev-gate/dev-mvp-gate-report.json", @@ -608,10 +757,21 @@ } ], "DEV-LIVE": [ + { + "milestone": "M2", + "issue": "pikasTech/HWLAB#23", + "taskId": "m2-dev-deploy-smoke", + "lifecycleState": "active", + "status": "pass", + "category": "public-entrypoints-read-only", + "reportPath": "reports/dev-gate/dev-m2-deploy-smoke-active.json", + "summary": "Read-only probes prove the frozen public DEV entrypoints on :16666/:16667 are reachable; this is EDGE/ROUTE evidence only." + }, { "milestone": "M2", "issue": "pikasTech/HWLAB#36", "taskId": "dev-edge-health", + "lifecycleState": "active", "status": "blocker", "category": "edge-frp-contract", "reportPath": "reports/dev-gate/dev-edge-health.json", @@ -623,7 +783,8 @@ "milestone": "M2", "issue": "pikasTech/HWLAB#46", "taskId": "d601-k3s-readonly-observability", - "status": "blocked", + "lifecycleState": "active", + "status": "ready", "category": "d601-observability", "reportPath": "reports/d601-k3s-readonly-observability.json", "summary": "D601 k3s observability is blocked; cluster state has not been read." @@ -632,15 +793,17 @@ "milestone": "M3", "issue": "pikasTech/HWLAB#38", "taskId": "dev-m3-hardware-loop", + "lifecycleState": "active", "status": "not_run", "category": "hardware-loop-live", "reportPath": "reports/dev-gate/dev-m3-hardware-loop.json", - "summary": "No live DEV operation has run yet." + "summary": "No live DEV operation has run yet. Blocker: patch-panel active DO1 -> DI1 connection missing." }, { "milestone": "M4", "issue": "pikasTech/HWLAB#37", "taskId": "dev-m4-agent-loop", + "lifecycleState": "active", "status": "blocked", "category": "agent-loop-live-preflight", "reportPath": "reports/dev-gate/dev-m4-agent-loop.json", @@ -650,6 +813,7 @@ "milestone": "M5", "issue": "pikasTech/HWLAB#39", "taskId": "dev-mvp-gate-report", + "lifecycleState": "active", "status": "blocked", "category": "mvp-e2e-live", "reportPath": "reports/dev-gate/dev-mvp-gate-report.json", @@ -662,7 +826,7 @@ "scope": "artifact-source-commit", "sourceIssue": "pikasTech/HWLAB#34", "source": "reports/dev-gate/dev-preflight-report.json", - "summary": "source commit origin/main 82ad96c is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs.", + "summary": "source commit origin/main 8e89409 is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs.", "nextTask": "Refresh without fake digests using `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked`, or after a successful publish run `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json`." }, { @@ -672,39 +836,9 @@ "scope": "dev-artifact-publish", "sourceIssue": "pikasTech/HWLAB#34", "source": "reports/dev-gate/dev-preflight-report.json", - "summary": "reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 82ad96c; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled.", + "summary": "reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 8e89409; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled.", "nextTask": "Complete DEV artifact publishing for every enabled required HWLAB service at the artifact source commit, or prove the target commit has no artifact build input changes; keep disabled services marked not_published with reasons." }, - { - "priority": "P1", - "order": 4, - "type": "environment_blocker", - "scope": "d601-k3s-client-binary", - "sourceIssue": "pikasTech/HWLAB#46", - "source": "reports/d601-k3s-readonly-observability.json", - "summary": "Neither kubectl nor k3s is installed in this runner PATH.", - "nextTask": "Install kubectl in the D601 Code Queue runner image, or mount an approved k3s kubectl client path for read-only hwlab-dev observation." - }, - { - "priority": "P1", - "order": 4, - "type": "environment_blocker", - "scope": "d601-kubeconfig-path", - "sourceIssue": "pikasTech/HWLAB#46", - "source": "reports/d601-k3s-readonly-observability.json", - "summary": "No readable KUBECONFIG/default k3s kubeconfig path was found by metadata checks.", - "nextTask": "Mount a read-only kubeconfig for hwlab-dev, or document the approved k3s local kubeconfig path without exposing token material." - }, - { - "priority": "P1", - "order": 4, - "type": "environment_blocker", - "scope": "d601-maintenance-ssh-bridge", - "sourceIssue": "pikasTech/HWLAB#46", - "source": "reports/d601-k3s-readonly-observability.json", - "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": 5, @@ -735,27 +869,8 @@ "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": "environment_blocker", - "scope": "kubectl-dry-run", - "sourceIssue": "pikasTech/HWLAB#33", - "source": "reports/dev-gate/dev-deploy-report.json", - "summary": "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"},\\\"name\\\":\\\"hwlab-agent-worker-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_AGENT_SESSION_MODE\\\",\\\"value\\\":\\\"session-scoped\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\\\",\\\"name\\\":\\\"hwlab-agent-worker\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-agent-worker\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-agent-worker-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-agent-worker-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"batch.kubernetes.io/job-name\":\"hwlab-agent-worker-template\",\"controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\",\"job-name\":\"hwlab-agent-worker-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-agent-worker\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_AGENT_SESSION_MODE\",\"Value\":\"session-scoped\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/activation\\\":\\\"manual\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"},\\\"name\\\":\\\"hwlab-cli-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_CLI_ENDPOINT\\\",\\\"value\\\":\\\"http://74.48.78.17:16667\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\\\",\\\"name\\\":\\\"hwlab-cli\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-cli\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-cli-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-cli-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"batch.kubernetes.io/job-name\":\"hwlab-cli-template\",\"controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\",\"job-name\":\"hwlab-cli-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-cli\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_CLI_ENDPOINT\",\"Value\":\"http://74.48.78.17:16667\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable", - "nextTask": "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"},\\\"name\\\":\\\"hwlab-agent-worker-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_AGENT_SESSION_MODE\\\",\\\"value\\\":\\\"session-scoped\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\\\",\\\"name\\\":\\\"hwlab-agent-worker\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-agent-worker\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-agent-worker-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-agent-worker-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"batch.kubernetes.io/job-name\":\"hwlab-agent-worker-template\",\"controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\",\"job-name\":\"hwlab-agent-worker-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-agent-worker\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_AGENT_SESSION_MODE\",\"Value\":\"session-scoped\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/activation\\\":\\\"manual\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"},\\\"name\\\":\\\"hwlab-cli-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_CLI_ENDPOINT\\\",\\\"value\\\":\\\"http://74.48.78.17:16667\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\\\",\\\"name\\\":\\\"hwlab-cli\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-cli\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-cli-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-cli-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"batch.kubernetes.io/job-name\":\"hwlab-cli-template\",\"controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\",\"job-name\":\"hwlab-cli-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-cli\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_CLI_ENDPOINT\",\"Value\":\"http://74.48.78.17:16667\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable" - }, - { - "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": "patch-panel active DO1 -> DI1 connection missing" - }, - { - "priority": "P3", - "order": 99, + "priority": "P1", + "order": 5, "type": "runtime_blocker", "scope": "db-live", "sourceIssue": "pikasTech/HWLAB#37", @@ -763,8 +878,8 @@ "summary": "cloud-api /health/live reports DB degraded; connected=false; ready=false." }, { - "priority": "P3", - "order": 99, + "priority": "P1", + "order": 5, "type": "runtime_blocker", "scope": "db-live", "sourceIssue": "pikasTech/HWLAB#39", @@ -772,8 +887,17 @@ "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, + "priority": "P0", + "order": 6, + "type": "runtime_blocker", + "scope": "m3-hardware-loop-runtime", + "sourceIssue": "pikasTech/HWLAB#38", + "source": "reports/dev-gate/dev-m3-hardware-loop.json", + "summary": "patch-panel active DO1 -> DI1 connection missing" + }, + { + "priority": "P0", + "order": 6, "type": "runtime_blocker", "scope": "m3-hardware-loop-runtime", "sourceIssue": "pikasTech/HWLAB#39", @@ -791,7 +915,7 @@ "status": "open", "source": "reports/dev-gate/dev-preflight-report.json", "sourceIssue": "pikasTech/HWLAB#34", - "summary": "source commit origin/main 82ad96c is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs.", + "summary": "source commit origin/main 8e89409 is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs.", "nextTask": "Refresh without fake digests using `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked`, or after a successful publish run `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json`.", "unblockOrder": 3, "unblocks": [ @@ -809,7 +933,7 @@ "status": "open", "source": "reports/dev-gate/dev-preflight-report.json", "sourceIssue": "pikasTech/HWLAB#34", - "summary": "reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 82ad96c; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled.", + "summary": "reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 8e89409; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled.", "nextTask": "Complete DEV artifact publishing for every enabled required HWLAB service at the artifact source commit, or prove the target commit has no artifact build input changes; keep disabled services marked not_published with reasons.", "unblockOrder": 3, "unblocks": [ @@ -819,63 +943,6 @@ ], "rationale": "The gate cannot promote deploy or runtime observations without immutable image provenance and digests." }, - { - "id": "d601-k3s-readonly-observability:d601-k3s-client-binary", - "priority": "P1", - "type": "environment_blocker", - "scope": "d601-k3s-client-binary", - "status": "open", - "source": "reports/d601-k3s-readonly-observability.json", - "sourceIssue": "pikasTech/HWLAB#46", - "summary": "Neither kubectl nor k3s is installed in this runner PATH.", - "nextTask": "Install kubectl in the D601 Code Queue runner image, or mount an approved k3s kubectl client path for read-only hwlab-dev observation.", - "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": "d601-k3s-readonly-observability:d601-kubeconfig-path", - "priority": "P1", - "type": "environment_blocker", - "scope": "d601-kubeconfig-path", - "status": "open", - "source": "reports/d601-k3s-readonly-observability.json", - "sourceIssue": "pikasTech/HWLAB#46", - "summary": "No readable KUBECONFIG/default k3s kubeconfig path was found by metadata checks.", - "nextTask": "Mount a read-only kubeconfig for hwlab-dev, or document the approved k3s local kubeconfig path without exposing token material.", - "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": "d601-k3s-readonly-observability:d601-maintenance-ssh-bridge", - "priority": "P1", - "type": "environment_blocker", - "scope": "d601-maintenance-ssh-bridge", - "status": "open", - "source": "reports/d601-k3s-readonly-observability.json", - "sourceIssue": "pikasTech/HWLAB#46", - "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.", - "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-edge-health:cloud-api-db", "priority": "P1", @@ -929,84 +996,71 @@ ], "rationale": "Cloud API DB env and health readiness block runtime health and MVP evidence even if ingress starts responding." }, - { - "id": "dev-deploy-apply:kubectl-dry-run", - "priority": "P2", - "type": "environment_blocker", - "scope": "kubectl-dry-run", - "status": "open", - "source": "reports/dev-gate/dev-deploy-report.json", - "sourceIssue": "pikasTech/HWLAB#33", - "summary": "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"},\\\"name\\\":\\\"hwlab-agent-worker-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_AGENT_SESSION_MODE\\\",\\\"value\\\":\\\"session-scoped\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\\\",\\\"name\\\":\\\"hwlab-agent-worker\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-agent-worker\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-agent-worker-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-agent-worker-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"batch.kubernetes.io/job-name\":\"hwlab-agent-worker-template\",\"controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\",\"job-name\":\"hwlab-agent-worker-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-agent-worker\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_AGENT_SESSION_MODE\",\"Value\":\"session-scoped\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/activation\\\":\\\"manual\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"},\\\"name\\\":\\\"hwlab-cli-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_CLI_ENDPOINT\\\",\\\"value\\\":\\\"http://74.48.78.17:16667\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\\\",\\\"name\\\":\\\"hwlab-cli\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-cli\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-cli-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-cli-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"batch.kubernetes.io/job-name\":\"hwlab-cli-template\",\"controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\",\"job-name\":\"hwlab-cli-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-cli\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_CLI_ENDPOINT\",\"Value\":\"http://74.48.78.17:16667\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable", - "nextTask": "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"},\\\"name\\\":\\\"hwlab-agent-worker-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_AGENT_SESSION_MODE\\\",\\\"value\\\":\\\"session-scoped\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\\\",\\\"name\\\":\\\"hwlab-agent-worker\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-agent-worker\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-agent-worker-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-agent-worker-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"batch.kubernetes.io/job-name\":\"hwlab-agent-worker-template\",\"controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\",\"job-name\":\"hwlab-agent-worker-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-agent-worker\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_AGENT_SESSION_MODE\",\"Value\":\"session-scoped\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/activation\\\":\\\"manual\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"},\\\"name\\\":\\\"hwlab-cli-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_CLI_ENDPOINT\\\",\\\"value\\\":\\\"http://74.48.78.17:16667\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\\\",\\\"name\\\":\\\"hwlab-cli\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-cli\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-cli-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-cli-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"batch.kubernetes.io/job-name\":\"hwlab-cli-template\",\"controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\",\"job-name\":\"hwlab-cli-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-cli\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_CLI_ENDPOINT\",\"Value\":\"http://74.48.78.17:16667\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable", - "unblockOrder": 6, - "unblocks": [ - "pikasTech/HWLAB#36", - "pikasTech/HWLAB#38", - "pikasTech/HWLAB#37", - "pikasTech/HWLAB#39" - ], - "rationale": "The :16667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected." - }, - { - "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": "patch-panel active DO1 -> DI1 connection missing", - "unblockOrder": 99, - "unblocks": [ - "pikasTech/HWLAB#39" - ], - "rationale": "Residual blocker that must be classified before claiming a green DEV gate." - }, { "id": "dev-m4-agent-loop:db-live", - "priority": "P3", + "priority": "P1", "type": "runtime_blocker", "scope": "db-live", "status": "open", "source": "reports/dev-gate/dev-m4-agent-loop.json", "sourceIssue": "pikasTech/HWLAB#37", "summary": "cloud-api /health/live reports DB degraded; connected=false; ready=false.", - "unblockOrder": 99, + "unblockOrder": 5, "unblocks": [ + "pikasTech/HWLAB#37", "pikasTech/HWLAB#39" ], - "rationale": "Residual blocker that must be classified before claiming a green DEV gate." + "rationale": "M4 and M5 cannot claim live agent or MVP evidence until cloud-api /health/live proves DB readiness with redacted live evidence." }, { "id": "dev-mvp-gate-report:db-live", - "priority": "P3", + "priority": "P1", "type": "runtime_blocker", "scope": "db-live", "status": "open", "source": "reports/dev-gate/dev-mvp-gate-report.json", "sourceIssue": "pikasTech/HWLAB#39", "summary": "cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established.", - "unblockOrder": 99, + "unblockOrder": 5, "unblocks": [ + "pikasTech/HWLAB#37", "pikasTech/HWLAB#39" ], - "rationale": "Residual blocker that must be classified before claiming a green DEV gate." + "rationale": "M4 and M5 cannot claim live agent or MVP evidence until cloud-api /health/live proves DB readiness with redacted live evidence." + }, + { + "id": "dev-m3-hardware-loop:m3-hardware-loop-runtime", + "priority": "P0", + "type": "runtime_blocker", + "scope": "m3-hardware-loop-runtime", + "status": "open", + "source": "reports/dev-gate/dev-m3-hardware-loop.json", + "sourceIssue": "pikasTech/HWLAB#38", + "summary": "patch-panel active DO1 -> DI1 connection missing", + "unblockOrder": 6, + "unblocks": [ + "pikasTech/HWLAB#38", + "pikasTech/HWLAB#39", + "pikasTech/HWLAB#64" + ], + "rationale": "M3 remains blocked until the real DEV hardware trusted loop proves DO1 -> patch-panel -> DI1 with operation, trace, audit, and evidence identifiers." }, { "id": "dev-mvp-gate-report:m3-hardware-loop-runtime", - "priority": "P3", + "priority": "P0", "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, + "unblockOrder": 6, "unblocks": [ - "pikasTech/HWLAB#39" + "pikasTech/HWLAB#38", + "pikasTech/HWLAB#39", + "pikasTech/HWLAB#64" ], - "rationale": "Residual blocker that must be classified before claiming a green DEV gate." + "rationale": "M3 remains blocked until the real DEV hardware trusted loop proves DO1 -> patch-panel -> DI1 with operation, trace, audit, and evidence identifiers." } ], "nextSteps": [ @@ -1030,36 +1084,18 @@ }, { "order": 2, - "blockerOrder": 4, - "priority": "P1", - "scopes": [ - "d601-k3s-client-binary", - "d601-kubeconfig-path", - "d601-maintenance-ssh-bridge" - ], - "sourceIssues": [ - "pikasTech/HWLAB#33", - "pikasTech/HWLAB#34", - "pikasTech/HWLAB#36", - "pikasTech/HWLAB#38", - "pikasTech/HWLAB#46" - ], - "rationale": "D601 hwlab-dev cluster state must be observable read-only before any live apply or M3/M4/M5 acceptance.", - "action": "Install kubectl in the D601 Code Queue runner image, or mount an approved k3s kubectl client path for read-only hwlab-dev observation.", - "evidenceRequired": "Read-only kubectl/k3s report proving pods/services/configmaps are observable in hwlab-dev without reading Secrets." - }, - { - "order": 3, "blockerOrder": 5, "priority": "P1", "scopes": [ "cloud-api-db", - "cloud-api-db-health-gate" + "cloud-api-db-health-gate", + "db-live" ], "sourceIssues": [ "pikasTech/HWLAB#33", "pikasTech/HWLAB#34", "pikasTech/HWLAB#36", + "pikasTech/HWLAB#37", "pikasTech/HWLAB#39" ], "rationale": "Cloud API DB env and health readiness block runtime health and MVP evidence even if ingress starts responding.", @@ -1067,39 +1103,20 @@ "evidenceRequired": "Cloud API health/live output showing DB env ready and redacted secret references, without secret material." }, { - "order": 4, + "order": 3, "blockerOrder": 6, - "priority": "P2", + "priority": "P0", "scopes": [ - "kubectl-dry-run" + "m3-hardware-loop-runtime" ], "sourceIssues": [ - "pikasTech/HWLAB#33", - "pikasTech/HWLAB#36", - "pikasTech/HWLAB#37", "pikasTech/HWLAB#38", - "pikasTech/HWLAB#39" + "pikasTech/HWLAB#39", + "pikasTech/HWLAB#64" ], - "rationale": "The :16667/frp path must be reachable before any DEV-LIVE M3, M4, or M5 evidence can be collected.", - "action": "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"},\\\"name\\\":\\\"hwlab-agent-worker-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-agent-worker\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-agent-worker\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_AGENT_SESSION_MODE\\\",\\\"value\\\":\\\"session-scoped\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\\\",\\\"name\\\":\\\"hwlab-agent-worker\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-agent-worker\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-agent-worker-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-agent-worker-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"batch.kubernetes.io/job-name\":\"hwlab-agent-worker-template\",\"controller-uid\":\"0f7b16d1-562b-40a3-8ff8-961c10d1b182\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\",\"job-name\":\"hwlab-agent-worker-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-agent-worker\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_AGENT_SESSION_MODE\",\"Value\":\"session-scoped\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable Error from server (Invalid): error when applying patch: {\"metadata\":{\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"kind\\\":\\\"Job\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/activation\\\":\\\"manual\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"},\\\"name\\\":\\\"hwlab-cli-template\\\",\\\"namespace\\\":\\\"hwlab-dev\\\"},\\\"spec\\\":{\\\"suspend\\\":true,\\\"template\\\":{\\\"metadata\\\":{\\\"labels\\\":{\\\"app.kubernetes.io/name\\\":\\\"hwlab-cli\\\",\\\"app.kubernetes.io/part-of\\\":\\\"hwlab\\\",\\\"hwlab.pikastech.local/environment\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/profile\\\":\\\"dev\\\",\\\"hwlab.pikastech.local/service-id\\\":\\\"hwlab-cli\\\"}},\\\"spec\\\":{\\\"containers\\\":[{\\\"env\\\":[{\\\"name\\\":\\\"HWLAB_CLI_ENDPOINT\\\",\\\"value\\\":\\\"http://74.48.78.17:16667\\\"}],\\\"image\\\":\\\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\\\",\\\"name\\\":\\\"hwlab-cli\\\"}],\\\"restartPolicy\\\":\\\"Never\\\"}}}}\\n\"}},\"spec\":{\"template\":{\"spec\":{\"$setElementOrder/containers\":[{\"name\":\"hwlab-cli\"}],\"containers\":[{\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}]}}}} to: Resource: \"batch/v1, Resource=jobs\", GroupVersionKind: \"batch/v1, Kind=Job\" Name: \"hwlab-cli-template\", Namespace: \"hwlab-dev\" for: \"deploy/k8s/dev\": error when patching \"deploy/k8s/dev\": Job.batch \"hwlab-cli-template\" is invalid: spec.template: Invalid value: {\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"batch.kubernetes.io/controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"batch.kubernetes.io/job-name\":\"hwlab-cli-template\",\"controller-uid\":\"ce763736-b67b-400c-8a09-5b3f62019b09\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\",\"job-name\":\"hwlab-cli-template\"},\"Spec\":{\"Volumes\":null,\"InitContainers\":null,\"Containers\":[{\"Name\":\"hwlab-cli\",\"Image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"Command\":null,\"Args\":null,\"WorkingDir\":\"\",\"Ports\":null,\"EnvFrom\":null,\"Env\":[{\"Name\":\"HWLAB_CLI_ENDPOINT\",\"Value\":\"http://74.48.78.17:16667\",\"ValueFrom\":null}],\"Resources\":{\"Limits\":null,\"Requests\":null,\"Claims\":null},\"ResizePolicy\":null,\"RestartPolicy\":null,\"RestartPolicyRules\":null,\"VolumeMounts\":null,\"VolumeDevices\":null,\"LivenessProbe\":null,\"ReadinessProbe\":null,\"StartupProbe\":null,\"Lifecycle\":null,\"TerminationMessagePath\":\"/dev/termination-log\",\"TerminationMessagePolicy\":\"File\",\"ImagePullPolicy\":\"IfNotPresent\",\"SecurityContext\":null,\"Stdin\":false,\"StdinOnce\":false,\"TTY\":false}],\"EphemeralContainers\":null,\"RestartPolicy\":\"Never\",\"TerminationGracePeriodSeconds\":30,\"ActiveDeadlineSeconds\":null,\"DNSPolicy\":\"ClusterFirst\",\"NodeSelector\":null,\"ServiceAccountName\":\"\",\"AutomountServiceAccountToken\":null,\"NodeName\":\"\",\"SecurityContext\":{\"HostNetwork\":false,\"HostPID\":false,\"HostIPC\":false,\"ShareProcessNamespace\":null,\"HostUsers\":null,\"SELinuxOptions\":null,\"WindowsOptions\":null,\"RunAsUser\":null,\"RunAsGroup\":null,\"RunAsNonRoot\":null,\"SupplementalGroups\":null,\"SupplementalGroupsPolicy\":null,\"FSGroup\":null,\"FSGroupChangePolicy\":null,\"Sysctls\":null,\"SeccompProfile\":null,\"AppArmorProfile\":null,\"SELinuxChangePolicy\":null},\"ImagePullSecrets\":null,\"Hostname\":\"\",\"Subdomain\":\"\",\"SetHostnameAsFQDN\":null,\"Affinity\":null,\"SchedulerName\":\"default-scheduler\",\"Tolerations\":null,\"HostAliases\":null,\"PriorityClassName\":\"\",\"Priority\":null,\"PreemptionPolicy\":null,\"DNSConfig\":null,\"ReadinessGates\":null,\"RuntimeClassName\":null,\"Overhead\":null,\"EnableServiceLinks\":null,\"TopologySpreadConstraints\":null,\"OS\":null,\"SchedulingGates\":null,\"ResourceClaims\":null,\"Resources\":null,\"HostnameOverride\":null}}: field is immutable", - "evidenceRequired": "Read-only kubectl/k3s report proving pods/services/configmaps are observable in hwlab-dev without reading Secrets." - }, - { - "order": 5, - "blockerOrder": 99, - "priority": "P3", - "scopes": [ - "m3-hardware-loop-runtime", - "db-live" - ], - "sourceIssues": [ - "pikasTech/HWLAB#37", - "pikasTech/HWLAB#38", - "pikasTech/HWLAB#39" - ], - "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." + "rationale": "M3 remains blocked until the real DEV hardware trusted loop proves DO1 -> patch-panel -> DI1 with operation, trace, audit, and evidence identifiers.", + "action": "Prove the real DEV M3 trusted loop res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1 with operation, trace, audit, and evidence identifiers.", + "evidenceRequired": "Operation, trace, audit, and evidence IDs from the real DEV DO1 -> patch-panel -> DI1 trusted loop." } ], "validationCommands": [ @@ -1109,13 +1126,5 @@ "node scripts/dev-evidence-blocker-aggregator.mjs --markdown", "node --check scripts/validate-dev-gate-report.mjs", "node scripts/validate-dev-gate-report.mjs" - ], - "reportLifecycle": { - "version": "v1", - "state": "active", - "activeEndpoint": "http://74.48.78.17:16667", - "activeBrowserEndpoint": "http://74.48.78.17:16666", - "deprecatedEndpoint": null, - "summary": "Current M5 evidence aggregator report; source, local, and dry-run evidence are not DEV-LIVE acceptance." - } + ] } diff --git a/reports/dev-gate/dev-m5-gate-aggregator-v2.md b/reports/dev-gate/dev-m5-gate-aggregator-v2.md index c717b5f3..79781e2d 100644 --- a/reports/dev-gate/dev-m5-gate-aggregator-v2.md +++ b/reports/dev-gate/dev-m5-gate-aggregator-v2.md @@ -1,12 +1,22 @@ # HWLAB M5 DEV Gate Aggregator v2 Status: blocked -Generated from: `721bc37c084e` +Generated from: `8e89409dda5d` Scope: DEV only, report-only ## Summary -SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is still blocked by artifact, observability, DB, and loop evidence gaps. +EDGE/ROUTE DEV-LIVE evidence exists on :16666/:16667, but M5 remains blocked by artifact source drift, DB live degradation, missing M3 trusted loop operation evidence, and blocked M4 agent-loop preflight. + +## Current DEV Layering + +| Layer | Status | Evidence level | Current conclusion | Required next proof | +| --- | --- | --- | --- | --- | +| EDGE/ROUTE live | pass | DEV-LIVE | 16666 browser, 16667 /health, and 16667 /health/live returned accepted HWLAB DEV responses in the active M2 read-only smoke. | Keep this separated from DB readiness, M3/M4 loop evidence, and M5 acceptance. | +| DB live/degraded | blocked | BLOCKED | cloud-api DB status=degraded; configReady=true; ready=false; connected=false; liveDbEvidence=false. | Provide live DB connection evidence through redacted health output; route reachability alone is insufficient. | +| M3 hardware trusted loop | blocked | BLOCKED | No live DEV operation has run yet. Blocker: patch-panel active DO1 -> DI1 connection missing. | Only a real DEV res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1 observation with operation/trace/audit/evidence can clear M3. | +| M4 agent loop | blocked | BLOCKED | Blocked at DB live readiness before scheduling a DEV agent task. | Do not schedule or claim the agent loop as live until DB live and required runtime/evidence preconditions pass. | +| artifact/desired-state source | blocked | BLOCKED | artifact targetCovered=false; artifactSource=7e29522b65c8; target=8e89409dda5d; desiredApplyMode=dry-run; mutationAttempted=false. | Refresh artifact/source coverage for current origin/main and keep desired-state apply separate from read-only route proof. | ## Milestones @@ -14,7 +24,7 @@ SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is sti | --- | --- | --- | --- | --- | | 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 | DEV-LIVE | missing_or_blocked | deploy/runtime readiness is blocked before live DEV; highest visible level is DEV-LIVE; status is blocked. | +| M2 | blocked | DEV-LIVE | pass | 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. | | 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. | @@ -25,42 +35,36 @@ SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is sti | --- | --- | --- | --- | | m0-source-contract | pass | SOURCE | M0 contract checks are source-level evidence only. | | m1-local-smoke | pass | LOCAL | M1 local smoke is not a live DEV substitute. | -| artifact-publish-digests | pass | DEV-LIVE | artifactState=published, ciPublished=true, registryVerified=true, sha256=13, not_published=0 | -| d601-k3s-observability | blocked | BLOCKED | D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev. | -| dev-edge-frp-16667 | blocked | BLOCKED | 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. | +| artifact-publish-digests | blocked | BLOCKED | artifactState=published, ciPublished=true, registryVerified=true, sha256=13, not_published=0, targetCovered=false | +| d601-k3s-observability | pass | DEV-LIVE | D601 hwlab-dev cluster was readable. | +| dev-edge-frp-16667 | pass | DEV-LIVE | Committed edge report proves read-only public HTTP on :16667 /health and /health/live; this is route evidence, not DB/M3/M4/M5 acceptance. | +| cloud-api-db-ready | blocked | BLOCKED | cloud-api DB status=degraded; ready=false; connected=false; liveDbEvidence=false. | +| m3-hardware-trusted-loop | blocked | BLOCKED | M3 trusted loop is blocked until res_boxsimu_1:DO1 -> patch-panel -> res_boxsimu_2:DI1 is proven with operation/trace/audit/evidence. | +| m4-agent-loop-live | blocked | BLOCKED | M4 agent loop live path is blocked before accepted agent scheduling/evidence closure. | | m5-mvp-dev-live | blocked | BLOCKED | M5 dry-run passed; bounded DEV-LIVE MVP e2e has not passed. | ## Blockers | Priority | Order | Type | Scope | Summary | | --- | ---: | --- | --- | --- | -| P1 | 3 | contract_blocker | artifact-source-commit | source commit origin/main 82ad96c is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs. | -| P1 | 3 | runtime_blocker | dev-artifact-publish | reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 82ad96c; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled. | -| 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 | 3 | contract_blocker | artifact-source-commit | source commit origin/main 8e89409 is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs. | +| P1 | 3 | runtime_blocker | dev-artifact-publish | reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 8e89409; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled. | | 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 | network_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 | environment_blocker | kubectl-dry-run | # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"batch/v1\",\"kind\":\"Job\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\"},\"name\":\"hwlab-agent-worker-template\",\"namespace\":\"hwlab-dev\"},\"spec\":{\"suspend\":true,\"template\":{\"metadata\":{\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\"}},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"HWLAB_AGENT_SESSION_MODE\",\"value\":\"session-scoped\"}],\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}],\"restartPolicy\":\"Never\"}}}}\n"}},"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"hwlab-agent-worker"}],"containers":[{"image":"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522","name":"hwlab-agent-worker"}]}}}} to: Resource: "batch/v1, Resource=jobs", GroupVersionKind: "batch/v1, Kind=Job" Name: "hwlab-agent-worker-template", Namespace: "hwlab-dev" for: "deploy/k8s/dev": error when patching "deploy/k8s/dev": Job.batch "hwlab-agent-worker-template" is invalid: spec.template: Invalid value: {"labels":{"app.kubernetes.io/name":"hwlab-agent-worker","app.kubernetes.io/part-of":"hwlab","batch.kubernetes.io/controller-uid":"0f7b16d1-562b-40a3-8ff8-961c10d1b182","batch.kubernetes.io/job-name":"hwlab-agent-worker-template","controller-uid":"0f7b16d1-562b-40a3-8ff8-961c10d1b182","hwlab.pikastech.local/environment":"dev","hwlab.pikastech.local/profile":"dev","hwlab.pikastech.local/service-id":"hwlab-agent-worker","job-name":"hwlab-agent-worker-template"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":[{"Name":"hwlab-agent-worker","Image":"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522","Command":null,"Args":null,"WorkingDir":"","Ports":null,"EnvFrom":null,"Env":[{"Name":"HWLAB_AGENT_SESSION_MODE","Value":"session-scoped","ValueFrom":null}],"Resources":{"Limits":null,"Requests":null,"Claims":null},"ResizePolicy":null,"RestartPolicy":null,"RestartPolicyRules":null,"VolumeMounts":null,"VolumeDevices":null,"LivenessProbe":null,"ReadinessProbe":null,"StartupProbe":null,"Lifecycle":null,"TerminationMessagePath":"/dev/termination-log","TerminationMessagePolicy":"File","ImagePullPolicy":"IfNotPresent","SecurityContext":null,"Stdin":false,"StdinOnce":false,"TTY":false}],"EphemeralContainers":null,"RestartPolicy":"Never","TerminationGracePeriodSeconds":30,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":{"HostNetwork":false,"HostPID":false,"HostIPC":false,"ShareProcessNamespace":null,"HostUsers":null,"SELinuxOptions":null,"WindowsOptions":null,"RunAsUser":null,"RunAsGroup":null,"RunAsNonRoot":null,"SupplementalGroups":null,"SupplementalGroupsPolicy":null,"FSGroup":null,"FSGroupChangePolicy":null,"Sysctls":null,"SeccompProfile":null,"AppArmorProfile":null,"SELinuxChangePolicy":null},"ImagePullSecrets":null,"Hostname":"","Subdomain":"","SetHostnameAsFQDN":null,"Affinity":null,"SchedulerName":"default-scheduler","Tolerations":null,"HostAliases":null,"PriorityClassName":"","Priority":null,"PreemptionPolicy":null,"DNSConfig":null,"ReadinessGates":null,"RuntimeClassName":null,"Overhead":null,"EnableServiceLinks":null,"TopologySpreadConstraints":null,"OS":null,"SchedulingGates":null,"ResourceClaims":null,"Resources":null,"HostnameOverride":null}}: field is immutable Error from server (Invalid): error when applying patch: {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"batch/v1\",\"kind\":\"Job\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/activation\":\"manual\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\"},\"name\":\"hwlab-cli-template\",\"namespace\":\"hwlab-dev\"},\"spec\":{\"suspend\":true,\"template\":{\"metadata\":{\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\"}},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"HWLAB_CLI_ENDPOINT\",\"value\":\"http://74.48.78.17:16667\"}],\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}],\"restartPolicy\":\"Never\"}}}}\n"}},"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"hwlab-cli"}],"containers":[{"image":"127.0.0.1:5000/hwlab/hwlab-cli:7e29522","name":"hwlab-cli"}]}}}} to: Resource: "batch/v1, Resource=jobs", GroupVersionKind: "batch/v1, Kind=Job" Name: "hwlab-cli-template", Namespace: "hwlab-dev" for: "deploy/k8s/dev": error when patching "deploy/k8s/dev": Job.batch "hwlab-cli-template" is invalid: spec.template: Invalid value: {"labels":{"app.kubernetes.io/name":"hwlab-cli","app.kubernetes.io/part-of":"hwlab","batch.kubernetes.io/controller-uid":"ce763736-b67b-400c-8a09-5b3f62019b09","batch.kubernetes.io/job-name":"hwlab-cli-template","controller-uid":"ce763736-b67b-400c-8a09-5b3f62019b09","hwlab.pikastech.local/environment":"dev","hwlab.pikastech.local/profile":"dev","hwlab.pikastech.local/service-id":"hwlab-cli","job-name":"hwlab-cli-template"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":[{"Name":"hwlab-cli","Image":"127.0.0.1:5000/hwlab/hwlab-cli:7e29522","Command":null,"Args":null,"WorkingDir":"","Ports":null,"EnvFrom":null,"Env":[{"Name":"HWLAB_CLI_ENDPOINT","Value":"http://74.48.78.17:16667","ValueFrom":null}],"Resources":{"Limits":null,"Requests":null,"Claims":null},"ResizePolicy":null,"RestartPolicy":null,"RestartPolicyRules":null,"VolumeMounts":null,"VolumeDevices":null,"LivenessProbe":null,"ReadinessProbe":null,"StartupProbe":null,"Lifecycle":null,"TerminationMessagePath":"/dev/termination-log","TerminationMessagePolicy":"File","ImagePullPolicy":"IfNotPresent","SecurityContext":null,"Stdin":false,"StdinOnce":false,"TTY":false}],"EphemeralContainers":null,"RestartPolicy":"Never","TerminationGracePeriodSeconds":30,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":{"HostNetwork":false,"HostPID":false,"HostIPC":false,"ShareProcessNamespace":null,"HostUsers":null,"SELinuxOptions":null,"WindowsOptions":null,"RunAsUser":null,"RunAsGroup":null,"RunAsNonRoot":null,"SupplementalGroups":null,"SupplementalGroupsPolicy":null,"FSGroup":null,"FSGroupChangePolicy":null,"Sysctls":null,"SeccompProfile":null,"AppArmorProfile":null,"SELinuxChangePolicy":null},"ImagePullSecrets":null,"Hostname":"","Subdomain":"","SetHostnameAsFQDN":null,"Affinity":null,"SchedulerName":"default-scheduler","Tolerations":null,"HostAliases":null,"PriorityClassName":"","Priority":null,"PreemptionPolicy":null,"DNSConfig":null,"ReadinessGates":null,"RuntimeClassName":null,"Overhead":null,"EnableServiceLinks":null,"TopologySpreadConstraints":null,"OS":null,"SchedulingGates":null,"ResourceClaims":null,"Resources":null,"HostnameOverride":null}}: field is immutable | -| 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. | +| P1 | 5 | runtime_blocker | db-live | cloud-api /health/live reports DB degraded; connected=false; ready=false. | +| P1 | 5 | runtime_blocker | db-live | cloud-api /health/live reports DB degraded; db.ready=false, db.connected=false, and live DB evidence is not established. | +| P0 | 6 | runtime_blocker | m3-hardware-loop-runtime | patch-panel active DO1 -> DI1 connection missing | +| P0 | 6 | 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. Refresh without fake digests using `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked`, or after a successful publish run `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json`. Evidence required: Artifact publish report with ciPublished=true, registryVerified=true, and sha256 digest for each frozen service ID. -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. -3. Deploy cloud-api DB runtime readiness probe and/or repair DEV DB connectivity, then rerun the read-only health smoke without reading or printing the DB secret value. +2. Deploy cloud-api DB runtime readiness probe and/or repair DEV DB connectivity, then rerun the read-only health smoke without reading or printing the DB secret value. Evidence required: Cloud API health/live output showing DB env ready and redacted secret references, without secret material. -4. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. # Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically. Error from server (Invalid): error when applying patch: {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"batch/v1\",\"kind\":\"Job\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\"},\"name\":\"hwlab-agent-worker-template\",\"namespace\":\"hwlab-dev\"},\"spec\":{\"suspend\":true,\"template\":{\"metadata\":{\"labels\":{\"app.kubernetes.io/name\":\"hwlab-agent-worker\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-agent-worker\"}},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"HWLAB_AGENT_SESSION_MODE\",\"value\":\"session-scoped\"}],\"image\":\"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522\",\"name\":\"hwlab-agent-worker\"}],\"restartPolicy\":\"Never\"}}}}\n"}},"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"hwlab-agent-worker"}],"containers":[{"image":"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522","name":"hwlab-agent-worker"}]}}}} to: Resource: "batch/v1, Resource=jobs", GroupVersionKind: "batch/v1, Kind=Job" Name: "hwlab-agent-worker-template", Namespace: "hwlab-dev" for: "deploy/k8s/dev": error when patching "deploy/k8s/dev": Job.batch "hwlab-agent-worker-template" is invalid: spec.template: Invalid value: {"labels":{"app.kubernetes.io/name":"hwlab-agent-worker","app.kubernetes.io/part-of":"hwlab","batch.kubernetes.io/controller-uid":"0f7b16d1-562b-40a3-8ff8-961c10d1b182","batch.kubernetes.io/job-name":"hwlab-agent-worker-template","controller-uid":"0f7b16d1-562b-40a3-8ff8-961c10d1b182","hwlab.pikastech.local/environment":"dev","hwlab.pikastech.local/profile":"dev","hwlab.pikastech.local/service-id":"hwlab-agent-worker","job-name":"hwlab-agent-worker-template"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":[{"Name":"hwlab-agent-worker","Image":"127.0.0.1:5000/hwlab/hwlab-agent-worker:7e29522","Command":null,"Args":null,"WorkingDir":"","Ports":null,"EnvFrom":null,"Env":[{"Name":"HWLAB_AGENT_SESSION_MODE","Value":"session-scoped","ValueFrom":null}],"Resources":{"Limits":null,"Requests":null,"Claims":null},"ResizePolicy":null,"RestartPolicy":null,"RestartPolicyRules":null,"VolumeMounts":null,"VolumeDevices":null,"LivenessProbe":null,"ReadinessProbe":null,"StartupProbe":null,"Lifecycle":null,"TerminationMessagePath":"/dev/termination-log","TerminationMessagePolicy":"File","ImagePullPolicy":"IfNotPresent","SecurityContext":null,"Stdin":false,"StdinOnce":false,"TTY":false}],"EphemeralContainers":null,"RestartPolicy":"Never","TerminationGracePeriodSeconds":30,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":{"HostNetwork":false,"HostPID":false,"HostIPC":false,"ShareProcessNamespace":null,"HostUsers":null,"SELinuxOptions":null,"WindowsOptions":null,"RunAsUser":null,"RunAsGroup":null,"RunAsNonRoot":null,"SupplementalGroups":null,"SupplementalGroupsPolicy":null,"FSGroup":null,"FSGroupChangePolicy":null,"Sysctls":null,"SeccompProfile":null,"AppArmorProfile":null,"SELinuxChangePolicy":null},"ImagePullSecrets":null,"Hostname":"","Subdomain":"","SetHostnameAsFQDN":null,"Affinity":null,"SchedulerName":"default-scheduler","Tolerations":null,"HostAliases":null,"PriorityClassName":"","Priority":null,"PreemptionPolicy":null,"DNSConfig":null,"ReadinessGates":null,"RuntimeClassName":null,"Overhead":null,"EnableServiceLinks":null,"TopologySpreadConstraints":null,"OS":null,"SchedulingGates":null,"ResourceClaims":null,"Resources":null,"HostnameOverride":null}}: field is immutable Error from server (Invalid): error when applying patch: {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"batch/v1\",\"kind\":\"Job\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/activation\":\"manual\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\"},\"name\":\"hwlab-cli-template\",\"namespace\":\"hwlab-dev\"},\"spec\":{\"suspend\":true,\"template\":{\"metadata\":{\"labels\":{\"app.kubernetes.io/name\":\"hwlab-cli\",\"app.kubernetes.io/part-of\":\"hwlab\",\"hwlab.pikastech.local/environment\":\"dev\",\"hwlab.pikastech.local/profile\":\"dev\",\"hwlab.pikastech.local/service-id\":\"hwlab-cli\"}},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"HWLAB_CLI_ENDPOINT\",\"value\":\"http://74.48.78.17:16667\"}],\"image\":\"127.0.0.1:5000/hwlab/hwlab-cli:7e29522\",\"name\":\"hwlab-cli\"}],\"restartPolicy\":\"Never\"}}}}\n"}},"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"hwlab-cli"}],"containers":[{"image":"127.0.0.1:5000/hwlab/hwlab-cli:7e29522","name":"hwlab-cli"}]}}}} to: Resource: "batch/v1, Resource=jobs", GroupVersionKind: "batch/v1, Kind=Job" Name: "hwlab-cli-template", Namespace: "hwlab-dev" for: "deploy/k8s/dev": error when patching "deploy/k8s/dev": Job.batch "hwlab-cli-template" is invalid: spec.template: Invalid value: {"labels":{"app.kubernetes.io/name":"hwlab-cli","app.kubernetes.io/part-of":"hwlab","batch.kubernetes.io/controller-uid":"ce763736-b67b-400c-8a09-5b3f62019b09","batch.kubernetes.io/job-name":"hwlab-cli-template","controller-uid":"ce763736-b67b-400c-8a09-5b3f62019b09","hwlab.pikastech.local/environment":"dev","hwlab.pikastech.local/profile":"dev","hwlab.pikastech.local/service-id":"hwlab-cli","job-name":"hwlab-cli-template"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":[{"Name":"hwlab-cli","Image":"127.0.0.1:5000/hwlab/hwlab-cli:7e29522","Command":null,"Args":null,"WorkingDir":"","Ports":null,"EnvFrom":null,"Env":[{"Name":"HWLAB_CLI_ENDPOINT","Value":"http://74.48.78.17:16667","ValueFrom":null}],"Resources":{"Limits":null,"Requests":null,"Claims":null},"ResizePolicy":null,"RestartPolicy":null,"RestartPolicyRules":null,"VolumeMounts":null,"VolumeDevices":null,"LivenessProbe":null,"ReadinessProbe":null,"StartupProbe":null,"Lifecycle":null,"TerminationMessagePath":"/dev/termination-log","TerminationMessagePolicy":"File","ImagePullPolicy":"IfNotPresent","SecurityContext":null,"Stdin":false,"StdinOnce":false,"TTY":false}],"EphemeralContainers":null,"RestartPolicy":"Never","TerminationGracePeriodSeconds":30,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":{"HostNetwork":false,"HostPID":false,"HostIPC":false,"ShareProcessNamespace":null,"HostUsers":null,"SELinuxOptions":null,"WindowsOptions":null,"RunAsUser":null,"RunAsGroup":null,"RunAsNonRoot":null,"SupplementalGroups":null,"SupplementalGroupsPolicy":null,"FSGroup":null,"FSGroupChangePolicy":null,"Sysctls":null,"SeccompProfile":null,"AppArmorProfile":null,"SELinuxChangePolicy":null},"ImagePullSecrets":null,"Hostname":"","Subdomain":"","SetHostnameAsFQDN":null,"Affinity":null,"SchedulerName":"default-scheduler","Tolerations":null,"HostAliases":null,"PriorityClassName":"","Priority":null,"PreemptionPolicy":null,"DNSConfig":null,"ReadinessGates":null,"RuntimeClassName":null,"Overhead":null,"EnableServiceLinks":null,"TopologySpreadConstraints":null,"OS":null,"SchedulingGates":null,"ResourceClaims":null,"Resources":null,"HostnameOverride":null}}: field is immutable - Evidence required: Read-only kubectl/k3s report proving pods/services/configmaps are observable in hwlab-dev without reading Secrets. -5. 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. +3. Prove the real DEV M3 trusted loop res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1 with operation, trace, audit, and evidence identifiers. + Evidence required: Operation, trace, audit, and evidence IDs from the real DEV DO1 -> patch-panel -> DI1 trusted loop. ## Validation diff --git a/reports/dev-gate/dev-preflight-report.json b/reports/dev-gate/dev-preflight-report.json index 914a2ef2..3245124d 100644 --- a/reports/dev-gate/dev-preflight-report.json +++ b/reports/dev-gate/dev-preflight-report.json @@ -24,13 +24,21 @@ ], "target": { "ref": "origin/main", - "commitId": "82ad96c5c67c3906732a057d52395ec72851e4a9", - "shortCommitId": "82ad96c" + "commitId": "8e89409dda5d0b028de7f7b7b0e006a60bdd6d44", + "shortCommitId": "8e89409" }, - "generatedAt": "2026-05-22T05:35:39.805Z", + "generatedAt": "2026-05-22T07:12:46.951Z", "mode": "read-only", "devOnly": true, "prodDisabled": true, + "reportLifecycle": { + "version": "v1", + "state": "active", + "activeEndpoint": "http://74.48.78.17:16667", + "activeBrowserEndpoint": "http://74.48.78.17:16666", + "deprecatedEndpoint": null, + "summary": "Current read-only DEV preflight report; source, local, and dry-run checks are not DEV-LIVE acceptance." + }, "forbiddenActions": [ "prod-deploy", "secret-material-read", @@ -52,8 +60,8 @@ "artifactIdentity": { "source": { "ref": "origin/main", - "commitId": "82ad96c5c67c3906732a057d52395ec72851e4a9", - "shortCommitId": "82ad96c" + "commitId": "8e89409dda5d0b028de7f7b7b0e006a60bdd6d44", + "shortCommitId": "8e89409" }, "artifactSource": { "source": "artifact-publish-report", @@ -67,17 +75,21 @@ "sourceCommitId": "7e29522b65c8a316b7c3fde12bebcb5f6baf8c33", "sourceShortCommitId": "7e29522", "targetRef": "origin/main", - "targetCommitId": "82ad96c5c67c3906732a057d52395ec72851e4a9", - "targetShortCommitId": "82ad96c", + "targetCommitId": "8e89409dda5d0b028de7f7b7b0e006a60bdd6d44", + "targetShortCommitId": "8e89409", "mode": "artifact-input-drift", "covered": false, "artifactBuildInputChanged": true, - "changedPathCount": 22, + "changedPathCount": 48, "changedArtifactInputPaths": [ + "internal/dev-report-lifecycle.mjs", "internal/mvp-gate/summary.mjs", + "internal/protocol/index.mjs", + "package.json", + "scripts/dev-artifact-publish.mjs", "web/hwlab-cloud-web/gate-summary.mjs" ], - "changedNonArtifactPathCount": 20, + "changedNonArtifactPathCount": 42, "reason": "target changes since the artifact source touch artifact build inputs" }, "deployManifest": { @@ -274,7 +286,7 @@ "registryCapabilities": { "version": "v1", "registryPrefix": "127.0.0.1:5000/hwlab", - "generatedAt": "2026-05-22T05:35:38.863Z", + "generatedAt": "2026-05-22T07:12:45.056Z", "classification": "degraded", "dimensions": { "processHttpAccess": { @@ -322,7 +334,7 @@ "names": "unidesk-artifact-registry", "ports": "127.0.0.1:5000->5000/tcp", "state": "running", - "status": "Up 28 hours" + "status": "Up 30 hours" } ], "pushAttempted": false, @@ -461,13 +473,13 @@ "id": "target-commit-pinning", "category": "contract", "status": "blocked", - "summary": "Source origin/main 82ad96c is not covered by artifact source 7e29522: target changes since the artifact source touch artifact build inputs.", + "summary": "Source origin/main 8e89409 is not covered by artifact source 7e29522: target changes since the artifact source touch artifact build inputs.", "evidence": [ { "source": { "ref": "origin/main", - "commitId": "82ad96c5c67c3906732a057d52395ec72851e4a9", - "shortCommitId": "82ad96c" + "commitId": "8e89409dda5d0b028de7f7b7b0e006a60bdd6d44", + "shortCommitId": "8e89409" }, "artifactSource": { "source": "artifact-publish-report", @@ -481,17 +493,21 @@ "sourceCommitId": "7e29522b65c8a316b7c3fde12bebcb5f6baf8c33", "sourceShortCommitId": "7e29522", "targetRef": "origin/main", - "targetCommitId": "82ad96c5c67c3906732a057d52395ec72851e4a9", - "targetShortCommitId": "82ad96c", + "targetCommitId": "8e89409dda5d0b028de7f7b7b0e006a60bdd6d44", + "targetShortCommitId": "8e89409", "mode": "artifact-input-drift", "covered": false, "artifactBuildInputChanged": true, - "changedPathCount": 22, + "changedPathCount": 48, "changedArtifactInputPaths": [ + "internal/dev-report-lifecycle.mjs", "internal/mvp-gate/summary.mjs", + "internal/protocol/index.mjs", + "package.json", + "scripts/dev-artifact-publish.mjs", "web/hwlab-cloud-web/gate-summary.mjs" ], - "changedNonArtifactPathCount": 20, + "changedNonArtifactPathCount": 42, "reason": "target changes since the artifact source touch artifact build inputs" }, "deployManifest": { @@ -778,7 +794,7 @@ "names": "unidesk-artifact-registry", "ports": "127.0.0.1:5000->5000/tcp", "state": "running", - "status": "Up 28 hours" + "status": "Up 30 hours" } ], "pushAttempted": false, @@ -916,7 +932,7 @@ { "version": "v1", "registryPrefix": "127.0.0.1:5000/hwlab", - "generatedAt": "2026-05-22T05:35:38.863Z", + "generatedAt": "2026-05-22T07:12:45.056Z", "classification": "degraded", "dimensions": { "processHttpAccess": { @@ -964,7 +980,7 @@ "names": "unidesk-artifact-registry", "ports": "127.0.0.1:5000->5000/tcp", "state": "running", - "status": "Up 28 hours" + "status": "Up 30 hours" } ], "pushAttempted": false, @@ -1406,7 +1422,7 @@ "method": "GET", "status": 200, "statusText": "OK", - "body": "{\"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-22T05:35:39.607Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"c" + "body": "{\"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-22T07:12:46.583Z\",\"db\":{\"contractVersion\":\"v1\",\"environment\":\"dev\",\"connected\":false,\"connectionChecked\":false,\"c" } ] }, @@ -1528,7 +1544,7 @@ "status": "open", "type": "contract_blocker", "scope": "artifact-source-commit", - "summary": "source commit origin/main 82ad96c is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs.", + "summary": "source commit origin/main 8e89409 is not covered by artifact source 7e29522; target changes since the artifact source touch artifact build inputs.", "nextTask": "Refresh without fake digests using `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked`, or after a successful publish run `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json`." }, { @@ -1542,7 +1558,7 @@ "status": "open", "type": "runtime_blocker", "scope": "dev-artifact-publish", - "summary": "reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 82ad96c; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled.", + "summary": "reports/dev-gate/dev-artifacts.json does not prove all required HWLAB service artifacts for origin/main 8e89409; current status is published with 13/13 required services published and source states resolved: 13 source-present, 0 intentionally-disabled.", "nextTask": "Complete DEV artifact publishing for every enabled required HWLAB service at the artifact source commit, or prove the target commit has no artifact build input changes; keep disabled services marked not_published with reasons." }, { @@ -1553,13 +1569,5 @@ "nextTask": "Deploy cloud-api DB runtime readiness probe and/or repair DEV DB connectivity, then rerun the read-only health smoke without reading or printing the DB secret value." } ], - "notes": "No PROD action, secret read, UniDesk runtime substitution, heavy e2e, browser e2e, runtime restart, or force push was performed.", - "reportLifecycle": { - "version": "v1", - "state": "active", - "activeEndpoint": "http://74.48.78.17:16667", - "activeBrowserEndpoint": "http://74.48.78.17:16666", - "deprecatedEndpoint": null, - "summary": "Current read-only DEV preflight report; source, local, and dry-run checks are not DEV-LIVE acceptance." - } + "notes": "No PROD action, secret read, UniDesk runtime substitution, heavy e2e, browser e2e, runtime restart, or force push was performed." } diff --git a/scripts/m2-dev-deploy-smoke.mjs b/scripts/m2-dev-deploy-smoke.mjs index 000e6c93..6313ca42 100644 --- a/scripts/m2-dev-deploy-smoke.mjs +++ b/scripts/m2-dev-deploy-smoke.mjs @@ -6,6 +6,7 @@ import path from "node:path"; import { promisify } from "node:util"; import { fileURLToPath } from "node:url"; +import { activeReportLifecycle } from "../internal/dev-report-lifecycle.mjs"; import { DEV_ENDPOINT, DEV_FRONTEND_ENDPOINT, @@ -299,6 +300,9 @@ function buildActiveReport({ fixture, probes, generatedAt, commitId }) { acceptanceLevel: "dev_m2_deploy_smoke", devOnly: true, prodDisabled: true, + reportLifecycle: activeReportLifecycle( + "Active M2 read-only public endpoint smoke; route reachability is not M5 DEV-LIVE acceptance." + ), status, generatedAt, endpoint: DEV_ENDPOINT, diff --git a/scripts/src/d601-k3s-readonly-observability.mjs b/scripts/src/d601-k3s-readonly-observability.mjs index ba3faaaa..13a2af35 100644 --- a/scripts/src/d601-k3s-readonly-observability.mjs +++ b/scripts/src/d601-k3s-readonly-observability.mjs @@ -113,15 +113,20 @@ async function run(command, args = [], options = {}) { timeout: options.timeoutMs ?? 5000, maxBuffer: 1024 * 1024 }); - return { + const probe = { ok: true, command: commandText(command, args), exitCode: 0, stdout: redacted(result.stdout.trim()), stderr: redacted(result.stderr.trim()) }; + Object.defineProperty(probe, "rawStdout", { + value: result.stdout.trim(), + enumerable: false + }); + return probe; } catch (error) { - return { + const probe = { ok: false, command: commandText(command, args), exitCode: typeof error.code === "number" ? error.code : 1, @@ -129,6 +134,11 @@ async function run(command, args = [], options = {}) { stderr: redacted(String(error.stderr ?? "").trim()), error: oneLine(error.message) }; + Object.defineProperty(probe, "rawStdout", { + value: String(error.stdout ?? "").trim(), + enumerable: false + }); + return probe; } } @@ -239,9 +249,10 @@ async function collectSshBridge(binaries) { } function parseJsonProbe(probe) { - if (!probe.ok || !probe.stdout) return null; + const raw = probe.rawStdout ?? probe.stdout; + if (!probe.ok || !raw) return null; try { - return JSON.parse(probe.stdout); + return JSON.parse(raw); } catch { return null; } @@ -407,7 +418,7 @@ function buildBlockers({ binaries, kubeconfig, sshBridge, cluster }) { nextTask: "Mount a read-only kubeconfig for hwlab-dev, or document the approved k3s local kubeconfig path without exposing token material." }); } - if (!sshBridge.configured) { + if (!sshBridge.configured && !cluster.readable) { addBlocker(blockers, { type: "environment_blocker", scope: "d601-maintenance-ssh-bridge", diff --git a/scripts/src/dev-evidence-blocker-aggregator.mjs b/scripts/src/dev-evidence-blocker-aggregator.mjs index 181c5e98..ad95707d 100644 --- a/scripts/src/dev-evidence-blocker-aggregator.mjs +++ b/scripts/src/dev-evidence-blocker-aggregator.mjs @@ -5,7 +5,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import { activeReportLifecycle, reportIsHistorical, reportLifecycleState } from "../../internal/dev-report-lifecycle.mjs"; -import { DEV_ENDPOINT, ENVIRONMENT_DEV, SERVICE_IDS } from "../../internal/protocol/index.mjs"; +import { DEV_ENDPOINT, DEV_FRONTEND_ENDPOINT, ENVIRONMENT_DEV, SERVICE_IDS } from "../../internal/protocol/index.mjs"; export const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); @@ -42,6 +42,7 @@ const reportPaths = Object.freeze({ devDeploy: "reports/dev-gate/dev-deploy-report.json", devArtifacts: "reports/dev-gate/dev-artifacts.json", devEdgeHealth: "reports/dev-gate/dev-edge-health.json", + devM2Smoke: "reports/dev-gate/dev-m2-deploy-smoke-active.json", devM3Hardware: "reports/dev-gate/dev-m3-hardware-loop.json", devM4Agent: "reports/dev-gate/dev-m4-agent-loop.json", devM5Gate: "reports/dev-gate/dev-mvp-gate-report.json", @@ -189,6 +190,19 @@ function hasBlocker(blockers, predicate) { return blockers.some(predicate); } +function isRouteTransportBlocker(blocker) { + const scope = blocker.scope ?? ""; + return scope === "m2-public-endpoints" || + scope === "dev-edge" || + scope === "dev-edge-health" || + scope === "hwlab-router" || + scope === "hwlab-tunnel-client" || + scope === "hwlab-edge-proxy" || + scope.includes("edge-frp") || + scope.includes("ingress") || + scope.includes("frp"); +} + function applyPriority(blocker) { if (blocker.scope === "base-image") { return { @@ -234,6 +248,16 @@ function applyPriority(blocker) { }; } + if (blocker.scope === "hwlab-dev-readonly-rbac") { + return { + ...blocker, + priority: "P1", + unblockOrder: 4, + unblocks: [issue(34), issue(33), issue(36), issue(38), issue(39)], + rationale: "D601 has a client path, but read-only hwlab-dev pods/services/configmaps must be observable before live acceptance evidence can be trusted." + }; + } + if (blocker.scope.includes("cloud-api-db")) { return { ...blocker, @@ -244,6 +268,16 @@ function applyPriority(blocker) { }; } + if (blocker.scope === "db-live") { + return { + ...blocker, + priority: "P1", + unblockOrder: 5, + unblocks: [issue(37), issue(39)], + rationale: "M4 and M5 cannot claim live agent or MVP evidence until cloud-api /health/live proves DB readiness with redacted live evidence." + }; + } + if (isEdgeOrFrpBlocker(blocker)) { return { ...blocker, @@ -254,6 +288,16 @@ function applyPriority(blocker) { }; } + if (blocker.scope === "m3-hardware-loop-runtime") { + return { + ...blocker, + priority: "P0", + unblockOrder: 6, + unblocks: [issue(38), issue(39), issue(64)], + rationale: "M3 remains blocked until the real DEV hardware trusted loop proves DO1 -> patch-panel -> DI1 with operation, trace, audit, and evidence identifiers." + }; + } + return { ...blocker, priority: blocker.priority ?? "P3", @@ -264,11 +308,7 @@ 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"); + return isRouteTransportBlocker(blocker); } function sourceEntry(entry) { @@ -309,9 +349,11 @@ function collectM2Evidence(reports) { const deploy = reports.devDeploy; const artifacts = reports.devArtifacts; const edge = reports.devEdgeHealth; + const m2Smoke = reports.devM2Smoke; const d601 = reports.d601Observability; const artifactIdentity = preflight.artifactIdentity; const edgeLive = hasCurrentLiveEdgeEvidence(edge); + const m2EndpointLive = hasCurrentM2EndpointEvidence(m2Smoke); return [ reportEvidence({ @@ -352,6 +394,18 @@ function collectM2Evidence(reports) { commands: artifacts.validationCommands, summary: "Artifact publish preflight exists but is blocked before any real image publish." }), + reportEvidence({ + milestone: "M2", + level: m2EndpointLive ? "DEV-LIVE" : "BLOCKED", + report: m2Smoke, + status: m2Smoke.runtimeSmoke?.status ?? primaryStatus(m2Smoke), + category: "public-entrypoints-read-only", + evidence: publicEndpointEvidence(m2Smoke), + commands: m2Smoke.devPreconditions?.commands ?? [], + summary: m2EndpointLive + ? "Read-only probes prove the frozen public DEV entrypoints on :16666/:16667 are reachable; this is EDGE/ROUTE evidence only." + : "The active M2 public endpoint smoke does not prove the frozen :16666/:16667 entrypoints." + }), reportEvidence({ milestone: "M2", level: edgeLive ? "DEV-LIVE" : "SOURCE", @@ -388,6 +442,7 @@ function collectM2Evidence(reports) { function collectM3Evidence(reports) { const m3 = reports.devM3Hardware; const m5Milestone = reports.devM5Gate.milestones?.find((item) => item.id === "M3"); + const liveSummary = m3TrustedLoopSummary(m3); return [ reportEvidence({ milestone: "M3", @@ -422,11 +477,20 @@ function collectM3Evidence(reports) { `evidenceId=${m3.liveOperation?.evidenceId ?? "not_observed"}` ], commands: ["node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --confirmed-non-production"], - summary: m3.liveOperation?.summary ?? "No live M3 hardware operation was observed." + summary: liveSummary }) ]; } +function m3TrustedLoopSummary(m3Report) { + const operationSummary = m3Report.liveOperation?.summary ?? "No live M3 hardware operation was observed."; + const blockerSummary = m3Report.blockers?.find((blocker) => blocker.scope === "m3-hardware-loop-runtime")?.summary; + if (statusIsPass(m3Report.liveOperation?.status) || !blockerSummary) { + return operationSummary; + } + return `${operationSummary} Blocker: ${blockerSummary}.`; +} + function collectM4Evidence(reports) { const m4 = reports.devM4Agent; return [ @@ -537,6 +601,25 @@ function hasCurrentLiveEdgeEvidence(edgeReport) { publicHttp.some((probe) => probe.url === `${DEV_ENDPOINT}/health/live` && probe.ok === true && probe.status === 200); } +function hasCurrentM2EndpointEvidence(m2Report) { + const probes = m2Report?.runtimeSmoke?.probes ?? []; + return m2Report?.endpoint === DEV_ENDPOINT && + m2Report?.frontendEndpoint === DEV_FRONTEND_ENDPOINT && + m2Report?.runtimeSmoke?.mode === "live-read-only" && + m2Report?.runtimeSmoke?.status === "pass" && + probes.some((probe) => probe.url === `${DEV_ENDPOINT}/health` && probe.ok === true && probe.status === 200) && + probes.some((probe) => probe.url === `${DEV_ENDPOINT}/health/live` && probe.ok === true && probe.status === 200) && + probes.some((probe) => probe.url === `${DEV_FRONTEND_ENDPOINT}/` && probe.ok === true && probe.status === 200); +} + +function publicEndpointEvidence(m2Report) { + return (m2Report?.runtimeSmoke?.probes ?? []).map((probe) => { + const identity = probe.json?.serviceId ?? probe.title ?? "unknown"; + const status = probe.json?.status ?? (probe.ok ? "ok" : "failed"); + return `${probe.url} -> HTTP ${probe.status ?? "none"} identity=${identity} status=${status}`; + }); +} + function isStaleLegacyIngressBlocker(blocker, sourceReport, reports) { const text = `${blocker.scope ?? ""} ${blocker.summary ?? ""}`; const staleLegacyPort = text.includes(deprecatedLegacyPublicEndpoint); @@ -571,6 +654,7 @@ function deriveMilestones(evidence, blockers) { const liveItems = items.filter((item) => item.level === "DEV-LIVE"); const highestVisibleLevel = levels.findLast((level) => items.some((item) => item.level === level && level !== "BLOCKED" && statusHasEvidence(item.status))) ?? "BLOCKED"; const hasPassingLive = liveItems.some((item) => statusIsPass(item.status)); + const hasBlockedEvidence = items.some((item) => item.level === "BLOCKED" && ["blocked", "failed", "degraded"].includes(item.status)); const milestoneBlockers = blockers.filter((blocker) => { if (milestone === "M2") return blocker.unblocks.includes(issue(33)) || blocker.unblocks.includes(issue(35)) || blocker.unblocks.includes(issue(36)); if (milestone === "M3") return blocker.unblocks.includes(issue(38)); @@ -578,7 +662,7 @@ function deriveMilestones(evidence, blockers) { if (milestone === "M5") return blocker.unblocks.includes(issue(39)); return false; }); - const status = milestoneBlockers.length > 0 || (liveItems.length > 0 && !hasPassingLive) + const status = milestoneBlockers.length > 0 || hasBlockedEvidence || (liveItems.length > 0 && !hasPassingLive) ? "blocked" : worstStatus(items.map((item) => item.status)); @@ -642,7 +726,16 @@ function buildDoD(reports, milestones, blockers) { const preflight = reports.devPreflight; const artifactIdentity = preflight.artifactIdentity; const d601 = reports.d601Observability; + const d601HasClient = d601.environment?.binaries?.kubectl?.available === true || + d601.environment?.binaries?.k3s?.available === true; const edgeLive = hasCurrentLiveEdgeEvidence(reports.devEdgeHealth); + const artifactCurrent = artifactIdentity.publishVerified === true && + artifactIdentity.targetCoverage?.covered !== false && + artifactIdentity.artifactCatalog?.matchesTarget !== false; + const cloudApiDb = cloudApiDbStatus(reports); + const dbReady = cloudApiDb.ready === true && cloudApiDb.connected === true && cloudApiDb.liveDbEvidence === true; + const m3Live = statusIsPass(reports.devM3Hardware.liveOperation?.status); + const m4Live = statusIsPass(reports.devM4Agent.livePreflight?.status); return { status: blockers.length === 0 && milestones.every((item) => item.status === "pass") ? "green" : "blocked", @@ -662,9 +755,9 @@ function buildDoD(reports, milestones, blockers) { }, { id: "artifact-publish-digests", - status: artifactIdentity.publishVerified ? "pass" : "blocked", - evidenceLevel: artifactIdentity.publishVerified ? "DEV-LIVE" : "BLOCKED", - summary: `artifactState=${artifactIdentity.artifactCatalog.artifactState}, ciPublished=${artifactIdentity.artifactCatalog.ciPublished}, registryVerified=${artifactIdentity.artifactCatalog.registryVerified}, sha256=${artifactIdentity.artifactCatalog.digestCounts.sha256}, not_published=${artifactIdentity.artifactCatalog.digestCounts.notPublished}` + status: artifactCurrent ? "pass" : "blocked", + evidenceLevel: artifactCurrent ? "DEV-LIVE" : "BLOCKED", + summary: `artifactState=${artifactIdentity.artifactCatalog.artifactState}, ciPublished=${artifactIdentity.artifactCatalog.ciPublished}, registryVerified=${artifactIdentity.artifactCatalog.registryVerified}, sha256=${artifactIdentity.artifactCatalog.digestCounts.sha256}, not_published=${artifactIdentity.artifactCatalog.digestCounts.notPublished}, targetCovered=${artifactIdentity.targetCoverage?.covered ?? "unknown"}` }, { id: "d601-k3s-observability", @@ -672,21 +765,39 @@ function buildDoD(reports, milestones, blockers) { evidenceLevel: d601.cluster?.readable ? "DEV-LIVE" : "BLOCKED", summary: d601.cluster?.readable ? "D601 hwlab-dev cluster was readable." - : "D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev." + : d601HasClient + ? "D601 kubectl/k3s clients are present, but read-only hwlab-dev pods/services/configmaps probes are still blocked." + : "D601 runner lacks kubectl/k3s/kubeconfig observability for hwlab-dev." }, { id: "dev-edge-frp-16667", - status: edgeLive && !hasBlocker(blockers, isEdgeOrFrpBlocker) ? "pass" : "blocked", - evidenceLevel: edgeLive && !hasBlocker(blockers, isEdgeOrFrpBlocker) ? "DEV-LIVE" : "BLOCKED", + status: edgeLive && !hasBlocker(blockers, isRouteTransportBlocker) ? "pass" : "blocked", + evidenceLevel: edgeLive && !hasBlocker(blockers, isRouteTransportBlocker) ? "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." + ? "Committed edge report proves read-only public HTTP on :16667 /health and /health/live; this is route evidence, not DB/M3/M4/M5 acceptance." : "No committed report proves live HTTP 200/JSON on http://74.48.78.17:16667." }, { id: "cloud-api-db-ready", - status: hasBlocker(blockers, (blocker) => blocker.scope.includes("cloud-api-db")) ? "blocked" : "pass", - evidenceLevel: "BLOCKED", - summary: "Manifest-level DB env exists, but live DB health readiness is still blocked/missing." + status: dbReady ? "pass" : "blocked", + evidenceLevel: dbReady ? "DEV-LIVE" : "BLOCKED", + summary: `cloud-api DB status=${cloudApiDb.status}; ready=${cloudApiDb.ready}; connected=${cloudApiDb.connected}; liveDbEvidence=${cloudApiDb.liveDbEvidence}.` + }, + { + id: "m3-hardware-trusted-loop", + status: m3Live ? "pass" : "blocked", + evidenceLevel: m3Live ? "DEV-LIVE" : "BLOCKED", + summary: m3Live + ? "M3 hardware trusted loop has operation, trace, audit, and evidence identifiers." + : "M3 trusted loop is blocked until res_boxsimu_1:DO1 -> patch-panel -> res_boxsimu_2:DI1 is proven with operation/trace/audit/evidence." + }, + { + id: "m4-agent-loop-live", + status: m4Live ? "pass" : "blocked", + evidenceLevel: m4Live ? "DEV-LIVE" : "BLOCKED", + summary: m4Live + ? "M4 agent loop live preflight passed." + : "M4 agent loop live path is blocked before accepted agent scheduling/evidence closure." }, { id: "m5-mvp-dev-live", @@ -698,6 +809,99 @@ function buildDoD(reports, milestones, blockers) { }; } +function cloudApiDbStatus(reports) { + const db = reports.devEdgeHealth.edgeHealth?.contracts?.deploy?.cloudApiDb ?? {}; + return { + status: db.status ?? "unknown", + ready: db.ready === true, + connected: db.connected === true || db.liveConnected === true, + configReady: db.configReady === true, + connectionChecked: db.connectionChecked === true, + liveDbEvidence: db.liveDbEvidence === true + }; +} + +function buildCurrentDevLayering(reports, blockers) { + const m2EndpointLive = hasCurrentM2EndpointEvidence(reports.devM2Smoke); + const edgeLive = hasCurrentLiveEdgeEvidence(reports.devEdgeHealth); + const cloudDb = cloudApiDbStatus(reports); + const dbReady = cloudDb.ready && cloudDb.connected && cloudDb.liveDbEvidence; + const m3Live = statusIsPass(reports.devM3Hardware.liveOperation?.status); + const m4Live = statusIsPass(reports.devM4Agent.livePreflight?.status); + const artifactIdentity = reports.devPreflight.artifactIdentity; + const artifactCurrent = artifactIdentity.publishVerified === true && + artifactIdentity.targetCoverage?.covered !== false && + artifactIdentity.artifactCatalog?.matchesTarget !== false; + const desired = reports.devDeploy.devDeployApply ?? {}; + const artifactSourceStates = artifactSourceStateCounts(reports.devArtifacts); + + return { + edgeRoute: { + label: "EDGE/ROUTE live", + status: m2EndpointLive || edgeLive ? "pass" : "blocked", + evidenceLevel: m2EndpointLive || edgeLive ? "DEV-LIVE" : "BLOCKED", + summary: m2EndpointLive + ? "16666 browser, 16667 /health, and 16667 /health/live returned accepted HWLAB DEV responses in the active M2 read-only smoke." + : "No active read-only public endpoint report proves both 16666 and 16667.", + evidence: publicEndpointEvidence(reports.devM2Smoke), + nextRequired: "Keep this separated from DB readiness, M3/M4 loop evidence, and M5 acceptance." + }, + dbLive: { + label: "DB live/degraded", + status: dbReady ? "pass" : "blocked", + evidenceLevel: dbReady ? "DEV-LIVE" : "BLOCKED", + summary: `cloud-api DB status=${cloudDb.status}; configReady=${cloudDb.configReady}; ready=${cloudDb.ready}; connected=${cloudDb.connected}; liveDbEvidence=${cloudDb.liveDbEvidence}.`, + evidence: reports.devM5Gate.devPreconditions?.evidence?.filter((line) => line.includes("/health/live") || line.includes("DB")) ?? [], + nextRequired: "Provide live DB connection evidence through redacted health output; route reachability alone is insufficient." + }, + m3HardwareTrustedLoop: { + label: "M3 hardware trusted loop", + status: m3Live ? "pass" : "blocked", + evidenceLevel: m3Live ? "DEV-LIVE" : "BLOCKED", + summary: m3TrustedLoopSummary(reports.devM3Hardware), + evidence: [ + `operationId=${reports.devM3Hardware.liveOperation?.operationId ?? "not_observed"}`, + `traceId=${reports.devM3Hardware.liveOperation?.traceId ?? "not_observed"}`, + `auditId=${reports.devM3Hardware.liveOperation?.auditId ?? "not_observed"}`, + `evidenceId=${reports.devM3Hardware.liveOperation?.evidenceId ?? "not_observed"}` + ], + nextRequired: "Only a real DEV res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1 observation with operation/trace/audit/evidence can clear M3." + }, + m4AgentLoop: { + label: "M4 agent loop", + status: m4Live ? "pass" : "blocked", + evidenceLevel: m4Live ? "DEV-LIVE" : "BLOCKED", + summary: reports.devM4Agent.livePreflight?.summary ?? reports.devM4Agent.devPreconditions?.summary ?? "No live M4 observation was recorded.", + evidence: reports.devM4Agent.livePreflight?.evidence ?? [], + nextRequired: "Do not schedule or claim the agent loop as live until DB live and required runtime/evidence preconditions pass." + }, + artifactDesiredStateSource: { + label: "artifact/desired-state source", + status: artifactCurrent && desired.conclusion?.status === "ready" ? "pass" : "blocked", + evidenceLevel: artifactCurrent ? "SOURCE" : "BLOCKED", + summary: `artifact targetCovered=${artifactIdentity.targetCoverage?.covered ?? "unknown"}; artifactSource=${short(artifactIdentity.artifactSource?.commitId)}; target=${short(artifactIdentity.source?.commitId)}; desiredApplyMode=${desired.mode ?? "unknown"}; mutationAttempted=${desired.mutationAttempted === true}.`, + evidence: [ + `artifactState=${artifactIdentity.artifactCatalog?.artifactState ?? "unknown"}`, + `sourceStates=${artifactSourceStates.sourcePresent} source-present, ${artifactSourceStates.intentionallyDisabled} intentionally-disabled`, + `desiredState=${desired.conclusion?.status ?? "not_reported"} dry-run-only` + ], + nextRequired: "Refresh artifact/source coverage for current origin/main and keep desired-state apply separate from read-only route proof." + } + }; +} + +function artifactSourceStateCounts(artifactReport) { + const counts = { sourcePresent: 0, intentionallyDisabled: 0 }; + for (const service of artifactReport.artifactPublish?.services ?? []) { + if (service.sourceState === "source-present") { + counts.sourcePresent += 1; + } else if (service.sourceState === "intentionally-disabled") { + counts.intentionallyDisabled += 1; + } + } + return counts; +} + function buildNextSteps(blockers) { const byOrder = new Map(); for (const blocker of blockers) { @@ -737,6 +941,8 @@ function fallbackAction(scope) { 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") || 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 === "db-live") return "Repair DEV cloud-api DB live readiness, then rerun the read-only health and M4 preflight reports without exposing secret values."; + if (scope === "m3-hardware-loop-runtime") return "Prove the real DEV M3 trusted loop res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1 with operation, trace, audit, and evidence identifiers."; 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."; } @@ -747,6 +953,8 @@ 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 === "db-live") return "Cloud API /health/live output with ready=true, connected=true, liveDbEvidence=true, and redacted secret references."; + if (scope === "m3-hardware-loop-runtime") return "Operation, trace, audit, and evidence IDs from the real DEV DO1 -> patch-panel -> DI1 trusted loop."; 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."; } @@ -787,6 +995,7 @@ export async function buildReport() { const blockers = collectBlockers(reports); const milestones = deriveMilestones(evidence, blockers); const dod = buildDoD(reports, milestones, blockers); + const currentDevLayering = buildCurrentDevLayering(reports, blockers); const nextSteps = buildNextSteps(blockers); const report = { "$schema": "https://hwlab.pikastech.local/schemas/dev-m5-gate-aggregator-v2.schema.json", @@ -794,7 +1003,7 @@ export async function buildReport() { reportVersion: "v2", reportKind: "dev-m5-gate-aggregator", issue: issue(58), - supports: [issue(7), issue(9), issue(31), issue(33), issue(34), issue(35), issue(36), issue(37), issue(38), issue(39), issue(46)], + supports: [issue(7), issue(9), issue(23), issue(26), issue(31), issue(33), issue(34), issue(35), issue(36), issue(37), issue(38), issue(39), issue(46), issue(64)], generatedAt: new Date().toISOString(), generatedFromCommit: gitCommit(), environment: ENVIRONMENT_DEV, @@ -832,9 +1041,10 @@ export async function buildReport() { green: dod.green, reason: dod.green ? "All #9 DEV DoD checks are green." - : "SOURCE, LOCAL, DRY-RUN, and edge DEV-LIVE evidence exists, but acceptance is still blocked by artifact, observability, DB, and loop evidence gaps." + : "EDGE/ROUTE DEV-LIVE evidence exists on :16666/:16667, but M5 remains blocked by artifact source drift, DB live degradation, missing M3 trusted loop operation evidence, and blocked M4 agent-loop preflight." }, dod, + currentDevLayering, milestones, evidence, levels: groupByLevel(evidence, blockers), @@ -862,6 +1072,9 @@ export function formatCheckSummary(report) { } export function renderMarkdown(report) { + const layeringLines = Object.entries(report.currentDevLayering) + .map(([, layer]) => `| ${layer.label} | ${layer.status} | ${layer.evidenceLevel} | ${layer.summary} | ${layer.nextRequired} |`) + .join("\n"); const milestoneLines = report.milestones .map((milestone) => `| ${milestone.id} | ${milestone.status} | ${milestone.highestVisibleLevel} | ${milestone.liveEvidence} | ${milestone.summary} |`) .join("\n"); @@ -885,6 +1098,12 @@ Scope: DEV only, report-only ${report.overall.reason} +## Current DEV Layering + +| Layer | Status | Evidence level | Current conclusion | Required next proof | +| --- | --- | --- | --- | --- | +${layeringLines} + ## Milestones | Milestone | Status | Highest visible level | Live evidence | Summary |