# 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.
