Sloth-ninja makes UK legislation research answerable, not ornamental

This fork turns statutory references in chat from plausible-looking citations into government-sourced research a lawyer can inspect.

searchcompliance

Sloth-ninja has added UK legislation research using publicly licensed government data, so the feature does not require a separate paid-data account or API key. It can recognise common references to Acts, regulations and statutory instruments, retrieve the relevant provision, and link back to the canonical government page.

  • Citation checking: the chat verifies legislation references before giving a final answer and drops ones it cannot confirm.
  • Provision research: users can look up, search and check several statutory citations at once, with the provision text, heading and territorial extent available in a side panel.
  • Currency warnings: an amber notice highlights outstanding legislative effects when government data reports them; where that data is absent, the product says the status is unknown.

Case-law research remains deliberately excluded until a permitted source is available.

So what UK legal teams using AI for statute-heavy questions should care because it adds visible sourcing and honest uncertainty where confident but uncheckable citations create real risk.

View this fork on GitHub →

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

Commits in this thread

7 commits from Sloth-ninja/JessicaOSS, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
469e76a2 WS2: legislation.gov.uk client + LLM tools + vitest harness sloth-ninja 2026-07-08 ↗ GitHub
commit body
Add backend/src/lib/legislation.ts - a no-key legislation.gov.uk client:
natural-citation parsing (s./section/reg/SI/act-first forms), Atom
title-feed resolution (incl. pre-1963 regnal-year Act ids), CLML
fetch/extraction (provision text, heading, extent, and the
ukm:UnappliedEffects outstanding-amendments flag, verified against live
responses and documented in-file), a local ~1req/s token-bucket limiter,
and bounded TTL caches. Add legalSourcesTools/legislationTools.ts (the
three OpenAI-shaped tools + system prompt + executor).

Introduce vitest (backend has no test framework yet): vitest.config.ts,
package.json test script, 38 unit tests against captured CLML/Atom
fixtures (mocked fetch, no live calls).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
342687b5 WS2: wire legislation research tools into the chat loop sloth-ninja 2026-07-08 ↗ GitHub
commit body
- ParsedCitation widens to ParsedDocumentCitation | ParsedLegislationCitation;
  normalizeCitation/createCitationAnnotation branch on legislation_uri; the
  CITATIONS prompt block documents the legislation JSON shape.
- buildSystemPrompt/buildMessages gain a ResearchSources param and splice
  LEGISLATION_SYSTEM_PROMPT in when sources.legislation is set.
- runLLMStream populates the previously-empty researchTools seam from
  researchSources.legislation; runToolCalls gains a legislation_* branch
  mirroring the mcp_ branch (legislation_tool_start/result SSE pair,
  legislationEvents accumulator pushed into AssistantEvent[] alongside
  mcpEvents).
- chat.ts / projectChat.ts: replace the hardcoded includeResearchTools:
  false with { legislation: true } - no key needed, so always on (mirrors
  the Companies House "available whenever configured" decision for WS1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
02358fb4 WS2: eval golden cases for legislation.gov.uk + regnal-year Act fix sloth-ninja 2026-07-08 ↗ GitHub
commit body
Add 3 deterministic cases (TUPE reg.4, ERA 1996 s.98, the Companies Act
2006 title-search feed) and 1 citation-gate case exercising a realistic
tool-output-shaped answer citing an Act section, an act-first section
reference, an SI-by-number with a regulation reference, and a pre-1963
Act. All four verified live before committing.

Fix evals/src/citations.ts resolveActUri: pre-1963 Acts (e.g. Landlord
and Tenant Act 1954) are catalogued on legislation.gov.uk under
regnal-year ids (/id/ukpga/Eliz2/2-3/56) rather than a plain calendar
year in the URI path, so the existing regex-only match silently failed
to resolve them. Match the Atom entry by its <ukm:Year Value="..."> and
take the id's full path suffix as a fallback - modern Acts still hit the
existing fast path first, so this is additive, not a behaviour change
for the passing cases. Discovered while verifying the new golden case
live per the WS2 brief; left unfixed it would have blocked WS4's planned
LTA 1954 lease-renewal workflow template later.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
14dbda68 WS2: legislation research UI - tool chips, citation pills, LegislationPanel sloth-ninja 2026-07-08 ↗ GitHub
commit body
- shared/types.ts: legislation_tool_call AssistantEvent variant;
  LegislationCitationAnnotation; CitationAnnotation re-widened to a union
  with kind-guards in getDocumentCitationQuotes/expandCitationToEntries/
  formatCitationPage/displayCitationQuote.
- useAssistantChat.ts: legislation_tool_start/result via the MCP
  start/result pairing pattern.
- AssistantMessage.tsx: extract the inline mcp_tool_call chip JSX into a
  shared ToolCallChip (reused, not cloned) and add the legislation_tool_call
  branch (amber "outstanding amendments" note on flagged results);
  toolCallLabel gains the three legislation tool names; citation-source
  helpers (key/label/icon) branch on kind (Landmark icon for legislation).
- New LegislationPanel.tsx: provision heading/text/extent, canonical
  legislation.gov.uk link, prominent amber banner when a lookup reported
  outstanding effects. Degrades honestly (no fabricated "all clear") when
  opened from a citation pill that only carries title/url/quote.
- AssistantSidePanel.tsx: new LegislationTab kind (no documentId, doesn't
  extend CommonTab). ChatView.tsx: openLegislation dedupes tabs by URL
  (bypasses upsertTab's document-keyed dedupe); openCitation branches on
  citation.kind.
- projects/[id]/assistant/chat/[chatId]/page.tsx (a second, simpler
  project-chat surface outside the frontend seam map's scope, no
  LegislationPanel there): falls back to opening the canonical
  legislation.gov.uk link for a legislation citation instead of erroring.

tsc --noEmit clean; eslint 112 problems (35/77), identical to base commit
and zero findings in any file touched here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
68ea6e20 docs: BUILD_LOG entry for WS2 legislation.gov.uk integration sloth-ninja 2026-07-08 ↗ GitHub
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
abd3b978 WS2 design polish: fix legislation chip dead-click and empty-quote tooltip sloth-ninja 2026-07-08 ↗ GitHub
commit body
- ToolCallChip for legislation_tool_call rendered as a clickable button even
  when the host page (e.g. projects/[id] chat, which has no LegislationPanel)
  never passed onOpenLegislation - clicking silently did nothing. Gate the
  onClick on the handler actually being provided, same as every other
  optional callback in this file.
- Citation pill/annotation tooltips showed `Companies Act 2006, s.994: ""`
  when a legislation citation carried a title but no verbatim quote.
  Extracted a shared citationTooltip() helper that omits the empty quote
  wrapper, keeping the tooltip "title + quote, not an artifact" per the
  design bar for legislation citations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bba4e01a WS2: carry the provision payload on the live legislation_tool_result SSE sloth-ninja 2026-07-08 ↗ GitHub
commit body
Review finding: without it, opening the LegislationPanel from a chip
during the live turn had no provision data (heading/text/extent/amber
banner) until the page was reloaded and events re-hydrated from
chat_messages. Matches the persisted AssistantEvent shape and the
pattern WS1 uses for the company payload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

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-1210.md from inside the repo you want the changes in.

⬇ Download capture-thread-1210.md