Sloth-ninja gives JessicaOSS a UK statute desk

The fork can now research UK legislation directly inside its legal research experience, with citations built for the awkward realities of UK law.

searchintegration

Sloth-ninja has added direct research against legislation.gov.uk, the UK government's legislation database, and has done the legal-domain work needed for citations to find the right Act or regulation. That includes older Acts cited by regnal year, a detail that can trip general-purpose search.

  • Ask questions in chat and see when legislation has informed the answer.
  • Open individual provisions in a research panel, with quoted text and citations alongside the answer.
  • Follow statutory-instrument search results into the same research view, rather than reaching a dead end.

The integration is backed by substantial testing and has been refined around the moments that matter in use: opening sources, viewing quotations, and moving from results to the relevant provision.

So what UK-facing legal teams and product builders should care because this turns statutory lookup from a separate research chore into part of the working legal analysis.

View this fork on GitHub →

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

Commits in this thread

12 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>
40c8448c Merge pull request #8 from Sloth-ninja/ws2-legislation Ezana.H 2026-07-12 ↗ GitHub
WS2: legislation.gov.uk integration - statute/SI lookup, citation verification, outstanding-effects transparency
0892e306 WS7: Legislation panel (legislation.gov.uk) sloth-ninja 2026-07-20 ↗ GitHub
commit body
Research › Legislation page + /legislation backend routes, per the approved
WS7 mock-up. One prominent input with two modes (look up a natural UK
citation, or search by Act/SI title), example chips teaching the citation
grammar, master-detail split for title search, and a provision view reusing
assistant/LegislationPanel with the amber outstanding-amendments band and a
per-effect list beneath it.

Backend: new src/routes/legislation.ts (both requireAuth, per-handler
try/catch), thin wrappers over the tested lib/legislation.ts - GET
/legislation/search?title= → {matches}; GET /legislation/lookup?citation= →
lookupCitation. No key gating (open OGL API). A failed lookup is a domain
result: HTTP 200 {resolved:false, citation, reason}; only unexpected throws
yield a fixed generic 502 (raw errors logged server-side only). Success
payload uses the same snake_case field names the chat tool emits so
LegislationPanel props align. Mounted behind the existing researchLimiter.

Frontend: new (pages)/legislation/page.tsx (submit-on-enter only - no
search-as-you-type, title search can take 3-6s). mikeApi searchLegislation /
lookupLegislation. Sidebar "Legislation" (Landmark) added to the Research
group between Company Search and Citation Checker.

Tests: 7 route-mapping tests (vi.mock("../lib/legislation")). Backend tsc +
vitest 140/140 green; frontend tsc clean; lint at the main baseline (34/78);
evals:smoke 4/4 from the main checkout. CLAUDE.md module map + BUILD_LOG
entry updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
f863815f WS7: fix SI search results dead-ending on lookup sloth-ninja 2026-07-20 ↗ GitHub
commit body
selectMatch resolved every chosen search result by its bare title.
Acts parse from a bare title but a whole statutory instrument has no
title-only parse branch, so SI results dead-ended on the "could not
parse" card. Resolve SI-typed matches by their parseable
"SI {year}/{number}" citation instead; Acts still resolve by title,
and the title stays the human label for the Assistant prefill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
00869878 Merge remote-tracking branch 'origin/main' into ws7-legislation-panel sloth-ninja 2026-07-20 ↗ GitHub
# Conflicts:
#	docs/BUILD_LOG.md
b0594f4b Merge pull request #29 from Sloth-ninja/ws7-legislation-panel Ezana.H 2026-07-20 ↗ GitHub
WS7: Legislation panel (legislation.gov.uk)

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

⬇ Download capture-thread-848.md