MikeOSS Legal AI

Open source legal AI document assistant with cryptographic guardrail verification.

Drop-in cryptographic verification for Mike, the open-source legal AI assistant by Will Chen. Every assistant response is checked against a plain-English policy compiled to SMT-LIB before it reaches the user. The proof is referenced by a proof_id persisted on the message row and surfaced as a "Verified" badge that any third party can independently re-verify.

Status. This page describes the Mike + Preflight integration as designed. Deployed systems are the source of truth: Preflight's API at api.icme.io and Mike upstream at github.com/willchen96/mike. If anything here conflicts with the deployed system, the deployed system wins.

Legal AI is the canonical "high downside, low margin for error" use case, and the guardrails that ship with it solve only half the problem. Two things have to be true, and today neither is.

Enforcement has to be deterministic. LLM-as-judge guardrails are probabilistic. A second model reads the first model's output and decides whether it looks compliant. That is pattern matching, not enforcement. It can be jailbroken, it drifts between model versions, and it has no ground truth. Preflight compiles each plain-English policy to SMT-LIB and discharges it through the Z3 SMT solver. The verdict is mathematical, not stylistic, and the same input always yields the same answer.

The verdict has to be independently checkable. Even a perfectly enforced policy is worth little if a regulator, opposing counsel, or auditor has to take the firm's word for it. Today they would need access to the firm's logs, infrastructure, and the original model. Preflight emits a proof_id with every verdict, referencing a zero-knowledge proof. A zero-knowledge proof is independently and repeatedly verifiable by anyone who holds it, without re-running the check: a regulator, opposing counsel, or auditor can confirm the verdict with no Mike access, no firm credentials, and no model access.

Deterministic enforcement makes the guardrail trustworthy. Third-party verifiability makes that trust transferable.

How Preflight closes it

user query


[ Preflight middleware ] ──▶ checkIt(action, policy) ──▶ SAT / UNSAT / ERROR
   │                                                         │
   ▼                                                         ▼
LLM call                                          proof_id + policy_hash
   │                                              persisted on chat_messages row

assistant response  ──▶  UI badge linking to icme.io/proofs/<proof_id>

Three stages:

  1. Extract. The proposed assistant action (matter, input, intended tool) is extracted from the request.

  2. Verify. Preflight checks the action against the firm's compiled policy via POST /v1/checkIt and returns result (SAT or UNSAT), a proof_id, and a policy_hash.

  3. Persist. The proof_id and policy_hash are written to new columns on chat_messages and rendered as a re-verifiable badge in the UI.

How verification works

Three independent paths check each action against the same compiled policy. OxiZ, a local extraction model, maps the action text to the policy's SMT variables. Automated Reasoning independently translates the raw action text to formal logic and checks it against the rules. Z3, the SMT solver, evaluates the extracted values. The system fails closed: any UNSAT from any path blocks the action. When Automated Reasoning returns TRANSLATION_AMBIGUOUS, the action can still clear if OxiZ and Z3 both confirm SAT.

Every decision is sealed into a zero-knowledge proof by JOLT, ICME's adaptation of the JOLT zkVM, wrapping the SMT verification pipeline. The proof generates in the background (typically 30 to 60 seconds) and is retrievable via GET /v1/proof/{id}. Anyone can verify it against /v1/verifyProof with no API key, learning only that the verdict was correctly computed against the compiled policy version named by policy_hash.

A note on JOLT Atlas. ICME is developing JOLT Atlas, a separate zkML framework that will add cryptographic proofs for the AI extraction step itself. Today's proofs are produced by the JOLT zkVM and cover the SMT verification. JOLT Atlas is under active development and does not power production verification yet.

What this integration ships

The preflight-mike repository ships four files plus a one-shot git am patch:

File
Drops into Mike at

backend/lib/preflight.ts

backend/src/lib/preflight.ts

backend/middleware/preflight.ts

backend/src/middleware/preflight.ts

backend/migrations/2026_01_preflight.sql

backend/migrations/2026_01_preflight.sql

frontend/components/VerifiedBadge.tsx

frontend/src/app/components/assistant/VerifiedBadge.tsx

The patch applies cleanly against Mike main and wires the middleware, DB columns, types, mikeApi mapping, and the badge into AssistantMessage in two commits.

Suggested policies

A starter policy set for a legal-AI deployment. Each compiles to SMT-LIB and is referenced by policy_id (UUID) at verification time.

Policy
Plain English

Matter scope

References must resolve to the current project_id only (privilege boundary).

Citation integrity

Every cited case, statute, or document must exist in the project's corpus.

No specific advice

Jurisdictional outputs require a disclaimer and a cited authority.

PII egress

No SSNs, account numbers, or DOBs in output.

Escalation scope

Securities, healthcare, and M&A questions must flag for human review.

Install

One-shot patch (recommended)

Manual drop-in

Copy the four files into the paths in the table above, then follow INSTALL.md for the wiring edits across chat.ts, mikeApi.ts, types.ts, AssistantMessage.tsx, and ChatView.tsx.

A note on shadow mode. Shadow is the default and the recommended starting point. It calls Preflight, persists the verdict and proof_id on every message, but never blocks a response. Run shadow for a few days, review real verdicts, then flip to enforce.

