docs: clarify durable runtime readiness boundary
This commit is contained in:
@@ -84,6 +84,40 @@ this agreement offline. A live pass still requires `/health/live` to report
|
||||
`db.ready=true`, `db.connected=true`, and `liveDbEvidence=true` with secret
|
||||
values redacted.
|
||||
|
||||
## Durable Runtime Readiness Contract
|
||||
|
||||
DB live readiness and durable runtime readiness are separate gates. A
|
||||
`/health/live` payload with `db.connected=true` and `db.liveDbEvidence=true`
|
||||
only proves that the Cloud API reached the DEV DB endpoint without exposing
|
||||
secret values. It does not prove that runtime writes are persisted through a
|
||||
durable store.
|
||||
|
||||
When health reports:
|
||||
|
||||
- `runtime.adapter: "memory"`
|
||||
- `runtime.durable: false`
|
||||
- `runtime.status: "degraded"`
|
||||
|
||||
the Cloud API is using the process-local runtime store in
|
||||
`internal/db/runtime-store.mjs`. Gateway sessions, box resources, operations,
|
||||
audit events, and evidence records accepted through the runtime can be lost on
|
||||
pod restart, redeploy, or scale-out, and cannot be treated as durable M3/M4/M5
|
||||
evidence. Users may see accepted operations or evidence disappear after a
|
||||
runtime replacement, and agent-loop/MVP acceptance must remain degraded or
|
||||
blocked even if the DB connection layer is green.
|
||||
|
||||
Readiness reports must keep these dimensions distinct:
|
||||
|
||||
| Dimension | Green condition | Degraded/blocking condition |
|
||||
| --- | --- | --- |
|
||||
| DB live | `db.ready=true`, `db.connected=true`, `db.liveDbEvidence=true` | Missing env, failed connection, disabled probe, or no `liveDbEvidence` |
|
||||
| Runtime durability | `runtime.durable=true` with a durable adapter | `runtime.adapter="memory"` or `runtime.durable=false` |
|
||||
|
||||
Do not declare DEV-LIVE complete while `runtime.adapter="memory"` or
|
||||
`runtime.durable=false`, even when DB live readiness is connected. The next
|
||||
fix boundary is a durable runtime store and migration path; documenting or
|
||||
testing this contract must not mutate runtime state or PROD.
|
||||
|
||||
## Runtime Substitution Ban
|
||||
|
||||
UniDesk services, provider-gateway, backend-core, microservice proxies, local
|
||||
|
||||
@@ -117,6 +117,10 @@ test("cloud api health reports DB env presence and live connection classificatio
|
||||
assert.equal(payload.db.evidence, "live_db_tcp_connection_ready");
|
||||
assert.equal(payload.db.safety.liveDbEvidence, true);
|
||||
assert.equal(payload.db.safety.liveDbConnectedEvidence, true);
|
||||
assert.equal(payload.runtime.adapter, "memory");
|
||||
assert.equal(payload.runtime.durable, false);
|
||||
assert.equal(payload.runtime.status, "degraded");
|
||||
assert.match(payload.runtime.reason, /process-local/u);
|
||||
assert.equal(payload.db.redaction.valuesRedacted, true);
|
||||
assert.equal(payload.db.redaction.endpointRedacted, true);
|
||||
assert.equal(payload.db.redaction.secretMaterialRead, false);
|
||||
|
||||
@@ -92,8 +92,10 @@ async function run() {
|
||||
assert.equal(health.body.db.connectionResult, "not_attempted_missing_env");
|
||||
assert.equal(health.body.db.ready, false);
|
||||
assert.deepEqual(health.body.db.missingEnv, ["HWLAB_CLOUD_DB_URL", "HWLAB_CLOUD_DB_SSL_MODE"]);
|
||||
assert.equal(health.body.runtime.adapter, "memory");
|
||||
assert.equal(health.body.runtime.durable, false);
|
||||
assert.equal(health.body.runtime.status, "degraded");
|
||||
assert.match(health.body.runtime.reason, /process-local/u);
|
||||
logOk("health degraded DB contract");
|
||||
|
||||
const v1 = await requestJson(`${baseUrl}/v1`);
|
||||
|
||||
Reference in New Issue
Block a user