[pull] main from Open-Legal-Products:main

✅ merged · #16 · admariner/mike ← Open-Legal-Products/mike · opened 1mo ago by pull[bot] · merged 1mo ago by pull[bot] · +2,472-98 across 24 files · ↗ on GitHub

From the PR description

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

Our analysis

Merge fork updates — read the full analysis →

Think the analysis missed something the PR description covers?

Commits in this PR (15)

SHA Subject Author Date
7f09e475 test(backend): document-integrity tier - docxTrackedChanges, prompts, documentTypes, systemWorkflows Amalanand Muthukumaran 2026-07-25 ↗ GitHub
commit body
Four new unit suites (46 tests) for the document-integrity tier of the
coverage backlog:

- docxTrackedChanges: in-memory docx fixtures via JSZip; insert/delete
  runs, minimal tracked spans, accept/reject round-trips, id numbering,
  ambiguous/not-found/malformed-input paths (19 tests)
- chat/prompts: base prompt invariants, citation contract markers, and
  CourtListener splice on/off (8 tests)
- documentTypes: type predicates, pdf-conversion policy, MIME fallbacks
  (12 tests)
- systemWorkflows: unique builtin ids, well-formed metadata/columns,
  non-empty skill markdown, assistant-list sync (7 tests)

Coverage ratchet raised from 11/10/14/10 to 23/17/23/23 (measured
23.88% stmts / 17.98% branches / 23.06% funcs / 23.79% lines); backlog
doc updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2392e677 test(frontend): SSE/client unit tests + coverage ratchet Amalanand Muthukumaran 2026-07-25 ↗ GitHub
commit body
Unit tests for the frontend client library and the SSE stream consumer,
plus a v8 coverage ratchet over src/app/lib/** mirroring the backend's
(floors just below measured, only ever raised):

- mikeApi.ts: request/auth/error plumbing, blob downloads, getChat and
  mapTRMessages mapping, and all four streaming endpoints (the frontend
  half of the SSE contract - raw Response passed through unconsumed).
- useAssistantChat: SSE parse loop against real ReadableStream bodies -
  chunk-boundary reassembly, multi-event chunks, reasoning/content
  interleave, error events, malformed lines, EOF without trailing newline.
- documentUploadValidation.ts and modelAvailability.ts: full coverage.
- test:coverage script + @vitest/coverage-v8; CI frontend test step now
  runs it (still --if-present).
- docs/frontend-testing.md: how to run, ratchet rules, TODO backlog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
22169c14 security: SSRF guardrails for server-side connector fetches Amalanand Muthukumaran 2026-07-25 ↗ GitHub
commit body
Port the fork's SSRF hardening for MCP connector egress into the
upstream layout:

- Extract private/reserved IP classification into lib/privateIp.ts and
  fix IPv6 gaps: fe80::/10 link-local matching (the /^fe[89ab]:/ regex
  only matched the hextet "fe8:" and let fe80::1 through), hex-form
  IPv4-mapped addresses (::ffff:a00:1), NAT64 (64:ff9b::/96) and 6to4
  (2002::/16) embedded IPv4 ranges.
- Strip brackets from IPv6 literals in validateRemoteMcpUrl so [::1]
  et al. are classified by the private-IP guard instead of falling
  through to DNS lookup.
- Route all OAuth egress (metadata fetch, discovery probes, dynamic
  client registration, token refresh) through guardedFetch so every
  outbound MCP request gets the same HTTPS-only / blocked-host /
  private-IP / no-redirect checks; the discovery probes were previously
  raw, unvalidated fetches.
- Add SSRF regression tests (run atop the test-harness PR) and exclude
  test files from the tsc production build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CEguyEgXa9JjCciXCcVemC
f28d9d14 security: pin MCP egress DNS at connect time (undici dispatcher) Amalanand Muthukumaran 2026-07-25 ↗ GitHub
commit body
Restore the fork's pinnedGuardAgent verbatim: guardedFetch now routes
through a per-request undici Agent whose connect-time DNS lookup runs
the private-IP guard and returns only validated addresses, so the
address we validate is the address we connect to - closing the
DNS-rebinding/TOCTOU window between the pre-fetch validation lookup and
the socket's own resolution. Adds the undici runtime dependency the
fork ships for exactly this purpose ("undici": "^6.27.0"), and restores
the dispatcher assertions in the SSRF test so it matches the fork's
byte for byte.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CEguyEgXa9JjCciXCcVemC
e639dbfc security: block IPv4-compatible IPv6 embeds in the private-IP guard Amalanand Muthukumaran 2026-07-25 ↗ GitHub
3068002e security: production CORS allowlist with fail-safe denial Amalanand Muthukumaran 2026-07-25 ↗ GitHub
Ported from the security pack's index.ts change to the post-refactor
app.ts (the Express app moved in the integration-test extraction).
Adapted-from: https://github.com/Open-Legal-Products/mike/pull/227 (4c44c15, CORS half)
ef80cc70 Remove dead jsonLimitForPath abstraction b1rdmania 2026-07-29 ↗ GitHub
commit body
jsonLimitForPath() ignores its path argument and always returns "50mb",
and the per-request middleware wrapper re-invokes express.json() on every
request for no effect. Replace with a single static express.json() mount.
Behaviour is identical; if per-path body limits are wanted later, happy
to implement them properly against a list of routes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8206df51 Name the JSON body limit constant Andy 2026-07-31 ↗ GitHub
Per review: a named constant reads better than a bare string at the
mount site, and gives the value somewhere to be documented.
65cbf0ee security: harden SSRF IP guard and reuse dispatcher willchen96 2026-08-03 ↗ GitHub
57bd8776 Merge pull request #242 from amal66/olp-pr/sec-ssrf Will Chen 2026-08-03 ↗ GitHub
[Security 1/9] SSRF guardrails for server-side connector fetches
961457c7 Merge pull request #245 from amal66/olp-pr/sec-cors Will Chen 2026-08-03 ↗ GitHub
[Security 3/9] Production CORS allowlist with fail-safe denial
435b27d9 docs: clarify JSON body limit scope willchen96 2026-08-03 ↗ GitHub
133ecb3f Merge pull request #273 from b1rdmania/chore/remove-dead-json-limit Will Chen 2026-08-03 ↗ GitHub
Remove dead jsonLimitForPath abstraction
7d1ea6f9 Merge pull request #253 from amal66/olp-pr/doc-integrity-tests Will Chen 2026-08-03 ↗ GitHub
[Testing 17] test(backend): document-integrity unit tests + ratchet raise
2266446b Merge pull request #255 from amal66/olp-pr/frontend-coverage Will Chen 2026-08-03 ↗ GitHub
[Testing 18] test(frontend): API-client/SSE tests + coverage ratchet

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-16.md from inside the repo you want the changes in.

⬇ Download capture-pull-16.md