Gadoes builds a citation spine into Mike

Every answer the assistant gives now comes with sourced, link-checkable citations rendered as cards under the message.

chat-uisearch

Gadoes has wired citations through the whole stack: when the assistant pulls from a source, that source gets captured, stored, and rendered as its own card under the reply - with a coloured dot showing whether the link is live, unreachable, or simply unchecked.

A few choices stand out. The fork separates whether a citation is reachable from whether it's trustworthy, leaving room for a future review layer without having to redo the plumbing. Short citation lists stay expanded; longer ones collapse so the message doesn't drown. Arabic excerpts flip to right-to-left automatically. A 'Verify & read' button is stubbed in but not yet wired - clearly the next move.

So what For anyone evaluating legal-AI tools, this is what defensible answers start to look like: every claim tied to a source, every source flagged as live or not.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

4 commits from Gadoes/dispumike, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
d17c6e96 Chunk 4: Citation Data Model + Storage Gadoes 2026-05-02 ↗ GitHub
commit body
- Migration 001_citations.sql: citations table with liveness_status
  (unchecked|live|unreachable only - verified/unverified reserved for
  hallucination council Feature 2)
- Updated types.ts: Citation, CitationLivenessStatus, CitationSourceType types
- citationParser.ts: parseSingleCitation() and parseMcpResultToCitations()
  map MCP tool results to Citation schema for all 6 sources
- chatTools.ts: runToolCalls() extracts and accumulates citations from MCP results
- chatTools.ts: runLLMStream() emits mcp_citations SSE event at end of each
  assistant message (empty array emitted if no MCP tools called)

Acceptance criteria:
[x] Citation parser maps mock MCP response to citation schema for each source_type
[x] mcp_citations SSE event emitted with correct shape
[x] Empty array emitted if no MCP tools called
[x] Excerpt truncated to ≤500 chars
[x] liveness_status defaults to 'unchecked'

Tests: 37 pass (13 new citation parser tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2797ac86 Merge Chunk 4: Citation Data Model + Storage Gadoes 2026-05-02 ↗ GitHub
3631a865 Chunk 5: Citation rendering component with CitationCard, compact list, RTL support Gadoes 2026-05-02 ↗ GitHub
commit body
- Add McpCitation and McpCitationLiveness types to shared/types.ts
- Create CitationCard.tsx with SingleCitationCard, CompactRow, CitationList
  - ≤3 citations: expanded card view; ≥4: compact list with expand-on-click
  - RTL support for Arabic excerpts (dir=rtl on U+0600-U+06FF detection)
  - Liveness dot (grey/green/red), source badge with region glyph
  - "Verify & read" button stub (to be wired in Chunk 20)
- Add mcp_citations SSE event handler in useAssistantChat.ts
- Update AssistantMessage.tsx to render CitationList below message content
- Set up Vitest + React Testing Library; 22 component tests all passing
- npx tsc --noEmit passes with no errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4c3d2b52 Merge chunk-5-citation-rendering into main Gadoes 2026-05-02 ↗ GitHub

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-21.md from inside the repo you want the changes in.

⬇ Download capture-thread-21.md