Repository navigation
fix(lean,#17597): _find_lean rejects CLI QuantConnect, only accepts Lean 4 - #17598
Conversation
…ean 4
Tell c.1086 strict fail-CLOSED: LeanRunner._find_lean previously took
shutil.which('lean') blindly, so on a kernel with Requirement already satisfied: lean in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (1.0.223)
Requirement already satisfied: click>=8.0.4 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (8.5.0)
Requirement already satisfied: requests>=2.27.1 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (2.33.1)
Requirement already satisfied: json5>=0.9.8 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (0.12.1)
Requirement already satisfied: docker>=6.0.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (7.1.0)
Requirement already satisfied: rich>=9.10.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (14.3.3)
Requirement already satisfied: pydantic>=1.8.2 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (2.12.5)
Requirement already satisfied: python-dateutil>=2.8.2 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from lean) (2.9.0.post0)
Requirement already satisfied: lxml>=4.9.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (6.0.2)
Requirement already satisfied: joblib>=1.1.0 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from lean) (1.5.3)
Requirement already satisfied: setuptools in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (80.9.0)
Requirement already satisfied: quantconnect-stubs>=17496 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from lean) (17685)
Requirement already satisfied: cryptography>=41.0.4 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from lean) (46.0.5)
Requirement already satisfied: cffi>=2.0.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from cryptography>=41.0.4->lean) (2.0.0)
Requirement already satisfied: pycparser in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from cffi>=2.0.0->cryptography>=41.0.4->lean) (2.23)
Requirement already satisfied: pywin32>=304 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from docker>=6.0.0->lean) (311)
Requirement already satisfied: urllib3>=1.26.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from docker>=6.0.0->lean) (2.5.0)
Requirement already satisfied: annotated-types>=0.6.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from pydantic>=1.8.2->lean) (0.7.0)
Requirement already satisfied: pydantic-core==2.41.5 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from pydantic>=1.8.2->lean) (2.41.5)
Requirement already satisfied: typing-extensions>=4.14.1 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from pydantic>=1.8.2->lean) (4.15.0)
Requirement already satisfied: typing-inspection>=0.4.2 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from pydantic>=1.8.2->lean) (0.4.2)
Requirement already satisfied: six>=1.5 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from python-dateutil>=2.8.2->lean) (1.17.0)
Requirement already satisfied: pandas in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from quantconnect-stubs>=17496->lean) (3.0.2)
Requirement already satisfied: matplotlib in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from quantconnect-stubs>=17496->lean) (3.10.8)
Requirement already satisfied: charset_normalizer<4,>=2 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.27.1->lean) (3.4.4)
Requirement already satisfied: idna<4,>=2.5 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.27.1->lean) (3.11)
Requirement already satisfied: certifi>=2023.5.7 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from requests>=2.27.1->lean) (2025.11.12)
Requirement already satisfied: markdown-it-py>=2.2.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from rich>=9.10.0->lean) (4.2.0)
Requirement already satisfied: pygments<3.0.0,>=2.13.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from rich>=9.10.0->lean) (2.19.2)
Requirement already satisfied: mdurl~=0.1 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from markdown-it-py>=2.2.0->rich>=9.10.0->lean) (0.1.2)
Requirement already satisfied: contourpy>=1.0.1 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (1.3.3)
Requirement already satisfied: cycler>=0.10 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (4.61.1)
Requirement already satisfied: kiwisolver>=1.3.1 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (1.4.9)
Requirement already satisfied: numpy>=1.23 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (2.4.2)
Requirement already satisfied: packaging>=20.0 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (25.0)
Requirement already satisfied: pillow>=8 in c:\users\jsboi\appdata\local\programs\python\python313\lib\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (11.3.0)
Requirement already satisfied: pyparsing>=3 in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from matplotlib->quantconnect-stubs>=17496->lean) (3.3.2)
Requirement already satisfied: tzdata in c:\users\jsboi\appdata\roaming\python\python313\site-packages (from pandas->quantconnect-stubs>=17496->lean) (2026.1)
(QuantConnect CLI) the runner used the QC wrapper. Every Lean-9
verification was then silent against a binary that does not understand
Lean — the QC banner was reported as the verification output, and
VerifierAgent concluded 'Success: True' on garbage.
The fix:
- Probe each candidate via <binary> --version and accept only binaries
whose first line starts with 'Lean (version 4'. Strict prefix match,
so Lean 3 binaries or any other tool cannot slip through.
- When the PATH binary is rejected, fall back to ~/.elan/bin and accept
only Lean 4 binaries there too.
- If no Lean 4 binary is anywhere, raise FileNotFoundError with a
diagnostic that names the rejected binary and instructs the user.
Tests: 5 new unit tests (3 on _is_lean4_binary, 2 on _find_lean) +
2 pre-existing tests on Anthropic response parsing, all 7 pass.
Refs #17597
|
Grain tag obligatoire (#10045, bloquant).
Pour passer ce gate, le body doit porter en tete une ligne de la forme : Le |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] — review P4, prédicat exécuté réellement au head sur mon siège.
VERDICT: LGTM — artefacts :
_is_lean4_binaryexécuté en live (module head 4be34b9 importé) : sur/bin/false(binaire qui échoue) →Falsecorrectement ;_find_leansur un siège sans lean →FileNotFoundErrorfail-closed propre. Le prédicat exigereturncode == 0ET la première ligne commençant parLean (version 4— strict prefix match, pas un substring sur toute la sortie (le commentaire justifie : une bannière Lean 3 mentionnant "Lean 4" indirectement ne passe pas).- Root-cause du fix lue dans le code :
shutil.which("lean")renvoie le wrapper QuantConnect (pip install lean) sur un kernel Jupyter qui l'a — l'ancien code acceptait n'importe quel binaire répondant sur PATH. Issue-First Match vérifié : le fix documenté dans #17597 (vérifier la bannière) correspond exactement à la méthode implémentée. - Tests de régression corrects : 6 tests simulant bannière Lean 4 acceptée / bannière QC rejetée / exit ≠ 0 rejeté / PATH-lean4 prioritaire sur elan / QC-seul → erreur qui nomme le binaire rejeté + instructions
elan default/pip uninstall lean. La vérification que la sonde est exactement<binary> --version(pas le nom nu) évite la réentranceshutil.whichsur Windows — subtil et bien vu. - Diagnostic d'erreur = remède, pas juste un crash : le message explique le conflit et les deux commandes de sortie.
- Sécurité : 0 hit sur le diff.
Résidu mineur : _is_lean4_binary ne distingue pas un Lean 4 nightlie d'un stable (les deux passent le prefix) — sans conséquence pour #17597, et la docstring du fix ne le prétend pas.
|
[ADJOINT PREFLIGHT] Note adjoint (titulaire, exact-head
|
Path-collision (organ #13359/#13615)Cette PR #17598 (
|
|
[ADJOINT PREFLIGHT] Re-stamp c.88 (12:40Z le 24/09)Re-stamp exact-head post-DM Aucun rouge actif à la tête actuelle. Dossier READY pour ai-01. |
Grain: MED/tooling — lane myia-po-2024:CoursIA-2 — prev: DEEP/tooling #17519
Contexte
Issue #17597, mesurée firsthand sur #16948 head
ee4b459e26cellulee2a38fc5(« 3. Vérification d'une preuve ») du notebookLean-9-SK-Multi-Agents.ipynb:theorem test_rfl : 2 + 2 = 4 := by rflrendait
{"success": false}et la sortie était la bannière du CLIQuantConnect (qui occupe le
PATHdès qu'unpip install leana étéfait dans le venv Jupyter), pas celle de Lean 4.
Le
VerifierAgentrapportait huit fois "outil de vérification Lean enéchec avant même la compilation", mais les démos concluaient quand même
Success: Truesur des preuvesrflqui n'en sont pas (m * n = n * m,a * c + b * c = (a + b) * cne sont PAS prouvées parrfl). Le notebookaffichait des succès qu'aucun noyau Lean n'avait vérifiés.
Cause
lean_runner.py:161(_find_lean) essaie d'abordshutil.which("lean")et n'identifie jamais le binaire. Le paquet pip
leanest le CLIQuantConnect — il installe un
lean.exedans le dossierScriptsduvenv Python. Sur un kernel Jupyter qui contient ce paquet, le runner
prend le CLI QC pour Lean 4 sans rien vérifier.
Fix (
lean_runner.py:161-233)_is_lean4_binary(lean_path)qui exécute<path> --versionet accepte uniquement un binaire dont la premièreligne commence par
Lean (version 4(préfixe strict, pas unsubstring — un Lean 3 ou tout outil mentionnant "Lean 4" en prose ne
passe pas).
_find_leanprobe maintenant chaque candidat avant de l'accepter.Si le binaire PATH est rejeté, le runner tente
~/.elan/bin/lean(.)exe.FileNotFoundErroravec un diagnosticqui nomme le binaire rejeté et indique comment fixer :
elan default leanprover/lean4:stableoupip uninstall leansi c'est le CLI QC.Tests
Cinq nouveaux tests unitaires dans
scripts/tests/test_lean_runner.py(_is_lean4_binary× 3,_find_lean× 2). Les 2 tests préexistants (Anthropic response parsing) passent
toujours. 7/7 verts localement.
Le test d'intégration end-to-end (ré-exécuter Lean-9 pour vérifier que
le vérificateur produit maintenant de vraies sorties Lean 4) reste à
faire dans la suite du PR — il demande un kernel papermill côté WSL et
un run de 2-6 min par démo multi-agents, ce qui sort du périmètre
d'un patch ciblé
_find_lean.Acceptance de #17597
_find_leann'accepte plus un binaire sans l'avoiridentifié. Diagnostic explicite qui nomme le binaire rejeté si
aucun Lean 4 n'est trouvé.
lean(bannière QC) d'abordsur PATH. Le runner le rejette.
multi-agents et constater
{"success": true}sur une preuve qui n'estPAS
rfl. À faire en suivi post-merge par le porteur de Lean-9.Périmètre
subprocess,shutil,pathlib).scripts/verify_lean.py:313a le même défaut maisdans un rôle de diagnostic, pas d'exécution. Le fix direct sur
verify_lean.pyest orthogonale et peut faire l'objet d'une PRséparée si le user le souhaite.
See #17597