diff --git a/src/app/(dashboard)/grid/loading.tsx b/src/app/(dashboard)/grid/loading.tsx
new file mode 100644
index 0000000..4d3b3df
--- /dev/null
+++ b/src/app/(dashboard)/grid/loading.tsx
@@ -0,0 +1,39 @@
+export default function GridLoading() {
+ return (
+
+
+ {/* Spinner */}
+
+
+
+
+ Chargement des données
+
+
+ Récupération des articles et calcul des scores...
+
+
+
+
+ );
+}
diff --git a/src/features/ai-copilot/business/analysis-engine.ts b/src/features/ai-copilot/business/analysis-engine.ts
index a51ceba..d45d18f 100644
--- a/src/features/ai-copilot/business/analysis-engine.ts
+++ b/src/features/ai-copilot/business/analysis-engine.ts
@@ -46,8 +46,9 @@ PROMOUVOIR (Z → A) : Le verdict pré-calculé est Z, MAIS :
DÉGRADER (A → Z) : Le verdict pré-calculé est A, MAIS :
• Tendance en effondrement (H2/H1 < 0.4)
• ET aucune réception récente
- • ET score < 55
+ • ET score < 55 ⚠️ SI LE SCORE EST ≥ 55, TU NE PEUX JAMAIS DÉGRADER EN Z
→ Les 3 conditions doivent être remplies SIMULTANÉMENT.
+ → Un score élevé (≥ 55) INTERDIT toute dégradation, quelle que soit la tendance.
Si AUCUNE condition d'ajustement n'est remplie → CONFIRME le verdict pré-calculé.
diff --git a/src/features/ai-copilot/data/open-router-client.ts b/src/features/ai-copilot/data/open-router-client.ts
index ba8d7f2..3a94403 100644
--- a/src/features/ai-copilot/data/open-router-client.ts
+++ b/src/features/ai-copilot/data/open-router-client.ts
@@ -86,6 +86,17 @@ export class OpenRouterClient {
// Ré-appliquer le garde-fou pour la reco extraite du texte.
if (!ruleApplies && (reco === "B" || reco === "C" || reco === "D")) reco = "A";
}
+
+ // Garde-fou anti-dégradation : l'IA ne peut PAS dégrader A → Z
+ // si le score pré-calculé est ≥ 55 (sauf si règle manager).
+ // Corrige les hallucinations du LLM qui ignore la condition "score < 55".
+ const preScore = p.scoring?.score ?? p.score ?? 0;
+ const preVerdict = p.scoring?.verdict ?? (preScore >= 45 ? "A" : "Z");
+ if (!ruleApplies && preVerdict === "A" && reco === "Z" && preScore >= 55) {
+ console.warn(`[AI Guardrail] Blocked A→Z degradation for ${p.codein} (score ${preScore} ≥ 55)`);
+ reco = "A";
+ cleanInsight += " [Garde-fou : score élevé, dégradation bloquée]";
+ }
} catch (e) {
console.error("Failed to parse AI JSON response:", content, e);
// Fallback to text parsing