claimSteering matched steering rows by runId even after they were
claimed, and still returned them when updateMany updated zero rows.
That could inject duplicate user context into an active run.
Filter findMany to claimedAt: null and return nothing when the claim
update does not land.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
answerRunInput already blocked cross-member answers for credential
secret asks and always-allow approvals, but one-time allow/deny and
generic OTP secret asks had no run.userId check. Align the DB gate so
shared-space prompt answers cannot be hijacked at the persistence layer.
Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
When a delegated bot finishes but its wake message was deleted (e.g.
thread clear), returnBotMessageOutcome used to mark botOutcomeReturnedAt
and drop the coordinator reply silently. Retry instead, and block
clearThread while completed bot_message runs still owe a return.
Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>