test(webapp): chat.agent durability regression suite - #4550
Conversation
A chat/session belongs to one (org, user) pair. Pin that every store read — getChatMessages, getSession, chatExists, listChats, countUserMessages — and appendChatMessageOnce refuse a foreign tenant, so a chatId from another org reads as not-found and never leaks a transcript or the session's public access token. TRI-11166.
The primitive resumes a turn by replaying its snapshot; pin the store seam that replay lands on: a streamed-then-resumed turn is not double-appended, a crash mid-turn keeps the mid-turn append and rebuilds the session cursor, a failed write commits nothing and the retry replays with no loss, and an OOM restart replays idempotently. TRI-11166.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…o test/chat-agent-durability-tri-11166
@trigger.dev/build
trigger.dev
@trigger.dev/core
@trigger.dev/python
@trigger.dev/react-hooks
@trigger.dev/redis-worker
@trigger.dev/rsc
@trigger.dev/schema-to-json
@trigger.dev/sdk
commit: |
…o test/chat-agent-durability-tri-11166
What & why
Test-only hardening for chat.agent durability. chat.agent gets its durability from the primitive — object-store snapshot + S2
.in/.outreplay + continuation boot — but several store-level mechanisms that replay lands on had no regression test, and two of them were criticals in the 2026-06-10 chat.agent audit: cross-tenant isolation and no duplicate mid-stream turn. This adds those cases against a real Postgres table (testcontainers, no mocks). TRI-11166.Stack
Stacked on #4549 (query boundary). Merge that first.
What's inside
dashboardAgentTenantIsolation.test.tsdashboardAgentDurableResume.test.tsdashboardAgentDurableResume.test.tsdashboardAgentDurableResume.test.tspackages/trigger-sdk/src/v3/chat.test.ts— not duplicateddashboardAgentDurableResume.test.ts.outtrimming / OOM retry restarts cleanlydashboardAgentDurableResume.test.ts.outtrimming and the OOM restart itself are inside the closed primitive (not reachable)The "Full" vs "Seam-only" column is the honest distinction: full means the whole mechanism is exercised from the repos we own; seam-only means we pin the store contract the primitive depends on, and the primitive-internal half lives where we can't reach it.
Key decisions
organizationIdfilter fromgetChatMessagesleaks org A's transcript to the owner's user id under another org — the test fails attoBeNull(). No-duplicate: removing the stored-id drop instoreChatMessagesmakes a replayed persistTurn over-reserve positions (next free slot jumps 3 → 7) — the test fails on the allocator assertion. Both reverted.Residual follow-ups
These live inside the closed chat.agent primitive package and can't be unit-tested from the repos we own; the tests above are the store-level backstop they depend on:
.in/.outreplay at the transport level..outtrimming never dropping in-flight data, and the OOM restart mechanism itself.Testing
pnpm run test --filter webapp—dashboardAgentTenantIsolation.test.tsanddashboardAgentDurableResume.test.ts.