Skip to content

feat(health): C3b — internal/health thin readiness poller (spec 10) - #4

Merged
gustavobertoi merged 1 commit into
mainfrom
nightly/C3b
Jun 29, 2026
Merged

feat(health): C3b — internal/health thin readiness poller (spec 10)#4
gustavobertoi merged 1 commit into
mainfrom
nightly/C3b

Conversation

@gustavobertoi

Copy link
Copy Markdown
Contributor

Chunk C3b (M2-remainder)

New read-only, lock-free internal/health package — the readiness gate the up saga (C5) stands on. Per spec 10 (thin v1).

What

  • Compile(*config.Healthcheck) → Timing with spec-10 defaults (interval 5s, timeout 3s, retries 10, startPeriod 30s). The "60s for stateful images" rule lives in the engine templates, not here (no hardcoded engine knowledge). Budget() = startPeriod + interval*retries.
  • Poll(ctx, docker.Client, Target, Timing) — polls .State.Health.Status until Healthy (or Started: container running), failing fast on unhealthy / a fatal container state (exited/dead/restarting) / timeout / ctx cancel. Transient inspect errors (container not created yet) are tolerated until the deadline.
  • On failure → a *ProbeError carrying the --json Record and the last 20 log lines (fetched on a detached context so a timed-out poll still has a diagnostic) + a one-line remediation (ARCHITECTURE §7.6).
  • Record is the machine-readable health contract (service/project/kind/status/attempts/elapsedMs/lastError, lastError null on success).

Scope

Thin v1 — single-target Poll consumed linearly by the caller. The full workspace DAG (cycle paths, topo waves, profile pruning, generate-time "condition:healthy needs a healthcheck") is X2.

Tests

  • Daemon-free unit tests via a scripted client: healthy-after-starting, fail-fast unhealthy/exited, started condition, timeout, transient-error recovery, ctx cancel, Compile defaults/overrides/bad-durations.
  • //go:build integration test polls real healthy + unhealthy containers and asserts the log diagnostic (verified locally against Engine 29.5.3).

Gate

make ci green; go test -tags=integration ./internal/health green locally.

🤖 Generated with Claude Code

New read-only, lock-free package that gates the up saga on real readiness:

- Compile(*config.Healthcheck) → Timing with spec-10 defaults (interval 5s,
  timeout 3s, retries 10, startPeriod 30s); the "60s for stateful images"
  rule stays in the engine templates (no hardcoded engine knowledge here).
  Budget() = startPeriod + interval*retries.
- Poll(ctx, docker.Client, Target, Timing): polls .State.Health.Status until
  Healthy (or Started: container running), failing fast on unhealthy / a fatal
  container state (exited/dead/restarting) / timeout / ctx cancel. Transient
  inspect errors (container not created yet) are tolerated until the deadline.
- On failure returns a *ProbeError carrying the --json Record AND the last 20
  log lines (fetched on a detached context so a timed-out poll still has a
  diagnostic) + a one-line remediation (ARCHITECTURE §7.6).
- Record is the machine-readable health contract (service/project/kind/status/
  attempts/elapsedMs/lastError, lastError null on success).

Thin v1 — single-target Poll consumed linearly by the caller (C5). The full
workspace DAG (cycle paths, topo waves, profile pruning, generate-time
"condition:healthy needs a healthcheck") is X2.

Unit tests use a scripted client (healthy-after-starting, fail-fast unhealthy/
exited, started condition, timeout, transient-error recovery, ctx cancel,
Compile defaults/overrides/bad-durations). A `//go:build integration` test
polls real healthy + unhealthy containers and asserts the log diagnostic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gustavobertoi
gustavobertoi merged commit fa338aa into main Jun 29, 2026
9 checks passed
@gustavobertoi
gustavobertoi deleted the nightly/C3b branch June 29, 2026 12:43
gustavobertoi added a commit that referenced this pull request Jun 29, 2026
…& packages (#77)

Completes the autonomously-doable part of G4 (release plumbing). goreleaser's
default archive globs bundle LICENSE*/README* but NOT NOTICE — an Apache-2.0
distribution must ship NOTICE. Adds an explicit archive `files:` list
(LICENSE + NOTICE + README + docs/QUICKSTART) and embeds LICENSE+NOTICE under
/usr/share/doc/devstack in the .deb/.rpm via nfpm `contents:`.

Validated locally: `goreleaser check` passes and a full `--snapshot` build
produces all 8 artifacts (4 tar.gz + 2 .deb + 2 .rpm) with NOTICE present in the
tarball. release-dryrun continues to cover this on every PR.

Remaining G4 is owner-only (outward-facing / irreversible, locked decision #4):
create the Homebrew tap repo (Q-NAME) + wire `brews:`, then cut the release —
`git tag v1.0.0 && git push origin v1.0.0` — and flip the repo public.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant