Files
konstruct/.planning/phases/06-web-chat/06-VERIFICATION.md

14 KiB

phase, verified, status, score, human_verification
phase verified status score human_verification
06-web-chat 2026-03-25T16:39:57Z human_needed 13/13 automated must-haves verified
test expected why_human
Log in as customer_admin, click Chat in the sidebar navigation, click New Conversation, select an AI Employee, type a message, press Enter Animated typing dots appear immediately; agent response arrives as a left-aligned bubble; user message appears right-aligned End-to-end requires live gateway, orchestrator, Celery worker, Redis, and LLM backend — cannot verify WebSocket round-trip programmatically
test expected why_human
Send a message that requests a formatted response (e.g. 'Give me a bulleted list of 3 tips') Response renders with proper markdown: bold text, bullet lists, and code blocks display correctly Markdown rendering quality requires visual inspection in a running browser
test expected why_human
Navigate away from /chat then back; click a previous conversation Sidebar shows previous conversation with last message preview; clicking loads full message history Persistence across page navigations requires a running DB and portal session
test expected why_human
Log in as customer_operator, navigate to /chat, start a conversation Chat link visible in sidebar; chat works; admin-only nav items (Billing, API Keys, Users) remain hidden RBAC nav suppression and operator chat access require a live session with correct role claims
test expected why_human
If an agent has tools configured, send a message that triggers tool use Agent invokes the tool and incorporates the result into its response Full pipeline with tool execution requires configured tools and a live Celery worker

Phase 6: Web Chat Verification Report

Phase Goal: Users can chat with AI Employees directly in the portal through a real-time web chat interface — no external messaging platform required Verified: 2026-03-25T16:39:57Z Status: human_needed Re-verification: No — initial verification


Goal Achievement

Observable Truths

# Truth Status Evidence
1 Web channel messages normalize into valid KonstructMessage with channel='web' VERIFIED normalize_web_event() in gateway/channels/web.py:64-104 sets channel=ChannelType.WEB; test_normalize_web_event_channel_is_web passes
2 Celery _send_response publishes web channel responses to Redis pub-sub VERIFIED _send_response in orchestrator/tasks.py:794-817 handles channel_str == "web" with aioredis.publish; test_send_response_web_publishes_to_redis passes
3 WebSocket endpoint accepts connections and dispatches messages to Celery pipeline VERIFIED chat_websocket at web.py:319-340 routes to _handle_websocket_connection; handle_message.delay(task_payload) at line 245; mounted in gateway/main.py:155
4 Typing indicator event is sent immediately after receiving a user message VERIFIED web.py:183 sends {"type": "typing"} before any DB or Celery work; test_typing_indicator_sent_before_dispatch passes
5 Chat REST API enforces RBAC — non-members get 403 VERIFIED chat.py:107 calls require_tenant_member; test_chat_rbac_enforcement confirms 403 for non-member
6 Platform admin can access conversations for any tenant VERIFIED chat.py:117 bypasses user_id filter for platform_admin; test_platform_admin_cross_tenant passes
7 Conversation history persists in DB and is loadable via REST VERIFIED list_messages at chat.py:234-299 queries WebConversationMessage; test_list_conversation_history passes
8 User can navigate to /chat from the sidebar and see a conversation list VERIFIED nav.tsx line 57-62 adds { href: "/chat", label: "Chat", icon: MessageSquare } with no allowedRoles restriction; chat/page.tsx renders ChatSidebar
9 User can select an agent and start a new conversation VERIFIED AgentPickerDialog in chat/page.tsx:50-105 lists agents via useAgents; handleAgentSelect calls useCreateConversation and sets active conversation
10 User messages appear right-aligned; agent responses left-aligned with markdown VERIFIED chat-message.tsx:36-76 renders user messages right-aligned (justify-end), assistant left-aligned with ReactMarkdown + remarkGfm
11 Typing indicator (animated dots) shows while waiting for agent response VERIFIED TypingIndicator component in typing-indicator.tsx with three animate-bounce dots and staggered delays; chat-window.tsx:180 renders {isTyping && <TypingIndicator />}
12 Conversation history loads when user returns to a previous conversation VERIFIED useConversationHistory(conversationId) called in chat-window.tsx:60; history populates messages state via useEffect at line 62-73
13 End-to-end chat works with full agent pipeline (memory, tools, escalation) HUMAN NEEDED All plumbing is wired; actual pipeline execution requires live services

