CLI de recherche · ocl

Vérifier les citations et conserver les preuves depuis le terminal

ocl est un petit client sans dépendances pour l’API de recherche OpenCaseLaw. Il sert autant l’avocate au terminal que l’agent IA dans un script : texte lisible à l’écran, JSON en pipe. Tout ce qu’il affiche vient du service tel quel : identifiants, chaînes de citation, texte des considérants.

Installation

Python 3.10 ou plus récent. Installez-le depuis PyPI comme outil avec pipx ou uv ; les deux créent l’environnement isolé qu’exigent les installations Python actuelles. ocl doctor vérifie la connexion, le serveur et le client.

pipx install opencaselaw-cli        # or: uv tool install opencaselaw-cli
ocl --help

Sans pipx ni uv, utilisez un environnement virtuel : python3 -m venv .venv && .venv/bin/pip install opencaselaw-cli, puis lancez .venv/bin/ocl. Mise à jour avec pipx upgrade opencaselaw-cli (ou uv tool upgrade opencaselaw-cli).

1. Vérifier les citations d’un projet

Placez les références de votre projet dans un fichier, une par ligne, ou en lignes JSON lorsqu’une référence vise un considérant. Chacune revient comme resolved, missing ou ambiguous avec la décision trouvée ; un considérant n’est resolved que s’il existe dans l’index.

cat > references.jsonl <<'JSONL'
{"reference":"BGE 136 III 513","pinpoint":"2.3"}
{"reference":"4A_747/2012"}
{"reference":"BGE 999 III 1"}
{"reference":"BGE 140 III 86","pinpoint":"2.3"}
JSONL
ocl citations resolve --input references.jsonl

Au terminal, cela affiche :

resolved              BGE 136 III 513  bge_BGE_136_III_513  E. 2.3 retrieved
resolved              4A_747/2012      bger_4A_747_2012     BGer 4A_747/2012 vom 5. April 2013
missing               BGE 999 III 1                         not in the corpus
pinpoint_unavailable  BGE 140 III 86   bge_BGE_140_III_86   E. 2.3 not in the index

partial: 2 resolved, 1 missing, 1 pinpoint_unavailable.
Existence and pinpoints only; no assessment of legal support.

Le code de sortie est 4 parce que tout n’a pas été résolu. Ce que la vérification ne fait pas : elle ne dit jamais qu’une décision soutient votre thèse, qu’elle est toujours applicable ou qu’elle correspond à vos faits. Cette lecture vous appartient.

2. Conserver les preuves derrière une note

Une commande lance la recherche et enregistre les décisions sélectionnées, les considérants et les articles de loi que vous nommez dans un dossier : textes intégraux tels que servis, un INDEX.md lisible et un manifest.json avec chaque requête, horodatage, lien source et empreinte de fichier. Les fichiers enregistrés ne sont jamais écrasés ; --resume termine un passage interrompu.

ocl bundle create 'Rachekündigung Art. 336 OR' --max-results 10 --passage 2 \
  --law OR:336 --out rachekuendigung-2026-09

Le dossier se lit sans aucun outil :

rachekuendigung-2026-09/
  INDEX.md                                    what was saved, in plain language
  manifest.json                               every request, timestamp, hash, source link
  decisions/bge_BGE_136_III_513-5b3e22ef.txt  full text as served (+ .json metadata)
  passages/bge_BGE_136_III_513_2-ff487655.txt E. 2, verbatim
  laws/OR_336-812a5382.json                   Art. 336 OR, consolidation date, Fedlex link
  search/page-0000-1850ce82.json              the search page the selection came from

Un dossier est complete lorsque chaque élément demandé a été enregistré, sinon partial avec chaque élément manqué, par exemple une décision cantonale sans considérants numérotés. Il conserve ce que le service a renvoyé ce jour-là ; le corpus est reconstruit chaque nuit, la même requête peut sélectionner d’autres décisions le mois suivant.

