Add Légifrance API integration for live legal text injection

Implements a two-layer approach to ensure legal texts are accurate and current:

Option A — runtime injection (legifrance_client.py):
- LegifranceClient: OAuth2 via PISTE (oauth.piste.gouv.fr), fetches consolidated
  article text via api.piste.gouv.fr/dila/legifrance/lf-engine-app
- Redis cache with 24h TTL (in-memory fallback if no Redis)
- build_filter_prompt() injects live texts into the prompt with explicit priority
  over static descriptions — model uses official Légifrance text, not training memory
- Graceful fallback to static prompt if API is unavailable — filtering never blocks

Option B — weekly sync script (scripts/check_legal_refs.py):
- Reads legal_refs.yaml (11 tracked articles, priority critical/high/medium)
- Fetches current text from Légifrance, diffs against stored baseline
- --init: resolves LEGIARTI IDs on first run
- --check: report only; --update: saves new texts to YAML
- Exit code 2 when changes detected (CI/n8n-compatible)

Supporting changes:
- legal_refs.yaml: tracked articles with code LEGITEXT IDs, priorities, rationale
- requirements.txt: add pyyaml>=6.0.2 and requests>=2.32.0
- .env.example: document PISTE_CLIENT_ID, PISTE_CLIENT_SECRET, LEGIFRANCE_CACHE_TTL
- transparence.tsx: document the Légifrance injection for public transparency
- Fixed portal URL: piste.gouv.fr (not piste.api.gouv.fr — verified June 2026)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 09:19:23 +02:00
parent e8b4bde2f4
commit 67bb0095fa
8 changed files with 764 additions and 2 deletions
@@ -86,6 +86,23 @@ export default function Transparence() {
</p>
</div>
<div className="bg-muted/40 border border-border/50 p-5 space-y-2">
<p className="font-mono text-xs font-semibold uppercase tracking-widest text-primary">Sources légales — Légifrance en temps réel</p>
<p className="text-foreground/90 text-sm leading-relaxed">
Les textes des articles légaux critiques (Art. 225-1, 24 Loi 1881, Art. 421-2-5…) sont
récupérés en temps réel depuis <strong>l'API officielle Légifrance (PISTE)</strong> et injectés
dans le prompt avant chaque analyse. Le modèle travaille ainsi sur le texte
consolidé du jour, pas sur sa mémoire d'entraînement figée.
</p>
<p className="text-foreground/90 text-sm leading-relaxed">
Les textes sont mis en cache 24 h. Un script de surveillance hebdomadaire
(<code className="bg-muted px-1 py-0.5 rounded text-xs">scripts/check_legal_refs.py</code>) détecte
tout changement législatif et alerte en cas de modification. Si l'API Légifrance
est indisponible, le système bascule automatiquement sur le cadre légal statique
intégré au prompt le filtrage continue sans interruption.
</p>
</div>
<div>
<p className="font-semibold mb-2">Ce que le filtre vérifie</p>
<p className="text-foreground/80 text-sm leading-relaxed mb-3">