Skip to content

lifecycle.mdx "Health Status Response" shows the internal health-monitor model under a heading that reads as the GET /health wire body #11760

Description

@os-steve

Found while fixing #11295 (discovery version literals). Out of that card's scope — different endpoint, different defect — so it is filed rather than fixed.

What was measured

content/docs/protocol/kernel/lifecycle.mdx:640, under the heading ### Health Status Response:

{
"status": "healthy",
"uptime": 3600,
"version": "2.0.0",
"timestamp": "2024-01-15T11:00:00.000Z",
"checks": {
"database": { "status": "healthy", "latency_ms": 5, ... },
"redis": { "status": "healthy", "latency_ms": 2, ... }
}
}

What GET /health actually serves (packages/runtime/src/http-dispatcher.ts:567-577, registerBuiltinDomains()):

this.domainRegistry.register({prefix: '/health',match: 'exact',methods: ['GET'],handler: async()=>({handled: true,response: this.success({status: 'ok',timestamp: newDate().toISOString(),version: this.runtimeVersion,uptime: typeofprocess!=='undefined' ? process.uptime() : undefined,}),}),});

Three divergences:

fielddoc sample/health actually
status"healthy""ok"
checksa per-subsystem map (database, redis)absent — the handler emits no such key
envelopebare objectthis.success(...), i.e. { "success": true, "data": { … } }

Why this is a framing defect, not a stale literal

The page is not simply wrong — the Callout immediately above the sample already says the richer report is a different thing:

GET /health returns a compact liveness body (status, version, uptime) … The richer per-subsystem report and the plugin-declared custom checks below describe the internal health-monitor model (PluginHealthMonitor), which covers plugins, not driver connections — they are not yet exposed as a dedicated HTTP endpoint or as a declarative plugin field.

So the JSON is an accurate-enough illustration of the internal model, sitting under a heading (Health Status Response) and in a document section that reads as an HTTP response body. A reader who skips the callout writes a client against checks.database.status and a "healthy" literal, neither of which any endpoint serves.

The "version": "2.0.0" on that line is not asserted here as the same defect as #11295: /health's real version is derived (resolveRuntimeVersion()OS_RUNTIME_VERSION, else the resolved @objectstack/runtime version, #10993), but this sample belongs to the unexposed model, which has no producer to be stale against. That is precisely why it is a separate card rather than folded into #11295 — asserting it would be an unmeasured claim.

Suggested direction

Not obvious, hence no PR. Two readings, and the choice is a judgement call:

  • A — retitle and relabel. Change the heading to name the model (### Health Monitor Report (internal model)) and keep the sample. Cheapest; leaves a documented shape with no endpoint, which is the declared ≠ enforced smell AGENTS.md Prime Directive chore: version packages #10 warns about.
  • B — show the real body, move the model. Replace the sample with what /health serves (enveloped, status: "ok", no checks), and relocate the PluginHealthMonitor shape into the section that already discusses the internal model. Truthful at the HTTP boundary; more edit.

B looks right — the section sits in protocol/kernel/, whose subject is the wire protocol — but it turns on whether the page intends to document the internal model at all, which is a maintainer call rather than a mechanical one.

Not asserting more than was checked

Only lifecycle.mdx was examined for this. The /ready sample on the same page was not compared against registerBuiltinDomains(), and no sweep for other endpoint samples that drifted from their handlers was run.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions