P03 : la preuve du diff-vide peut enfin echouer — et elle echoue
instancier.py comparer affichait l'ecart puis renvoyait TOUJOURS 0. P03 « Diff-vide du plan » ne pouvait donc pas echouer : elle est passee au vert pendant que quatorze hotes divergeaient du plan. Deux appelants, deux besoins — d'ou un MODE plutot qu'un changement de comportement : `make instancier` est une INSPECTION (voir le diff avant de decider ; un code d'erreur y transformerait la lecture en panne), P03 est une AFFIRMATION (« le plan reproduit l'inventaire »). prouver sort desormais a 1, et c'est EXACT : depuis le retrait du decalage de +10, le plan derive 10.17.x.x tandis que l'inventaire applique — et les quatorze VM qui tournent — portent 10.27.x.x. Le depot est sciemment dans cet etat jusqu'au renumerotage. Une preuve rouge qui dit vrai vaut mieux qu'une verte qui ne regarde rien. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
8b4ad276ca
commit
2c7849f6b3
3 changed files with 39 additions and 7 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
|
@ -1,5 +1,23 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-08-12 — P03 peut enfin échouer, et elle échoue
|
||||
|
||||
`instancier.py comparer` affichait l'écart puis renvoyait **toujours `0`**. La preuve P03
|
||||
« Diff-vide du plan » ne pouvait donc pas échouer : elle a passé au vert pendant que
|
||||
quatorze hôtes divergeaient du plan.
|
||||
|
||||
Deux appelants, deux besoins — d'où un mode plutôt qu'un changement de comportement :
|
||||
|
||||
| Appelant | Attente |
|
||||
|---|---|
|
||||
| `make instancier` | **inspection** : voir le diff avant de décider. Un code d'erreur y transformerait la lecture en panne |
|
||||
| **P03** | **affirmation** : « le plan reproduit l'inventaire ». Sans `--strict`, elle n'affirmait rien |
|
||||
|
||||
**`prouver` sort désormais à 1**, et c'est exact : depuis le retrait du décalage de `+10`,
|
||||
le plan dérive `10.17.x.x` tandis que l'inventaire appliqué — et les quatorze VM qui
|
||||
tournent — portent `10.27.x.x`. Le dépôt est sciemment dans cet état jusqu'au
|
||||
renumérotage. Une preuve rouge qui dit vrai vaut mieux qu'une verte qui ne regarde rien.
|
||||
|
||||
## 2026-08-12 — L'index est borné : `10.300.0.0/16` n'est pas un réseau
|
||||
|
||||
Rien ne bornait `index`. `supernet_de(300)` rendait `"10.300.0.0/16"` — **une chaîne qui
|
||||
|
|
|
|||
|
|
@ -296,14 +296,26 @@ def compter_ecarts(reference: Path, genere: Path) -> int:
|
|||
return ecarts
|
||||
|
||||
|
||||
def comparer() -> int:
|
||||
def comparer(strict: bool = False) -> int:
|
||||
"""Compare le genere a l'applique. `strict` fait ECHOUER sur un ecart.
|
||||
|
||||
DEUX APPELANTS, DEUX BESOINS. `make instancier` est une INSPECTION : on veut voir
|
||||
le diff avant de decider, et un code d'erreur y transformerait la lecture en panne.
|
||||
La preuve P03, elle, AFFIRME que « le plan reproduit l'inventaire » — sans `strict`,
|
||||
elle renvoyait 0 quel que soit le nombre d'hotes divergents et ne pouvait donc pas
|
||||
echouer. Constate le 2026-08-12 : quatorze hotes divergeaient, la preuve passait.
|
||||
"""
|
||||
ecrire(GENERE)
|
||||
ecarts = compter_ecarts(INVENTAIRE, GENERE)
|
||||
if ecarts == 0:
|
||||
print("DIFF VIDE : le plan reproduit exactement l'inventaire actuel. Bascule possible.")
|
||||
else:
|
||||
print(f"\n{ecarts} hote(s) avec ecart.")
|
||||
return 0
|
||||
return 0
|
||||
print(f"\n{ecarts} hote(s) avec ecart.")
|
||||
if strict:
|
||||
print("L'inventaire APPLIQUE ne correspond plus au plan. Soit le plan a change et "
|
||||
"il faut le basculer (`make instancier-appliquer`), soit hosts.yml a ete "
|
||||
"edite a la main — ce que le depot interdit.")
|
||||
return 1 if strict else 0
|
||||
|
||||
|
||||
def appliquer(force: bool = False) -> int:
|
||||
|
|
@ -325,7 +337,9 @@ def main() -> int:
|
|||
parser = argparse.ArgumentParser(description="Generateur d'inventaire Set-OPS (Phase 3).")
|
||||
sub = parser.add_subparsers(dest="commande", required=True)
|
||||
sub.add_parser("generer", help="Ecrit hosts.genere.yml depuis le plan.")
|
||||
sub.add_parser("comparer", help="Compare le genere a l'inventaire actuel (semantique).")
|
||||
sp_cmp = sub.add_parser("comparer", help="Compare le genere a l'inventaire actuel (semantique).")
|
||||
sp_cmp.add_argument("--strict", action="store_true",
|
||||
help="Sortir en erreur si le diff n'est pas vide (P03).")
|
||||
pa = sub.add_parser("appliquer", help="Ecrit hosts.yml depuis le plan (refuse si diff non vide).")
|
||||
pa.add_argument("--force", action="store_true", help="Applique meme si le diff n'est pas vide.")
|
||||
args = parser.parse_args()
|
||||
|
|
@ -334,7 +348,7 @@ def main() -> int:
|
|||
ecrire()
|
||||
print(f"{os.path.relpath(GENERE, RACINE)} genere depuis le plan.")
|
||||
elif args.commande == "comparer":
|
||||
return comparer()
|
||||
return comparer(strict=getattr(args, "strict", False))
|
||||
elif args.commande == "appliquer":
|
||||
return appliquer(force=args.force)
|
||||
except Exception as exc:
|
||||
|
|
|
|||
|
|
@ -703,7 +703,7 @@ PREUVES: list[dict] = [
|
|||
{"id": "P03", "titre": "Diff-vide du plan (inventaire genere)", "refs": ["AFF-001", "AFF-004", "AFF-030", "AFF-031", "AFF-032"],
|
||||
"refs": ["AFF-001", "AFF-004", "AFF-030", "AFF-031", "AFF-032"],
|
||||
"cmds": [[sys.executable, "scripts/instancier.py", "generer"],
|
||||
[sys.executable, "scripts/instancier.py", "comparer"]]},
|
||||
[sys.executable, "scripts/instancier.py", "comparer", "--strict"]]},
|
||||
{"id": "P04", "titre": "Groupes <-> playbooks homonymes", "refs": ["AFF-008"],
|
||||
"cmds": [[sys.executable, "scripts/inventory_host.py", "--inventaire", INV,
|
||||
"verifier-playbooks", "--dossier-playbooks", GROUPES]]},
|
||||
|
|
|
|||
Loading…
Reference in a new issue