All 11 articles resolved manually via Légifrance web search and validated
against the PISTE API (getArticle endpoint). The search endpoint returned
HTTP 500 consistently; IDs were extracted from canonical Légifrance URLs
and cross-checked against the API for num/état correctness.
Articles covered: CP-225-1, L1881-24, CP-222-33, CP-222-33-2-2,
CP-421-2-5, CP-211-1, L1881-24bis, CP-226-4-1, CP-212-1, CP-223-13,
L1881-29. Baseline texts stored for drift detection via --check.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>