From a62db79b917db5582cf7f688efe33a26b9a7e594 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 10:16:08 +0000 Subject: [PATCH] =?UTF-8?q?=C3=89carter=20la=20s=C3=A9ance=20douteuse,=20p?= =?UTF-8?q?as=20tout=20l'incr=C3=A9ment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VOTRE CLÉ EST EN PLACE — le journal de l'exécution #9 affiche « CLE_PRESENTE: true » — et le garde-fou de la séance republiée a mordu en production dès son premier passage : il a refusé l'artefact du 6 août, qui dort encore chez GitHub pour trente jours. C'est en lisant ce journal qu'un défaut de conception est apparu. Le refus était TOUT OU RIEN. Ce soir à 16 h 45, l'incrément aurait porté la séance du jour ET le 6 août empoisonné, et tout aurait été refusé. Un seul artefact fautif aurait bloqué le versement chaque jour pendant un mois, sans que personne ait le temps d'aller le retirer. Deux niveaux désormais : `refus` met en cause l'incrément entier — en-têtes différents, lignes déjà présentes, lignes antérieures sur des séances connues. Ce sont des signaux de dysfonctionnement, pas des données douteuses, et rien ne s'écrit. `quarantaine` porte les séances individuellement suspectes : séance republiée, clôture nulle ou négative. La séance est écartée, le reste est versé, et le journal dit lesquelles et pourquoi. Éprouvé sur la vraie donnée, en mélangeant l'incrément fautif du 6 août avec une séance saine : les 47 lignes du 6 sont retirées, les 5 de la séance saine sont versées. Dix-huit cas au harnais, dont les deux qui bornent le nouveau comportement — une fautive et une bonne dans le même lot, et une fautive seule dont il ne subsiste rien. CE QUI RESTE NON PROUVÉ : la signature elle-même. L'étape « Signer et verser » n'a jamais tourné, faute d'avoir eu quelque chose de valide à verser. La première vraie occasion est l'ingestion de ce lundi, versée à 16 h 45 UTC. C'est ce commit-là qu'il faudra regarder — il doit porter « Verified » et l'auteur « versement automatique ». Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Mu7CkW6727S9ZyRbiYyRk9 --- .github/workflows/versement.yml | 44 +++++++++++++++++++++++++++------ README.md | 8 ++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.github/workflows/versement.yml b/.github/workflows/versement.yml index 59d3c92..5e0be14 100644 --- a/.github/workflows/versement.yml +++ b/.github/workflows/versement.yml @@ -288,6 +288,7 @@ jobs: incr = [l.rstrip("\n") for l in f if l.strip()] refus = [] + quarantaine: dict[str, list[str]] = {} if tete != entete: refus.append(f"en-têtes différents : {tete!r} vs {entete!r}") @@ -331,6 +332,8 @@ jobs: valeur = float(cloture) if valeur <= 0: absurdes.append(f"{date} {ticker} {valeur}") + quarantaine.setdefault(date, []).append( + f"clôture {valeur} sur {ticker}") veille = derniers.get(ticker) if veille: ecart = valeur / veille - 1 @@ -338,8 +341,8 @@ jobs: hors.append(f"{date} {ticker} {ecart:+.2%}") derniers[ticker] = valeur if absurdes: - refus.append(f"{len(absurdes)} clôtures nulles ou négatives : " - + ", ".join(absurdes[:5])) + print(f"{len(absurdes)} clôtures nulles ou négatives : " + + ", ".join(absurdes[:5])) # LA SÉANCE REPUBLIÉE, ET J'EN AI VERSÉ UNE. Le 6 août 2026 a été # « rattrapé » par rapatriement, et les 47 lignes obtenues étaient @@ -374,10 +377,10 @@ jobs: repetees = sum(1 for t, v, c in valeurs if derniers_volumes.get(t) == (v, c)) if repetees >= 0.9 * len(valeurs): - refus.append( - f"séance {date} : {repetees}/{len(valeurs)} valeurs au " - "volume ET au cours identiques à leur séance " - "précédente — séance republiée, pas une séance neuve") + quarantaine.setdefault(date, []).append( + f"{repetees}/{len(valeurs)} valeurs au volume ET au " + "cours identiques à leur séance précédente — séance " + "republiée, pas une séance neuve") # LA LIMITE DE ±7,5 % EST DÉCRITE, JAMAIS OPPOSÉE, et ce n'est pas # de la mollesse — c'est ce que le projet a MESURÉ. Sur l'archive, @@ -400,8 +403,21 @@ jobs: f"({', '.join(hors[:5])}) — décrites, pas opposées. " "« brvm qualite » les range par cause probable.") + # DEUX NIVEAUX DE REFUS, ET LE DEUXIÈME EST NÉ D'UN DÉFAUT RÉEL. + # + # `refus` porte ce qui met en cause l'incrément ENTIER : en-têtes + # différents, lignes déjà présentes, lignes antérieures sur des + # séances connues. Ce sont des signaux de dysfonctionnement, pas + # des données douteuses, et rien ne doit s'écrire. + # + # `quarantaine` porte les séances individuellement suspectes. Le + # tout ou rien s'y montrait ruineux : le 6 août republié dort dans + # un artefact pendant trente jours, et il aurait bloqué CHAQUE + # versement suivant — la bonne séance du jour refusée avec lui, le + # pipeline arrêté par une seule donnée fautive que personne n'a le + # temps de retirer. On écarte donc la séance, et on verse le reste. if refus: - print("VERSEMENT REFUSÉ :") + print("VERSEMENT REFUSÉ EN BLOC :") for motif in refus: print(f" - {motif}") print("\nL'incrément part dans le journal ; à verser à la main " @@ -409,6 +425,20 @@ jobs: sortie(applique="false", motif="controle") raise SystemExit(0) + if quarantaine: + print("SÉANCES ÉCARTÉES, le reste est versé :") + for date, motifs in sorted(quarantaine.items()): + for motif in motifs: + print(f" - {date} : {motif}") + avant = len(incr) + incr = [l for l in incr if cle(l)[0] not in quarantaine] + print(f" {avant - len(incr)} lignes retirées de l'incrément.") + if not incr: + print("\nRien ne subsiste : l'incrément part dans le " + "journal, à examiner.") + sortie(applique="false", motif="quarantaine") + raise SystemExit(0) + # LA GARANTIE N'EST PLUS « ÇA S'AJOUTE EN QUEUE » : combler un trou # insère au milieu. Ce qui doit rester vrai, et qui est vérifié # ici, c'est que la fusion est triée, qu'elle ne perd aucune ligne diff --git a/README.md b/README.md index a53778d..9f59cc3 100644 --- a/README.md +++ b/README.md @@ -458,6 +458,14 @@ ressusciter 38 séances fantômes — tri préservé, aucune clôture nulle ou négative, et **aucune séance republiée**. Un seul contrôle qui tombe annule le versement. +**Une séance douteuse n'arrête pas les autres.** Ce qui met en cause +l'incrément entier — en-têtes, lignes déjà présentes, lignes antérieures +sur une séance connue — bloque tout : ce sont des signaux de +dysfonctionnement. Une séance individuellement suspecte, elle, est +**écartée seule** et le reste est versé. Le tout ou rien s'est montré +ruineux : un artefact fautif vit trente jours, et il aurait bloqué chaque +versement suivant — la bonne séance du jour refusée avec lui. + La séance republiée mérite son nom : le 6 août 2026, rattrapé par rapatriement, est revenu avec les 47 cours et les 47 volumes du 7 — la même séance sous une autre date. Versée, elle a mis toutes les variations