Modes

ICME_PREFLIGHT_ENFORCE controls runtime behavior:

Mode
Behavior

off

Middleware no-ops. Disable without removing code.

shadow

Calls Preflight, persists verdict and proof_id on every message, never blocks. Default.

enforce

Returns HTTP 451 on UNSAT or verification error. Use in production.

Express middleware

The middleware writes the Preflight result to res.locals.preflight so the chat handler can persist proof_id and policy_hash on the new chat_messages columns when it inserts the assistant message.

Database migration

API reference

Endpoint
Method
Purpose

/v1/checkIt

POST

Verify an action against a policy. Returns result, proof_id, policy_hash.

/v1/proof/{id}

GET

Retrieve the zero-knowledge proof once generation completes (30 to 60 seconds).

/v1/verifyProof

POST

Public re-verification. No firm credentials required.

Sample /v1/checkIt response:

Sample /v1/verifyProof response (public, no API key):

Verified badge

Rendered next to each AssistantMessage. The badge links to a third-party verification page; no Mike credentials are needed to re-check the proof. Note that the proof generates in the background, so the badge may link to a proof that is still being produced for the first 30 to 60 seconds after a message.

What this integration does not do

  • Does not replace Mike's citation extraction or document parsing.

  • Does not modify Mike's model routing or per-user API key handling.

  • Does not store, proxy, or have visibility into the prompt or response body. Only the structured action and the verdict.

  • Does not run the LLM.

  • Does not require schema changes outside chat_messages.

Privacy, privilege, and what the verifier sees

In a legal-AI deployment, the most sensitive object is often not the prompt or the response. It is the policy itself. Firms encode work product into their guardrail policies: conflicts watchlists, jurisdictional disclaimers, partner sign-off thresholds, engagement-scope caps, counterparties on a litigation watchlist. Disclosing that policy to a regulator, opposing counsel, or a client during an audit is itself a confidentiality concern, and in some jurisdictions a potential privilege waiver.

Preflight's privacy properties are shaped around this.

Property
What stays private
From whom

Policy privacy

The policy text and the specific rule that fired

The user, the LLM, the auditor, opposing counsel, the regulator

Action privacy at verification time

The prompt, the response, the matter, the documents

Any third party re-checking the proof from a proof_id

Versioned binding

Which compiled policy version decided this message

Nobody. The policy_hash is public, the policy text is not

The public /v1/verifyProof receipt contains valid, verify_ms, policy_hash, claimed_result, and proof metadata. It does not contain the prompt, the response, the matter name, the document text, or any rule of the policy. A regulator or opposing counsel verifying a proof learns that a specific compiled policy version decided a specific message. They do not learn what the policy says, what the message was about, or which matter it touched.

The policy_hash is the legal-tech-specific property. Firms revise policies over time. When a regulator later asks "what guardrails were in force on the date of this advice," the answer is the compiled policy version hash bound to every proof issued that day. The hash is public; the policy is not.

Honest scope

Preflight's cryptographic guarantees protect downstream verifiers: the regulator, the client, opposing counsel, the state bar. They do not anonymize the submission path:

  • ICME's server sees the plain-English policy at the time the firm compiles it via /v1/makeRules.

  • ICME's server sees the structured action at the time Mike calls /v1/checkIt to check it.

  • Mike itself, and the firm's chosen model vendor (Claude, Gemini, or OpenAI via the firm's API keys), sees the prompt and the response in cleartext as usual. Preflight does not change that surface.

For firms that need cryptographic inference privacy on top, including encrypted prompts, hardware-attested inference, and model-vendor blindness, Preflight composes cleanly with privacy-preserving inference providers. The inference layer keeps the prompt private from the model vendor; Preflight keeps the policy private from everyone downstream of enforcement.

Compliance alignment

Regime
Relevance

ABA Model Rule 1.6

Confidentiality. Policy privacy and non-disclosing receipts mean firm-side confidentiality is not waived during third-party audit.

ABA Model Rule 5.3

Supervision of nonlawyer assistants (AI). Each proof receipt is the supervision artifact.

ABA Model Rule 1.1 cmt 8

Technological competence. Formally verified guardrails, not LLM-judge pattern matching.

ABA Formal Opinion 512 (July 2024)

Competent and confidential use of GAI; verifiable enforcement is in scope.

Privilege and work product

The policy itself may be work product. Preflight never returns the compiled policy to any caller; the policy_hash proves enforcement without disclosing the rules.

State bar AI guidance (CA, FL, NY)

Verifiable enforcement records satisfy emerging "demonstrable supervision" expectations without requiring the firm to surrender its policy.

The proof receipt is the audit artifact. A state bar, opposing counsel, or client can verify a proof_id at icme.io and confirm the verdict without firm access, the original model, the original prompt, or sight of the policy itself.

Try it yourself

Resource
Link

Drop-in repo (patch + files)

Patched reference fork

github.com/hshadab/mikeoss on feat/icme-preflight-verification

Preflight quickstart

Credits

  • Will Chen for building Mike as open source.

  • Built by ICME for the Mike community. AGPL-3.0 on Mike's side, MIT on the integration glue.

Last updated