Score: 13/13 automated truths verified (1 requires human confirmation)


Required Artifacts

Artifact Expected Status Details
packages/shared/shared/models/chat.py WebConversation and WebConversationMessage ORM models VERIFIED Both classes present, SQLAlchemy 2.0 Mapped[]/mapped_column() style, UniqueConstraint on (tenant_id, agent_id, user_id)
packages/gateway/gateway/channels/web.py WebSocket endpoint and web channel normalizer VERIFIED normalize_web_event() at line 64; chat_websocket at line 320; 341 lines total
packages/shared/shared/api/chat.py REST API for conversation CRUD VERIFIED chat_router defined at line 42; all 4 endpoints present (list, create, messages, delete)
migrations/versions/008_web_chat.py DB migration for web_conversations and web_conversation_messages tables VERIFIED Both tables created with FORCE RLS, RLS policies, index on (conversation_id, created_at), CHECK constraint on channel_type updated
tests/unit/test_web_channel.py Unit tests for web channel adapter VERIFIED 13 tests; all pass
tests/unit/test_chat_api.py Unit tests for chat REST API with RBAC VERIFIED 6 tests; all pass
packages/portal/app/(dashboard)/chat/page.tsx Main chat page with sidebar + active conversation VERIFIED 235 lines; ChatSidebar + ChatWindow rendered; useConversations and useCreateConversation wired
packages/portal/components/chat-sidebar.tsx Conversation list with agent names and timestamps VERIFIED ChatSidebar exported; scrollable list, "New Conversation" button, empty state
packages/portal/components/chat-window.tsx Active conversation with message list, input, and send button VERIFIED ChatWindow exported; useChatSocket and useConversationHistory wired; TypingIndicator rendered conditionally
packages/portal/components/chat-message.tsx Message bubble with markdown rendering and role-based alignment VERIFIED ChatMessage exported; user=right+plain text; assistant=left+ReactMarkdown+remarkGfm
packages/portal/components/typing-indicator.tsx Animated typing dots component VERIFIED TypingIndicator exported; 3 dots with animate-bounce and staggered animationDelay
packages/portal/lib/use-chat-socket.ts React hook managing WebSocket lifecycle VERIFIED useChatSocket exported; connects to /chat/ws/{conversationId}; sends auth JSON on open; handles typing/response events; reconnects up to 3 times

From To Via Status Details
packages/portal/lib/use-chat-socket.ts packages/gateway/gateway/channels/web.py new WebSocket to /chat/ws/{conversationId} VERIFIED use-chat-socket.ts:59: new WebSocket(url) where url = \${WS_BASE}/chat/ws/${conversationId}``
packages/portal/app/(dashboard)/chat/page.tsx packages/portal/lib/queries.ts useConversations + useConversationHistory hooks VERIFIED chat/page.tsx:143 calls useConversations(tenantId); chat-window.tsx:60 calls useConversationHistory(conversationId)
packages/portal/components/nav.tsx packages/portal/app/(dashboard)/chat/page.tsx Nav link to /chat VERIFIED nav.tsx:57-62: { href: "/chat", label: "Chat", icon: MessageSquare } with no role restriction
packages/gateway/gateway/channels/web.py packages/orchestrator/orchestrator/tasks.py handle_message.delay() Celery dispatch VERIFIED web.py:245: handle_message.delay(task_payload)
packages/orchestrator/orchestrator/tasks.py packages/shared/shared/redis_keys.py Redis pub-sub publish via webchat_response_key VERIFIED tasks.py:80: from shared.redis_keys import escalation_status_key, webchat_response_key; used at line 805
packages/gateway/gateway/channels/web.py packages/shared/shared/redis_keys.py Redis pub-sub subscribe via webchat_response_key VERIFIED web.py:50: from shared.redis_keys import webchat_response_key; used at line 250
packages/shared/shared/api/chat.py packages/shared/shared/api/rbac.py require_tenant_member RBAC guard VERIFIED chat.py:36: imports require_tenant_member; called at lines 107 and 163

Requirements Coverage

