Skip to content

feat(node): seictl node watch --until=caught-up — SDK-backed readiness gate#214

Merged
bdchatham merged 1 commit into
mainfrom
feat/seictl-readiness-gate
Jun 22, 2026
Merged

feat(node): seictl node watch --until=caught-up — SDK-backed readiness gate#214
bdchatham merged 1 commit into
mainfrom
feat/seictl-readiness-gate

Conversation

@bdchatham

Copy link
Copy Markdown
Contributor

Wires seictl to the SDK's shared chain-readiness primitive so the nightly's bespoke bash catching_up probe can be deleted — the readiness logic lives once, in reusable Go.

What

  • seictl node watch --until=caught-up: waits for Running, then gates on the node's published endpoints via sei.WaitCaughtUp (TM /status: height>1 && catching_up==false) and sei.WaitEVMServing (EVM eth_blockNumber bound, when the node serves EVM).
  • Inputs come from .status.endpoint (read verbatim, never reconstructed). endpointsFrom unit-tested across fullNode / non-EVM / pre-publish shapes.

Why

The nightly orchestration stays seictl-CLI-driven; the win is the readiness/wait complexity moving out of bespoke curl /status | jq '(.catching_up==false) and height>1' bash into one reusable Go implementation (sdk/sei) shared by the SDK, the seitask Task steps, and the CLI.

Interim dependency note

Imports github.com/sei-protocol/sei-k8s-controller/sdk/sei (core) — a temporary mutual module require (the controller already imports seictl/sidecar/client). The seictl→controller monorepo consolidation (designed + xreviewed) later dissolves this into a clean in-repo cliseiclient import via go.work. Verified the import adds nothing to seictl's build beyond what it already carries (it's already a k8s CLI with client-go + controller-runtime): go mod tidy made only benign indirect bumps; seictl stays at its own k8s v0.36, and sdk/sei core is stdlib-only (0 k8s/controller-runtime deps) so pruning keeps the controller's k8s graph out.

Test

go build/golangci-lint (0 issues)/go test ./seinode/... green; gofmt clean.

🤖 Generated with Claude Code

…s gate

Add a serve-readiness sentinel to `seictl node watch`: --until=caught-up waits
for Running, then gates on the node's published endpoints via the SDK's shared
readiness primitive (sei.WaitCaughtUp = TM /status height>1 && catching_up==false;
sei.WaitEVMServing = EVM eth_blockNumber bound, when the node serves EVM). This
replaces the nightly's bespoke curl/jq catching_up loop with one reusable Go
implementation shared across the SDK, the seitask Task steps, and the CLI.

Imports github.com/sei-protocol/sei-k8s-controller/sdk/sei (core, stdlib-only) as
an interim cross-repo dep — a temporary mutual module require that the seictl->
controller monorepo consolidation later dissolves. Verified the import does not
drag the controller's k8s graph into seictl beyond what seictl already carries
(go mod tidy: only benign indirect bumps; seictl stays at its own k8s v0.36).

Inputs come from the node's .status.endpoint (read verbatim); endpointsFrom is
unit-tested against the fullNode/non-EVM/pre-publish shapes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cursor

cursor Bot commented Jun 22, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New cross-module dependency and live HTTP readiness probes against published node endpoints; behavior change for automation replacing bash catching_up checks.

Overview
Adds seictl node watch --until=caught-up, a readiness sentinel distinct from phase-based --until. After the existing watch reaches Running, the CLI reads Tendermint and optional EVM RPC URLs from .status.endpoint (verbatim) and gates on sei.WaitCaughtUp and, when EVM is published, sei.WaitEVMServing from github.com/sei-protocol/sei-k8s-controller/sdk/sei.

go.mod gains a direct require on sei-k8s-controller (plus routine indirect bumps from go mod tidy). Help text and validation now accept caught-up alongside the SeiNode phase enum. TestEndpointsFrom locks the .status.endpoint field paths used by the gate.

Reviewed by Cursor Bugbot for commit 5e70706. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5e70706. Configure here.

Comment thread seinode/watch.go
if err := sei.WaitEVMServing(ctx, nil, evmRPC); err != nil {
cliutil.EmitStatus(os.Stderr, err)
return cli.Exit("", 1)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caught-up wait timeout wrong reason

Medium Severity

For --until=caught-up, after the Running watch succeeds, failures from sei.WaitCaughtUp or sei.WaitEVMServing (including when the shared --timeout elapses during those polls) are emitted via EmitStatus without the same WatchExitError mapping RunWatch uses. stderr then shows InternalError instead of Timeout, which breaks the command’s documented metav1.Status.reason contract for nightly orchestration.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5e70706. Configure here.

@bdchatham bdchatham merged commit 2ff2be8 into main Jun 22, 2026
3 checks passed
@bdchatham bdchatham deleted the feat/seictl-readiness-gate branch June 22, 2026 21:20
bdchatham added a commit that referenced this pull request Jun 22, 2026
Cuts **v0.0.60**.

**Includes:** `seictl node watch --until=caught-up` (#214) — waits for
`Running`, then gates on the node's published endpoints via the SDK's
shared readiness primitive (`sei.WaitCaughtUp` TM caught-up;
`sei.WaitEVMServing` EVM serving). Lets the nightly orchestration retire
its bespoke `curl /status | jq` catching_up probe.

Additive flag value, backward-compatible → patch bump (v0.0.59 →
v0.0.60).

Merging this `version.json` bump triggers `uci-release-publish` → tag +
goreleaser binary, which the platform nightly then pins via
`SEICTL_VERSION`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <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