HWLAB L6 Frontend / CLI MVP
\ndiff --git a/docs/m2-dev-deploy-smoke.md b/docs/m2-dev-deploy-smoke.md index a465feea..2a2c842b 100644 --- a/docs/m2-dev-deploy-smoke.md +++ b/docs/m2-dev-deploy-smoke.md @@ -1,4 +1,4 @@ -# M2 DEV Deployment Smoke Dry-Run +# M2 DEV Deployment Smoke `m2-dev-deploy-smoke` is a local dry-run smoke harness for the HWLAB DEV deployment shape. It validates the frozen route phases, service identities, @@ -32,18 +32,24 @@ node scripts/m2-dev-deploy-smoke.mjs --dry-run ## Live Gate The live gate is intentionally strict. It is only for a future real DEV smoke -observation, not for deployment, and this harness stays fixture-only by -default. +observation, not for deployment, and this harness stays fixture-only unless the +operator supplies the live flags. The public DEV endpoint split is: + +- browser/frontend: `http://74.48.78.17:16666/` +- API/edge health: `http://74.48.78.17:16667/health` and + `http://74.48.78.17:16667/health/live` +- legacy public `:6667`: deprecated and never accepted as active green evidence Required flags: ```sh -node scripts/m2-dev-deploy-smoke.mjs --live --confirm-dev --confirmed-non-production +node scripts/m2-dev-deploy-smoke.mjs --live --confirm-dev --confirmed-non-production --write-report ``` Before using `--live`, confirm all of the following: -- the target remains `http://74.48.78.17:16667`; +- the API/edge target remains `http://74.48.78.17:16667`; +- the frontend target remains `http://74.48.78.17:16666`; - the workspace is not a PROD or shared deployment context; - no prohibited action is being attempted; - the request is observational only and does not mutate runtime state. @@ -57,6 +63,17 @@ The script rejects live execution if any of these are missing: - `--read-secret` - `--force-push` +When `--write-report` is provided, the script writes +`reports/dev-gate/dev-m2-deploy-smoke-active.json`. The report contains only +read-only GET evidence and marks legacy `:6667` observations as ineligible for +active green. + +Validate the written report with: + +```sh +node scripts/validate-m2-deploy-smoke-active.mjs +``` + ## Boundary This harness does not: diff --git a/fixtures/dev-deploy-smoke/dev-deploy-smoke.json b/fixtures/dev-deploy-smoke/dev-deploy-smoke.json index 4f0f8ab3..57a54928 100644 --- a/fixtures/dev-deploy-smoke/dev-deploy-smoke.json +++ b/fixtures/dev-deploy-smoke/dev-deploy-smoke.json @@ -3,6 +3,12 @@ "issue": "pikasTech/HWLAB#23", "environment": "dev", "endpoint": "http://74.48.78.17:16667", + "frontendEndpoint": "http://74.48.78.17:16666", + "legacyPublicEndpoint": { + "endpoint": "http://74.48.78.17:6667", + "status": "deprecated", + "activeGreenEligible": false + }, "defaultMode": "dry-run", "safetyGates": { "dryRunOnly": true, diff --git a/internal/protocol/index.mjs b/internal/protocol/index.mjs index 4b25cb64..3c68799c 100644 --- a/internal/protocol/index.mjs +++ b/internal/protocol/index.mjs @@ -1,5 +1,6 @@ export const ENVIRONMENT_DEV = "dev"; export const DEV_ENDPOINT = "http://74.48.78.17:16667"; +export const DEV_FRONTEND_ENDPOINT = "http://74.48.78.17:16666"; export const JSON_RPC_VERSION = "2.0"; export const SERVICE_IDS = Object.freeze([ diff --git a/reports/dev-gate/dev-m2-deploy-smoke-active.json b/reports/dev-gate/dev-m2-deploy-smoke-active.json new file mode 100644 index 00000000..1156c3fa --- /dev/null +++ b/reports/dev-gate/dev-m2-deploy-smoke-active.json @@ -0,0 +1,256 @@ +{ + "$schema": "https://hwlab.pikastech.local/schemas/dev-gate-report.schema.json", + "$id": "https://hwlab.pikastech.local/reports/dev-gate/dev-m2-deploy-smoke-active.json", + "reportVersion": "v1", + "issue": "pikasTech/HWLAB#23", + "taskId": "m2-dev-deploy-smoke", + "commitId": "54f927b02bc1", + "acceptanceLevel": "dev_m2_deploy_smoke", + "devOnly": true, + "prodDisabled": true, + "status": "pass", + "generatedAt": "2026-05-22T04:53:00.375Z", + "endpoint": "http://74.48.78.17:16667", + "frontendEndpoint": "http://74.48.78.17:16666", + "sourceContract": { + "status": "pass", + "documents": [ + "docs/m2-dev-deploy-smoke.md", + "docs/dev-acceptance-matrix.md", + "fixtures/dev-deploy-smoke/dev-deploy-smoke.json" + ], + "summary": "M2 DEV deploy smoke is rebaselined to frontend :16666 and API/edge :16667." + }, + "validationCommands": [ + "node --check scripts/m2-dev-deploy-smoke.mjs", + "node scripts/m2-dev-deploy-smoke.mjs --dry-run", + "node scripts/m2-dev-deploy-smoke.mjs --live --confirm-dev --confirmed-non-production --write-report", + "node --check scripts/validate-dev-gate-report.mjs", + "node scripts/validate-dev-gate-report.mjs" + ], + "localSmoke": { + "status": "pass", + "commands": [ + "node scripts/m2-dev-deploy-smoke.mjs --dry-run" + ], + "evidence": [ + "[m2-smoke] validated 11 service contracts", + "[m2-smoke] mode=dry-run endpoint=http://74.48.78.17:16667", + "[m2-smoke] no real DEV/PROD request was made" + ], + "summary": "The fixture smoke validates the M2 route and artifact contract without contacting DEV." + }, + "dryRun": { + "status": "pass", + "commands": [ + "node scripts/m2-dev-deploy-smoke.mjs --dry-run" + ], + "evidence": [ + "fixture endpoint=http://74.48.78.17:16667", + "fixture frontendEndpoint=http://74.48.78.17:16666", + "legacy :6667 public evidence is marked ineligible for active green" + ], + "summary": "Dry-run evidence is contract-only and pinned to the current DEV public endpoints." + }, + "devPreconditions": { + "status": "pass", + "requirements": [ + "GET http://74.48.78.17:16667/health returns HWLAB DEV JSON", + "GET http://74.48.78.17:16667/health/live returns HWLAB DEV JSON", + "GET http://74.48.78.17:16666/ returns the HWLAB DEV frontend", + "No PROD, secret read, runtime restart, deployment, or heavyweight e2e action is performed" + ], + "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": [ + "api-health: HTTP 200 accepted=yes identity=hwlab-edge-proxy url=http://74.48.78.17:16667/health", + "api-live: HTTP 200 accepted=yes identity=hwlab-cloud-api url=http://74.48.78.17:16667/health/live", + "frontend-root: HTTP 200 accepted=yes identity=HWLAB DEV MVP Gate url=http://74.48.78.17:16666/" + ], + "summary": "Read-only DEV public endpoint probes passed on :16666/:16667." + }, + "blockers": [], + "runtimeSmoke": { + "mode": "live-read-only", + "status": "pass", + "generatedAt": "2026-05-22T04:53:00.375Z", + "apiEndpoint": "http://74.48.78.17:16667", + "frontendEndpoint": "http://74.48.78.17:16666", + "safety": { + "environment": "dev", + "prodTouched": false, + "secretsRead": false, + "restarts": false, + "deployAttempted": false, + "heavyE2E": false, + "unideskRuntimeSubstitute": false + }, + "probes": [ + { + "id": "api-health", + "url": "http://74.48.78.17:16667/health", + "ok": true, + "status": 200, + "statusText": "OK", + "durationMs": 939, + "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" + }, + "json": { + "serviceId": "hwlab-edge-proxy", + "environment": "dev", + "status": "ok", + "service": { + "id": "hwlab-edge-proxy", + "role": "public-dev-ingress", + "healthPath": "/health", + "livePath": "/health/live" + }, + "commit": { + "id": "cb35ada6860653b27269b0a57991184118cbf4b1", + "source": "runtime-env" + }, + "image": { + "reference": "ghcr.io/pikastech/hwlab-edge-proxy:cb35ada", + "tag": "cb35ada", + "digest": "unknown" + }, + "endpoint": "http://74.48.78.17:16667", + "observedAt": "2026-05-22T04:53:00.143Z", + "details": { + "upstream": "http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667", + "mode": "dev-edge-proxy" + } + }, + "title": null, + "bodyPreview": "{\n \"serviceId\": \"hwlab-edge-proxy\",\n \"environment\": \"dev\",\n \"status\": \"ok\",\n \"service\": {\n \"id\": \"hwlab-edge-proxy\",\n \"role\": \"public-dev-ingress\",\n \"healthPath\": \"/health\",\n \"livePath\": \"/health/live\"\n },\n \"commit\": {\n \"id\": \"cb35ada6860653b27269b0a57991184118cbf4b1\",\n \"source\": \"runtime-env\"\n },\n \"image\": {\n \"reference\": \"ghcr.io/pikastech/hwlab-edge-proxy:cb35ada\",\n \"tag\": \"cb35ada\",\n \"digest\": \"unknown\"\n },\n \"endpoint\": \"http://74.48.78.17:16667\",\n \"observedAt\": \"20" + }, + { + "id": "api-live", + "url": "http://74.48.78.17:16667/health/live", + "ok": true, + "status": 200, + "statusText": "OK", + "durationMs": 936, + "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" + }, + "json": { + "serviceId": "hwlab-cloud-api", + "environment": "dev", + "status": "degraded", + "service": { + "id": "hwlab-cloud-api", + "role": "cloud-api", + "healthPath": "/health", + "livePath": "/health/live" + }, + "commit": { + "id": "cb35ada", + "source": "runtime-env" + }, + "image": { + "reference": "127.0.0.1:5000/hwlab/hwlab-cloud-api:cb35ada", + "tag": "cb35ada", + "digest": "unknown" + }, + "endpoint": "http://74.48.78.17:16667", + "observedAt": "2026-05-22T04:53:00.145Z", + "db": { + "contractVersion": "v1", + "environment": "dev", + "connected": false, + "connectionChecked": false, + "configReady": true, + "ready": false, + "status": "degraded", + "mode": "configured_without_live_connection", + "fields": [ + { + "name": "HWLAB_CLOUD_DB_URL", + "present": true, + "redacted": true, + "source": "k8s-secret-ref", + "required": true + }, + { + "name": "HWLAB_CLOUD_DB_SSL_MODE", + "present": true, + "redacted": false, + "source": "runtime-env", + "required": true + } + ], + "missingEnv": [], + "secretRefs": [ + { + "env": "HWLAB_CLOUD_DB_URL", + "secretName": "hwlab-cloud-api-dev-db", + "secretKey": "database-url", + "present": true, + "redacted": true + } + ], + "safety": { + "devOnly": true, + "prodAllowed": false, + "secretsRead": false, + "valuesRedacted": true, + "liveDbEvidence": false + }, + "evidence": "env_presence_only_no_live_db" + }, + "runtime": { + "adapter": "memory", + "durable": false, + "status": "degraded", + "reason": "live DB persistence is not connected; L1 runtime writes are process-local only", + "counts": { + "gatewaySessions": 0, + "boxResources": 0, + "boxCapabilities": 0, + "hardwareOperations": 0, + "auditEvents": 0, + "evidenceRecords": 0 + } + } + }, + "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\":" + }, + { + "id": "frontend-root", + "url": "http://74.48.78.17:16666/", + "ok": true, + "status": 200, + "statusText": "OK", + "durationMs": 923, + "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" + }, + "json": null, + "title": "HWLAB DEV MVP Gate", + "bodyPreview": "\n\n
\n \n \nHWLAB L6 Frontend / CLI MVP
\n