128 lines
6.0 KiB
Markdown
128 lines
6.0 KiB
Markdown
# Cloud API Runtime
|
|
|
|
The L1 `hwlab-cloud-api` runtime is a minimal local HTTP/JSON-RPC service. It
|
|
does not deploy to DEV or PROD from source tests and does not claim live
|
|
database persistence unless both DB readiness and the durable runtime adapter
|
|
readiness are live.
|
|
|
|
## Local Smoke
|
|
|
|
Run:
|
|
|
|
```sh
|
|
node scripts/cloud-api-runtime-smoke.mjs
|
|
```
|
|
|
|
The smoke starts `cmd/hwlab-cloud-api` on `127.0.0.1` with an ephemeral port
|
|
and verifies:
|
|
|
|
- `GET /health` reports `status: "degraded"` when live DB persistence is not
|
|
connected.
|
|
- `GET /health` reports DB readiness and runtime durable adapter readiness as
|
|
separate components. A memory adapter remains non-durable even when DB env
|
|
fields are present.
|
|
- The DB contract reports required env names, redacted Secret refs, env
|
|
injection, connection attempt status, connection result, `liveConnected`,
|
|
`liveDbEvidence`, DNS/TCP/auth/schema readiness layers, and redaction/safety
|
|
fields without exposing DB URL or secret values.
|
|
- `gateway.session.register`, `box.resource.register`,
|
|
`box.capability.report`, `hardware.invoke.shell`, `audit.event.query`, and
|
|
`evidence.record.query` round-trip through the same runtime store.
|
|
- Shell invoke requests are accepted as recorded cloud operations but report
|
|
`dispatchStatus: "not_connected"` until a real gateway shell adapter exists.
|
|
- Audit and evidence records use the protocol schema field names.
|
|
|
|
## Persistence Boundary
|
|
|
|
The default local runtime store is process-local memory:
|
|
|
|
- `runtime.adapter: "memory"`
|
|
- `runtime.durable: false`
|
|
- `runtime.status: "degraded"`
|
|
|
|
This remains the safe local default. DEV can opt into the durable adapter with
|
|
non-secret env flags:
|
|
|
|
- `HWLAB_CLOUD_RUNTIME_ADAPTER=postgres`
|
|
- `HWLAB_CLOUD_RUNTIME_DURABLE=true`
|
|
|
|
The Postgres adapter uses `HWLAB_CLOUD_DB_URL` from
|
|
`hwlab-cloud-api-dev-db/database-url`; source records only the Secret reference
|
|
and non-secret DNS contract. The adapter reports `runtime.durable: true` only
|
|
after the configured adapter proves all durable gates through read-only runtime
|
|
checks:
|
|
|
|
- auth/query access to the configured DB path;
|
|
- required runtime table and column schema;
|
|
- the source-controlled migration ledger row for
|
|
`0001_cloud_core_skeleton` / `runtime-durable-postgres-v1`;
|
|
- read readiness against the runtime tables used by audit and evidence
|
|
queries.
|
|
|
|
If DB auth, schema, migration, or read readiness is missing, `/health/live`
|
|
stays degraded with `runtime.durable: false`, `runtime.durableRequested: true`,
|
|
and a runtime blocker such as `runtime_durable_adapter_auth_blocked`,
|
|
`runtime_durable_adapter_schema_blocked`, or
|
|
`runtime_durable_adapter_migration_blocked`. Fixture data and env presence are
|
|
never promoted to `runtime.liveRuntimeEvidence`.
|
|
|
|
When the Postgres durable adapter is selected or requested, JSON-RPC
|
|
`audit.event.query` and `evidence.record.query` must also honor that durability
|
|
gate. If auth, schema, migration, durability-query, or table read-query evidence
|
|
is blocked, the method returns a JSON-RPC error with redacted blocker data such
|
|
as `adapter: "postgres"`, `durableRequested: true`,
|
|
`liveRuntimeEvidence: false`, `secretMaterialRead: false`, and the classified
|
|
blocker. It must not
|
|
return `events: []`, `records: []`, or `count: 0` on a blocked durable read.
|
|
Empty successful result sets are valid only after the durable adapter has
|
|
completed the read and the matching durable table rows are actually absent.
|
|
|
|
If `HWLAB_CLOUD_DB_URL` and `HWLAB_CLOUD_DB_SSL_MODE` are absent, health
|
|
reports `db.status: "blocked"`.
|
|
If both env vars are present, cloud-api attempts a short read-only TCP
|
|
connection to the DB endpoint from the injected runtime env. The health payload
|
|
keeps all endpoint details redacted and reports only:
|
|
|
|
The runtime DB readiness authority is the host parsed from the injected
|
|
`HWLAB_CLOUD_DB_URL` Secret value. Health reports this as
|
|
`db.endpointSource: "secret-url-host"` without printing the host, username,
|
|
password, or full URL. The `cloud-api-db` name is only an optional future alias;
|
|
it is not the TCP probe target and a missing alias must not reverse-fail live DB
|
|
success from the Secret URL host.
|
|
`.invalid` hosts, including `hwlab-dev-db.invalid`, are forbidden as DEV
|
|
runtime targets and may be used only as negative fixtures.
|
|
|
|
- `db.configReady`: required env names are present.
|
|
- `db.endpointSource`: `secret-url-host`, the authoritative redacted TCP dial
|
|
target parsed from `HWLAB_CLOUD_DB_URL`.
|
|
- `db.optionalPublicDnsAlias`: diagnostic metadata for the non-authoritative
|
|
`cloud-api-db` alias; `requiredForReadiness` and `usedForProbe` stay false.
|
|
- `db.connectionAttempted`: the runtime tried the live connection path.
|
|
- `db.connectionResult`: redacted classifier such as `connected`, `refused`,
|
|
`timeout`, `dns_error`, `invalid_url`, or `unsupported_protocol`.
|
|
- `db.liveConnected`: the TCP connection completed.
|
|
- `db.liveDbEvidence`: true only when the live connection completed; env
|
|
presence, fixtures, and disabled probes must keep this false.
|
|
- `db.redaction` and `db.safety`: confirm values/endpoints are redacted and
|
|
secret material was not read by the health path.
|
|
- `db.readinessLayers`: records DNS, TCP, auth, and schema status separately so
|
|
DNS/TCP repair cannot be confused with authenticated schema readiness.
|
|
- `db.ready`: currently aliases `db.liveConnected`.
|
|
|
|
Env presence alone is not treated as green. If the runtime has env injection
|
|
but `db.connectionAttempted` is false, `db.liveConnected` is false, or
|
|
`db.liveDbEvidence` is false, the gate must stay blocked/degraded with the
|
|
reported blocker.
|
|
|
|
Fixture: `fixtures/cloud-api-runtime/minimal-runtime.json`.
|
|
|
|
## Code Agent Provider Boundary
|
|
|
|
`hwlab-cloud-api` supports OpenAI Responses for the Code Agent chat endpoint.
|
|
DEV source contracts require `OPENAI_API_KEY` from Secret
|
|
`hwlab-code-agent-provider/openai-api-key` and
|
|
`HWLAB_CODE_AGENT_OPENAI_BASE_URL` through the DEV egress/proxy URL. Runtime
|
|
health and `/v1` may report provider status, missing env names, Secret ref
|
|
names, model, and redacted egress status, but must never print the API key or a
|
|
Bearer token.
|