Ce que signifient les résultats

  • resolved : la décision existe dans le corpus. Avec un considérant, celui-ci existe et son texte figure dans la ligne.
  • pinpoint_unavailable : la décision existe ; le considérant numéroté n’est pas dans l’index structurel. Pour un sous-considérant à lettre (consid. 2a, 3c/aa), le numéro parent est livré (parent_retrieved) ; y repérer la lettre.
  • missing : aucune décision avec cette citation ou ce numéro de dossier. Une citation erronée ou une lacune de couverture, jamais la preuve qu’une citation a été inventée.
  • ambiguous : plus d’une décision porte ce libellé (les numéros de dossier sont réutilisés d’un tribunal à l’autre). Choisissez un decision_id.
  • unrecognized : la décision proposée par le service ne porte aucun libellé écrit dans la référence ; la proposition figure sous service_candidate, jamais dans decision_id. resolution_incomplete, error : identité non établie ou requête en échec. Rien n’est deviné.
  • total_is_lower_bound: true signifie « au moins autant ». Une recherche textuelle est classée sur un ensemble borné de candidats ; has_more: false ne prouve jamais que chaque décision pertinente a été vue.
  • Codes de sortie : 0 complet, 2 entrée invalide, 3 service ou réseau en échec, 4 partiel ou non résolu (y compris une décision ou un considérant que le service n’a pas). Les scripts s’y branchent sans analyser de prose.
  • discrepancy : la décision est identifiée, mais la date ou le numéro de dossier écrit à côté de la référence ATF contredit le dossier ; discrepancies énumère chaque écart.

Recettes

Chercher, puis récupérer les décisions complètes, en un seul pipeline :

ocl decisions search 'Rachekündigung Art. 336 OR' --max-results 5 --format jsonl |
  ocl decisions get --stdin --format jsonl > decisions.jsonl

Tout ce qu’un tribunal a décidé sur une période. Sans texte de requête, les filtres énumèrent un ensemble exact, page par page :

ocl decisions search --court bge --date-from 2026-01-01 --date-to 2026-06-30 \
  --sort date_desc --max-results 500 --format jsonl > bge-2026-h1.jsonl

Citer un considérant mot pour mot, avec la citation qui va avec :

ocl decisions passage bge_BGE_136_III_513 2.3
ocl cite 'BGE 136 III 513' --pinpoint 2.3 --language fr

Une loi telle qu’elle était en vigueur à une date :

ocl laws get OR --article 41 --as-of 2015-01-01

Qui cite un arrêt de principe :

ocl citations list bge_BGE_140_III_86 --direction incoming --limit 50

Les agents de code comme Claude Code ou Codex lancent les mêmes commandes depuis un shell et lisent le JSON ; les preuves restent dans des fichiers que vous pouvez contrôler, pas dans la mémoire du modèle.

Pour les agents

Un agent a besoin de quatre choses : une installation sans question, une sortie qu’il peut analyser, des verdicts sur lesquels brancher, et des règles qu’il ne peut pas contourner. ocl fournit les quatre : du JSON dès que la sortie est redirigée ; des codes de sortie qui portent le verdict (0 tout résolu, 2 entrée invalide, 3 service ou réseau, 4 quelque chose n’a pas été résolu) ; --cache pour que les répétitions au sein d’une génération de la base ne coûtent rien ; et trois skills livrés avec l’outil (contrôle des citations, recherche, dossier de preuves). ocl tool call atteint chaque outil de recherche du service.

ocl agent-guide                  # the contract on one page: JSON, exit codes, statuses, rules
ocl skills install --claude      # citation-check, research, evidence-bundle into ~/.claude/skills
ocl tool list                    # every research tool of the service
ocl tool call find_leading_cases query='Rachekündigung Art. 336 OR' limit=5
ocl quotes check --input quotes.jsonl --format jsonl
ocl citations resolve --input refs.jsonl --format jsonl --cache ~/.cache/ocl

Les règles ne se négocient pas : les libellés de citation et les citations viennent du service tels quels ; un close_match ou un service_candidate renseigne l’auteur, il ne remplace jamais rien ; l’outil établit l’existence et le libellé, pas la portée juridique. opencaselaw_cli.api offre la même chose sous forme de bibliothèque.

Sa place

  • Conversation : connectez Claude, ChatGPT ou un autre client MCP à mcp.opencaselaw.ch (configuration par client).
  • Scripts, notebooks et agents : ocl, ou directement l’API REST. Mêmes enregistrements, mêmes limites.
  • Analyse à l’échelle du corpus : le jeu de données Parquet.

Limites

Une recherche textuelle est envoyée en une seule requête classée de 800 résultats au plus ; les recherches par filtres seuls sont paginées. Les requêtes larges peuvent dépasser le délai et sont signalées comme un échec, pas comme un résultat vide. Les lois cantonales s’indiquent sous la forme --law ZH/StG:1. Les requêtes vont au service hébergé et relèvent de la déclaration de confidentialité ; --base-url désigne un serveur exploité séparément.

Le guide complet avec les sections de référence (recherche et récupération, dossiers, résolution des citations, contrat de l’API) est sur GitHub : docs/research-cli.md.