Phase 4 : impacts par public, arbitrages, calendrier — les 7 critères §7 passent

Impacts : le rapport ne dresse pas de tableau texte × public, mais il consacre
un chapitre à chacun (sec04 individus, sec05 associations, sec06 entreprises).
C'est ce placement éditorial — un choix explicite de l'auteur, pas une
inférence — qui sert de base à la ventilation. Le sens vient de la cotation
manuelle de l'annexe quand elle existe, sinon du vocabulaire, et le texte est
alors marqué « à vérifier » (17 cas).

Arbitrages de la validation de phase 5 portés en points clés :
loi-riposte affiche l'AFD à 500 €, et le montant de 1 500 € n'apparaît que
présenté comme la version sénatoriale abandonnée.

Migration 004 + calendrier : 9 échéances nationales transcrites du corpus avec
leur extrait source. Celle des sénatoriales porte explicitement
concerne_guadeloupe = 0 — série 1, renouvelée en 2023.

Défaut de qualité corrigé : un titre de section nommant plusieurs textes
(« Cohésion républicaine, logement, GloBE, entrisme ») faisait hériter chaque
phrase de transition aux quatre, polluant leurs résumés. Une section n'est
dédiée que si elle nomme un seul texte.

118 tests, 92 % de couverture. Les 7 garde-fous du §7 et les 5 démos du §8.7
sont automatisés dans tests/test_acceptation.py.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Cyber Mawonaj
2026-07-25 20:23:51 -04:00
co-authored by Claude Opus 5
parent c28243cf87
commit f3e546cfc4
8 changed files with 922 additions and 3 deletions
+35
View File
@@ -223,6 +223,40 @@ def enregistrer_decision_cc(
)
def enregistrer_echeance(cx: sqlite3.Connection, echeance, *, texte_id: str | None = None) -> None:
"""Écrit une échéance de calendrier (nationale ou rattachée à un texte)."""
cx.execute(
"""
INSERT INTO echeances (code, date_echeance, libelle, description, portee,
texte_id, concerne_guadeloupe, note_guadeloupe,
previsionnel, source_url, source_extrait)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (code) DO UPDATE SET
date_echeance = excluded.date_echeance,
libelle = excluded.libelle,
description = excluded.description,
concerne_guadeloupe = excluded.concerne_guadeloupe,
note_guadeloupe = excluded.note_guadeloupe,
previsionnel = excluded.previsionnel,
source_url = COALESCE(excluded.source_url, source_url),
source_extrait = COALESCE(excluded.source_extrait, source_extrait)
""",
(
echeance.code,
echeance.date_echeance.isoformat(),
echeance.libelle,
echeance.description,
"texte" if texte_id else "nationale",
texte_id,
None if echeance.concerne_guadeloupe is None else int(echeance.concerne_guadeloupe),
echeance.note_guadeloupe,
int(echeance.previsionnel),
echeance.source_url,
echeance.source_extrait,
),
)
def enregistrer_insight(cx: sqlite3.Connection, insight: Insight) -> None:
cx.execute(
"""
@@ -332,6 +366,7 @@ def statistiques(cx: sqlite3.Connection) -> dict[str, Any]:
"evenements": un("SELECT COUNT(*) FROM evenements"),
"decisions_cc": un("SELECT COUNT(*) FROM decisions_cc"),
"insights": un("SELECT COUNT(*) FROM insights"),
"echeances": un("SELECT COUNT(*) FROM echeances"),
"textes_sans_source": un(
"SELECT COUNT(*) FROM textes t "
"WHERE NOT EXISTS (SELECT 1 FROM sources s WHERE s.texte_id = t.id)"