Requirement Source Plan(s) Description Status Evidence
CHAT-01 06-01, 06-02, 06-03 Users can open a chat window with any AI Employee and have a real-time conversation within the portal SATISFIED WebSocket endpoint + useChatSocket + ChatWindow + full message loop
CHAT-02 06-01, 06-02, 06-03 Web chat supports the full agent pipeline (memory, tools, escalation, media) SATISFIED (automated) + HUMAN NEEDED handle_message.delay() dispatches into the same pipeline as Slack/WhatsApp; ChannelType.WEB flows through orchestrator; end-to-end pipeline needs human verification with live services
CHAT-03 06-01, 06-02, 06-03 Conversation history persists and is visible when the user returns to the chat SATISFIED web_conversation_messages table persists messages; GET /conversations/{id}/messages REST endpoint; useConversationHistory hook loads on ChatWindow mount
CHAT-04 06-01, 06-02, 06-03 Chat respects RBAC — users can only chat with agents belonging to tenants they have access to SATISFIED require_tenant_member guards all REST endpoints; WebSocket auth validates userId/tenantId; test_chat_rbac_enforcement and test_platform_admin_cross_tenant pass
CHAT-05 06-01, 06-02, 06-03 Chat interface feels responsive — typing indicators, message streaming or fast response display SATISFIED (automated) + HUMAN NEEDED {"type": "typing"} sent before Celery dispatch; TypingIndicator component animates; test_typing_indicator_sent_before_dispatch passes; visual quality requires human review

All 5 CHAT requirements are claimed by all three plans. No orphaned requirements.


Anti-Patterns Found

File Pattern Severity Impact
packages/portal/components/chat-window.tsx:39 <div className="text-4xl mb-3">💬</div> — emoji in source code Info Visual, not a blocker; per CLAUDE.md "avoid emojis" but this is a UI element not user-facing text

No stubbed implementations, placeholder returns, or TODOs found in any phase 6 files. All API routes perform real DB queries and return non-static data.


Human Verification Required

1. End-to-End Chat (CHAT-01, CHAT-05)

Test: Log in as customer_admin, click "Chat" in the sidebar navigation, click "New Conversation", select an AI Employee, type a message, press Enter. Expected: Animated typing dots appear immediately; the agent response arrives as a left-aligned bubble with the agent avatar; the user's message appears right-aligned. Why human: Requires live gateway, Celery worker, Redis, and an LLM backend. The WebSocket round-trip cannot be verified programmatically.

2. Markdown Rendering (CHAT-05)

Test: Send a message that requests a formatted response (e.g., "Give me a bulleted list of 3 tips"). Expected: The agent response renders proper markdown — bullet lists, bold text, and code blocks display correctly rather than as raw markdown syntax. Why human: Markdown rendering quality and visual appearance require a browser.

3. Conversation History Persistence (CHAT-03)

Test: Exchange several messages, navigate away from /chat (e.g., go to /dashboard), then navigate back. Expected: The previous conversation appears in the sidebar with a last message preview; clicking it loads the full message history. Why human: Cross-page navigation persistence requires a live DB session.

4. RBAC Enforcement for Operators (CHAT-04)

Test: Log in as customer_operator, navigate to /chat, start a conversation with an agent. Expected: The "Chat" link is visible in the sidebar; chat works for operators; admin-only nav items (Billing, API Keys, Users) remain hidden. Why human: Role-based nav suppression and operator chat access require a live session with correct role claims from the auth system.

5. Full Pipeline with Tools (CHAT-02)

Test: If an agent has tools configured, send a message that triggers tool use. Expected: The agent invokes the tool and incorporates the result into its response (rather than hallucinating). Why human: Requires a configured agent with registered tools and a live Celery worker.


Gaps Summary

No automated gaps. All 13 must-have truths are verified at the code level:

  • All backend infrastructure exists and is substantive (not stubs): WebSocket endpoint, REST API, ORM models, migration, orchestrator routing.
  • All frontend components exist and are substantive: page, sidebar, window, message bubble, typing indicator, WebSocket hook.
  • All 7 key links are wired: Celery dispatch, Redis pub-sub subscribe/publish, RBAC guard, WebSocket URL, query hooks, nav link.
  • All 19 unit tests pass (run with uv run pytest tests/unit/test_web_channel.py tests/unit/test_chat_api.py).
  • Portal builds successfully with /chat route.
  • 5 human verification items remain for visual quality, live pipeline behavior, and session-dependent RBAC checks.

Verified: 2026-03-25T16:39:57Z Verifier: Claude (gsd-verifier)