feat(db): add closed_state_consistency CHECK to execution_workspaces (SHA-2492)#13
Open
Mlaz-code wants to merge 1 commit into
Open
Conversation
…(SHA-2492)
execution_workspaces rows must satisfy closed_at IS NULL OR
status IN ('archived','cleanup_failed'). The contradictory state
(closed_at stamped, status='active'/'idle') fails-closed in
isClosedIsolatedExecutionWorkspace and 409s issue comments/PATCHes.
Added with NOT VALID so the deploy is fast and does not lock the table
while validating every existing row. The constraint takes effect for
all INSERTs and UPDATEs immediately.
Existing violators (1037 rows on prod paperclip DB at filing time) need
to be backfilled to status='archived' before
ALTER TABLE execution_workspaces VALIDATE CONSTRAINT
execution_workspaces_closed_state_consistency runs as a follow-up.
A pre-validate audit confirmed 0 violator rows have a non-terminal
source issue, so the bulk archive is safe.
Companion: PR sha-2492-patch-normalize-closed-at fixes the PATCH route
so reopens clear closed_at (otherwise the new CHECK would reject them).
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.
Summary
Adds a
CHECKconstraint toexecution_workspacesmaking the contradictory state representationally impossible:closed_at IS NULL OR status IN ('archived', 'cleanup_failed'). Companion to PR #12 (PATCH route normalize-on-reopen).Without this DB-level invariant, every cleanup author has to remember to pair
closed_at = now()with a closed status. Historically that's failed in multiple places (stale_7d_SHA-{1835,2221},source_issue_terminalrecipe, and a Coordinator manual PATCH) — see SHA-2492 for the full forensic.Why NOT VALID
There are 1037 existing violator rows on the prod paperclip DB.
ADD CONSTRAINT ... CHECK ... NOT VALIDskips the table-scan-and-validate step at migration time, so the deploy is fast and lock-free. The constraint takes effect for all INSERTs and UPDATEs immediately. Validating against the existing data happens as a separate manual step:…which must run after the violator rows are backfilled. Pre-audit on the prod DB confirmed 0 violator rows have a non-terminal source issue, so the backfill is safe:
Deploy / rollout order
closed_at.0077_workspace_closed_state_consistency.sqlships theNOT VALIDconstraint.UPDATEabove (1037 rows). Pre-audit attached in SHA-2492 confirms safety.VALIDATE CONSTRAINTon prod paperclip DB (Board approval needed): proves no violators remain forever.Changes
packages/db/src/schema/execution_workspaces.ts— addcheck()constraint to the drizzle schema for consistency with the SQL migration.packages/db/src/migrations/0077_workspace_closed_state_consistency.sql— hand-rolled migration withNOT VALID(drizzle-kit would generate a validating ADD which would reject on the existing 1037 violators).packages/db/src/migrations/meta/_journal.json— register migration 77.Companion work
/shared-tmp/worktree-cleanup.sh(the recurringworktree-cleanup.timerjob that was producing contradictory rows daily) was patched 2026-05-12 to writestatus='archived'. Verified live on the 2026-05-13 04:33 EDT timer fire.Test plan
SELECT count(*) FROM execution_workspaces WHERE closed_at IS NOT NULL AND status NOT IN ('archived','cleanup_failed')→ 0 forever.