You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of VforVitorio#884 (Fable-5 red-team audit 2026-07-05). Sprint 4 — Availability & multi-tenant posture.
S4.1security(chat): off-load tool dispatch via asyncio.to_thread (availability DoS)[S][P2] — each tool runs as a SYNCHRONOUS call directly inside the async SSE generator — result = _run_tool_call(call) (chat/streaming.py:337), not await asyncio.to_thread(...); search_law scans 12k laws, search_semantic_top_k can trigger a full cold embed build (chat/mcp_server.py:191 → ensure_semantic_index → index.build, search/service.py:22-33) — all on the event loop, freezing every other request/stream (warmup itself is correctly off-loaded, api/warmup.py:130-163, so this is specific to the chat-tool path). AC: await asyncio.to_thread(_run_tool_call, call). Cross-ref backend-perf Epic: Backend performance & scale at 12k laws — cold start, memory, event loop (Fable-5 audit 2026-07-05) VforVitorio/LexFlow#870 S1.1 + frontend-perf Epic: Frontend runtime perf layer 2 — input-driven cost, post #712/#713 (Fable-5 audit 2026-07-05) VforVitorio/LexFlow#875 (there it's perf; here it's the DoS/availability angle) — coordinate so it's fixed ONCE. (P2-7, CONFIRMED)
S4.2security(multi-tenant): scope threads/tags/secrets to a user OR formally enforce single-user[S][P1] — _load_thread_or_404 is session.get(ChatThread, thread_id) with no owner filter (api/routers/chat_threads.py:76-81); ChatThread has no user column (chat/storage_models.py:46-68); GET /chat/threads lists ALL threads regardless of caller; same for user_tags and the single global keyring. Thread ids are uuid4().hex (not enumerable) but the list endpoint bypasses that. Fine desktop; cross-tenant exposure of privileged legal Q&A + a shared attacker-settable key set if networked. AC: add a user/session scope column + filter to threads/tags + per-user secret namespacing before any multi-user mode; until then document single-user as a security invariant. (P1-3, CONFIRMED)
Full detail: memory/fable_redteam_audit_2026-07-05.md.
Part of VforVitorio#884 (Fable-5 red-team audit 2026-07-05). Sprint 4 — Availability & multi-tenant posture.
security(chat): off-load tool dispatch via asyncio.to_thread (availability DoS)[S] [P2] — each tool runs as a SYNCHRONOUS call directly inside the async SSE generator —result = _run_tool_call(call)(chat/streaming.py:337), notawait asyncio.to_thread(...);search_lawscans 12k laws,search_semantic_top_kcan trigger a full cold embed build (chat/mcp_server.py:191→ensure_semantic_index→index.build,search/service.py:22-33) — all on the event loop, freezing every other request/stream (warmup itself is correctly off-loaded,api/warmup.py:130-163, so this is specific to the chat-tool path). AC:await asyncio.to_thread(_run_tool_call, call). Cross-ref backend-perf Epic: Backend performance & scale at 12k laws — cold start, memory, event loop (Fable-5 audit 2026-07-05) VforVitorio/LexFlow#870 S1.1 + frontend-perf Epic: Frontend runtime perf layer 2 — input-driven cost, post #712/#713 (Fable-5 audit 2026-07-05) VforVitorio/LexFlow#875 (there it's perf; here it's the DoS/availability angle) — coordinate so it's fixed ONCE. (P2-7, CONFIRMED)security(multi-tenant): scope threads/tags/secrets to a user OR formally enforce single-user[S] [P1] —_load_thread_or_404issession.get(ChatThread, thread_id)with no owner filter (api/routers/chat_threads.py:76-81);ChatThreadhas no user column (chat/storage_models.py:46-68);GET /chat/threadslists ALL threads regardless of caller; same foruser_tagsand the single global keyring. Thread ids areuuid4().hex(not enumerable) but the list endpoint bypasses that. Fine desktop; cross-tenant exposure of privileged legal Q&A + a shared attacker-settable key set if networked. AC: add a user/session scope column + filter to threads/tags + per-user secret namespacing before any multi-user mode; until then document single-user as a security invariant. (P1-3, CONFIRMED)Full detail:
memory/fable_redteam_audit_2026-07-05.md.Upstream: VforVitorio#888