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:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout. (14)
🧰 Additional context used📓 Path-based instructions (9)**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
{packages/core,apps/webapp}/**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{test,spec}.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.ts📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)
Files:
apps/webapp/**/*.{ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Files:
apps/webapp/**/*.test.{ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Files:
apps/**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
apps/webapp/**/*.{test,spec}.{ts,tsx}📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)
Files:
🧠 Learnings (18)📚 Learning: 2026-03-22T13:26:12.060ZApplied to files:
📚 Learning: 2026-03-22T19:24:14.403ZApplied to files:
📚 Learning: 2026-05-18T08:21:27.694ZApplied to files:
📚 Learning: 2026-05-18T08:21:27.694ZApplied to files:
📚 Learning: 2026-06-13T19:53:13.759ZApplied to files:
📚 Learning: 2026-06-17T17:13:49.929ZApplied to files:
📚 Learning: 2026-06-23T13:04:21.413ZApplied to files:
📚 Learning: 2026-05-07T12:25:18.271ZApplied to files:
📚 Learning: 2026-05-28T20:02:10.647ZApplied to files:
📚 Learning: 2026-07-30T18:43:56.874ZApplied to files:
📚 Learning: 2026-08-08T12:49:17.489ZApplied to files:
📚 Learning: 2026-05-12T21:04:05.815ZApplied to files:
📚 Learning: 2026-06-25T18:21:51.905ZApplied to files:
📚 Learning: 2026-07-03T17:10:21.498ZApplied to files:
📚 Learning: 2026-05-18T14:40:02.173ZApplied to files:
📚 Learning: 2026-06-04T18:16:35.386ZApplied to files:
📚 Learning: 2026-06-09T17:58:04.699ZApplied to files:
📚 Learning: 2026-06-16T09:19:47.637ZApplied to files:
🔇 Additional comments (5)
WalkthroughAdds PostgreSQL integration tests for dashboard-agent durability and tenant isolation. The durability tests cover turn replay, crash recovery, session cursor persistence, transactional rollback and retry, and OOM restart replay. The tenant isolation tests verify scoped transcript and session reads, chat discovery, message counts, and append restrictions for foreign organizations and users. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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
…at/query-safety-tri-11165
…constraint violation
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.