1. The Confidentiality Crisis & The Cloud LLM Trap
The rapid adoption of generative AI in legal practice has collided head-on with legal ethics. Litigators and corporate counsel are routinely enticed by commercial cloud platforms promising instant document summaries, deposition cross-examination, and brief drafting. However, routing sensitive client disclosures, internal work product, and discovery documents through multi-tenant cloud APIs exposes law firms to severe professional liability under California and federal rules:
- Duty of Confidentiality (Cal. Rules of Professional Conduct, Rule 1.6 & Bus. & Prof. Code § 6068(e)(1)): Attorneys have an absolute, affirmative duty to preserve client confidences and secrets at every peril to themselves. Transmitting client narratives, financial records, or medical histories to external cloud model providers whose terms of service permit telemetry logging, model training, or third-party vendor review risks a catastrophic breach of privilege.
- Duty of Competence & Technology Diligence (CRPC Rule 1.1 & State Bar COPRAC Formal Op. 2023-204): California State Bar guidance explicitly warns that attorneys utilizing artificial intelligence must understand the technology's operational limitations, risks of data disclosure, and susceptibility to hallucination. Delegating research to unverified cloud services without verifying data-retention boundaries fails the ethical duty of technological competence.
- HIPAA & Discovery Sprawl: In personal injury, workers' compensation, and employment litigation, case records routinely contain Protected Health Information (PHI) and confidential employee records. Transmitting this information to unauthorized cloud APIs creates federal HIPAA liability and broad discovery exposure.
Commercial cloud vendors attempt to soothe these concerns with business associate agreements (BAAs) and "zero-retention" marketing claims. Yet for high-stakes litigation, enterprise sovereignty means the data never traverses a public network interface in the first place. We built KruschLaw to prove that a modern, highly capable statutory intelligence platform can execute entirely inside a firm's private perimeter on self-hosted hardware.
2. Why Naive RAG Fails in Statutory Law
Most developer tutorials suggest that building a legal search engine is trivial: chunk a document into 500-token blocks, generate dense embeddings with OpenAI or HuggingFace, store them in a vector database, and query a language model with top-$k$ nearest neighbors.
In statutory and municipal law, this naive pipeline fails immediately. It introduces three critical failure modes:
A. The Semantic Neighbor Fallacy
Vector embeddings evaluate semantic similarity, not legal authority. In municipal law, a query about "tenant eviction protections for non-payment of rent during emergency declarations" will produce high cosine similarity matches across general lease termination provisions, commercial eviction rules, and residential noise complaints.
Cosine distance cannot distinguish between an advisory preamble and a mandatory operative mandate; it cannot determine whether an ordinance has been preempted by state statute; and it cannot recognize that a subsection is subject to a narrow jurisdictional exception appearing in an entirely separate title.
B. Arbitrary Token Slicing Destroys Statutory Hierarchy
Statutory codifications are structured hierarchically: Title → Chapter → Article → Section → Subsection → Paragraph. Naive token chunkers slice text at arbitrary boundaries, separating operational clauses from their parent section headers. An extracted snippet reading:
"(c) The civil penalty prescribed in subsection (a) shall not apply if the owner has filed an appeal within fourteen (14) calendar days."
is completely useless—and legally dangerous—if the chunking boundary severed the preceding text identifying which municipal code title, chapter, and underlying violation subsection (c) actually governs.
C. Fabricated Citations & Judicial Sanctions Risk
When language models are asked to draft legal briefs from loosely retrieved context, they exhibit an innate propensity to "smooth over" gaps by synthesizing statutory numbering. A model might generate an authoritative analysis citing Oakland Municipal Code § 8.24.050 for emergency rent relief, when that specific section actually governs solid waste disposal.
Submitting fabricated citations or confabulated judicial quotes to a court violates California Code of Civil Procedure § 128.7 and Federal Rule of Civil Procedure 11, subjecting trial counsel to severe court sanctions, fee-shifting penalties, and disciplinary referral.
3. System Architecture & Localhost Topology
KruschLaw is engineered as a zero-cloud-egress research platform. Its default networking topology binds strictly to loopback interfaces (127.0.0.1), preventing unauthorized broadcast across local area networks or third-party internet gateways:
The platform consists of four sovereign components:
- Streamlit Interface (
:8505): Interactive litigation portal designed with an offline system font stack (no Google Fonts network requests), supporting live ordinance search, matter creation, batch ingestion, and Markdown brief export. - FastAPI Control Plane (
:8085): High-throughput asynchronous backend managing lifespan database migrations, Ollama batch embeddings, chunk normalization, and the citation grounding scanner. - PostgreSQL 16 Database with pgvector (
:5435): Persistent relational store hosting legal vector embeddings, full-text inverted indexes, and matter audit records. - Local Inference Node (Ollama /
:11434): Self-hosted runtime executingbge-largefor dense semantic embedding andqwen2.5:14b(or7b) for factual legal synthesis and issue-spotting.
4. Hybrid Retrieval via Reciprocal Rank Fusion (RRF)
To eliminate the "semantic neighbor" failure mode, KruschLaw pairs dense semantic vectors with cover-density full-text lexical ranking. Dense embeddings capture conceptual meaning (e.g., matching "unlawful detainer" to "eviction"), while sparse lexical queries capture exact statutory numbering (e.g., "§ 12.08.020"), named municipal codes, and statutory terms of art.
In PostgreSQL 16, KruschLaw executes this via a Common Table Expression (CTE) combining pgvector HNSW distance with tsvector cover-density ranking (ts_rank_cd):
WITH vec_matches AS (
SELECT id,
(1 - (embedding <=> CAST(:vec AS vector))) AS cos_sim,
ROW_NUMBER() OVER (ORDER BY embedding <=> CAST(:vec AS vector)) as v_rank
FROM laws_vectors
WHERE is_substantive = true AND embedding IS NOT NULL
LIMIT 50
),
lex_matches AS (
SELECT id,
ts_rank_cd(
to_tsvector('english', coalesce(title, '') || ' ' || coalesce(section, '') || ' ' || coalesce(content, '')),
plainto_tsquery('english', :text_q)
) as l_score,
ROW_NUMBER() OVER (
ORDER BY ts_rank_cd(
to_tsvector('english', coalesce(title, '') || ' ' || coalesce(section, '') || ' ' || coalesce(content, '')),
plainto_tsquery('english', :text_q)
) DESC
) as l_rank
FROM laws_vectors
WHERE is_substantive = true
AND to_tsvector('english', coalesce(title, '') || ' ' || coalesce(section, '') || ' ' || coalesce(content, '')) @@ plainto_tsquery('english', :text_q)
LIMIT 50
)
SELECT l.id, l.jurisdiction, l.state, l.city, l.county, l.city_or_county,
l.topic, l.title, l.section, l.content, l.chunk_index,
COALESCE(1.0 / (60 + v.v_rank), 0.0) + COALESCE(1.0 / (60 + lex.l_rank), 0.0) AS hybrid_score,
COALESCE(v.cos_sim, 0.0) as similarity
FROM laws_vectors l
LEFT JOIN vec_matches v ON l.id = v.id
LEFT JOIN lex_matches lex ON l.id = lex.id
WHERE v.id IS NOT NULL OR lex.id IS NOT NULL
ORDER BY hybrid_score DESC
LIMIT :limit;
By fusing vector rank and lexical rank via Reciprocal Rank Fusion (with constant $k=60$), documents that score exceptionally well on exact section numbers or statutory phrases surface at the top of the context window even if their abstract embedding similarity is moderate.
5. Section-Aware Chunking & LOCUS-v1 Ingestion
To solve the boundary severance problem, KruschLaw introduces element-aware statutory chunking. When processing municipal codes or external datasets (such as the Hugging Face LocalLaws/LOCUS-v1 corpus), the ingestion engine preserves hierarchical context:
- Jurisdiction & Section Prefixing: Rather than embedding naked paragraphs, every chunk is explicitly prepended with its jurisdictional metadata:
For example:[{jurisdiction} {section}] {title}\n{chunk_text}[Oakland Municipal Code § 8.24.040] Property Maintenance Standards & Nuisance Abatement.... This guarantees that vector embeddings encode jurisdictional boundaries directly into high-dimensional space. - SHA-256 Deduplication: Every statutory chunk is hashed upon ingestion. Re-running batch ingestion on amended municipal codes updates existing records rather than producing redundant vector duplicates.
- LOCUS-v1 Parquet Normalization: The engine includes a built-in adapter for Hugging Face LOCUS-v1 municipal ordinance files, extracting standardized fields (
header,content,state,city,county,topic, and booleanis_substantiveflags) while skipping non-binding procedural tables.
6. Two-Pass Assertion Grounding & 0.00% False Support Rate
In legal practice, an automated assistant that hallucinates 5% of the time is just as dangerous as one that hallucinates 50% of the time—either failure mode risks disciplinary action and sanctions under Cal. CCP § 128.7 and FRCP 11.
In KruschLaw (v0.6.0+), we upgraded our verification engine from a single-pass regex scanner to an authoritative Two-Pass Assertion Grounding Pipeline (src/backend/rag.py):
# Pass 1: Structural Extraction with Character Offsets
# Extracts cited statutory sections, verbatim quotes (>=20 chars), and candidate factual assertions.
# Pass 2: Proposition Entailment & 5-Class Grounding Taxonomy
# Each assertion is audited against raw StatutoryArtifact texts:
# 1. ENTAILED: Direct semantic entailment supported by retrieved statutory text.
# 2. CONTRADICTED: Directly in conflict with statutory mandate or floor/ceiling.
# 3. EXCEPTION_APPLIES: Assertion relies on a general rule overridden by a statutory exception.
# 4. INSUFFICIENT_CONTEXT: Authority does not provide enough textual support.
# 5. NOT_IN_CORPUS: Section number or quoted proposition missing from retrieved corpus.
# Enforce Strict Generation Constraints:
def enforce_generation_citation_constraints(generated_text: str, retrieved_laws: List[Dict]) -> str:
"""Bans unretrieved bare citations; replaces unverified propositions with explicit gap notices."""
...
The 0.00% False Support Rate Invariant:
To objectively verify this architecture, we implemented a dedicated labeled golden benchmark (scripts/eval_retrieval_and_grounding.py evaluating labeled_grounding_golden.json). The benchmark tests hostile adversarial prompts, subtle subsection swaps, and repealed provisions. KruschLaw enforces a non-negotiable headline metric: 0.00% False Support Rate. If an assertion is not rigorously grounded in retrieved statutory text, the engine refuses the assertion and highlights it as a STATUTORY COVERAGE GAP rather than confabulating.
7. Versioned Statutory Precedence & Temporal Time-Travel (resolve_controlling_law)
Statutory law changes over time. When analyzing an eviction notice served in March 2024 versus September 2024, the applicable legal standard may be completely different (for example, California AB 12's security deposit cap took effect on July 1, 2024). Naive RAG systems retrieve whatever text happens to be in their vector index, frequently applying newly enacted laws retroactively or citing repealed statutes.
KruschLaw solves this with a Versioned Statutory Precedence Directed Acyclic Graph (DAG):
- First-Class
as_of_dateParameter: Every search query, case brief, and defense checklist accepts an ISO-8601as_of_date. The resolver executes temporal time-travel, filtering out statutory editions enacted after that date and prioritizing amended provisions active on that date. - Hierarchical Preemption Walk: The engine resolves overrides across jurisdictional tiers:
Federal > California State Statute > Municipal Code Ordinance > Local Administrative Rule. - Typed Resolution Traces: Every resolution returns a structured
ResolutionTracecontaining sequentialResolutionHoprecords. If an ordinance is discarded, the diagnostic toolexplain_why_not_controllingprovides counsel with the exact statutory reason (e.g., "Oakland OMC § 8.22.360 was partially preempted by AB 1482 effective 2020-01-01").
8. Tenant Defense Checklists & Rigid Statutory Letter Assembly
To directly assist legal aid organizations, pro bono clinics, and housing defense attorneys, KruschLaw v0.7.0 implements dedicated tenant defense workflows (src/backend/checklist.py):
A. Evidentiary Checklists & Mandatory Deadlines (GET /api/cases/{case_id}/defense-checklist)
The engine parses matter facts against California tenant protection statutes and produces actionable defense audits with binding statutory deadlines and rent caps:
- 1-Month Security Deposit Statutory Ceiling (Cal. Civ. Code § 1950.5(c)(1) / AB 12): Flags any security deposit exceeding one month's rent for tenancies commenced or renewed on or after July 1, 2024, evaluating lease execution dates against the statutory effective date.
- 21-Day Deposit Accounting Deadline (Cal. Civ. Code § 1950.5(g)): Flags landlord failure to provide an itemized statement and refund within 21 calendar days of surrender.
- 3-Court-Day Notice Cure Period (CCP § 1161(2)): Computes court-day calculation, automatically excluding weekends and state judicial holidays to detect premature unlawful detainer filings.
- 180-Day Retaliation Presumption (Cal. Civ. Code § 1942.5): Checks if landlord adverse action occurred within 180 days of tenant exercising legal rights (e.g., reporting code violations or requesting habitability repairs).
- 24-Hour Entry Notice Floor (Cal. Civ. Code § 1954): Audits lease provisions or landlord entry attempts that fail to provide reasonable 24-hour written notice.
- Oakland Rent Board 10-Day Notice Filing (OMC § 8.22.360): Verifies whether landlord filed the eviction notice with the rent board within 10 days of service.
- Statutory Rent Cap & Notice Period Shortfall (Cal. Civ. Code § 1947.12 & § 827): Flags any rent increase exceeding the statutory ceiling of 5% plus local CPI (or 10% maximum) under the Tenant Protection Act of 2019 (AB 1482), and audits written notice periods (30 days for increases ≤ 10%, 90 days for increases > 10%).
- No-Fault Eviction & Relocation Assistance Default (Cal. Civ. Code § 1946.2(d)): Flags landlord default in providing direct relocation payment or rent waiver within 15 calendar days of notice service, rendering the termination of tenancy void as a matter of law (§ 1946.2(d)(4)).
- Curable Lease Breach Opportunity to Cure (Cal. Civ. Code § 1946.2(c) / CCP § 1161(3)): Verifies mandatory written notice and 3-day opportunity to cure prior to serving any notice to quit.
B. Rigid Statutory Demand Letter Assembly (POST /api/cases/{case_id}/assemble-letter)
Instead of prompting an LLM to generate creative prose, KruschLaw assembles formal demand letters using rigid statutory templates:
- Security Deposit Demand (§ 1950.5(l)): Incorporates mandatory statutory language advising landlords of bad-faith retention penalties of up to twice the amount of the deposit.
- Habitability Defect Notices (Civ. Code § 1941.1 & Health & Safety Code § 17920.3): Details specific substandard conditions with statutory citations.
- Defective Notice Objections: Cites improper cure periods or defective service under CCP §§ 1161 and 1162.
- Unlawful Rent Increase Objection: Demands immediate rent rollback and restitution of excess rent paid under Cal. Civ. Code § 1947.12 and § 827, citing mandatory notice shortfalls.
- No-Fault Relocation Demand: Asserts statutory entitlement to 1 month's relocation assistance under Cal. Civ. Code § 1946.2(d) or local municipal ordinance (Oakland OMC § 8.22.360), citing termination voidance upon default.
Under KruschLaw's refusal-first export policy, if key statutory elements or facts are missing, the generator does not guess; it outputs explicit STATUTORY COVERAGE GAP callout blocks in the exported Word (DOCX) document for attorney review.
9. Sovereign Privilege, Air-Gap Surface & Verifiable Cryptographic Purge
Under California Rules of Professional Conduct Rule 1.6, law firms owe an absolute duty to protect client confidences. KruschLaw enforces a zero-trust privilege architecture:
- Isolated Internal Docker Network: The database and Ollama workers communicate over an isolated bridge network (
kruschlaw_internalwithinternal: true), blocking all outbound internet egress at the kernel routing layer. - Encrypted Matter Evidence: All uploaded client documents, leases, and case notes are encrypted at rest using AES-CBC/Fernet (
enc:v1:...) before being written to disk or database tables. - Verifiable Cryptographic Purge (
execute_verifiable_purge): When a client matter closes or data retention mandates require deletion, KruschLaw executes a verified purge:- Evicts all vector embeddings and search index entries from PostgreSQL / SQLite.
- Calculates and logs a SHA-256 tombstone recording the deletion event into an append-only audit log.
- Scrubs cached disk artifacts and temporary upload files.
- Executes a physical
VACUUMto zero underlying storage pages, guaranteeing data cannot be recovered by forensic drive inspection.
10. Hardware Profiles & Deployment Topology
KruschLaw is architected to operate across flexible hardware profiles, from single-workstation office deployments to dedicated rackmount servers:
- Lightweight CPU Profile (16 GB System RAM):
- Model:
qwen2.5:7borllama3.1:8bwithbge-largeCPU quantization. - Use Case: Quick statutory retrieval, issue spotting on laptop or office workstations without discrete GPUs.
- Inference Latency: ~4.5s for 4-part legal brief generation.
- Model:
- Standard GPU Profile (12 GB+ VRAM / RTX 3060, 4070, or RTX 6000 Ada):
- Model:
qwen2.5:14b(8K context window) with GPU-accelerated batch embeddings. - Use Case: High-precision statutory synthesis, multi-matter ingestion, and concurrent staff queries.
- Inference Latency: ~1.2s to 2.0s Time-To-First-Token (TTFT), complete brief generation in under 3.5s.
- Model:
11. Quickstart & Verification
KruschLaw is fully containerized and verified by a 159-test automated suite passing with zero lint errors:
# 1. Clone the repository
git clone https://github.com/kruschdev/krusch-law.git
cd krusch-law
# 2. Configure environment (default: localhost-only bindings)
cp .env.example .env
# 3. Pull required local models in Ollama
ollama pull bge-large
ollama pull qwen2.5:14b
# 4. Launch the sovereign stack
docker compose up --build -d
# 5. Run the full verification suite (159 passing tests)
pytest tests/ -v
Once launched, access the platform locally:
- Streamlit Legal Interface:
http://localhost:8505 - FastAPI Documentation:
http://localhost:8085/docs - Diagnostic Health Check:
http://localhost:8085/health
12. Ecosystem Orchestration: The Sovereign Triad & Gateway MCP
KruschLaw does not operate as an isolated silo. It serves as the statutory foundation of the Sovereign Triad, operating alongside:
- KruschBiz (v0.8.0): Resolving controlling commercial contract precedence and cross-referencing agreements against statutory floors via
POST /conflicts/contract-vs-statute. - KruschContext MCP: Serving as the 5-verb working memory substrate (
retrieve,remember,revise,nudge,health) with pre-commit invariant enforcement. - Gateway MCP Router: Compact 5-verb router (
ask_law,ask_biz,check_compliance,ingest,purge) fitting in <450 prompt tokens for local 7B/14B models.
By substituting probabilistic approximations with deterministic statutory graphs, assertion grounding, and mathematical verification, KruschLaw provides attorneys with AI assistance they can ethically and reliably cite in court.