Skip to content

Use OpenClaw readiness endpoint for health probes - #358

Merged
mostlydev merged 1 commit into
masterfrom
issue-357-openclaw-readiness
Aug 3, 2026
Merged

Use OpenClaw readiness endpoint for health probes#358
mostlydev merged 1 commit into
masterfrom
issue-357-openclaw-readiness

Conversation

@mostlydev

Copy link
Copy Markdown
Owner

Summary

  • use the local unauthenticated OpenClaw readiness endpoint for generated and CLI health probes
  • validate readiness JSON and preserve the legacy CLI fallback for older images
  • pin the compiled healthcheck contract and readiness parser behavior with tests

Verification

  • go test -count=1 ./...
  • go vet ./...
  • go test -count=1 -tags integration ./...
  • go test -run no-tests -tags spike ./cmd/claw/...
  • go test -count=1 -tags spike -run TestQuickstartDocsRunInFreshDockerContainer -v ./cmd/claw/...
  • live current-image claw up -d, claw health, and Docker health inspection

Closes #357

@mostlydev

Copy link
Copy Markdown
Owner Author

Adversarial review (claude), at exact head 94d2801. Accepted — no defects found. I did not take the shell string on trust; every challenged property was verified empirically.

Compose escaping, verified end to end. Built a fixture compose file containing the generated healthcheck string verbatim, ran docker compose config and then created the container and inspected .Config.Healthcheck.Test. The runtime string is exactly right: $$response unescapes to $response, and $(curl ...) survives as a literal command substitution. One robustness note, not a blocker: the single-$ form relies on compose treating $( leniently (current compose normalizes it to $$( in canonical output). The uniformly-escaped $$(curl form would be byte-identical at runtime and immune to stricter template parsers. Worth folding into any future touch of this string; not worth churning the pinned contract for now, since the quickstart docs spike — which installs the real toolchain in a fresh container — passed against the form as written.

Probe decision matrix, all seven paths exercised in a real container (alpine + curl + jq + a fake openclaw CLI with selectable exit code + a local server on 18789):

case exit CLI fallback verdict
{"ready":true} 0 not invoked healthy
{"ready":false,"failing":["discord"]} 1 not invoked authoritative unhealthy — not masked
endpoint absent, CLI exits 0 0 invoked older-image path works
endpoint absent, CLI exits 7 7 invoked CLI verdict propagates
wrong JSON ({"status":"ok"}) 0 invoked falls back, no false positive
HTML/SPA body 0 invoked falls back, no false positive
HTTP 500 with valid body 0 invoked curl -f gates status correctly

The ready:false row is the one that mattered most: a valid negative readiness result terminates the probe unhealthy without giving the CLI a chance to disagree, exactly as the issue requires.

Localhost binding — correct by construction, not just by test: internal/driver/openclaw/baseimage.go:34 starts the gateway with --port 18789 --bind loopback, so the probe target matches how the driver itself launches the gateway.

Go probe path — mirrors the shell semantics: readiness parse success (either polarity) is authoritative; exec failure, non-zero curl exit, or unparseable body all fall through to the legacy CLI path, which keeps its full stderr/exit-code detail reporting. ParseOpenClawReadinessJSON uses a *bool so an unrelated 200 JSON body cannot be mistaken for a readiness verdict, and the no-ready-field case is covered by test.

Independent verification at the head: go test -count=1 ./... clean across the repo, go vet ./... clean, focused packages (internal/health, internal/driver/openclaw, cmd/claw) pass, CI Go green at 94d2801, mergeable. Merging the reviewed head.

@mostlydev
mostlydev merged commit e2b621c into master Aug 3, 2026
1 check passed
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.

Use OpenClaw unauthenticated readiness endpoint after gateway auth drift

1 participant