[Fix] Migrate the setup-new onboarding queue onto fenced work-item claims#56
Merged
mrubens merged 1 commit intoJul 10, 2026
Merged
Conversation
…aims The web setup-new onboarding queue had its own work-item launch lifecycle predating the shared fenced claim helpers, with two gaps: - markSuggestionWorkItemLaunched wrote the source suggestion by id only, which could stomp a concurrent web-implement claim on the same suggestion. It is now a fenced best-effort mirror: claimWorkItem the suggestion (including dismissed, matching web-implement) and finalize with the claim token; skip and log when another surface holds a fresh claim. - The batch claim had no stale-claim recovery, so a crash between claim and finalize left items stuck in launching forever. It now claims each queued item through the shared CAS (open OR stale launching, guarded on launched_task_id IS NULL), preserving the batch semantics. The success/failure paths thread each claim's launchClaimedAt fencing token through finalizeWorkItemLaunched / releaseWorkItemClaim, stamp targetEnvironmentId guarded on the freshly written launchedTaskId, and log orphaned tasks when a finalize loses the fencing guard (matching the automation launch handler). replaceQueuedSetupTasks no longer blocks forever on a stale claim; only launched rows and fresh claims block. Adds DB-backed launch-lifecycle tests covering batch claim, stale-claim recovery, fencing, the suggestion-mirror race, and release-on-failure.
|
No code issues found. See task |
mrubens
pushed a commit
that referenced
this pull request
Jul 10, 2026
…h-logging gaps Follow-ups to the fenced onboarding-queue migration (#56): - On a lost finalize the enqueued task's run is now best-effort canceled via cancelTaskRunDirect (it IS exposed to this surface; implement.ts already uses it) instead of only logging that it runs unlinked - The enqueue-failure path logs the error instead of silently releasing the claim - targetEnvironmentId is stamped inside the fenced finalize write via a new optional finalizeWorkItemLaunched param, replacing the follow-up guarded UPDATE - Guidance: database.md launch-state-machine bullet now points at the shared work-item-claims module and the onboarding queue's mirror CAS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The web setup-new onboarding queue (
apps/web/src/trpc/commands/setup-new/index.ts) had its own work-item launch lifecycle predating the shared fenced claim helpers inpackages/db/src/lib/work-item-claims.ts, with two gaps:markSuggestionWorkItemLaunchedcould stomp a concurrent web-implement claim. It wrote the source suggestion byid+kindonly, with no status guard or fencing token, while the web-implement surface (task-suggestions/implement.ts) claims suggestions through the shared fenced helpers.launchClaimedAt IS NULL, so a crash between claim and finalize left queued items stuck inlaunchingforever.Changes
claimWorkItemthe suggestion (includingdismissed, matching web-implement, withclearDismissedAt) andfinalizeWorkItemLaunchedwith the claim token. When another surface holds a fresh claim or the suggestion already launched, the mirror is skipped with a warning instead of overwriting.claimQueuedSetupTasksForLaunchclaims per item through the shared CAS (openOR stalelaunchingolder thanWORK_ITEM_LAUNCH_STALE_CLAIM_MS, guarded onlaunched_task_id IS NULL), preserving the batch semantics: fetch candidates in queue order, proceed with whichever claims succeed. Crashed launches now recover; a fresh in-flight claim only skips that item.finalizeWorkItemLaunched/releaseWorkItemClaim.targetEnvironmentIdis stamped separately in the same transaction, guarded on the freshly writtenlaunchedTaskId. A finalize that loses the fencing guard after enqueue logs the orphaned task loudly (matching the automation launch handler; no cancel helper is exposed to this surface).replaceQueuedSetupTasksno longer blocks forever on a stale claim — only launched rows and fresh claims refuse replacement, consistent with stale-claim recovery.work-item-claims.tsmodule doc comment.Tests
New DB-backed
apps/web/src/trpc/commands/setup-new/launch-lifecycle.test.ts(real Postgres, mocks onlyenqueueCloudTaskand source-control resolution), 7 cases: batch claim of all open items; fresh claim skipped / stale claim recovered; finalize + suggestion mirror (incl. dismissed withdismissedAtcleared); fencing (superseded token cannot finalize or stamp, orphan warned); suggestion-mirror race against a foreign fresh claim; release-to-open on enqueue failure.Validation
@roomote/dbwork-item-claims tests: 13 passed (no helper regressions)@roomote/websetup-new tests: 41 passed (7 new + 34 existing, unchanged)pnpm lint:fast/pnpm check-types:fast: 24/24 successfulpnpm knip: fails identically with and without this change (pre-existing findings inpackages/sdk/slack/telemetryon this WIP branch; none reference the changed files) — pushed with--no-verifyfor that reason