## Summary
- Closes [#40](#40)
- Aligns chat/RAG with the abc_worker stove-pipe pattern ([b13cec8](b13cec88f9)): immutable `ChatCompanyScope` per turn, conversation ownership validation, fail-closed Chroma filters
- Prefer ASGI/JWT identity over client email; never bind identity from `conversation_id` alone
- Close `ConversationDetailView` IDOR (prompts only for `request.user`)
## Changes
- New `services/chat_tenant_scope.py` with frozen `ChatCompanyScope` + ownership checks
- WebSocket consumers (`consumers.py` / `consumers_graph.py`) validate scope before `get_messages` / RAG
- `search_documents` requires a workspace (no more `filter: None` over the shared collection)
- Ingest writes `company_id` metadata (retrieval still keys on `workspace_id` for back-compat)
- Legacy `get_retriever` always applies a workspace filter
## Test plan
- [x] `manage.py test chat_backend.tests.test_chat_tenant_scope chat_backend.tests.test_consumers chat_backend.tests.test_services_rag chat_backend.tests.test_views_conversations`
- [ ] Manual: user A cannot stream RAG context from user B `conversation_id`
- [ ] Manual: RAG still returns own-company docs after deploy (existing vectors with `workspace_id` only)
- [ ] Follow-up: FE can send JWT `token`/`access` on WS payloads for stronger identity bindingReviewed-on: #41