fix: rebind send now claims on session handoff (#3845)

Co-authored-by: ayattara <alassane.yattara@savoirfairelinux.com>
Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
This commit is contained in:
Alassane
2026-09-24 18:34:28 -04:00
committed by GitHub
parent cb591c303c
commit 4d3c5a236c
11 changed files with 866 additions and 27 deletions
@@ -0,0 +1,34 @@
---
created: 2026-09-21
status: complete
requirements:
- REQ-UI-MESSAGE-QUEUE-SEND-NOW-001
system_design:
- ../../specs/ui/system-design/message-queue-send-now.md
legacy_specs: []
---
# Implementation Plan: Preserve Send Now claim identity across session handoff
Session handoff must carry pending Send Now claims to the successor session
without carrying the retired session's incarnation or operation generation.
This corrective package records the narrow persistence repair and its restart
reconciliation proof. The existing Send Now requirement and system design
remain authoritative for queue ownership, FIFO ordering, and fencing.
## Scope
- Rebind accepted and unaccepted pending claims to the live destination
session identity during both direct and durable owned transfers.
- Preserve claim IDs, accepted state, source ordering, dispatch metadata,
transaction rollback, and stale source fencing.
- Prove recovery after the source session is removed and the process restarts.
## Out of scope
Queue feature behavior, UI changes, provider routing, schema changes, incident
database repair, deployment, and backup cleanup.
## Delivery
See [Task 01: Rebind transferred Send Now claims](task-01-rebind-claims.md).
@@ -0,0 +1,56 @@
---
id: "01-rebind-claims"
title: "Rebind transferred Send Now claims"
status: complete
wave: 1
depends_on: []
plan: "plan.md"
requirements:
- REQ-UI-MESSAGE-QUEUE-SEND-NOW-001
acceptance_criteria:
- AC-UI-MESSAGE-QUEUE-SEND-NOW-001.8
- AC-UI-MESSAGE-QUEUE-SEND-NOW-001.10
system_design:
- ../../specs/ui/system-design/message-queue-send-now.md
---
# Task 01: Rebind transferred Send Now claims
## Summary
When a session handoff moves a pending Send Now claim, persist the successor's
full queue session identity and operation generation. This keeps restart
reconciliation usable while retaining exact claim fencing.
## Acceptance
- Accepted and unaccepted claims transferred through direct and durable owned
paths use the destination session incarnation and generation.
- Claim IDs, accepted state, source rows, dispatch metadata, FIFO order, and
rollback behavior remain unchanged.
- Requests and settlements using the retired source identity remain fenced.
- Legacy transfer fallback fails closed when it encounters an identity-aware
claim instead of persisting the retired identity.
- Reconciliation after source-session removal and process restart can settle
both claim states under the successor identity.
## Verification
```bash
(cd apps/backend && go test -v -run '^(TestSQLiteTransferSessionIdentitiesRebindsPendingSendNowClaim|TestTransferredIdentityAwareSendNowClaimReconcilesAfterProcessRestart)$' ./internal/orchestrator/messagequeue ./internal/orchestrator)
(cd apps/backend && go test -race ./internal/orchestrator/messagequeue)
(cd apps/backend && go test ./internal/orchestrator/messagequeue ./internal/orchestrator)
```
## Results
The direct and durable transfer paths now pass the live destination identity
into the atomic transfer transaction, which validates it before rebinding the
claim and derives the claim generation from the destination session generation.
Durable transfer preparation also includes attachments held only by a pending
Send Now claim after the source queue row is removed. The legacy transfer
fallback rejects an identity-aware claim rather than retaining the retired
identity, while identity-free legacy claims keep their existing behavior.
Accepted and unaccepted transfer, restart reconciliation, source fencing,
fallback rejection, claim attachment preparation, and race coverage pass. No
UI or public documentation change is required.