docs: freeze DEV acceptance endpoint contract

Commander review: replaces conflicted #83 with a latest-main, docs-only PR. Scope is limited to endpoint contract and M3 evidence classification; no generated reports, no deploy, no PROD. Validated JSON parse, git diff --check, and node scripts/validate-contract.mjs.
This commit is contained in:
Lyon
2026-05-22 14:41:12 +08:00
committed by GitHub
2 changed files with 104 additions and 19 deletions
+68 -8
View File
@@ -5,6 +5,25 @@
"issue": "pikasTech/HWLAB#22", "issue": "pikasTech/HWLAB#22",
"environment": "dev", "environment": "dev",
"endpoint": "http://74.48.78.17:16667", "endpoint": "http://74.48.78.17:16667",
"publicEndpoints": {
"frontend": "http://74.48.78.17:16666",
"api": "http://74.48.78.17:16667",
"edge": "http://74.48.78.17:16667"
},
"internalServicePorts": [
{
"serviceId": "hwlab-cloud-api",
"scope": "k3s-service",
"port": 6667,
"note": "Internal k3s service port only; not a public DEV endpoint."
},
{
"serviceId": "hwlab-edge-proxy",
"scope": "k3s-service",
"port": 6667,
"note": "Internal k3s service/listen port only; public API/edge ingress is 16667."
}
],
"runtimeSubstitutePolicy": { "runtimeSubstitutePolicy": {
"allowedExternalRoles": [ "allowedExternalRoles": [
"scheduling", "scheduling",
@@ -17,6 +36,40 @@
"unidesk-microservice-proxy" "unidesk-microservice-proxy"
] ]
}, },
"m3EvidenceClassification": {
"p0Scope": "M3 virtual hardware trusted loop",
"requiredCardinality": {
"hwlab-box-simu": 2,
"hwlab-gateway-simu": 2,
"hwlab-patch-panel": 1
},
"m3Live": {
"requiredLink": "DO1 -> hwlab-patch-panel -> DI1",
"requiredIdentifiers": [
"operationId",
"traceId",
"auditId",
"evidenceId"
],
"classification": "DEV-LIVE"
},
"m3Support": [
"endpoint-freeze",
"read-only-edge-curl",
"source-contract",
"static-manifest-cardinality",
"local-smoke",
"dry-run-fixture"
],
"nonP0": [
"SOURCE",
"LOCAL",
"DRY-RUN",
"fixture-only",
"edge-only-diagnostic"
],
"promotionRule": "Do not classify M3 support or non-P0 evidence as DEV-LIVE unless the traced DO1 -> hwlab-patch-panel -> DI1 path is observed."
},
"artifactObservabilityFields": [ "artifactObservabilityFields": [
"serviceId", "serviceId",
"commitId", "commitId",
@@ -37,11 +90,18 @@
}, },
"route": [ "route": [
{ {
"id": "dev-endpoint", "id": "dev-api-edge-endpoint",
"label": "DEV endpoint", "label": "DEV API/edge endpoint",
"serviceId": "hwlab-edge-proxy", "serviceId": "hwlab-edge-proxy",
"endpoint": "http://74.48.78.17:16667", "endpoint": "http://74.48.78.17:16667",
"role": "public-dev-ingress" "role": "public-api-edge-ingress"
},
{
"id": "dev-frontend-endpoint",
"label": "DEV frontend endpoint",
"serviceId": "hwlab-cloud-web",
"endpoint": "http://74.48.78.17:16666",
"role": "public-frontend"
}, },
{ {
"id": "master-edge-proxy", "id": "master-edge-proxy",
@@ -343,8 +403,8 @@
"id": "endpoint-freeze", "id": "endpoint-freeze",
"order": 2, "order": 2,
"probe": "Compare documented and fixture DEV endpoints.", "probe": "Compare documented and fixture DEV endpoints.",
"successCriteria": "All DEV endpoints equal http://74.48.78.17:16667.", "successCriteria": "Public frontend is exactly http://74.48.78.17:16666; public API/edge is exactly http://74.48.78.17:16667; internal 6667 appears only as a k3s service/listen port.",
"failureCriteria": "Any alternate DEV endpoint or PROD target.", "failureCriteria": "Any alternate public DEV endpoint, old public :6667, or PROD target.",
"blockerClass": "environment_blocker" "blockerClass": "environment_blocker"
}, },
{ {
@@ -383,7 +443,7 @@
"id": "cloud-surface", "id": "cloud-surface",
"order": 7, "order": 7,
"probe": "Check cloud API health and cloud web endpoint configuration.", "probe": "Check cloud API health and cloud web endpoint configuration.",
"successCriteria": "Cloud API health is valid and web assets point at the fixed DEV endpoint.", "successCriteria": "Cloud API health is valid on public :16667; web assets are served on public :16666 and point API traffic at :16667 or the internal k3s API service.",
"failureCriteria": "Bad health, endpoint drift, or direct hardware control from web.", "failureCriteria": "Bad health, endpoint drift, or direct hardware control from web.",
"blockerClass": "runtime_blocker" "blockerClass": "runtime_blocker"
}, },
@@ -391,8 +451,8 @@
"id": "gateway-sim-patch-panel", "id": "gateway-sim-patch-panel",
"order": 8, "order": 8,
"probe": "Check gateway, gateway simulator, box simulator, and patch-panel health/status.", "probe": "Check gateway, gateway simulator, box simulator, and patch-panel health/status.",
"successCriteria": "Health/status JSON is parseable and topology keeps routing under patch-panel ownership.", "successCriteria": "Health/status JSON is parseable and topology keeps routing under patch-panel ownership; for M3 live, a traced DO1 -> patch-panel -> DI1 operation exists.",
"failureCriteria": "Missing health, invalid topology, or bypass path.", "failureCriteria": "Missing health, invalid topology, bypass path, or any attempt to promote support/fixture evidence to M3 live.",
"blockerClass": "runtime_blocker" "blockerClass": "runtime_blocker"
}, },
{ {
+36 -11
View File
@@ -6,15 +6,40 @@ DEV or PROD deployment.
## Fixed Boundary ## Fixed Boundary
- DEV endpoint: `http://74.48.78.17:16667` - DEV frontend endpoint: `http://74.48.78.17:16666`
- DEV API/edge endpoint: `http://74.48.78.17:16667`
- Deploy environment: `dev` - Deploy environment: `dev`
- Legacy endpoint `:6666` is deprecated; browser entry is `:16666` and API/health entry is `:16667`. - Legacy public endpoints `:6666` and `:6667` are deprecated; browser entry
is `:16666` and API/health entry is `:16667`.
- Internal k3s service ports may still use `6667`, for example
`hwlab-cloud-api` and `hwlab-edge-proxy`. Internal `6667` is not a public
DEV acceptance endpoint.
- Runtime route: client, master `hwlab-edge-proxy`, `frp`, D601 - Runtime route: client, master `hwlab-edge-proxy`, `frp`, D601
`hwlab-dev/hwlab-router`, then HWLAB cloud/runtime services. `hwlab-dev/hwlab-router`, then HWLAB cloud/runtime services.
- UniDesk backend, provider-gateway, and microservice proxy are not accepted as - UniDesk backend, provider-gateway, and microservice proxy are not accepted as
substitutes for HWLAB runtime services in this first version. They may remain substitutes for HWLAB runtime services in this first version. They may remain
external scheduling, CI, or CD support only. external scheduling, CI, or CD support only.
## M3 Evidence Classification
Current P0 DEV acceptance remains the M3 virtual hardware trusted loop: two
`hwlab-box-simu` instances, two `hwlab-gateway-simu` instances, and one
`hwlab-patch-panel`.
`M3 live` can be claimed only when a DEV observation proves a real
`DO1 -> hwlab-patch-panel -> DI1` path and records the operation, trace, audit,
and evidence identifiers. The patch panel must own the route decision; direct
box-to-box propagation or fixture output is not M3 live evidence.
`M3 support` includes this endpoint freeze, read-only public edge curl evidence,
source contracts, static manifest cardinality, local smoke output, and dry-run
fixtures. These items support release or pre-release decisions, but they are not
P0 live acceptance.
`Non-P0` includes SOURCE, LOCAL, DRY-RUN, fixture-only, diagnostic, and
edge-only observations that do not prove the full `DO1 -> patch-panel -> DI1`
link. These observations must not be written as `DEV-LIVE`.
## Required Artifact Observability ## Required Artifact Observability
Every deployable HWLAB artifact that participates in DEV acceptance must expose Every deployable HWLAB artifact that participates in DEV acceptance must expose
@@ -42,19 +67,19 @@ provide a current health timestamp. Existing skeleton services may expose
| Component | Service ID | Check | Success | Failure | | Component | Service ID | Check | Success | Failure |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| DEV ingress | `hwlab-edge-proxy` | `GET http://74.48.78.17:16667/health` or routed service health | HTTP 2xx/3xx reaches HWLAB DEV path and reports edge identity or downstream HWLAB identity | Timeout, non-HWLAB response, PROD route, missing artifact fields | | DEV API/edge ingress | `hwlab-edge-proxy` | `GET http://74.48.78.17:16667/health` or routed service health | HTTP 2xx/3xx reaches HWLAB DEV path and reports edge identity or downstream HWLAB identity | Timeout, non-HWLAB response, PROD route, missing artifact fields |
| master edge proxy | `hwlab-edge-proxy` | Edge proxy health and route table observation | Route for `http://74.48.78.17:16667` forwards to `frp` and identifies commit/image | No DEV route, wrong port, missing route observability | | master edge proxy | `hwlab-edge-proxy` | Edge proxy health and route table observation | Route for `http://74.48.78.17:16667` forwards to `frp` and identifies commit/image | No DEV route, wrong port, missing route observability |
| frp tunnel | `hwlab-tunnel-client` | Tunnel session/status observation | Tunnel for DEV route is established to D601 router and identifies commit/image | Tunnel down, wrong target, ambiguous service identity | | frp tunnel | `hwlab-tunnel-client` | Tunnel session/status observation | Tunnel for DEV route is established to D601 router and identifies commit/image | Tunnel down, wrong target, ambiguous service identity |
| D601 router | `hwlab-router` | `hwlab-dev/hwlab-router` health/status | Router is live, environment is `dev`, route target is cloud API/web or runtime service | Namespace mismatch, route missing, stale health timestamp | | D601 router | `hwlab-router` | `hwlab-dev/hwlab-router` health/status | Router is live, environment is `dev`, route target is cloud API/web or runtime service | Namespace mismatch, route missing, stale health timestamp |
| Cloud API | `hwlab-cloud-api` | `GET /health`, `GET /live`, optional JSON-RPC `/rpc` probe | Returns service ID, `dev`, healthy/live status, redacted DB env readiness, and accepts a harmless protocol probe | HTTP error, unknown service ID, wrong environment, invalid JSON-RPC envelope, missing DB env readiness | | Cloud API | `hwlab-cloud-api` | `GET /health`, `GET /live`, optional JSON-RPC `/rpc` probe | Returns service ID, `dev`, healthy/live status, redacted DB env readiness, and accepts a harmless protocol probe | HTTP error, unknown service ID, wrong environment, invalid JSON-RPC envelope, missing DB env readiness |
| Cloud Web | `hwlab-cloud-web` | Static asset check and configured DEV endpoint | Web bundle references `http://74.48.78.17:16667` and does not call hardware directly | Endpoint drift, direct hardware control path, missing asset | | Cloud Web | `hwlab-cloud-web` | `GET http://74.48.78.17:16666/` plus static asset check and configured API endpoint | Public browser entry serves the web bundle on `:16666`; API calls target `http://74.48.78.17:16667` or the internal k3s API service, and do not call hardware directly | Endpoint drift, public web served from `:6667`, direct hardware control path, missing asset |
| Agent manager | `hwlab-agent-mgr` | Agent scheduling health/status | Reports live manager, commit/image, and DEV environment; no worker leak after smoke | Scheduler unavailable, wrong environment, unbounded worker session | | Agent manager | `hwlab-agent-mgr` | Agent scheduling health/status | Reports live manager, commit/image, and DEV environment; no worker leak after smoke | Scheduler unavailable, wrong environment, unbounded worker session |
| Agent worker | `hwlab-agent-worker` | Worker health/status during dry-run or scoped smoke | Worker session is scoped to DEV project and emits trace/audit identifiers | Missing session identity, unsafe mutation, cleanup failure | | Agent worker | `hwlab-agent-worker` | Worker health/status during dry-run or scoped smoke | Worker session is scoped to DEV project and emits trace/audit identifiers | Missing session identity, unsafe mutation, cleanup failure |
| Agent skills | `hwlab-agent-skills` | Skill bundle version/status | Skill artifact is traceable to commit/build source and compatible with worker | Unversioned skill bundle, missing build source | | Agent skills | `hwlab-agent-skills` | Skill bundle version/status | Skill artifact is traceable to commit/build source and compatible with worker | Unversioned skill bundle, missing build source |
| Gateway | `hwlab-gateway` | `GET /health/live` and `GET /status` when present | Reports DEV gateway boundary and does not bypass patch-panel constraints | Hardware boundary unavailable, non-DEV gateway, direct box mutation | | Gateway | `hwlab-gateway` | `GET /health/live` and `GET /status` when present | Reports DEV gateway boundary and does not bypass patch-panel constraints | Hardware boundary unavailable, non-DEV gateway, direct box mutation |
| Gateway simulator | `hwlab-gateway-simu` | `GET /health/live`, `GET /status`, `GET /boxes` | Simulator is live, lists expected box resources, and identifies DEV project | Simulator down, box list missing, stale timestamp | | Gateway simulator | `hwlab-gateway-simu` | `GET /health/live`, `GET /status`, `GET /boxes` | Simulator is live, lists expected box resources, and identifies DEV project; this is M3 support until paired with the full patch-panel link observation | Simulator down, box list missing, stale timestamp |
| Box simulator | `hwlab-box-simu` | `GET /health/live`, `GET /status` | Simulator is live and reports resources, ports, and patch-panel-only propagation | Cross-device propagation outside patch panel, missing resource state | | Box simulator | `hwlab-box-simu` | `GET /health/live`, `GET /status` | Simulator is live and reports resources, ports, and patch-panel-only propagation; this is M3 support until paired with the full patch-panel link observation | Cross-device propagation outside patch panel, missing resource state |
| Patch panel | `hwlab-patch-panel` | `GET /health/live`, `GET /status`, `GET /wiring` | Wiring config is parseable and patch-panel state owns routing decisions | Invalid topology, direct bypass path, stale patch state | | Patch panel | `hwlab-patch-panel` | `GET /health/live`, `GET /status`, `GET /wiring` | Wiring config is parseable and patch-panel state owns routing decisions; M3 live also requires a traced `DO1 -> patch-panel -> DI1` operation | Invalid topology, direct bypass path, stale patch state |
| CLI | `hwlab-cli` | `npm run cli:health` and dry-run command | CLI uses DEV endpoint and dry-run states no DEV/PROD changes were made | Wrong endpoint, missing dry-run guard, real mutation attempted | | CLI | `hwlab-cli` | `npm run cli:health` and dry-run command | CLI uses DEV endpoint and dry-run states no DEV/PROD changes were made | Wrong endpoint, missing dry-run guard, real mutation attempted |
## DEV Smoke Matrix ## DEV Smoke Matrix
@@ -67,13 +92,13 @@ listed above.
| Step | Probe | Success Criteria | Failure Criteria | Blocker Class | | Step | Probe | Success Criteria | Failure Criteria | Blocker Class |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| 1 | Confirm repository contract files and JSON checklist parse. | `docs/dev-acceptance-matrix.md` exists and `docs/dev-acceptance-checklist.json` parses. | Missing file or invalid JSON. | `contract_blocker` | | 1 | Confirm repository contract files and JSON checklist parse. | `docs/dev-acceptance-matrix.md` exists and `docs/dev-acceptance-checklist.json` parses. | Missing file or invalid JSON. | `contract_blocker` |
| 2 | Verify frozen DEV endpoint. | Endpoint is exactly `http://74.48.78.17:16667` in docs/checklist/runtime fixtures. | Any alternate DEV endpoint or PROD target. | `environment_blocker` | | 2 | Verify frozen DEV endpoints. | Public frontend is exactly `http://74.48.78.17:16666`; public API/edge is exactly `http://74.48.78.17:16667`; internal `6667` appears only as a k3s service/listen port. | Any alternate public DEV endpoint, old public `:6667`, or PROD target. | `environment_blocker` |
| 3 | Observe DEV ingress health. | Request reaches HWLAB DEV route and returns HWLAB identity or accepted downstream health. | Timeout, non-HWLAB target, wrong port. | `network_blocker` | | 3 | Observe DEV API/edge ingress health. | Request reaches HWLAB DEV route and returns HWLAB identity or accepted downstream health. | Timeout, non-HWLAB target, wrong public port. | `network_blocker` |
| 4 | Observe master edge proxy route. | Edge route maps DEV endpoint to `frp` and records artifact identity. | Missing route, stale route, missing artifact identity. | `network_blocker` | | 4 | Observe master edge proxy route. | Edge route maps DEV endpoint to `frp` and records artifact identity. | Missing route, stale route, missing artifact identity. | `network_blocker` |
| 5 | Observe `frp` tunnel. | Tunnel links master edge to D601 router for DEV. | Tunnel down or target mismatch. | `network_blocker` | | 5 | Observe `frp` tunnel. | Tunnel links master edge to D601 router for DEV. | Tunnel down or target mismatch. | `network_blocker` |
| 6 | Observe D601 `hwlab-dev/hwlab-router`. | Router is live and forwards only to HWLAB DEV services. | Namespace mismatch or route bypass. | `runtime_blocker` | | 6 | Observe D601 `hwlab-dev/hwlab-router`. | Router is live and forwards only to HWLAB DEV services. | Namespace mismatch or route bypass. | `runtime_blocker` |
| 7 | Check cloud API/web surface. | Cloud API health is valid; web assets point at fixed DEV endpoint. | Bad health, endpoint drift, direct hardware control from web. | `runtime_blocker` | | 7 | Check cloud API/web surface. | Cloud API health is valid on public `:16667`; web assets are served on public `:16666` and point API traffic at `:16667` or the internal k3s API service. | Bad health, endpoint drift, direct hardware control from web. | `runtime_blocker` |
| 8 | Check gateway, simulator, box simulator, and patch-panel contracts. | Health/status JSON is parseable and topology keeps routing under patch-panel ownership. | Missing health, invalid topology, bypass path. | `runtime_blocker` | | 8 | Check gateway, simulator, box simulator, and patch-panel contracts. | Health/status JSON is parseable and topology keeps routing under patch-panel ownership; for M3 live, a traced `DO1 -> patch-panel -> DI1` operation exists. | Missing health, invalid topology, bypass path, or any attempt to promote support/fixture evidence to M3 live. | `runtime_blocker` |
| 9 | Check agent manager, worker, and skills contracts. | Agent artifacts are traceable; dry-run/scoped smoke emits session, trace, audit, and cleanup evidence. | Missing traceability, unsafe mutation, cleanup leak. | `agent_blocker` | | 9 | Check agent manager, worker, and skills contracts. | Agent artifacts are traceable; dry-run/scoped smoke emits session, trace, audit, and cleanup evidence. | Missing traceability, unsafe mutation, cleanup leak. | `agent_blocker` |
| 10 | Verify evidence and artifact observability. | Every accepted artifact has service ID, commit, image/tag/digest or reason, build source, env, and health timestamp. | Missing required observability field. | `observability_blocker` | | 10 | Verify evidence and artifact observability. | Every accepted artifact has service ID, commit, image/tag/digest or reason, build source, env, and health timestamp. | Missing required observability field. | `observability_blocker` |