chore: establish hwlab l0 contract skeleton
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# HWLAB Protocol Contract
|
||||
|
||||
The L0 protocol contract defines the common language between cloud services,
|
||||
gateway services, simulated boxes, agent workers, CLI tooling, and future
|
||||
hardware integrations.
|
||||
|
||||
All MVP implementations must preserve these invariants:
|
||||
|
||||
- Use JSON-RPC 2.0 envelopes for command-style API calls unless a later
|
||||
service contract explicitly narrows the transport.
|
||||
- Emit auditable records for user, system, gateway, worker, and hardware
|
||||
actions that mutate state or produce evidence.
|
||||
- Describe box hardware through capabilities, resource state, and wiring
|
||||
constraints instead of service-specific ad hoc fields.
|
||||
- Treat DEV as the only MVP acceptance environment.
|
||||
- Keep service identities within the frozen service ID list in the root
|
||||
README.
|
||||
|
||||
## Frozen Tables
|
||||
|
||||
The database contract is intentionally named here before migrations exist so
|
||||
parallel MVP work shares stable terminology:
|
||||
|
||||
- `projects`
|
||||
- `gateway_sessions`
|
||||
- `box_resources`
|
||||
- `box_capabilities`
|
||||
- `wiring_configs`
|
||||
- `patch_panel_status`
|
||||
- `hardware_operations`
|
||||
- `audit_events`
|
||||
- `agent_sessions`
|
||||
- `worker_sessions`
|
||||
- `agent_trace_events`
|
||||
- `evidence_records`
|
||||
|
||||
## Schema Status
|
||||
|
||||
Schemas in `protocol/schemas` are draft-2020-12 JSON Schemas. They define L0
|
||||
field names, identities, relationships, timestamps, and state enums. Later
|
||||
service work may tighten validation, but must not silently rename these L0
|
||||
contract fields.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Audit Fields
|
||||
|
||||
Mutating calls and evidence-producing workflows must carry audit metadata from
|
||||
the caller through to persisted `audit_events`.
|
||||
|
||||
## Required Fields
|
||||
|
||||
- `auditId`: stable audit event identifier.
|
||||
- `traceId`: cross-service trace identifier.
|
||||
- `actorType`: `user`, `service`, `agent`, `worker`, or `system`.
|
||||
- `actorId`: stable identity for the actor.
|
||||
- `action`: dotted action name such as `hardware.operation.requested`.
|
||||
- `targetType`: resource family affected by the action.
|
||||
- `targetId`: stable target identifier.
|
||||
- `serviceId`: frozen HWLAB service ID emitting the event.
|
||||
- `environment`: `dev` for MVP.
|
||||
- `occurredAt`: RFC 3339 timestamp.
|
||||
|
||||
## Recommended Fields
|
||||
|
||||
- `projectId`: project scope for the action.
|
||||
- `gatewaySessionId`: gateway session participating in the action.
|
||||
- `workerSessionId`: worker session participating in the action.
|
||||
- `operationId`: hardware operation connected to the action.
|
||||
- `outcome`: `accepted`, `succeeded`, `failed`, `rejected`, or `canceled`.
|
||||
- `reason`: short machine-readable reason for rejection or failure.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Capability Model
|
||||
|
||||
Box hardware is described with resources and capabilities.
|
||||
|
||||
## Resource
|
||||
|
||||
A box resource is a physical or simulated component that can be addressed by
|
||||
the gateway:
|
||||
|
||||
- board
|
||||
- power supply
|
||||
- serial port
|
||||
- network port
|
||||
- relay
|
||||
- sensor
|
||||
- simulator endpoint
|
||||
|
||||
Resources carry lifecycle state such as `available`, `reserved`, `running`,
|
||||
`maintenance`, or `offline`.
|
||||
|
||||
## Capability
|
||||
|
||||
A capability describes an action or measurement exposed by a resource. Examples:
|
||||
|
||||
- `power.cycle`
|
||||
- `power.set_voltage`
|
||||
- `serial.console`
|
||||
- `network.link`
|
||||
- `firmware.flash`
|
||||
- `sensor.read`
|
||||
|
||||
Capabilities declare:
|
||||
|
||||
- direction: `input`, `output`, or `bidirectional`
|
||||
- value type: `boolean`, `integer`, `number`, `string`, `object`, or `binary`
|
||||
- optional unit
|
||||
- constraints for allowed values or ranges
|
||||
- whether the operation mutates hardware state
|
||||
|
||||
## Operation Binding
|
||||
|
||||
Hardware operations reference capabilities by `capabilityId` and resources by
|
||||
`resourceId`. Implementations must not infer a capability from a free-form
|
||||
operation name when a capability record exists.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Error Codes
|
||||
|
||||
HWLAB uses JSON-RPC standard errors plus a reserved HWLAB server-error range.
|
||||
|
||||
| Code | Name | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `-32700` | `parse_error` | Invalid JSON payload. |
|
||||
| `-32600` | `invalid_request` | Invalid JSON-RPC envelope. |
|
||||
| `-32601` | `method_not_found` | Method is unknown to the target service. |
|
||||
| `-32602` | `invalid_params` | Method parameters failed validation. |
|
||||
| `-32603` | `internal_error` | Unexpected service failure. |
|
||||
| `-32000` | `hwlab_unknown` | Unclassified HWLAB runtime error. |
|
||||
| `-32010` | `project_not_found` | Project ID is not known or not visible. |
|
||||
| `-32011` | `session_not_found` | Gateway, agent, or worker session is missing. |
|
||||
| `-32020` | `capability_unavailable` | Requested hardware capability is unavailable. |
|
||||
| `-32021` | `resource_locked` | Box resource is already reserved or running. |
|
||||
| `-32022` | `wiring_invalid` | Wiring config violates topology constraints. |
|
||||
| `-32023` | `operation_rejected` | Hardware operation cannot be accepted. |
|
||||
| `-32030` | `evidence_missing` | Required evidence record was not produced. |
|
||||
| `-32040` | `audit_required` | A mutating action was attempted without audit metadata. |
|
||||
|
||||
Error responses must include `error.message`. `error.data` should carry stable
|
||||
machine-readable fields such as `projectId`, `sessionId`, `resourceId`, or
|
||||
`operationId` when available.
|
||||
@@ -0,0 +1,70 @@
|
||||
# JSON-RPC Envelope
|
||||
|
||||
HWLAB command-style APIs use JSON-RPC 2.0 envelopes.
|
||||
|
||||
## Request
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "req_01J00000000000000000000000",
|
||||
"method": "hardware.operation.request",
|
||||
"params": {
|
||||
"projectId": "prj_01J00000000000000000000000"
|
||||
},
|
||||
"meta": {
|
||||
"traceId": "trc_01J00000000000000000000000",
|
||||
"actorId": "usr_01J00000000000000000000000",
|
||||
"serviceId": "hwlab-cloud-api",
|
||||
"environment": "dev"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Response
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "req_01J00000000000000000000000",
|
||||
"result": {
|
||||
"accepted": true
|
||||
},
|
||||
"meta": {
|
||||
"traceId": "trc_01J00000000000000000000000",
|
||||
"serviceId": "hwlab-agent-mgr",
|
||||
"environment": "dev"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "req_01J00000000000000000000000",
|
||||
"error": {
|
||||
"code": -32020,
|
||||
"message": "Requested hardware capability is unavailable",
|
||||
"data": {
|
||||
"capabilityId": "cap_01J00000000000000000000000"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"traceId": "trc_01J00000000000000000000000",
|
||||
"serviceId": "hwlab-gateway",
|
||||
"environment": "dev"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Envelope Rules
|
||||
|
||||
- `jsonrpc` is always `2.0`.
|
||||
- `id` is required for request/response flows and must be echoed unchanged.
|
||||
- `method` names use dotted lower-case namespaces.
|
||||
- `params` must be an object when present.
|
||||
- A response contains exactly one of `result` or `error`.
|
||||
- `meta.traceId` is required for all cross-service calls.
|
||||
- `meta.environment` is `dev` for MVP.
|
||||
@@ -0,0 +1,31 @@
|
||||
# MVP E2E Contract
|
||||
|
||||
The L0 e2e contract is a sequence contract for future MVP tests. It is not a
|
||||
heavy e2e test suite.
|
||||
|
||||
## DEV Endpoint
|
||||
|
||||
All MVP acceptance traffic targets:
|
||||
|
||||
```text
|
||||
http://74.48.78.17:6667
|
||||
```
|
||||
|
||||
## Minimal Flow
|
||||
|
||||
1. Create or select a project.
|
||||
2. Start a gateway session for `hwlab-gateway` or `hwlab-gateway-simu`.
|
||||
3. Register box resources and capabilities.
|
||||
4. Apply a wiring config that passes topology validation.
|
||||
5. Start an agent session and worker session.
|
||||
6. Request a hardware operation through JSON-RPC.
|
||||
7. Emit trace events as the operation is accepted, dispatched, executed, and
|
||||
completed.
|
||||
8. Persist an evidence record for the operation.
|
||||
9. Emit audit events for mutating steps and final outcome.
|
||||
|
||||
## Acceptance Boundary
|
||||
|
||||
For L0, acceptance is limited to parseable schemas, stable contract names, and
|
||||
minimal in-process validation. PROD deployment, service restarts, and full e2e
|
||||
execution are explicitly out of scope.
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/agent-session.schema.json",
|
||||
"title": "HWLAB Agent Session",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"agentSessionId",
|
||||
"projectId",
|
||||
"serviceId",
|
||||
"status",
|
||||
"environment",
|
||||
"startedAt",
|
||||
"updatedAt"
|
||||
],
|
||||
"properties": {
|
||||
"agentSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"const": "hwlab-agent-mgr"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["starting", "active", "waiting", "completed", "failed", "canceled"]
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"requestedBy": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"goal": {
|
||||
"type": "string",
|
||||
"maxLength": 4000
|
||||
},
|
||||
"startedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"completedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/audit-event.schema.json",
|
||||
"title": "HWLAB Audit Event",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"auditId",
|
||||
"traceId",
|
||||
"actorType",
|
||||
"actorId",
|
||||
"action",
|
||||
"targetType",
|
||||
"targetId",
|
||||
"serviceId",
|
||||
"environment",
|
||||
"occurredAt"
|
||||
],
|
||||
"properties": {
|
||||
"auditId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"traceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"actorType": {
|
||||
"$ref": "common.json#/$defs/actorType"
|
||||
},
|
||||
"actorId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"
|
||||
},
|
||||
"targetType": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128
|
||||
},
|
||||
"targetId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"workerSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"operationId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"$ref": "common.json#/$defs/serviceId"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"outcome": {
|
||||
"$ref": "common.json#/$defs/auditOutcome"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"maxLength": 512
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
},
|
||||
"occurredAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/box-capability.schema.json",
|
||||
"title": "HWLAB Box Capability",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"capabilityId",
|
||||
"resourceId",
|
||||
"projectId",
|
||||
"name",
|
||||
"direction",
|
||||
"valueType",
|
||||
"mutatesState",
|
||||
"createdAt",
|
||||
"updatedAt"
|
||||
],
|
||||
"properties": {
|
||||
"capabilityId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"resourceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"maxLength": 1000
|
||||
},
|
||||
"direction": {
|
||||
"type": "string",
|
||||
"enum": ["input", "output", "bidirectional"]
|
||||
},
|
||||
"valueType": {
|
||||
"type": "string",
|
||||
"enum": ["boolean", "integer", "number", "string", "object", "binary"]
|
||||
},
|
||||
"unit": {
|
||||
"type": "string",
|
||||
"maxLength": 32
|
||||
},
|
||||
"constraints": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
},
|
||||
"mutatesState": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"createdAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/box-resource.schema.json",
|
||||
"title": "HWLAB Box Resource",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"resourceId",
|
||||
"projectId",
|
||||
"gatewaySessionId",
|
||||
"boxId",
|
||||
"resourceType",
|
||||
"state",
|
||||
"environment",
|
||||
"createdAt",
|
||||
"updatedAt"
|
||||
],
|
||||
"properties": {
|
||||
"resourceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"boxId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"resourceType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"board",
|
||||
"power_supply",
|
||||
"serial_port",
|
||||
"network_port",
|
||||
"relay",
|
||||
"sensor",
|
||||
"simulator_endpoint"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"maxLength": 160
|
||||
},
|
||||
"state": {
|
||||
"$ref": "common.json#/$defs/resourceState"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
},
|
||||
"createdAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/common.json",
|
||||
"title": "HWLAB Common Schema Definitions",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 128,
|
||||
"pattern": "^[a-z][a-z0-9]*_[A-Za-z0-9._:-]+$"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"environment": {
|
||||
"type": "string",
|
||||
"enum": ["dev"]
|
||||
},
|
||||
"serviceId": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"hwlab-cloud-api",
|
||||
"hwlab-cloud-web",
|
||||
"hwlab-agent-mgr",
|
||||
"hwlab-agent-worker",
|
||||
"hwlab-gateway",
|
||||
"hwlab-gateway-simu",
|
||||
"hwlab-box-simu",
|
||||
"hwlab-patch-panel",
|
||||
"hwlab-router",
|
||||
"hwlab-tunnel-client",
|
||||
"hwlab-edge-proxy",
|
||||
"hwlab-cli",
|
||||
"hwlab-agent-skills"
|
||||
]
|
||||
},
|
||||
"lifecycleStatus": {
|
||||
"type": "string",
|
||||
"enum": ["pending", "active", "inactive", "failed", "deleted"]
|
||||
},
|
||||
"resourceState": {
|
||||
"type": "string",
|
||||
"enum": ["available", "reserved", "running", "maintenance", "offline"]
|
||||
},
|
||||
"operationStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"requested",
|
||||
"accepted",
|
||||
"queued",
|
||||
"running",
|
||||
"succeeded",
|
||||
"failed",
|
||||
"rejected",
|
||||
"canceled",
|
||||
"timed_out"
|
||||
]
|
||||
},
|
||||
"actorType": {
|
||||
"type": "string",
|
||||
"enum": ["user", "service", "agent", "worker", "system"]
|
||||
},
|
||||
"auditOutcome": {
|
||||
"type": "string",
|
||||
"enum": ["accepted", "succeeded", "failed", "rejected", "canceled"]
|
||||
},
|
||||
"traceLevel": {
|
||||
"type": "string",
|
||||
"enum": ["debug", "info", "warn", "error"]
|
||||
},
|
||||
"labels": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
}
|
||||
},
|
||||
"jsonObject": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/evidence-record.schema.json",
|
||||
"title": "HWLAB Evidence Record",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"evidenceId",
|
||||
"projectId",
|
||||
"operationId",
|
||||
"kind",
|
||||
"uri",
|
||||
"sha256",
|
||||
"serviceId",
|
||||
"environment",
|
||||
"createdAt"
|
||||
],
|
||||
"properties": {
|
||||
"evidenceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"operationId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"agentSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"workerSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["log", "screenshot", "measurement", "artifact", "report", "trace"]
|
||||
},
|
||||
"uri": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 2048
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$"
|
||||
},
|
||||
"sizeBytes": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"serviceId": {
|
||||
"$ref": "common.json#/$defs/serviceId"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
},
|
||||
"createdAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/gateway-session.schema.json",
|
||||
"title": "HWLAB Gateway Session",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"gatewaySessionId",
|
||||
"projectId",
|
||||
"serviceId",
|
||||
"gatewayId",
|
||||
"status",
|
||||
"environment",
|
||||
"startedAt"
|
||||
],
|
||||
"properties": {
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"enum": ["hwlab-gateway", "hwlab-gateway-simu"]
|
||||
},
|
||||
"gatewayId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"endpoint": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["starting", "connected", "degraded", "disconnected", "stopped"]
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"startedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"lastSeenAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"stoppedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "common.json#/$defs/labels"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/hardware-operation.schema.json",
|
||||
"title": "HWLAB Hardware Operation",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"operationId",
|
||||
"projectId",
|
||||
"gatewaySessionId",
|
||||
"resourceId",
|
||||
"capabilityId",
|
||||
"requestedBy",
|
||||
"status",
|
||||
"environment",
|
||||
"requestedAt",
|
||||
"updatedAt"
|
||||
],
|
||||
"properties": {
|
||||
"operationId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"agentSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"workerSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"resourceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"capabilityId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"requestedBy": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"input": true,
|
||||
"output": true,
|
||||
"status": {
|
||||
"$ref": "common.json#/$defs/operationStatus"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"requestedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"startedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"completedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"error": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/json-rpc-envelope.schema.json",
|
||||
"title": "HWLAB JSON-RPC Envelope",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["jsonrpc", "id", "method", "meta"],
|
||||
"properties": {
|
||||
"jsonrpc": {
|
||||
"const": "2.0"
|
||||
},
|
||||
"id": {
|
||||
"type": ["string", "number"]
|
||||
},
|
||||
"method": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9]*(\\.[a-z][a-z0-9_]*)+$"
|
||||
},
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/$defs/meta"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["jsonrpc", "id", "result", "meta"],
|
||||
"properties": {
|
||||
"jsonrpc": {
|
||||
"const": "2.0"
|
||||
},
|
||||
"id": {
|
||||
"type": ["string", "number"]
|
||||
},
|
||||
"result": true,
|
||||
"meta": {
|
||||
"$ref": "#/$defs/meta"
|
||||
}
|
||||
},
|
||||
"not": {
|
||||
"required": ["error"]
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["jsonrpc", "id", "error", "meta"],
|
||||
"properties": {
|
||||
"jsonrpc": {
|
||||
"const": "2.0"
|
||||
},
|
||||
"id": {
|
||||
"type": ["string", "number", "null"]
|
||||
},
|
||||
"error": {
|
||||
"type": "object",
|
||||
"required": ["code", "message"],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"data": true
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/$defs/meta"
|
||||
}
|
||||
},
|
||||
"not": {
|
||||
"required": ["result"]
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"$defs": {
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"required": ["traceId", "serviceId", "environment"],
|
||||
"properties": {
|
||||
"traceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"actorId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"$ref": "common.json#/$defs/serviceId"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/patch-panel-status.schema.json",
|
||||
"title": "HWLAB Patch Panel Status",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"patchPanelStatusId",
|
||||
"projectId",
|
||||
"gatewaySessionId",
|
||||
"serviceId",
|
||||
"state",
|
||||
"environment",
|
||||
"observedAt"
|
||||
],
|
||||
"properties": {
|
||||
"patchPanelStatusId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"wiringConfigId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"const": "hwlab-patch-panel"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": ["unknown", "ready", "applying", "active", "faulted", "offline"]
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"activeConnections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["fromResourceId", "fromPort", "toResourceId", "toPort"],
|
||||
"properties": {
|
||||
"fromResourceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"fromPort": {
|
||||
"type": "string"
|
||||
},
|
||||
"toResourceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"toPort": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"observedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/project.schema.json",
|
||||
"title": "HWLAB Project",
|
||||
"type": "object",
|
||||
"required": ["projectId", "name", "status", "environment", "createdAt", "updatedAt"],
|
||||
"properties": {
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 160
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"maxLength": 2000
|
||||
},
|
||||
"status": {
|
||||
"$ref": "common.json#/$defs/lifecycleStatus"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "common.json#/$defs/labels"
|
||||
},
|
||||
"createdBy": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"createdAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/trace-event.schema.json",
|
||||
"title": "HWLAB Agent Trace Event",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"traceEventId",
|
||||
"traceId",
|
||||
"projectId",
|
||||
"serviceId",
|
||||
"level",
|
||||
"message",
|
||||
"environment",
|
||||
"occurredAt"
|
||||
],
|
||||
"properties": {
|
||||
"traceEventId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"traceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"agentSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"workerSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"operationId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"$ref": "common.json#/$defs/serviceId"
|
||||
},
|
||||
"level": {
|
||||
"$ref": "common.json#/$defs/traceLevel"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 4000
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
},
|
||||
"occurredAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/wiring-config.schema.json",
|
||||
"title": "HWLAB Wiring Config",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"wiringConfigId",
|
||||
"projectId",
|
||||
"gatewaySessionId",
|
||||
"status",
|
||||
"connections",
|
||||
"createdAt",
|
||||
"updatedAt"
|
||||
],
|
||||
"properties": {
|
||||
"wiringConfigId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"maxLength": 160
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["draft", "valid", "active", "rejected", "retired"]
|
||||
},
|
||||
"connections": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/connection"
|
||||
}
|
||||
},
|
||||
"constraints": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
},
|
||||
"createdAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"endpoint": {
|
||||
"type": "object",
|
||||
"required": ["resourceId", "port"],
|
||||
"properties": {
|
||||
"resourceId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"port": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128
|
||||
},
|
||||
"capabilityId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"connection": {
|
||||
"type": "object",
|
||||
"required": ["from", "to"],
|
||||
"properties": {
|
||||
"from": {
|
||||
"$ref": "#/$defs/endpoint"
|
||||
},
|
||||
"to": {
|
||||
"$ref": "#/$defs/endpoint"
|
||||
},
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": ["exclusive", "shared", "monitor"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://hwlab.pikastech.local/protocol/schemas/worker-session.schema.json",
|
||||
"title": "HWLAB Worker Session",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"workerSessionId",
|
||||
"agentSessionId",
|
||||
"projectId",
|
||||
"serviceId",
|
||||
"status",
|
||||
"environment",
|
||||
"startedAt",
|
||||
"updatedAt"
|
||||
],
|
||||
"properties": {
|
||||
"workerSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"agentSessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"projectId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"serviceId": {
|
||||
"const": "hwlab-agent-worker"
|
||||
},
|
||||
"gatewaySessionId": {
|
||||
"$ref": "common.json#/$defs/id"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["starting", "active", "blocked", "completed", "failed", "canceled"]
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "common.json#/$defs/environment"
|
||||
},
|
||||
"startedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"completedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"updatedAt": {
|
||||
"$ref": "common.json#/$defs/timestamp"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "common.json#/$defs/jsonObject"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
# Topology Constraints
|
||||
|
||||
The MVP topology separates cloud, gateway, worker, simulated box, patch panel,
|
||||
router, tunnel, and edge proxy responsibilities.
|
||||
|
||||
## Constraints
|
||||
|
||||
- `hwlab-cloud-api` is the cloud API boundary for DEV.
|
||||
- `hwlab-cloud-web` consumes cloud APIs and must not control hardware directly.
|
||||
- `hwlab-agent-mgr` schedules agent work and creates worker sessions.
|
||||
- `hwlab-agent-worker` executes scoped work through declared gateway and box
|
||||
capabilities.
|
||||
- `hwlab-gateway` is the hardware control boundary.
|
||||
- `hwlab-gateway-simu` and `hwlab-box-simu` may simulate gateway and box
|
||||
behavior for MVP validation.
|
||||
- `hwlab-patch-panel` owns patch panel state.
|
||||
- `hwlab-router`, `hwlab-tunnel-client`, and `hwlab-edge-proxy` own network
|
||||
reachability concerns.
|
||||
- `hwlab-cli` is a client and must not bypass service contracts.
|
||||
- `hwlab-agent-skills` contains reusable agent skill assets.
|
||||
|
||||
## Wiring
|
||||
|
||||
Wiring configs describe allowed connections between resource ports. A valid
|
||||
wiring config must:
|
||||
|
||||
- belong to a project
|
||||
- reference known gateway and box resources
|
||||
- declare endpoints explicitly
|
||||
- avoid cycles unless a later capability explicitly allows them
|
||||
- represent one active config per resource group unless the patch panel reports
|
||||
an override
|
||||
Reference in New Issue
Block a user