You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(serenity): guard fails closed only on genuine errors; async begin-sites reconcile stale attempts (LLMO-7418 external-review Findings 1, 9, 11)
Finding 1: guardAgainstConcurrentProvisioning's read (getBrandProvisioningState)
threw a bare Error on ANY PostgREST failure, including "column does not exist" —
meaning if this service ever deploys even briefly ahead of the mysticat-data-service
migrations that add the provisioning columns, every synchronous createMarket/activate
call 500s on an endpoint that worked a moment ago. Preserve the underlying SQLSTATE
on the thrown error and degrade to a no-op specifically for 42703 (undefined_column) —
no column means no attempt could possibly be in flight, so proceeding is correct, not
just convenient. Any other read error still fails closed, unchanged.
Finding 11 (adjacent, same function): a missing/unparseable updated_at yielded NaN,
which is never < the staleness threshold, so it fell through to "reconcile as stale" —
capable of tearing down a genuinely fresh, healthy attempt. Treat NaN as "assume
fresh" instead (409, never silently reconciled away).
Finding 9: beginProvisioningAttempt's own CAS has no staleness awareness, so a stuck
pending row (crashed worker, DLQ'd message) 409s forever once a brand's callers are
async-only — there is no scheduled sweep (architecturally impossible; Semrush only
accepts user-token auth). Call guardAgainstConcurrentProvisioning immediately before
beginProvisioningAttempt at the two async begin-sites in this branch (createMarket,
activate's project-activation batch) that operate on a pre-existing brand id — reusing
the guard's own tested reconcile-or-409 logic rather than inventing new logic. The
brand-create async sites (createBrandForOrg) are NOT touched: they mint a brand-new,
freshly-generated UUID in the same request, so no prior attempt could exist for it —
adding the guard there would be a pure no-op read on every call.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
0 commit comments