# Proposal — Migrate @suaveplan/health-check to genesis ## Why `@suaveplan/health-check` is the server-tier orchestrator for `/health`, `/ready`, and `/live` endpoints with dependency checks. The upstream package at `/mnt/s/web/suaveplan/packages/server/health-check/` predates the genesis enterprise gates: it uses the upstream `EventEmitter` shape, calls global `Date.now()`/`setTimeout`/`fetch`/`node:net` directly, has no error-code registry, no OTel self-telemetry, and no Zod boundary validation. This change re-lands the package at `packages/observability/monitor/health-check/` (sibling to `logger`, `audit-logging`, `opentelemetry`) at full feature surface with the genesis contract. ## What Land `@suaveplan/health-check@0.1.0` with the following feature modules (one per folder, 5-files-per-feature): - `health-checker/` — `HealthChecker` orchestrator with `EventBus` and injectable `Clock` / `TimersLike` / `LoggerLike` - `http-check/` — `createHttpCheck` factory with injectable `fetchImpl` + `Clock` - `tcp-check/` — `createTcpCheck` factory with injectable `TcpConnectFn` + `Clock` - `response-builder/` — `ResponseBuilder` mapping `CheckStatus` → HTTP status codes - `error-codes/` — `HEALTH_CHECK_CODES` via `defineCodes` + public-ctor `HealthCheckError` - `telemetry/` — OTel meter (`health_check_runs_total`, `health_check_aggregate_status_total`, `health_check_duration_ms`) - `types/` — shared `CheckResult`/`CheckFn`/`DependencyCheckConfig`/`HealthResponse`/`ReadinessResponse`/`LivenessResponse`/`HttpHealthResponse`/`HttpCheckConfig`/`TcpCheckConfig`/`HealthEvent`/`HealthEventMap` ## Source mapping | Upstream file | Genesis file | Notes | | --- | --- | --- | | `src/checker/health-checker.ts` | `src/health-checker/health-checker.ts` | `EventEmitter` → `EventBus`; `Clock`+`TimersLike`+`LoggerLike` injected; Zod-validated options; `HealthCheckError` on every failure | | `src/checks/http-check.ts` | `src/http-check/http-check.ts` | `fetchImpl` injection replaces global `fetch`; Zod options | | `src/checks/tcp-check.ts` | `src/tcp-check/tcp-check.ts` | `TcpConnectFn` injection replaces direct `node:net.connect`; settled-flag guards late events | | `src/response/response-builder.ts` | `src/response-builder/response-builder.ts` | Same algorithm, renamed file | | `src/types/types.ts` | `src/types/types.ts` | Adds `HealthEventMap`, `TcpConnectFn`/`TcpSocketLike`, `HttpCheckConfig.fetchImpl`, `TcpCheckConfig.connectImpl` | | `src/index.ts` | `src/index.ts` | Explicit named re-exports only | | (none) | `src/error-codes/error-codes.ts` | New — required by genesis rule | | (none) | `src/telemetry/telemetry.ts` | New — required by genesis rule | ## Deviations from upstream 1. Upstream uses `@suaveplan/events`' `EventEmitter` with variadic tuple payloads. Genesis `@suaveplan/events` exposes `EventBus` with single-payload `emit(type, payload)`. `STATUS_CHANGED` therefore emits `{ previous, current }` object instead of two positional args. Exposed as `HealthChecker.events`. 2. Upstream calls `Date.now()` and `setTimeout` directly. Genesis injects `Clock` + `TimersLike` per the universal-tier contract. 3. Upstream has no error-code registry. Genesis adds `HEALTH_CHECK_CODES` + public-ctor `HealthCheckError`. 4. Upstream HTTP / TCP checks depend on the runtime's global `fetch` and `node:net`. Genesis injects them so tests never touch real sockets. 5. Upstream emits no self-telemetry. Genesis adds a `telemetry/` module emitting per-check counters + duration histogram + aggregate-status counter. 6. Boundary validation: every public option object is now Zod-validated; failures throw `HealthCheckError(INVALID_OPTIONS)`.