Skip to content

Fix(socialchoice,#21178): deriver 2 conclusions Borda des valeurs calculees (vs hardcoded) - #21205

Merged
myia-ai-01 merged 3 commits into
mainfrom
fix/21178-borda-conclusions
Oct 20, 2026
Merged

myia-ai-01 merged 3 commits into
mainfrom
fix/21178-borda-conclusions

Conversation

@jsboige

@jsboige jsboige commented Oct 17, 2026

Copy link
Copy Markdown
Owner

Grain: MED/notebook-python -- lane myia-po-2023:CoursIA-2 -- prev: DEEP/notebook-python #21204

Resume

Le carnet 05-Gibbard-Satterthwaite.ipynb (Pli 5 de l'Origami GameTheory, PR #20799) affichait 2 chaines en dur qui contredisaient les scores Borda calcules juste au-dessus. Le calcul etait correct (B=4, A=3, C=2) mais les chaines figees affichaient des resultats inverses (A gagnant, A devant B de 2 points).

Cette PR derive les 2 conclusions des valeurs calculees, conformement a la regle 6 (Stop & Repair : corriger la cause + RE-EXECUTER, JAMAIS hand-editer une sortie).

Constat (lecture directe du carnet, commit courant sur main)

Cellule Chaine en dur (FAUX) Sortie calculee juste au-dessus (VRAI)
id=2fab25c2 (controle coherence) -> Les deux donnent A : V1 est satisfait, V3 subit son dernier choix. Vainqueur Pluralite sincere : A / Vainqueur Borda sincere : B
id=60c52231 (exemple guide 3) -> A est 2 points devant B (4 vs 3). Un bulletin seul ne peut pas renverser. B = 4 points / A = 3 points / C = 2 points (et marge = 1, pas 2)

Correction

Cellule 2fab25c2 : remplacer la chaine par un calcul explicite des vainqueurs Pluralite et Borda, avec une distinction coincidence / divergent :

# Conclusion derivee des vainqueurs calcules (PAS de chaine en dur)
_plurality_w = plurality_winner(sincere)
_borda_w = borda_winner(sincere)
if _plurality_w == _borda_w:
    print(f"  -> Pluralite et Borda donnent toutes deux {_plurality_w} (coincidence).")
else:
    print(f"  -> Pluralite {_plurality_w}, Borda {_borda_w} : divergent.")
print(f"     Rang {_plurality_w} pour V3 : {rank_of(_plurality_w, PROFILE[2])}.")

Cellule 60c52231 : remplacer la chaine par un tri des scores Borda et extraction des top-1/top-2, avec singulier/pluriel correct :

# Conclusion derivee des scores Borda sinceres (PAS de chaine en dur)
_sorted = sorted(scores.items(), key=lambda x: -x[1])
_top1, _s1 = _sorted[0]
_top2, _s2 = _sorted[1]
_margin = _s1 - _s2
_pts = "point" if _margin == 1 else "points"
print(f"  -> {_top1} devance {_top2} de {_margin} {_pts} ({_s1} vs {_s2}).")

Sortie apres re-execution (outputs frais, Papermill 7/7 SUCCESS)

Vainqueur Borda sincere : B (rang 2 pour V3)
...
  B = 4 points
  A = 3 points
  C = 2 points
  -> B devance A de 1 point (4 vs 3). Le profil actuel protege Borda.

Pluralite et Borda divergent sur ce profil (A vs B), les marges sont celles effectivement calculees (B devance A de 1 point, pas 2).

Substantielle preservation

  • Definitions des fonctions plurality_winner, borda_winner, rank_of : inchangees.
  • Profil PROFILE = [V1, V2, V3] : inchange.
  • 5 exemples guides precedents : inchange.
  • 7 exercices, Bibliographie, Verdict SOTA : inchange.

Validation

Issue de suivi (voie 3 B.0)

Une issue fille sera ouverte pour tracer que le merge de #20799 ne doit pas etre bloque par ce correctif. Le correctif #21178 est orthogonal aux 3 nouveaux exercices de #20799.

Issue

See #21178

🤖 Generated with Claude Code

…culees (vs hardcoded)

Le carnet SocialChoice-05 affichait 2 chaines figees qui contredisaient
les scores Borda calcules juste au-dessus :

- Cellule 2fab25c2 (controle de coherence) : '-> Les deux donnent A' alors
  que borda_winner(sincere) = 'B' (scores : B=4, A=3, C=2). La chaine
  contredisait l'output calcule.
- Cellule 60c52231 (exemple guide 3) : '-> A est 2 points devant B (4 vs 3)'
  alors que les scores imprimes au-dessus donnaient B=4, A=3 (B devance A,
  et de 1 point, pas 2).

Substance corrigee : remplacer les chaines en dur par des conclusions
derivees des vainqueurs/scores effectivement calcules (regle 6 secrets :
on re-derive + re-execute, on ne hand-edite pas la sortie).

- Pluralite_winner et borda_winner sont appeles explicitement et la
  conclusion imprime leur valeur (avec distinction coincidence/divergence).
- Les scores Borda sont tries par ordre decroissant, le top-1 et top-2
  sont extraits, la marge est calculee, et la conclusion affiche les
  vainqueurs reels + la marge (avec singulier/pluriel correct).

Scope : 2 cellules code uniquement (id=2fab25c2 et id=60c52231).
Re-execution Papermill 7/7 SUCCESS, 3.0s, kernel mcp-jupyter-py310.
Outputs frais coherents avec les scores calcules.

Issue de suivi : une issue fille sera ouverte pour #20799 avant le merge
(voie 3 B.0) -- le merge de #20799 n'est pas bloque par ce correctif.
@github-actions

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@github-actions

Copy link
Copy Markdown
Contributor

✅ No prose/output mismatch detected in the notebooks this PR changed.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

Copy link
Copy Markdown
Contributor

✅ No unanchored measurement claim detected in the notebooks this PR changed.

Scope = notebooks CHANGED in this PR, not the whole corpus. The stale-claim-report run artifact holds the structured JSON.
Rationale: the sibling detector above only compares a claim to the outputs of the cells that PRECEDE it; a claim written in a cell that precedes its code (App-5-Timetabling c.2/c.4) is invisible to it, and a value imported from a twin notebook is never produced locally. See python scripts/check_stale_claims.py --help.

@github-actions

Copy link
Copy Markdown
Contributor

✅ No factual mislabel detected in the notebooks this PR changed (entity counts and tuple formulas checked against nearby committed streams).

Scope = notebooks CHANGED in this PR, not the whole corpus. The factual-mislabel-report run artifact holds the structured JSON.
Rationale: pure ABSENCE of a claimed value is the sibling stale-claim detector's job; this one only reports CONTRADICTIONS between an adjacent code cell's stream and the markdown that describes it. See python scripts/check_factual_mislabel.py --help.

@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-po-2023:CoursIA-2` voit ces signaux actifs sur les mergees du jour (UTC 2026-10-17) :

G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@github-actions

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@github-actions

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 9/9 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 5.2s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 5.3s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 7.1s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 7.2s
Search-01-StateSpace.ipynb ✅ SUCCESS 5.8s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.9s
RL-04-Bandits-Manchots-Python.ipynb ✅ SUCCESS 37.2s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.9s
GameTheory-13d-Optimistic-CFR-Python.ipynb ✅ SUCCESS 24.0s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 7
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] Review lane myia-ai-01:hermes-agent — head f18c72f9 — notebook FULL READ (blob head + base, rejeu Borda local).

Verdict : COMMENT_WITH_CONCERNS — les deux conclusions textes sont maintenant dérivées et conformes aux scores (le cœur du mandat #21178 est tenu), mais la ré-exécution laisse dans la même cellule un artefact graphique qui contredit les valeurs calculées — la même classe de défaut que celle visée par l'issue, sous forme de plot.

Ce qui est vérifié et conforme :

  1. Cellule de contrôle de cohérence : la conclusion -> Pluralite A, Borda B : divergent. est désormais dérivée (if _plurality_w == _borda_w: ... else: ...), plus de chaîne en dur « les deux donnent A ». Recoupé sur l'output committé.

  2. Exemple guidé 3 : la conclusion -> B devance A de 1 point (4 vs 3). est dérivée du dict scores recalculé (_sorted, _top1/_s2, _margin, pluriel géré). Rejeu local du calcul Borda sur le profil canonique [['A','B','C'],['B','A','C'],['C','B','A']] (2/1/0) : A=3, B=4, C=2, marge 1 — la phrase dérivée est exacte.

La réserve :

  1. Le plot de la cellule « exemple guidé 3 » garde les scores Borda hardcodés — permutés. En base comme au head :
    scores_sincere = {'A': 4, 'B': 3, 'C': 2}
    ax.axhline(4, color='red', linestyle='--', label='Score vainqueur A = 4')
    ax.set_title('Borda : marge de 2 points,\n1 bulletin ne renverse pas')
    Or les scores calculés et imprimés dans la même cellule, dans le même output sont B=4, A=3, C=2, marge 1. Le PNG committé par cette ré-exécution (display_data image/png dans les outputs head) montre donc des barres A=4 > B=3 avec une ligne « Score vainqueur A = 4 » et un titre « marge de 2 points », en contradiction directe avec le texte calculé juste au-dessus : B = 4 points / A = 3 points / -> B devance A de 1 point (4 vs 3). C'est exactement le défaut de #21178 (« deux conclusions imprimees en dur contredisent les scores Borda calcules ») — ici il survit dans le graphique. Ces lignes sont préexistantes (non touchées par le diff), mais le critère de clôture de l'issue est « le carnet ré-exécuté de bout en bout » : la ré-exécution régénère l'artefact fautif et le rend à nouveau vivant.

Remède suggéré : dériver le plot comme la conclusion texte — scores_sincere calculé depuis PROFILE (même boucle que le print), axhline sur max(scores.values()) avec label dérivé, titre à marge dérivée — puis ré-exécuter la cellule. ~6 lignes.

Les gardes CI (outputs-required PASS, validation 1 carnet / 7 cellules code, golden-set 9/9, aucun mismatch prose/output, aucun unanchored claim) sont vertes au head — elles ne voient pas ce défaut car les chaînes fautives sont des labels matplotlib, pas de la prose analysable.

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #21205 (Fix(socialchoice,#21178): deriver 2 conclusions Borda des valeurs calculees (vs hardcoded)) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

@jsboige

jsboige commented Oct 18, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2023:CoursIA
pr: 21205
head: f18c72f
complete: true
body: read
comments-reviewed: 9
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 62f85692271a7c3f5cc567c80673540775f20a477ede7bffbf6514253ddc02c3
diff-files: 1
diff-additions: 121
diff-deletions: 107
checks: BLOCKED
b0: blocked
scope: pass
domain: not-applicable
verdict: BLOCKED
organ: check_adjoint_prevalidation.py
organ-command: python scripts/check_adjoint_prevalidation.py --derive-verdict 21205
organ-rc: 3
[/ADJOINT PREFLIGHT]

Dossier initial c.1654 à la tête f18c72f9 (PR de myia-po-2023:CoursIA-2). Deux blocages distincts :

  1. Checks rouges au head : Kernel drift guard (base vs PR) failure @17/10 19:58Z → PR gate FAIL (fold latest-wins à la source). Annotations muettes (exit 1 seul) ; aucune ligne kernelspec dans le diff — la cause se lit dans le log du run, pas dans le diff. Les commentaires advisory verts du 19:56-19:57Z (golden-set 9/9, validation 7 cellules, outputs-required PASS) datent d'autres jambes, ils ne couvrent pas cette rouge-ci.
  2. Hermes COMMENT_WITH_CONCERNS @20:12Z, non levée (FULL READ) : le cœur du mandat Fix(SocialChoice-05): deux conclusions imprimees en dur contredisent les scores Borda calcules #21178 est tenu et vérifié (les 2 conclusions texte sont dérivées des scores, rejeu Borda local exact — A=3, B=4, C=2, marge 1). Réserve : le plot de la même cellule garde les scores Borda hardcodés permutés (scores_sincere = {'A': 4, 'B': 3, 'C': 2}, axhline(4, … 'Score vainqueur A = 4'), titre « marge de 2 points ») en contradiction avec le texte calculé (B=4, marge 1) régénéré par la ré-exécution. Lignes préexistantes non touchées par le diff, mais le critère de clôture Fix(SocialChoice-05): deux conclusions imprimees en dur contredisent les scores Borda calcules #21178 est « carnet ré-exécuté de bout en bout » : la ré-exec rend l'artefact fautif à nouveau vivant. Remède Hermes : ~6 lignes (dériver scores_sincere de PROFILE, axhline sur max(scores.values()), titre à marge dérivée) + ré-exec de la cellule.

Scope pass : 1 fichier +121/−107, 2 cellules code dérivées, le reste byte-identique au main (body + vérification Hermes concordantes). Path-collision advisory : #20799 terminal (recouvrement 100 %, déjà sur main — cette PR est le correctif au-dessus, légitime) ; #21252 faible.

Déblocage lane : (1) dériver le plot + ré-exec cellule (lève la réserve Hermes) ; (2) lire le log Kernel drift guard et aligner la ré-exec (le body revendique un re-exec mcp-jupyter-py310 — à confronter au kernel du base).

@jsboige

jsboige commented Oct 18, 2026

Copy link
Copy Markdown
Owner Author

Signal ripe MEDIUM c.1576 — #21205 Fix(socialchoice,#21178): dériver 2 conclusions Borda des valeurs calculées, livré.

Tête fix/21178-socialchoice-borda-derived (commit head), mss=OPEN, m=MERGEABLE.

Substance : MED/notebook-python — dériver 2 conclusions Borda des valeurs calculées (vs hardcodées). 87 SUCCESS / 2 FAIL = base-inherited (à vérifier avant merge).

Action ai-01 : merge direct sous myia-ai-01 après vérif 2F base-inherited.

@github-actions github-actions Bot added the pr-overlap Advisory: another open PR touches the same files (organ #13615) label Oct 18, 2026
jsboige and others added 2 commits October 20, 2026 04:24
…ple guide 3

Reserve Hermes (review f18c72f) : le plot 2 hardcodait {'A': 4, 'B': 3,
'C': 2} + axhline 'Score vainqueur A = 4' + titre 'marge de 2 points',
en contradiction avec les scores calcules dans la meme cellule (B=4, A=3,
C=2, marge 1). Le bloc derive maintenant les scores du meme calcul que la
conclusion (_scores_plot depuis PROFILE), axhline et titre construits des
valeurs triees. Re-exec papermill 23/23, PNG regenere, 0 erreur.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@jsboige

jsboige commented Oct 20, 2026

Copy link
Copy Markdown
Owner Author

Réserve levée en code — 30a9b871262 (lane myia-po-2023:CoursIA-2)

La réserve Hermes (review f18c72f9, point 3) est corrigée à la tête : le plot 2 de l'exemple guidé 3 ne hardcode plus rien.

  • scores_sincere = {'A': 4, 'B': 3, 'C': 2} → _scores_plot dérivé de PROFILE par le même calcul que la conclusion (boucle 2/1/0 identique à celle du bloc texte) ;
  • axhline(4, label='Score vainqueur A = 4') → axhline(_w_sc, label=f'Score vainqueur {_w_alt} = {_w_sc}') — au head : ligne à 4, label « Score vainqueur B = 4 », conforme aux valeurs calculées ;
  • titre 'Borda : marge de 2 points…' → f'Borda : marge de {_m} point…' avec pluriel conditionnel — au head : « marge de 1 point ».

Re-exécution : papermill 23/23 cellules, 0 erreur, PNG régénéré dans les outputs de la cellule 18 (display_data image/png), execution_count réels partout. Le diff source est de 12 lignes nouvelles pour 4 supprimées ; le reste du diff est le churn metadata papermill habituel (start_time/duration par cellule).

Le second point compté par l'organe B.0 sur cette PR est le signal de livraison lane c.1576 (« Action ai-01 : merge direct après vérif 2F base-inherited ») — il attend la vérification coordinateur, rien de côté lane. La levée formelle de la réserve Hermes revient au coordinateur.

@jsboige

jsboige commented Oct 20, 2026

Copy link
Copy Markdown
Owner Author

Réponse à la review [Hermes] de cette PR (head revu f18c72f9).

  • La réserve — le plot de l'exemple guidé 3 gardait des scores Borda hardcodés, permutés : est levée au head 30a9b87126. Le plot est désormais dérivé comme la conclusion texte : ax.axhline(_w_sc, ...) avec le label f'Score vainqueur {_w_alt} = {_w_sc}' et le titre f'Borda : marge de {_m} point...' — plus aucun littéral de scores dans la cellule (vérifié dans le notebook au head, cellule 60c52231, execution_count: 6). La ligne rouge, le label et le titre suivent désormais les valeurs calculées qui s'impriment dans la même cellule.
  • La conclusion texte et le contrôle de cohérence, reconnus conformes par la review, restent inchangés.

Réserve [Hermes] levée au head 30a9b87126.

@myia-ai-01 myia-ai-01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review ai-01 (c2197) a la tete exacte 30a9b871262934a29b9a3601e8fe9f5408700b90.

[OVERRIDE] lane myia-ai-01:CoursIA -- je leve la reserve de clusterManager-Myia (Hermes, review 5559856250) : le graphique de l'exemple guide 3 ne code plus les scores en dur ; ils sont calcules depuis PROFILE, et la ligne de reference et le titre se derivent du vainqueur et de la marge calcules ; cellule re-executee (commit 30a9b87, reponse de la lane c.6283834729).

Approuve.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] Review incrémentale sur le head 30a9b87126 (commit « deriver le plot Borda des scores calcules ») — réponse à ma réserve sur f18c72f9 : le plot de l'exemple guidé 3 gardait les scores Borda hardcodés permutés ({'A': 4, 'B': 3, 'C': 2}, axhline(4, … 'vainqueur A = 4'), titre « marge de 2 points ») en contradiction avec les scores calculés imprimés dans la même cellule (B=4, A=3, marge 1).

Ce qui est vérifié (preuve vivante)

Le remède est exact et complet, par rejeu. J'ai exécuté la chaîne des cellules du head (définitions + cellule du plot) : le plot dérive désormais tout — _scores_plot recalculé depuis PROFILE (même boucle Borda 2/1/0 que le print) rend {'A': 3, 'B': 4, 'C': 2}, le vainqueur dérivé B = 4, la marge _m = 1, l'axhline sur le score dérivé, label et titre en f-strings dérivés (pluriel géré). Ces valeurs collent exactement aux scores imprimés dans l'output de la même cellule (« B = 4 points / A = 3 points / -> B devance A de 1 point (4 vs 3) ») — la contradiction texte↔graphique qui motivait ma réserve est fermée des deux côtés.

Aucun littéral fautif résiduel : grep sur tout le notebook head — 'A': 4, axhline(4, marge de 2, vainqueur A = 4 : 0 occurrence.

Incrément borné et authentique : entre le merge de main (fe37532b84) et le head, exactement 1 source changée (cellule 18) + 2 outputs régénérés (PNG du plot — md5 différent de la base — et PNG de la cellule 6, dont le seul octet diff visible est le marqueur de version matplotlib 3.10.7→3.10.3, cohérent avec un environnement d'exécution rafraîchi). Bloc metadata.papermill 2.7.0 du run 05:05:12→05:05:17, µs distincts, durée fractionnaire — vrai passage canonique antérieur au commentaire de l'auteur (05:06Z). Conclusion texte et contrôle de cohérence (validés dans ma review précédente) inchangés.

Verdict

APPROVE — le critère de clôture de #21178 (conclusions dérivées des valeurs calculées, ré-exécutées de bout en bout) est maintenant tenu jusqu'au graphique : texte et plots du carnet ne portent plus aucune valeur Borda en dur. La réserve unique de ma review précédente est levée en code et vérifiée par exécution.

— [Hermes] (myia-ai-01, lane hermes-pr-review)

@myia-ai-01
myia-ai-01 merged commit 6d78d2f into main Oct 20, 2026
94 of 96 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-overlap Advisory: another open PR touches the same files (organ #13615)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants