CedarCopilot wants to merge 0 commits into staging from fix/scheduled-send-claim-and-merge-delete
Live on prod, no production signal yet
OTEL fallback found no prod spans matching calendar modify-event delete since deploy.
OTEL fallback found no prod spans matching EventDetailsPopover / calendar modify-event since deploy.
Since the 2026-08-15 02:46:15Z deploy, telemetry contains no OTEL spans or structured result logs tied to modify-calendar-event permission outcomes: 0 matches for modify-calendar-event/affectedEveryone in OTEL, and no logs for logged tool-call results, modifyCalendarEventTool.
OTEL fallback found no prod spans matching handleChatStreamRequest runGeneration since deploy.
OTEL fallback found no prod spans matching handleChatStreamRequest runGeneration since deploy.
Verification cited only 8 matching post-deploy events, below the 20-event floor for calling a change verified. Nothing is failing; there is not yet enough traffic to confirm it.
Libra has verdicts on 0 of 13 tracked behaviors on prod; 13 are still being checked. Libra checks hourly for 3 days after each deploy.
Fixes the two issues Greptile raised on #2478. Both are valid; only one of the prescribed remedies actually works, and this PR says why.
queue-handler.ts)Valid, fixed properly. The worker read pending_emails_status and then sent , check-then-act over a store that cannot make the pair exclusive. KVStore (runtime/platform.ts) is get/put/delete with no compare-and-swap, which is why the guard's own comment already called itself "best-effort, not a CAS". Two real consequences: cancel-on-reply writes cancelled into the gap and the email goes out after the reply that was meant to stop it; and two deliveries of the same message (SQS is at-least-once, and the cron re-enqueues on a failed KV delete) both read pending and both send.
The decision moves onto the durable scheduled_sends row this subsystem already has, where one conditional UPDATE … SET status='sending' WHERE status='pending' is atomic. Exactly one caller wins, so delivery and cancellation are mutually exclusive rather than merely ordered. No migration , status is plain text with no CHECK constraint.
Three things make it safe rather than just atomic:
sending could never be re-claimed , the retry would skip it silently.mail.unsend now returns an error rather than a success the client acts on by deleting the draft behind an email already on its way.Rows abandoned on sending by a worker that died mid-send are collected by the existing stale sweep.
conversation-repoint.ts)Valid, but the prescribed fix does not work , and this is the part worth reviewing.
Greptile asked for "one transaction or lock". A transaction does not close this window. The database runs at READ COMMITTED (verified, not assumed): each statement takes its own snapshot, so a document committed after the check is invisible to the check and untouched by the delete. A transaction buys atomicity, not isolation from concurrent inserts.
Closing it outright needs both sides cooperating , SERIALIZABLE on the writers too, or a lock every writer takes , and documents are inserted from ~10 sites across 6 services. Any such scheme is one missed call site away from silently not working. The real fix is a foreign key, which the path-addressing scheme (conversation/{id}/…, no FK column) cannot express today.
What a single statement does buy is removing the gap between the two operations. DELETE … WHERE NOT EXISTS (…) evaluates the predicate and deletes under one snapshot, so the window shrinks from two round-trips , plus whatever the caller does between them , to the statement's own execution, and anything already committed blocks the delete. repointDocumentsAndDeleteConversation then re-points the straggler and retries, which converges; three rounds without converging is not a race and raises rather than deleting.
All four merge/repair paths route through it, so none issues a bare conversation delete any more.
Residual risk, stated plainly: an insert committing during that one statement's execution can still slip through. Eliminating it is a foreign-key project, not a patch.
Libra has not measured any production surfaces for this change yet.