# Plan d'implémentation — Plateforme « Veille Législative Guadeloupe » > Phase 0 du prompt `prompt-kimi-cli-veille-legislative.md`. Rédigé le 25 juillet 2026. > **Statut : en attente de validation.** --- ## A. Rapport de lecture du corpus (Phase 0) ### A.1 Volumétrie réelle | Ensemble | Fichiers | Mots | Rôle retenu | |---|---|---|---| | Rapport consolidé | `.agent.final.md` (+ `.converted.md`, doublon) | 38 271 | Source de vérité rédactionnelle (résumés, points clés) | | Chapitres | `sec00` → `sec10` | 28 642 | `sec10` = **parsing prioritaire** (2 tableaux structurés) ; `sec00` = synthèse | | Bibliographie | `_ref.md` | 9 591 | 481 références numérotées `[N] Éditeur. Titre [EB/OL]. Date. URL` | | Dimensions | `research/dim01` → `dim12` | 91 530 | Matière brute sourcée (claims + notes de bas de page) | | Méta-recherche | `cross_verification`, `insight`, `phase5_validation` | 5 857 | Confiance, analyses transversales, arbitrages | | Plan / outline | `plan.md`, `.agent.outline.md` | 2 332 | Taxonomie des chapitres | Total ≈ **214 500 mots**. Les `.docx` sont des dérivés du markdown — non ingérés. ### A.2 Découverte structurante : les fichiers `dim` ont **trois dialectes** Le prompt (§2) postule un format unique `Claim / Source / URL / Date / Excerpt / Confidence`. La réalité mesurée : | Dialecte | Fichiers | Motif | |---|---|---| | **A — claim plat** | dim01, dim02, dim03, dim04, dim07 | `Claim: …` puis `Source:` / `URL:` / `Date:` / `Excerpt:` / `Confidence:` en début de ligne | | **B — claim numéroté gras** | dim05 | `**Claim 3 :** …` puis champs plats | | **C — claim en liste** | dim10 (+ portions de dim06, dim08) | `**Claim 1.2** — …` puis `- **Source** : ` / `- **URL** : ` (URLs parfois multiples, séparées par ` ; `) | | **D — prose + notes** | dim06, dim08, dim09, dim11, dim12 | Aucun bloc claim ; sources en fin de fichier sous forme `[^N^] Éditeur — titre : URL` | Comptage : 153 blocs `Claim` explicites, 258 définitions de notes de bas de page, 884 usages de marqueurs `[^N^]` dans les dim. **Le parseur doit gérer les quatre dialectes**, sinon on perd dim06/08/09/11/12 — soit précisément les dimensions associations, entreprises, migration et calendrier. ### A.3 Résolution des citations `[^dimXX-N^]` Chaîne de résolution implémentable et vérifiée : ``` sec0X.md : « … chlordécone [^dim07-24^] » → dim07, note locale n° 24 → dim07 §« [^24^] Vie-publique — chlordécone … : https://… » (ou bloc Claim portant [^24^]) → URL + date + extrait verbatim + confiance ``` Marqueurs distincts recensés dans les chapitres : **333**, dont des marqueurs non-dim (`[^phase5-3.1^]`, `[^insight-5^]`) qui pointent vers `phase5_validation.md` et `insight.md` — à traiter comme deux « pseudo-dimensions ». ### A.4 Inventaire seed cible - **Tableau A de `sec10`** : 27 lois promulguées (23 avr. → 23 juill. 2026), colonnes `N° de loi | Promulgation/JO | Objet | Statut libertés | Pertinence Guadeloupe-OM`. - **Tableau B de `sec10`** : 24 lignes (adoptés non promulgués, navette, déposés, annoncés) — dont 2 lignes portant chacune 2 textes (accords Kazakhstan + Colombie ; MACF ratification + accord plateforme) → **26 textes** après éclatement. - **Décisions CC** identifiables : 2026-903, 904, 905, 906, 908, 909 (rendues) + 910 à 915 (en instance) = **12 affaires DC**. → Cible réaliste : **53 textes** (27 + 26), au-delà du plancher de 49 exigé au §2. Les décisions CC alimentent la table `decisions_cc` et non le compteur `textes`. ### A.5 Contradictions détectées dans le corpus (à encoder comme règles, pas à masquer) 1. `insight.md` §1 annonce « 5 décisions DC attendues fin août » puis en liste 6 ; `sec10` en compte 7 + Philippine hors suspension. → Règle : **`sec10` + `phase5_validation` priment** sur `insight` pour les faits ; `insight` n'est utilisé que comme contenu éditorial (encart « point de veille »). 2. `dim11` point de vigilance n° 1 dit la saisine Riposte « non confirmée par une source primaire » ; `phase5_validation` §3 la tranche comme **effective, 24/07/2026, n° 2026-915 DC**. → `phase5_validation` prime (règle explicite du §5.2 du prompt). 3. AFD free party : 1 500 € (dim09) vs 500 € (phase5). → **500 €**, conformément au test d'acceptation §7 du prompt. 4. Durées DOM chômage antérieures : divergence assumée `low` dans `cross_verification` → entrée marquée « à vérifier ». Ces quatre règles sont codées dans `pipeline/resolution_conflits.py` et testées. --- ## B. Architecture décidée ``` veille_legislative_971/ ├── data/ │ ├── input/ ← LECTURE SEULE (jamais modifié) │ ├── veille.db ← SQLite (généré) │ └── textes.json ← dump statique (généré, mode dégradé) ├── pipeline/ ← Python 3.12 (uv) │ ├── modeles.py ← pydantic : Texte, Source, Evenement, DecisionCC │ ├── db.py ← connexion, migrations, FTS5 │ ├── migrations/ ← 001_initial.sql, … │ ├── seed_from_research.py ← orchestrateur du seed │ ├── parseurs/ │ │ ├── tableaux_sec10.py ← tableaux A et B (chemin principal) │ │ ├── blocs_claim.py ← 4 dialectes dim (A/B/C/D) │ │ ├── notes_bas_page.py ← résolution [^dimXX-N^] → URL │ │ ├── bibliographie.py ← _ref.md, 481 entrées │ │ └── meta.py ← cross_verification, insight, phase5 │ ├── collecteurs/ ← legifrance.py (PISTE), assemblee.py, senat.py, │ │ conseil_constit.py, vie_publique.py │ ├── rapprochement.py ← matching numero_officiel puis fuzzy titre │ ├── classification.py ← thèmes/impacts heuristiques (config.yaml) │ ├── guadeloupe.py ← détection outre-mer │ ├── resolution_conflits.py ← hiérarchie JO > AN/Sénat > CC > presse │ ├── update.py ← run complet, --dry-run obligatoire │ └── config.yaml ├── web/ ← SvelteKit 2 + Svelte 5 runes + TS strict │ ├── src/lib/server/ ← better-sqlite3, requêtes FTS5, facettes │ ├── src/routes/ │ │ ├── +page.svelte SSR — tableau de bord │ │ ├── recherche/ SSR — facettes dans url.searchParams │ │ ├── textes/[slug]/ SSR — fiche + timeline + sources │ │ ├── calendrier/ SSR — échéances août-octobre │ │ ├── a-propos/ methode/ prerender = true │ │ └── api/textes|textes/[slug]|echeances/+server.ts │ └── svelte.config.js ← adapter-node, precompress ├── systemd/ │ ├── veille-legislative.service / .timer (6 h, 18 h + dimanche intensif) │ └── veille-web.service / .socket (activation par socket, IDLE_TIMEOUT=300) ├── tests/ ← pytest (parseurs, fixtures figées) ├── Makefile ← seed, update, dev, build, check, test ├── .env.example ├── README.md └── README-pipeline.md ``` ### B.1 Arbitrages prompt ↔ recommandations `doc2sveltekit-transition` | Sujet | Prompt | Playbook OKI | Décision | |---|---|---|---| | Adapter | `adapter-node`, SSR, « non négociable » (§3bis) | `adapter-static`, prerender intégral | **Prompt** — le playbook vise des sites vitrines, ici les facettes URL et la fraîcheur pipeline exigent le SSR | | Zéro tiers, self-hébergement polices | §3 « zéro CDN externe » | §2.2 idem | **Convergent** — appliqué | | Thème sombre / or / flag-bar | « sobre et institutionnel » | identité OKI obligatoire | **À valider** (question 2) | | Tailwind | imposé (§3) | interdit (§2.3) | **À valider** (question 1) | | Zéro emoji, set SVG kréyòl | non traité | obligatoire | **Playbook** — appliqué (badges de statut en SVG, pas d'emoji) | | Motion gwoka + `prefers-reduced-motion` | non traité | obligatoire | **Playbook**, dosé : transitions ≤ 120 ms, aucune animation de scroll | | Schema.org / SEO AI-Overview | non traité | PRD dédié | **Playbook** — `Legislation` + `Dataset` JSON-LD sur les fiches, sitemap, robots.txt | | Accessibilité WCAG AA | §6 | §2.8 | **Convergent** | --- ## C. Phases d'exécution | Phase | Contenu | Vérification exécutable | |---|---|---| | **1** | Squelette repo, `uv` + Python 3.12, schéma SQLite + FTS5, migrations, modèles pydantic | `make db-init` puis `sqlite3 data/veille.db .schema` | | **2** | Parseurs `sec10` (A + B) → 53 textes, avec statuts, dates, pertinence Guadeloupe | `make seed` → compte-rendu ≥ 49 textes ; `pytest tests/test_tableaux_sec10.py` | | **3** | Parseurs `dim` (4 dialectes) + résolution `[^dimXX-N^]` + `_ref.md` → sources, extraits verbatim, confiance | `make seed` → 100 % des textes avec ≥ 1 source URL ; couverture pytest ≥ 70 % | | **4** | Enrichissement : `resume`, `points_cles`, `impacts`, timeline `evenements`, `decisions_cc`, insights | Tests d'acceptation §7 du prompt (7 assertions) automatisés en pytest | | **5** | Collecteurs live + `update.py --dry-run` + résolution de conflits + `veille_log` + dump JSON | `make update-dry` → rapport de diffs réel affiché | | **6** | SvelteKit : layout, tokens, accueil, recherche à facettes, fiche, calendrier, à-propos/méthode, API JSON | `npm run build`, `npm run check` (0 erreur TS), `node build` répond sur 127.0.0.1 | | **7** | PWA, systemd (4 unités), README d'installation Debian vierge, doc des dégradations sans clé PISTE | grep de conformité §3bis, démo des 5 scénarios du §8.7 | Chaque phase se clôt par la sortie réelle des commandes, montrée telle quelle. --- ## D. Points bloquants à trancher avant la Phase 1 1. **Tailwind ou CSS vanilla + tokens OKI** (prompt vs playbook). 2. **Identité visuelle** : charte OKI complète, OKI sobrifiée, ou institutionnel neutre. 3. **Clé Légifrance** : la clé fournie ressemble à un `client_id` PISTE ; l'API OAuth2 `client_credentials` exige aussi un `client_secret`. Sans lui, le collecteur Légifrance sera codé mais désactivé (dégradation documentée : repli scraping AN/Sénat). 4. **Git** : le dossier n'est pas un dépôt. `git init` + commit initial recommandé avant toute écriture (règle transverse n° 2 du playbook) ; publication Gitea `labola.o-k-i.net` optionnelle.