docs(workflow): correct --name recovery semantics; document target eligibility - #243
Conversation
…igibility Re-Run Semantics claimed `--name` was a recovery path for either terminal phase. It is not one for a Failed workflow: removing the workflow is what releases the node, and adoption is exclusive (a node consults status.adoptedWorkflow only when nil), so a fresh --name workflow is never adopted. It compiles no plan and makes no progress while the node stays held, and the watch ends at --timeout having changed nothing. Also records that the force annotation is currently mandatory rather than a break-glass option: verifyWorkflowDataSafe fails closed until the sidecar exposes the data-state query, so an un-annotated delete parks the workflow Terminating with the node still held. Annotating after the fact recovers it on the next poll. Adds an Eligible Targets section for the adoption-time refusals, which were undocumented: a SeiNode is exactly one mode and only fullNode is eligible, so a validator/archive/replayer/seed target fails the workflow terminally at adoption (the workflow's own CEL cannot see the target's mode). Verified against sei-k8s-controller main @ 2d670ad and seictl main @ 821f2f8. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PR SummaryLow Risk Overview Adds Eligible Targets: state-sync applies to Re-Run Semantics is rewritten to separate Complete vs Failed recovery. A fresh Reviewed by Cursor Bugbot for commit 1e20fb1. Bugbot is set up for automated code reviews on this repo. Configure here. |
What
Two fixes to
workflow/README.md, both verified againstsei-k8s-controllermain @2d670adand this repo @821f2f8(v0.0.70).1.
--nameis not a recovery for a Failed workflowRe-Run Semanticsoffered, for either terminal phase: "pass--nameto run under a fresh workflow name instead." That holds for a Complete run, whose hold was already released — but not for a Failed one.Removing the workflow is what releases the node, and adoption is exclusive:
reconcileWorkflowdispatches todriveAdoptedWorkflowwheneverstatus.adoptedWorkflowis non-nil, somaybeAdoptWorkflownever runs while a Failed workflow is parked. The fresh--nameworkflow is therefore never adopted — it compiles no plan, makes no progress, and the watch ends at--timeoutwith the node still held.Worth stating plainly since the CLI's own
preflightPhaseErrorcarries the same suggestion on its Failed branch, and the pre-flight is name-scoped so a--namerun skips it entirely.2. The force annotation is currently mandatory, not break-glass
verifyWorkflowDataSafefails closed until the sidecar exposes the data-state query, so an un-annotateddeleteparks the workflowTerminatingwith the node still held and aWorkflowDeleteHeldwarning event. Now documented, along with the fact that annotating a workflow already stuckTerminatingreleases it on the next poll — order isn't load-bearing.Also: a new
Eligible TargetssectionThe adoption-time refusals weren't documented anywhere. A SeiNode is exactly one mode (CRD CEL), only
fullNodeis eligible, and because the workflow's own CEL can't see the target's mode the refusal lands at adoption — failing the workflow terminally sokubectl wait --for=condition=Failedresolves. Also covers one-workflow-per-node and the paused / mid-drift-plan deferrals.Not changed
Two claims I could not verify from this repo or the controller, both pre-existing:
--backend rocksdbrequiring a seid image built with-tags rocksdbBackend, and seid refusing to start when the new store layout is empty while the split is enabled. Both are sei-chain behavior.Test
Docs-only.
go test ./workflow/...green;make lintis gofmt-only. Nothing in the Go tree references the README.🤖 Generated with Claude Code