diff --git a/MyIA.AI.Notebooks/SymbolicAI/Planners/02-Classical/Planners-6-Domains-Csharp.ipynb b/MyIA.AI.Notebooks/SymbolicAI/Planners/02-Classical/Planners-6-Domains-Csharp.ipynb
index 3fa6407a8a..4b0adfc0b6 100644
--- a/MyIA.AI.Notebooks/SymbolicAI/Planners/02-Classical/Planners-6-Domains-Csharp.ipynb
+++ b/MyIA.AI.Notebooks/SymbolicAI/Planners/02-Classical/Planners-6-Domains-Csharp.ipynb
@@ -64,148 +64,20 @@
},
"outputs": [
{
+ "output_type": "display_data",
"data": {
- "text/html": [
- "\r\n",
- "
\r\n",
- "
\r\n",
- " The below script needs to be able to find the current output cell; this is an easy method to get it.\r\n",
- "
\r\n",
- " \r\n",
- "
"
- ]
+ "text/html": ""
},
- "metadata": {},
- "output_type": "display_data"
+ "metadata": {}
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Modèle STRIPS chargé : Atom, Action (pre/add/del), State (immuable).\r\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "\r\n",
- "(14,39): warning CS8632: L'annotation pour les types référence Nullable doit être utilisée uniquement dans le code au sein d'un contexte d'annotations '#nullable'.\r\n",
- "\r\n",
- "(28,51): warning CS8632: L'annotation pour les types référence Nullable doit être utilisée uniquement dans le code au sein d'un contexte d'annotations '#nullable'.\r\n",
- "\r\n",
- "(29,38): warning CS8632: L'annotation pour les types référence Nullable doit être utilisée uniquement dans le code au sein d'un contexte d'annotations '#nullable'.\r\n",
- "\r\n",
- "(29,71): warning CS8632: L'annotation pour les types référence Nullable doit être utilisée uniquement dans le code au sein d'un contexte d'annotations '#nullable'.\r\n",
- "\r\n",
- "(59,29): warning CS8632: L'annotation pour les types référence Nullable doit être utilisée uniquement dans le code au sein d'un contexte d'annotations '#nullable'.\r\n",
- "\r\n",
- "(61,39): warning CS8632: L'annotation pour les types référence Nullable doit être utilisée uniquement dans le code au sein d'un contexte d'annotations '#nullable'.\r\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "Modèle STRIPS chargé : Atom, Action (pre/add/del), State (immuable).\r\n"
}
],
"source": [
+ "#nullable enable\n",
"\n",
"// Modèle STRIPS from-scratch (BCL .NET 9, 0 NuGet)\n",
"using System;\n",
@@ -306,11 +178,9 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Planificateur BFS chargé : StripsPlanner.Solve (forward search + anti-cycle).\r\n"
- ]
+ "name": "stdout",
+ "text": "Planificateur BFS chargé : StripsPlanner.Solve (forward search + anti-cycle).\r\n"
}
],
"source": [
@@ -417,82 +287,59 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Problème 'blocks-tower' : construire la tour c <- b <- a\r\n"
- ]
+ "name": "stdout",
+ "text": "Problème 'blocks-tower' : construire la tour c <- b <- a\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "État initial : a, b, c sur la table\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "État initial : a, b, c sur la table\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Solution trouvée ! Longueur du plan : 4 action(s)\r\n"
- ]
+ "name": "stdout",
+ "text": "Solution trouvée ! Longueur du plan : 4 action(s)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 1. pick-up(b)\r\n"
- ]
+ "name": "stdout",
+ "text": " 1. pick-up(b)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 2. stack(b,c)\r\n"
- ]
+ "name": "stdout",
+ "text": " 2. stack(b,c)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 3. pick-up(a)\r\n"
- ]
+ "name": "stdout",
+ "text": " 3. pick-up(a)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 4. stack(a,b)\r\n"
- ]
+ "name": "stdout",
+ "text": " 4. stack(a,b)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds explorés (expanded) : 20\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds explorés (expanded) : 20\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds générés (generated) : 21\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds générés (generated) : 21\r\n"
}
],
"source": [
@@ -583,103 +430,74 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Problème 'blocks-reverse' : inverser deux tours (4 blocs)\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "Problème 'blocks-reverse' : inverser deux tours (4 blocs)\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Solution trouvée ! Longueur du plan : 8 action(s)\r\n"
- ]
+ "name": "stdout",
+ "text": "Solution trouvée ! Longueur du plan : 8 action(s)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 1. unstack(b,a)\r\n"
- ]
+ "name": "stdout",
+ "text": " 1. unstack(b,a)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 2. put-down(b)\r\n"
- ]
+ "name": "stdout",
+ "text": " 2. put-down(b)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 3. pick-up(a)\r\n"
- ]
+ "name": "stdout",
+ "text": " 3. pick-up(a)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 4. stack(a,b)\r\n"
- ]
+ "name": "stdout",
+ "text": " 4. stack(a,b)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 5. unstack(d,c)\r\n"
- ]
+ "name": "stdout",
+ "text": " 5. unstack(d,c)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 6. put-down(d)\r\n"
- ]
+ "name": "stdout",
+ "text": " 6. put-down(d)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 7. pick-up(c)\r\n"
- ]
+ "name": "stdout",
+ "text": " 7. pick-up(c)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 8. stack(c,d)\r\n"
- ]
+ "name": "stdout",
+ "text": " 8. stack(c,d)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds explorés (expanded) : 85\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds explorés (expanded) : 85\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds générés (generated) : 105\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds générés (generated) : 105\r\n"
}
],
"source": [
@@ -764,104 +582,74 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Tours de Hanoï : 3 disques de p1 vers p3\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "Tours de Hanoï : 3 disques de p1 vers p3\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Solution trouvée ! Longueur du plan : 7 action(s)\r\n"
- ]
+ "name": "stdout",
+ "text": "Solution trouvée ! Longueur du plan : 7 action(s)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 1. move(d1,d2->p3)\r\n"
- ]
+ "name": "stdout",
+ "text": " 1. move(d1,d2->p3)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 2. move(d2,d3->p2)\r\n"
- ]
+ "name": "stdout",
+ "text": " 2. move(d2,d3->p2)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 3. move(d1,p3->d2)\r\n"
- ]
+ "name": "stdout",
+ "text": " 3. move(d1,p3->d2)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 4. move(d3,p1->p3)\r\n"
- ]
+ "name": "stdout",
+ "text": " 4. move(d3,p1->p3)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 5. move(d1,d2->p1)\r\n"
- ]
+ "name": "stdout",
+ "text": " 5. move(d1,d2->p1)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 6. move(d2,p2->d3)\r\n"
- ]
+ "name": "stdout",
+ "text": " 6. move(d2,p2->d3)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 7. move(d1,p1->d2)\r\n"
- ]
+ "name": "stdout",
+ "text": " 7. move(d1,p1->d2)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds explorés (expanded) : 25\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds explorés (expanded) : 25\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds générés (generated) : 26\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds générés (generated) : 26\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "\n",
- "Théorie : 2^3 - 1 = 7 coups optimaux attendus.\r\n"
- ]
+ "name": "stdout",
+ "text": "\nThéorie : 2^3 - 1 = 7 coups optimaux attendus.\r\n"
}
],
"source": [
@@ -940,82 +728,59 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Gripper : transporter 2 balles de roomA vers roomB (2 pinces)\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "Gripper : transporter 2 balles de roomA vers roomB (2 pinces)\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Solution trouvée ! Longueur du plan : 5 action(s)\r\n"
- ]
+ "name": "stdout",
+ "text": "Solution trouvée ! Longueur du plan : 5 action(s)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 1. pick(b1,roomA,g1)\r\n"
- ]
+ "name": "stdout",
+ "text": " 1. pick(b1,roomA,g1)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 2. pick(b2,roomA,g2)\r\n"
- ]
+ "name": "stdout",
+ "text": " 2. pick(b2,roomA,g2)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 3. move(roomA->roomB)\r\n"
- ]
+ "name": "stdout",
+ "text": " 3. move(roomA->roomB)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 4. drop(b1,roomB,g1)\r\n"
- ]
+ "name": "stdout",
+ "text": " 4. drop(b1,roomB,g1)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- " 5. drop(b2,roomB,g2)\r\n"
- ]
+ "name": "stdout",
+ "text": " 5. drop(b2,roomB,g2)\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "==================================================\r\n"
- ]
+ "name": "stdout",
+ "text": "==================================================\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds explorés (expanded) : 25\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds explorés (expanded) : 25\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Nœuds générés (generated) : 26\r\n"
- ]
+ "name": "stdout",
+ "text": "Nœuds générés (generated) : 26\r\n"
}
],
"source": [
@@ -1097,67 +862,49 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Domaine Plan Nœuds explorés Statut\r\n"
- ]
+ "name": "stdout",
+ "text": "Domaine Plan Nœuds explorés Statut\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "------------------------------------------------------------------\r\n"
- ]
+ "name": "stdout",
+ "text": "------------------------------------------------------------------\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Block World (tour 3 blocs) 4 20 RÉSOLU\r\n"
- ]
+ "name": "stdout",
+ "text": "Block World (tour 3 blocs) 4 20 RÉSOLU\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Block World (reverse, 4 blocs) 8 85 RÉSOLU\r\n"
- ]
+ "name": "stdout",
+ "text": "Block World (reverse, 4 blocs) 8 85 RÉSOLU\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Tours de Hanoï (3 disques) 7 25 RÉSOLU\r\n"
- ]
+ "name": "stdout",
+ "text": "Tours de Hanoï (3 disques) 7 25 RÉSOLU\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Gripper (2 balles, 2 pinces) 5 25 RÉSOLU\r\n"
- ]
+ "name": "stdout",
+ "text": "Gripper (2 balles, 2 pinces) 5 25 RÉSOLU\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Lecture : le plan est optimal (BFS), mais 'Nœuds explorés' croît\r\n"
- ]
+ "name": "stdout",
+ "text": "Lecture : le plan est optimal (BFS), mais 'Nœuds explorés' croît\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "exponentiellement avec la taille du domaine — d'où les heuristiques de pyperplan.\r\n"
- ]
+ "name": "stdout",
+ "text": "exponentiellement avec la taille du domaine — d'où les heuristiques de pyperplan.\r\n"
}
],
"source": [
@@ -1233,68 +980,24 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "--- Block World tour (c←b←a) (Fast Downward 24.06.1, astar(lmcut())) ---\r\n",
- "returncode=0 | Coût du plan : 4 | États expansés : 6\r\n",
- " pick-up b\r\n",
- " stack b c\r\n",
- " pick-up a\r\n",
- " stack a b\r\n",
- "Parité from-scratch : BFS trouvait 4 actions → FD coût 4 = PARITÉ CONFIRMÉE\r\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "--- Block World tour (c←b←a) (Fast Downward 24.06.1, astar(lmcut())) ---\r\nreturncode=0 | Coût du plan : 4 | États expansés : 6\r\n pick-up b\r\n stack b c\r\n pick-up a\r\n stack a b\r\nParité from-scratch : BFS trouvait 4 actions → FD coût 4 = PARITÉ CONFIRMÉE\r\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "--- Block World reverse (4 blocs) (Fast Downward 24.06.1, astar(lmcut())) ---\r\n",
- "returncode=0 | Coût du plan : 8 | États expansés : 9\r\n",
- " unstack b a\r\n",
- " put-down b\r\n",
- " pick-up a\r\n",
- " stack a b\r\n",
- " unstack d c\r\n",
- " put-down d\r\n",
- " pick-up c\r\n",
- " stack c d\r\n",
- "Parité from-scratch : BFS trouvait 8 actions → FD coût 8 = PARITÉ CONFIRMÉE\r\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "--- Block World reverse (4 blocs) (Fast Downward 24.06.1, astar(lmcut())) ---\r\nreturncode=0 | Coût du plan : 8 | États expansés : 9\r\n unstack b a\r\n put-down b\r\n pick-up a\r\n stack a b\r\n unstack d c\r\n put-down d\r\n pick-up c\r\n stack c d\r\nParité from-scratch : BFS trouvait 8 actions → FD coût 8 = PARITÉ CONFIRMÉE\r\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "--- Tours de Hanoï (3 disques) (Fast Downward 24.06.1, astar(lmcut())) ---\r\n",
- "returncode=0 | Coût du plan : 7 | États expansés : 14\r\n",
- " move d1 d2 p3\r\n",
- " move d2 d3 p2\r\n",
- " move d1 p3 d2\r\n",
- " move d3 p1 p3\r\n",
- " move d1 d2 p1\r\n",
- " move d2 p2 d3\r\n",
- " move d1 p1 d2\r\n",
- "Parité from-scratch : BFS trouvait 7 actions → FD coût 7 = PARITÉ CONFIRMÉE\r\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "--- Tours de Hanoï (3 disques) (Fast Downward 24.06.1, astar(lmcut())) ---\r\nreturncode=0 | Coût du plan : 7 | États expansés : 14\r\n move d1 d2 p3\r\n move d2 d3 p2\r\n move d1 p3 d2\r\n move d3 p1 p3\r\n move d1 d2 p1\r\n move d2 p2 d3\r\n move d1 p1 d2\r\nParité from-scratch : BFS trouvait 7 actions → FD coût 7 = PARITÉ CONFIRMÉE\r\n\r\n"
},
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "--- Gripper (2 balles, 2 pinces) (Fast Downward 24.06.1, astar(lmcut())) ---\r\n",
- "returncode=0 | Coût du plan : 5 | États expansés : 8\r\n",
- " pick b1 rooma g1\r\n",
- " pick b2 rooma g2\r\n",
- " move rooma roomb\r\n",
- " drop b1 roomb g1\r\n",
- " drop b2 roomb g2\r\n",
- "Parité from-scratch : BFS trouvait 5 actions → FD coût 5 = PARITÉ CONFIRMÉE\r\n",
- "\r\n"
- ]
+ "name": "stdout",
+ "text": "--- Gripper (2 balles, 2 pinces) (Fast Downward 24.06.1, astar(lmcut())) ---\r\nreturncode=0 | Coût du plan : 5 | États expansés : 8\r\n pick b1 rooma g1\r\n pick b2 rooma g2\r\n move rooma roomb\r\n drop b1 roomb g1\r\n drop b2 roomb g2\r\nParité from-scratch : BFS trouvait 5 actions → FD coût 5 = PARITÉ CONFIRMÉE\r\n\r\n"
}
],
"source": [
@@ -1467,11 +1170,9 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Exercice 1 (Tirelire) — à compléter par l'étudiant.\r\n"
- ]
+ "name": "stdout",
+ "text": "Exercice 1 (Tirelire) — à compléter par l'étudiant.\r\n"
}
],
"source": [
@@ -1508,11 +1209,9 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Exercice 2 (Hanoï 4 disques) — à compléter par l'étudiant.\r\n"
- ]
+ "name": "stdout",
+ "text": "Exercice 2 (Hanoï 4 disques) — à compléter par l'étudiant.\r\n"
}
],
"source": [
@@ -1543,11 +1242,9 @@
},
"outputs": [
{
- "name": "stdout",
"output_type": "stream",
- "text": [
- "Exercice 3 (A* avec heuristique naïve) — à compléter par l'étudiant.\r\n"
- ]
+ "name": "stdout",
+ "text": "Exercice 3 (A* avec heuristique naïve) — à compléter par l'étudiant.\r\n"
}
],
"source": [
@@ -1634,4 +1331,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
-}
+}
\ No newline at end of file
diff --git a/scripts/notebook_tools/twin_pairs.d/planners-6-domains/0006-2026-09-12-myia-po-2025-CoursIA-2.yaml b/scripts/notebook_tools/twin_pairs.d/planners-6-domains/0006-2026-09-12-myia-po-2025-CoursIA-2.yaml
new file mode 100644
index 0000000000..39fe7b67ad
--- /dev/null
+++ b/scripts/notebook_tools/twin_pairs.d/planners-6-domains/0006-2026-09-12-myia-po-2025-CoursIA-2.yaml
@@ -0,0 +1,17 @@
+date: '2026-09-12'
+by: myia-po-2025:CoursIA-2
+python_sha: fae03adf2174f9ef984282a16c5e43d3dfc9891c
+csharp_sha: 4b0adfc0b62bd7ddb32a7439088432e5e3cf1cfd
+content_python_sha: 9f6748889b17f6fe1e239d6ff0ec3bce2e02d0c9b5febd06d1e2524ecf491355
+content_csharp_sha: febbe8cbaa7a5772e8254660c67a489a2a3401dc0db450e34b234fb02c970131
+reason: >-
+ Re-attestation cote C# uniquement (EPIC #14122 T7, purge warnings) : ajout de
+ '#nullable enable' en tete de la cellule 2 (modele STRIPS) -- seule cellule
+ source modifiee, les 6 annotations nullable existantes (object?,
+ IEnumerable? x3, State?) etant intentionnelles mais sans directive de
+ contexte (defaut disabled en notebook). Re-execution integrale .net-csharp
+ 11/11, 0 erreur : warnings CS8632 6 -> 0, stdout pedagogiques byte-identiques
+ sur les 11 cellules (plans BFS, compteurs de noeuds, resultats Fast Downward
+ identiques). Axe de parite intact (domaines modelises, BFS from-scratch, pont
+ FD Docker) ; jumeau Python byte-identique. probeAddresses banner strippe
+ (normalisation outillee) avant commit.