- Shipped
- July 19, 2026 at 3:26 AM UTC
- Author
- Kamo
- Commit
- 9be55e7
Creates or reuses the support session, copies the AI transcript in as one system event, routes it, and tells the visitor honestly what happens next. Confidentiality is split by audience, which the first pass got backwards. The AI's summary and reasonDetail are its private assessment OF the visitor, and the full payload was reaching the visitor's own browser through two REST doors and the STOMP frame while the agent saw nothing. Redaction now applies at every visitor-facing path; the persisted row keeps the full payload for the agent. chat.session.{guid} is a single topic both audiences subscribe to, so the live frame is cut to what the visitor may see and the agent UI re-reads the full row from its own authenticated endpoint. Idempotency is keyed on aiSessionGuid, org-scoped, and checked BEFORE creating anything. Keying it on the session and checking after creation - the obvious shape - is useless precisely when it matters: a retry that lost its session token always passes the check and produces a duplicate ticket and a second agent page. transcriptAttached now reports what actually happened. It previously came back true even when the write had silently failed, which is the worst possible combination: the visitor is told their context came across, the agent's thread is empty, and neither party knows. Copy-on-handoff, not migration: AI turns stay where analytics reads them.