Healthchecks Implementation Plan
Status: implementation handoff for the healthchecks[] contract.
This is a worker-facing plan for implementing the canonical Service Lasso healthchecks array contract.
Target manifest shape
"healthchecks": [
{
"id": "tcp-port-open",
"type": "tcp",
"host": "127.0.0.1",
"port": "${HTTP_PORT}",
"retries": 30,
"interval": 250
},
{
"id": "http-ready",
"type": "http",
"url": "http://127.0.0.1:${HTTP_PORT}/health",
"expected_status": 200,
"retries": 80,
"interval": 250
}
]
Product rules
healthchecksis canonical.- Singular
healthcheckis not the target schema. - Temporary singular support is allowed only as an internal migration bridge while checked-in manifests are converted.
- Do not support
tcphostortcpportaliases. - Every healthcheck item must have a unique
id. requireddefaults totrue.- Startup is ready only when all required checks pass.
- Optional checks are diagnostics only.
- Each check owns its own retries, interval, start period, and timeout.
Implementation phases
-
Contract and validation
- Add
healthchecks?: ServiceHealthcheck[]toServiceManifest. - Add
idandrequiredto healthcheck types. - Add
udphealthcheck type. - Add
timeoutshared option. - Validate unique check IDs.
- Reject empty
healthchecksarrays. - Reject both
healthcheckandhealthcheckstogether. - Reject
tcphostandtcpportwith a clear message.
- Add
-
Normalisation
- Add a helper such as
getServiceHealthchecks(manifest). - Return explicit
healthcheckswhen present. - Return temporary singular
healthcheckonly during migration if needed. - Return default process check only when no healthchecks are declared.
- Add a helper such as
-
Check execution
- Keep individual checkers small: process, http, tcp, udp, file, variable.
- Add
checkUdp.tswith send/expect semantics. - Resolve selectors before running each check.
- Ensure file checks resolve selectors before filesystem access.
- Ensure TCP supports default single-port, address, and host/port forms.
-
Readiness aggregation
- Update startup readiness to run each check independently.
- Honour per-check retries, interval, start period, and timeout.
- Required checks gate startup.
- Optional checks report diagnostics only.
-
Result contracts
- Return aggregate health plus per-check results.
- Start traces should include per-check outcomes.
- APIs should expose checks as rows/cards, not a single opaque status string.
-
Runtime variables
- Implement
outputvarregexcapture into runtime-scoped variables. - Make captured variables visible to variable healthchecks.
- Include runtime variable source metadata such as stdout/stderr.
- Implement
-
Manifest migration
- Convert checked-in manifests from
healthchecktohealthchecks. - Update examples in docs and tests.
- Once migrated, decide whether singular
healthcheckshould be rejected immediately or left as a short deprecation bridge.
- Convert checked-in manifests from
-
Tests
- Validator tests for valid and invalid schemas.
- Readiness tests for single and multiple checks.
- Required/optional aggregation tests.
- TCP default/address/host-port tests.
- UDP send/expect tests.
- File selector resolution tests.
- Variable from
outputvarregextests.
Result shape
Per-check result:
interface ServiceHealthcheckResult {
id: string;
type: ServiceHealthcheck["type"];
required: boolean;
healthy: boolean;
attempts: number;
detail: string;
}
Aggregate result:
interface ServiceHealthResult {
healthy: boolean;
detail: string;
checks: ServiceHealthcheckResult[];
}
The aggregate is healthy only when every required check is healthy.