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
{{ message }}
Repository navigation
Commit b7394be
Browse filesBrowse the repository at this point in the historyBrowse files
* fix(trigger): complete runs whose workflow was deleted or undeployed before they started
Not-found, archived, undeployed, unattached and suspended rejections come
from a successful read and never wait on an execution log (not-found and
undeployed never write one), so they complete without the hasCompleted gate.
Quota rejections (402/429) still complete only once their log is saved.
* fix(projects): finish a retired Project's storage sweep only on the provider's last page
Azure Blob, GCS and S3-compatible providers can return a short or empty page
that is not the last, which the sweep read as done and left the rest of the
prefix orphaned. The sweep now ends only on page.done, and follows a non-final
page that removed nothing to the next one within the run.
* fix(account-deletion): keep a public object a stored URL with a fragment still names
A relative /api/files/serve/<key>#frag kept the fragment in its candidate key,
so a live reference could be missed and the object purged. The guard now also
reads the path without its fragment, on both the decoded and fallback paths.
* fix(billing): withhold the free allowance from stats rows created outside signup
A storage write or an ownership transfer that creates a missing user_stats row
gave it the default free allowance without the deleted-identity check
ensureUserStatsExists makes. When either insert creates the row, the same
email-only check now runs on the caller's transaction, in a savepoint that
fails open; an existing row costs no extra query.
* docs(async-jobs): scope cancelByWorkspace to persisted queue jobs
* refactor(trigger): classify preprocessing rejections by meaning, not status code
Preprocessing tags not-found, archived, not-attached and not-deployed
rejections with an internal workflowState (isWorkflowStateRejection); these
write no execution log by design, so the job completes at once. Quota and
account rejections (usage limit, spent reservation headroom, rate limit,
suspended account) complete only once their log is saved; a suspended account
goes back behind that gate.
The tag is a separate field rather than a code because v2 execute, its
streaming error and MCP serve copy error.code into their responses; a new code
on a 404 would change those outputs. Headroom denials are matched through a
new isReservationHeadroomDenial next to their descriptors instead of joining
the deterministic-rejection set, which webhooks and polling read to stop
retries and which deliberately leaves headroom out.
* refactor(billing): create every fallback user_stats row through one creator
createUserStatsIfMissing inserts the row on the caller's executor and, only
when it created the row, runs the deleted-identity check and forfeits the
allowance (a transaction on db, a savepoint inside a caller's transaction),
failing open. ensureUserStatsExists, the storage write and the ownership
transfer all use it; the two forfeit paths merge into one.
One behavior delta: a stats row the ownership transfer creates for the new
owner now starts at getFreeTierLimit() instead of the schema default, the same
as every other creator (identical unless FREE_TIER_COST_LIMIT is set).
The admin credits route keeps its own insert: it is not behavior-identical
(short id, no usageLimitUpdatedAt, a plain insert that throws on a concurrent
create rather than a no-op), and it rewrites the limit right after.
* refactor(billing): drop the unused executor from the deleted-identity email check
isDeletedAccountIdentity reads on db as it did before; only
userHasDeletedAccountIdentity takes a caller's transaction, so its savepoint
wrapper moves inline. Hoist the headroom descriptors to a module constant.
0 commit comments