Buyer impact
A Global Ask answer is persisted before its citations are reauthorized for the final response. When that post-persist authorization check fails, the API correctly returns a generic 503, but the rejected turn and citation rows remain. The next question then fails the whole session with 409 because the stale citation is now part of session history.
This converts a narrow visibility/provider race into a permanently retired conversation session. Removing session continuity or weakening citation reauthorization is not acceptable.
Root cause
ask_agent currently performs:
persist_global_ask_turn
→ read_authorized_ask_evidence
→ raise 503 when not all citations remain visible
persist_global_ask_turn commits its inserts before the final check. The later 503 cannot roll them back.
Required fix
- Acquire one connection and open an outer database transaction.
- Persist the new turn and citations inside that transaction.
- Reauthorize the persisted citation set using the same knowledge cutoff and tenant scope before the outer transaction exits.
- Raise the existing generic 503 inside the outer transaction when evidence changed so all new turn/citation rows roll back.
- Preserve existing previous turns and their authorization state.
- Keep the post-persist race check; do not replace it with a precheck-only shortcut.
TDD acceptance
- RED on current code: force a cited post to lose eligibility between source selection and final reauthorization.
- The request returns the current generic 503 without hidden evidence.
- The failed answer creates no new
global_ask_turn or global_ask_turn_citation rows.
- The same session can immediately submit a safe follow-up and does not receive 409.
- Previously committed turns remain unchanged.
- Successful answers still persist exactly once under retry/idempotency expectations.
- Real PostgreSQL integration and unit tests cover commit and rollback paths.
- Full backend/API, SAST, security, migration, and exact-head checks pass.
Stack placement
Fix on the active #342 → #357 → #360 line through an ordinary stacked PR or a normal merge into the appropriate branch. Do not force-push, bypass protection, disable Global Ask, drop session persistence, or relax ABAC/cutoff checks.
Origin
Exact-head review thread on PR #342 (7d2654fb19ba7a88815edcefeb0a44f1bd05f619).
Buyer impact
A Global Ask answer is persisted before its citations are reauthorized for the final response. When that post-persist authorization check fails, the API correctly returns a generic 503, but the rejected turn and citation rows remain. The next question then fails the whole session with 409 because the stale citation is now part of session history.
This converts a narrow visibility/provider race into a permanently retired conversation session. Removing session continuity or weakening citation reauthorization is not acceptable.
Root cause
ask_agentcurrently performs:persist_global_ask_turncommits its inserts before the final check. The later 503 cannot roll them back.Required fix
TDD acceptance
global_ask_turnorglobal_ask_turn_citationrows.Stack placement
Fix on the active #342 → #357 → #360 line through an ordinary stacked PR or a normal merge into the appropriate branch. Do not force-push, bypass protection, disable Global Ask, drop session persistence, or relax ABAC/cutoff checks.
Origin
Exact-head review thread on PR #342 (
7d2654fb19ba7a88815edcefeb0a44f1bd05f619).