Skip to content

feat(world-postgres): event-first start-hook admission#2764

Draft
NathanColosimo wants to merge 1 commit into
nathan/start-hooks-02-world-localfrom
nathan/start-hooks-03-world-postgres
Draft

feat(world-postgres): event-first start-hook admission#2764
NathanColosimo wants to merge 1 commit into
nathan/start-hooks-02-world-localfrom
nathan/start-hooks-03-world-postgres

Conversation

@NathanColosimo

@NathanColosimo NathanColosimo commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Stack 3/4 · #2762#2763 → this PR → #2765

Implements start-hook admission claims for @workflow/world-postgres. start() enqueues first; run_created (from the sync call or the queued message) claims the token.

  • New workflow_hook_claims table (migration 0016): token PK, owning run, optional hookId, ttlSeconds, optional expiresAt. Lifecycle state is derived, not stored: unmaterialized start claim = hookId IS NULL; materialized = hookId set; retained = expiresAt set.
  • run_created claims the token in the same transaction as the run and event inserts; same-run duplicate deliveries resolve to EntityConflictError (never a self-conflict), foreign owners to HookConflictError with the owning run.
  • createHook materializes the claim and creates the hook row in one transaction; plain hooks get a ttlSeconds = 0 guard row (fixing a pre-existing token-uniqueness race — hooks.token has no unique index).
  • Disposal and run completion retain TTL claims with set-based guarded statements (no read-modify-write for a concurrent materialize to interleave with); cancellation releases unmaterialized claims; terminal cleanup GCs expired debris of terminal/missing runs.
  • Rebased over Fix Postgres step lifecycle event ordering #2714: preserves the transactional step_started path and lazy event-ID allocation, including its regression test.
  • Lifts the postgres-lane skip from the stack's e2e test.

@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3978dcb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@workflow/world-postgres Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, Comment Jul 7, 2026 12:08am
example-nextjs-workflow-webpack Ready Ready Preview, Comment Jul 7, 2026 12:08am
example-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-astro-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-express-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-fastify-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-hono-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-nitro-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-nuxt-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-sveltekit-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-tanstack-start-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workbench-vite-workflow Ready Ready Preview, Comment Jul 7, 2026 12:08am
workflow-docs Ready Ready Preview, Comment, Open in v0 Jul 7, 2026 12:08am
workflow-swc-playground Ready Ready Preview, Comment Jul 7, 2026 12:08am
workflow-tarballs Ready Ready Preview, Comment Jul 7, 2026 12:08am
workflow-web Ready Ready Preview, Comment Jul 7, 2026 12:08am

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 1442 0 241 1683
✅ 💻 Local Development 1483 0 200 1683
✅ 📦 Local Production 1617 0 219 1836
✅ 🐘 Local Postgres 1617 0 219 1836
✅ 🪟 Windows 153 0 0 153
✅ 📋 Other 893 0 178 1071
Total 7205 0 1057 8262

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 125 0 28
✅ example 125 0 28
✅ express 125 0 28
✅ fastify 125 0 28
✅ hono 125 0 28
✅ nextjs-turbopack 149 0 4
✅ nextjs-webpack 149 0 4
✅ nitro 125 0 28
✅ nuxt 125 0 28
✅ sveltekit 144 0 9
✅ vite 125 0 28
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 128 0 25
✅ express-stable 128 0 25
✅ fastify-stable 128 0 25
✅ hono-stable 128 0 25
✅ nextjs-turbopack-canary 134 0 19
✅ nextjs-turbopack-stable 153 0 0
✅ nextjs-webpack-stable 153 0 0
✅ nitro-stable 128 0 25
✅ nuxt-stable 128 0 25
✅ sveltekit-stable 147 0 6
✅ vite-stable 128 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 128 0 25
✅ express-stable 128 0 25
✅ fastify-stable 128 0 25
✅ hono-stable 128 0 25
✅ nextjs-turbopack-canary 134 0 19
✅ nextjs-turbopack-stable 153 0 0
✅ nextjs-webpack-canary 134 0 19
✅ nextjs-webpack-stable 153 0 0
✅ nitro-stable 128 0 25
✅ nuxt-stable 128 0 25
✅ sveltekit-stable 147 0 6
✅ vite-stable 128 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 128 0 25
✅ express-stable 128 0 25
✅ fastify-stable 128 0 25
✅ hono-stable 128 0 25
✅ nextjs-turbopack-canary 134 0 19
✅ nextjs-turbopack-stable 153 0 0
✅ nextjs-webpack-canary 134 0 19
✅ nextjs-webpack-stable 153 0 0
✅ nitro-stable 128 0 25
✅ nuxt-stable 128 0 25
✅ sveltekit-stable 147 0 6
✅ vite-stable 128 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 153 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 128 0 25
✅ e2e-local-dev-tanstack-start- 128 0 25
✅ e2e-local-postgres-nest-stable 128 0 25
✅ e2e-local-postgres-tanstack-start- 128 0 25
✅ e2e-local-prod-nest-stable 128 0 25
✅ e2e-local-prod-tanstack-start- 128 0 25
✅ e2e-vercel-prod-tanstack-start 125 0 28

📋 View full workflow run


Some E2E test jobs failed:

  • Vercel Prod: success
  • Local Dev: failure
  • Local Prod: success
  • Local Postgres: success
  • Windows: success

Check the workflow run for details.

@vercel vercel Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional Suggestion:

The catch block wrapping the fallback insert(events) in create() swallows all non-dedup database errors, masking them as EntityConflictError instead of propagating them.

Fix on Vercel

@NathanColosimo NathanColosimo force-pushed the nathan/start-hooks-03-world-postgres branch from 84e800b to 306be29 Compare July 3, 2026 00:06
@NathanColosimo NathanColosimo force-pushed the nathan/start-hooks-02-world-local branch from 78e0202 to 23c48fc Compare July 3, 2026 00:06
@NathanColosimo NathanColosimo force-pushed the nathan/start-hooks-02-world-local branch from 23c48fc to f31c202 Compare July 3, 2026 00:19
Adds the workflow_hook_claims table (single-owner token constraint;
lifecycle state derived from hookId/expiresAt). run_created claims the
token in the same transaction as the run and event inserts, createHook
materializes the claim, disposal and run completion retain TTL-carrying
claims with set-based statements (claims without a TTL are released at
run end), cancellation releases unmaterialized claims, and terminal-run
cleanup GCs expired claim debris. Also lifts the postgres-lane skip
from the start-hook e2e test.
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