Lobby × Lex — a zero-LLM toolkit to quantify a lawyer's litigation footprint in Swiss federal and cantonal case law.
Given a list of lawyers, it scans the published jurisprudence corpus for every decision in which each lawyer is named as counsel, then builds a quantified profile of their practice: total count, breakdown by court, by legal matter, by year, by language, first and last appearance.
The motivating application is the cohort of lawyer-parliamentarians in the Swiss federal parliament — members who also practise as attorneys — but the method is generic: feed it any list of names.
In Swiss court decisions, the names of the parties are anonymised (X._,
A._, B._) but the names of the attorneys are kept in clear, because
attorneys are public officers of the court (auxiliaires de justice) and their
identity is part of the public record.
That asymmetry is what makes it possible to quantify a given lawyer's litigation activity without ever touching the confidentiality of the parties.
For each lawyer, the scan looks for mentions of their name immediately
preceded by an explicit attorney marker (Me, Maître, Rechtsanwalt,
avv.…), which avoids false positives (doctrinal citations, magistrates,
witnesses, NGO legal officers). See docs/pattern-observations.md
for the patterns observed on real samples (TF, TPF, TAF).
The query strategy combines a PostgreSQL GIN full-text pre-filter on the surname
(~10 ms) with a strict per-language regex applied only to the decision header.
See docs/entscheidsuche-schema.md for the
database schema, index requirements, and noise measurements.
- Corpus: a PostgreSQL database (
entscheidsuche_all) mirroring the decisions published on entscheidsuche.ch, which aggregates federal and cantonal case law (~805k decisions, 1900–today, DE/FR/IT). The schema is documented indocs/entscheidsuche-schema.md. - Input list: a YAML registry of the lawyers you want to profile. A template
with the expected fields is provided in
data/lawyers.example.yaml. The registry itself is not shipped with this repository — you supply your own.
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# 1. Scan the corpus for counsel mentions (writes one YAML per lawyer)
python scan_jurisprudence.py --input data/lawyers.yaml
# 2. Enrich each hit with legal matter + subject (zero LLM)
python analyze_subjects.py
# 3. Render readable practice profiles in Markdown
python render_silhouettes.pyThe scripts expect a reachable PostgreSQL instance; connection settings live in
the DB_CONFIG constant at the top of each script.
- Phase 1 — scope TF + TPF (~206k decisions). Simple pre-fix pattern, target precision >98%.
- Phase 2 — extend to TAF + BGE + PATG. Extended pattern (pre-fix + post-fix) with exclusion of known NGO legal-aid organisations.
- Phase 3 — cantonal courts (~470k decisions). Regex calibrated per canton.
For each lawyer:
- identity (id, parliament number, party, canton…) as supplied in the input
- litigation profile: total count, by court, by year, by language, first/last appearance
- practice silhouette: distribution by legal matter and by court division, top recurring subjects
Named after Lex Luthor — the DC archetype of corporate power influencing politics — and the Latin lex ("law").
MIT — see LICENSE.