Skip to content

Fence scheduler rollback destination ownership - #47

Open
chaptersix wants to merge 1 commit into
migration-handoff/signalsfrom
migration-handoff/rollback
Open

chaptersix wants to merge 1 commit into
migration-handoff/signalsfrom
migration-handoff/rollback

Conversation

@chaptersix

@chaptersix chaptersix commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Problem

CHASM-to-workflow rollback generated a fresh V1 start request ID on every task attempt and accepted
every WorkflowExecutionAlreadyStarted response. A foreign destination could close the CHASM
source, and a source-close failure followed by destination closure could restart deleted state via
ALLOW_DUPLICATE. The admin preflight also treated completed and terminated dummy workflows as
live sentinels.

Fix

  • Persist the initiating rollback request ID in WorkflowMigrationState.
  • Reuse that ID for every V1 StartWorkflowExecution attempt.
  • Accept AlreadyStarted only when its recorded StartRequestId matches.
  • Reject a concurrent different rollback ID and fail old identity-less pending tasks closed.
  • Generate a request ID at the admin boundary when an older caller omits one.
  • Block dummy sentinels only while their workflow status is running.

The implementation and compatibility boundary are described in the commit-pinned
rollback note.

Foreign destination ownership sequence

Foreign destination regression

Stable rollback retry sequence

Stable source-close retry regression

Sentinel lifecycle sequence

Closed sentinel regression

Before/after

On the evidence parent, a foreign rollback destination closes CHASM and response-loss retries use
rotating UUIDs. On this branch, the collision regression passes with CHASM retained; retry
boundaries use the same durable ID and create one destination. Running sentinels remain blocked,
while completed and terminated sentinels proceed.

Compatibility and failure modes

An old pending rollback without a durable ID is retained for operator recovery. An owned V1 chain
that has already continued as new may no longer report the original current-run start request ID;
the strict check fails closed rather than guessing ownership. The ID is replicated CHASM state,
so crash and namespace failover do not depend on process-local memory. The change adds no RPC and
no ordinary scheduler hot-path work.

Validation

go test -tags test_dep ./chasm/lib/scheduler/migration ./chasm/lib/scheduler \
  ./service/worker/scheduler ./service/frontend -count=1
go test -tags test_dep ./service/worker/scheduler -run '^TestReplays$' -count=1
go test -tags test_dep ./chasm/lib/scheduler/migration -run '^$' \
  -fuzz '^FuzzMigrationRoundTrip$' -fuzztime=3s
make lint-code-fast GOLANGCI_LINT_BASE_REV=chaptersix/main GOLANGCI_LINT_FIX=false

All commands pass; fuzz seeds are 0, 1, 7, 42, 63 (432 executions in the final bounded run).

Stack

Foreign destination ownership sequence

Foreign destination regression

Stable rollback retry sequence

Stable source-close retry regression

Sentinel lifecycle sequence

Closed sentinel regression

@chaptersix
chaptersix marked this pull request as ready for review September 5, 2026 01:00
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T01:04:50.456956Z 735701f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 735701fda3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2301 to +2302
if migrationRequestID == "" {
migrationRequestID = uuid.NewString()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve generated migration IDs across client retries

When an older caller omits request_id, each Admin API invocation generates a different value. If the first invocation commits MigrateToWorkflow but its response is lost, the caller's retry reaches the pending migration with a new ID and Scheduler.MigrateToWorkflow returns AlreadyExists instead of idempotent success. The fallback ID must remain stable across external retries, or omission should be handled without treating retries as competing migrations.

Useful? React with 👍 / 👎.

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