Repository navigation
feat(lean,#15666): T5a validation charge bornée — harnais de sondes pendant un build lake réel sous lean_exec - #16299
Conversation
…pendant un build lake reel sous lean_exec Sondes pendant la charge (population via la mesure de l'organe, DriveFS sous garde-fou timeout, spawn p95 borne a la baseline, RAM) + postconditions last_run.json (status ok, orphelins 0, cmd reconciliee). --touch N genere la charge par mtime-bump (contenu inchange). 17 contrats, aucun lake requis. Mesure reelle (po-2026) : budget defaut 2 -> l'organe tue l'arbre a 96,8 s (budget_violation 4 > 2), orphelins 0, machine vivable (DriveFS p95 234 ms, spawn p95 78 ms) -- le scenario incident arrete net, chiffre. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
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 |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM — harnais T5a lu en entier (harnais 455 l. + tests 262 l.), preuve-vive vérifiée de bout en bout.
Vérifications réelles (pas advisory) :
- Imports sibling :
scan_native_population(l.172),state_dir(l.104),config(l.713) existent bien dansscripts/lean/lean_exec.pysur main — l'import du harnais ne cassera pas à l'exécution réelle. - Preuve-vive CI :
scripts-tests.ymldéclenche surpaths: scripts/**(couvre les 2 fichiers du PR), checkout v4 complet, et la commande pytest inclutscripts/tests→ leScripts Tests (CPU)vert sur89633a8ca réellement exécutétest_validate_bounded_load.py. Les tests échoueraient sievaluate()mentait : population hors cap citée, timeout DriveFS nommé, spawn étouffé, orphelins comptés, record stale rejeté — c'est un vrai garde. - Réconciliation record :
_emit(lean_exec.py l.759) écritstatus/cmd/orphansà chaque sortie —read_organ_recordlit le bon format. - Sans deadlock : sortie organe vers fichier (pas PIPE non drainé), sonde daemon +
join(timeout)rend la main — testé.
Réserve mineure (non bloquante) : organ_exit_code est enregistré mais n'est pas un critère dur. Si l'organe crash avant _emit (SIGKILL, traceback), last_run.json conserve le run précédent ; cmd identique (lake build) → record stale accepté et organ_postcondition peut PASSER sur le run d'avant. Fermeture possible : réconciliation par started_epoch > début harnais, ou critère dur organ_exit_code == 0. Fenêtre étroite (le mur du harnais couvre déjà le kill volontaire) — à traiter en follow-up, pas bloquant pour cette tranche.
[Hermes hermes-pr-review, cycle :13 15/09, host c92df397a786]
myia-ai-01
left a comment
There was a problem hiding this comment.
Approved at exact head 89633a8c12b72df32499cba7c6eca9e0c0b51577 after full review of the PR surface, implementation, tests, and current gates.
The bounded-load harness is scoped to two new files, its 17 contracts are collected by the successful Scripts Tests run on this head, and the failure signatures are discriminating rather than vacuous. The documented stale-record window remains a non-blocking follow-up: a future hardening should reconcile last_run.json with the current harness start or require organ_exit_code == 0.
The squash description must not claim that T2/T3 are already on main; #16098 and #16160 remain open. This wording correction is prepared for merge time and does not affect the implementation verdict.
No closing issue reference is present; #15666 remains open for later tranches.
myia-ai-01
left a comment
There was a problem hiding this comment.
Requesting changes at exact head 89633a8c12b72df32499cba7c6eca9e0c0b51577 after full review of the body, comments, reviews, complete diff, integration points on live main, tests, checks, and closing references.
Two fail-open paths contradict this harness's purpose and must be closed before merge:
scan_native_population()uses-1when population is not measurable.evaluate()currently keeps those samples, so an all--1run producesmax_pop = -1 <= capand markspopulation_capPASS with zero valid measurements. Filter invalid measurements and fail the criterion when none remain; add a contract for this exact case.read_organ_record()reconciles onlycmd. If the organ crashes before_emit, a prior successfullast_run.jsonfor the samelake buildcommand is accepted as evidence for the current run. Bind the record to this invocation using a freshrun_idor a recorded start timestamp at/after the harness start, and add a same-command stale-record false-negative test.
These are not optional hardening nits: both turn an unmeasurable or crashed run into a possible successful validation result. The existing approval on this head is superseded by this exact-head finding.
Please integrate current main (5a1989a92e2185678763a06a76032b7384cd70e5) with the fix, run the targeted suite and full collected Scripts Tests, then obtain fresh post-base gates and an exact-head review. Keep closingIssuesReferences empty; #15666 is a partial-tranche epic and must remain open.
… and stale organ record Two fail-open paths found in exact-head review of #16299: 1. scan_native_population() returns -1 when the scan fails; evaluate() kept those samples, so an all-invalid run produced max_pop = -1 <= cap and marked population_cap PASS with zero valid measurements. Invalid samples are now filtered and the criterion FAILs when none remain, citing valid/total counts. 2. read_organ_record() reconciled only cmd: an organ crash before emit leaves the previous run's last_run.json (same lake build command) accepted as evidence for the current run. The harness now captures known run_ids (last_run.json + live run registry) before launching and rejects any record whose run_id is missing or preexisting. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ded-load-validation
…ontract 7 valid measurements (1x6 + 6x3) among 8 samples, not 6. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Addressed both fail-open paths at new head 1. population_cap fail-open (all 2. stale same-command organ record — the harness now captures Post-base validation on
🤖 Generated with Claude Code |
myia-ai-01
left a comment
There was a problem hiding this comment.
Approving exact head c6a3d4d13ab2a01f4a3bb95d72c488402377dd4c after re-reading the complete repair surface and independently tracing both prior false-pass paths through the harness, tests, and current lean_exec.py organ contract.
The population cap now fails closed when every sample is invalid: invalid negative scans are excluded, an empty valid set makes the hard criterion false, and the new all-invalid contract asserts both the criterion and global verdict. Mixed populations are judged only on valid samples and report valid/total counts.
The organ record is now bound to the current invocation. Known run_id values are captured before launch from both last_run.json and the live-run registry; records with a missing or pre-existing id are rejected, so a crash before emission cannot reuse a same-command stale record. The new contracts distinguish stale, missing, fresh, and concurrently registered ids. Current main 5a1989a92e2185678763a06a76032b7384cd70e5 is integrated, the two-file delta is additive, file collisions are absent, and closingIssuesReferences is empty so #15666 remains open.
This approval lifts my stale CHANGES_REQUESTED on 89633a8c12b72df32499cba7c6eca9e0c0b51577. Merge remains blocked until the current-head Scripts Tests CPU run, ADK contracts, and PR gate complete successfully; the author's local full-suite result is not a substitute for those gates.
|
[ADJOINT PREFLIGHT] PR #16299 -- verdict: PREFLIGHT_HOLD (nits OK, mss=BLOCKED sans cause technique) c.32 21:30Z UTC. État mesuré firsthand c.32 (Tell c.32-L1 ★★★ fondateur):
B.0 organe canonique (Tell c.29-L3 ★★ parade §1):
Lecture 4 surfaces Tell c.28-L1 ★★★ EXHAUSTIF:
Hold = le mss=BLOCKED n'a pas de cause technique visible (code sain, 0 nit non levé, APPROVED granted) — c'est probablement un check stale qui se résoudra au prochain rerun, OU un job qui a timeout sans conclusion visible. Recommandation ai-01 : relancé une fois, et si mss reste BLOCKED sans cause technique investiguer en deeper (cf. #16643 slot WSL plafonné 3 GiB instance class). Si mss redevient CLEAN après rerun = MERGE_READY parfaite (la +substantielle des 5 APPROVED). Tell c.1502 ××131ᵉ strict single-lane OK: 0 merge / 0 close / 0 CHANGES_REQUESTED par adjoint — commentaire only. Grain: MED/coordination-watchdog. |
…ded-load-validation
|
[ADJOINT PREFLIGHT] |
Grain: MED/feat -- lane myia-po-2026:CoursIA -- prev: MED/tooling #16294
Le livrable
scripts/lean/validate_bounded_load.py— T5a de l'EPIC #15666 : le harnais qui valide l'organelean_exec(T1-T3, sur main) sur charge réelle. L'incident fondateur (~30lean.exeà ~95 % CPU → DriveFS tombe → Claudish → reboot) n'est contredit par aucune preuve tant que personne n'a mesuré la machine pendant une vraie compilation confinée. Ce harnais est cette preuve, réutilisable.Ce qu'il mesure PENDANT la compilation
population_caplean_exec.scan_native_population, importé — pas une seconde opinion qui dériverait) ; max observé ≤ capdrivefs_alivelistdirchronométré sur le lecteur monté (G:\Mon Drive), sous garde-fou temps — un timeout de sonde = ECHECspawn_p95organ_postconditionlast_run.jsonde l'organe : statusok, orphelins vides — lu et réconcilié avec la commande attendue et un run_id frais (un enregistrement d'un autre run — cmd différente, ou crash avant émission laissant le run précédent, même commande — est rejeté, pas validé)RAM libre rapportée sans seuil inventé (l'organe plafonne déjà le run via Job Object). Chaque critère PASS/FAIL cite sa mesure (chiffres dans le détail), jamais un aveu nu.
Génération de la charge — réelle, pas fictive
--touch Naugmente le mtime des N modules propres les plus anciens du lake (contenu strictement inchangé → arbre git propre ; modules sous.lake/etlakefile.leanexclus) — la cascade de recompilation qui suit est la charge. Le harnais lancelean_exec.py run -- lake builddans le lake fourni : c'est le chemin exact d'un futur appelant migré.La mesure réelle (siège po-2026, lake 5.0.0 / toolchain 4.31.0-rc1, cache Mathlib 8345 oleans)
Run 1 — le scénario incident, arrêté net (budget défaut 2) :
--touch 10surgame_theory_lean(47 modules propres, cascade StableMarriage + GameTheory.lean),lake build -Kjobs=5sous l'organe. La supervision budget de l'organe tire à 96,8 s :budget_violation: "4 lean/lake descendants > budget 2", statustimeout, exit 124, arbre tué, orphelins = 0. Pendant le kill et la charge (population max observée 7 ≤ cap 8, 31 échantillons) : DriveFS jamais en timeout (p95 234 ms), spawn p95 78 ms (baseline 47 ms), RAM libre min 28,3 Go. La machine est restée vivable pendant exactement le régime qui l'avait tuée en septembre — et le harnais le prouve chiffres en main, pas par affirmation.Run 2 — 15 minutes de charge soutenue (budget 8) : la cascade de 10 modules ne tient pas sous le plafond — l'organe tire au mur 900 s (duration 904 s, status
timeout, exit 124), orphelins = 0. Pendant ces 15 min de charge continue (population max 7 ≤ cap 8, 253 échantillons) : DriveFS jamais en timeout (p95 203 ms), spawn p95 79 ms contre 78 ms de baseline — indiscernable de l'inactif —, RAM libre min 26,9 Go. La preuve de sûreté vaut ici plus qu'un succès rapide : c'est un quart d'heure du régime exact de l'incident, sans qu'aucune sonde ne bronche, et un kill d'arbre propre à la fin.Run 3 — queue résiduelle, 30 min de charge (plafond 1800 s) : le run 2 a touché
CooperativeGames/Basic.lean, module racine — la cascade aval est le lake entier (47 modules + jumeaux_en). 30 minutes de compilation n'ont pas suffi : l'organe tire au mur 1800 s (duration 1805 s), orphelins = 0, et sur 414 échantillons de cette demi-heure de charge continue : population max 7 ≤ 8, DriveFS jamais en timeout (p95 47 ms), spawn p95 78 ms, RAM min 27,8 Go. Le kill au mur n'est pas un défaut de l'organe ni du harnais — c'est un plafond assume contre un build sous-dimensionne ; la leçon opérationnelle (dimensionner--timeouta la cascade visee) va dans les limites ci-dessous.Run 4 — le build mène à terme (lake borné, budget 8) :
social_choice_lean(sources via srcDir partagé, oleans en retard →lake buildavait du travail réel en attente ;touched: []est correct, aucun module propre dans le répertoire). PASS 4/4 : organestatus=ok, enfant exit 0, duration 150 s, orphelins = 0, population max 2 ≤ cap 8 (45 échantillons), DriveFS jamais en timeout (p95 125 ms), spawn p95 78 ms, RAM min 28,1 Go. La voie-success du harnais (verdict PASS sur un vrai build) est exercée, pas seulement la voie-échec.Constat opérationnel pour T5b (consigné mémoire lane) : les défauts de l'organe sont internement incohérents pour un
lake buildnu —jobs = cpu//4 = 5fait spawner ~7 lean/lake,budgetdéfaut = 2 les tue à ~100 s. Tout appelant migré devra passer--budget >= jobs+1. Ce n'est pas un bug du kill (il est propre, orphelins 0) ; c'est une contrainte à documenter au moment de la migration.Pourquoi T5a seul (le scoping, mesuré sur le source)
La moitié « migration » de T5 (T5b) exige des extensions de l'organe :
run_commandsur origin/main n'a nicwd, niinput, ni capture de sortie — orlean_rlvr_verifier._run_lean(MyIA.AI.Notebooks/GenAI/PostTraining/verifiers/lean_rlvr_verifier.py:185) a besoin des trois (cwd=project_dir, input=source, capture_output=True), etpo2026_recover_build.py:156,178decwd+ env PATH sanitizé. Migrer sans ça = soit empiler sur l'organe, soit maquiller enos.chdir(thread-unsafe). De plus l'allowlist T4 (PR #16196, OPEN) n'est pas mergée. T5b reste résiduel, documenté au claim (c.5679738618).Tests —
scripts/tests/test_validate_bounded_load.py(21 contrats)1-2. verdict propre : 4 critères cités avec leurs chiffres ; p95 sur listes connues
3-7. le régime de l'incident échoue : population 12 > cap 8 ; sonde DriveFS timeout ; spawn p95 40 s ; organe
refused; organe orphelins8. spawn dégradé mais SOUS le plancher (baseline lente 2 s → borne 10 s, charge 8 s) = PASS : la borne est relative à la machine, pas un absolu inventé
9-11. pas de faux pass : sonde DriveFS indisponible = note honnête, pas un succès ; 0 échantillon de charge = non vérifiable ; enregistrement organ absent ne valide rien
12-14. le harnais ne se bloque pas : sonde abandonnée au timeout rend la main (< 3 s) ; l'échantillonneur s'arrête à la mort de la charge et rend la main APRÈS ; mur du harnais signalé
15-17.
--touchexclut.lake/etlakefile.lean, bump exactement N mtimes, contenu inchangé ; CLI exige un lakefile ;read_organ_recordrejette le stale (cmd différente)18-21. les faux-pass de la review exact-head sont fermés : population non mesurable (run tout
-1) échoue le critère avec « 0 mesure de population valide » ; population mixte jugée sur les seules mesures valides, les deux comptes cités ;read_organ_recordrejette le stale même commande (run_id préexistant = crash avant émission, et format sans run_id) ;known_run_idslit aussi le registre des runs vivantsAucun lake ni lean requis pour les tests : le verdict est une fonction pure sur échantillons fabriqués, l'échantillonneur se teste sur un enfant python.
Deux défauts attrapés par le développement lui-même : un
stdout=PIPEnon drainé pendant l'échantillonnage (deadlock garanti — le build lake emplit bien plus que le buffer ; sortie redirigée vers fichier), etnargs="+"d'argparse qui s'arrête au premier token--de la commande (--cmd lake --versiondevenait--cmd lake+ flag inconnu → REMAINDER, même sémantique que l'organe).Validation
pytest scripts/tests/test_validate_bounded_load.py→ 21 passed in 1.90 s (17 contrats + 4 nouveaux contrats faux-pass)python -m pytest scripts/tests/→ 5665 passed, 30 skipped, 5 xfailed in 775.90 s (origin/main5a1989a92intégré, merge commitf5106afcc)lake --versionsous l'organe) → PASS 4/4, rc=0 ; et la version où l'organe échoue honnêtement (child_failed) → FAIL nommé, rc=1Limites honnêtes
G:\Mon Drivepar défaut) : absente → sondeunavailablenotée, le critère timeout n'est pas vérifiable sur ce siège (pas un faux pass).--touchsur un module racine invalide toute la cascade aval : dimensionner--timeoutà la cascade visée (mesuré : 47 modules + jumeaux_en> 30 min sous-Kjobs=5) ou toucher des feuilles.Conformité
scripts/testsest un répertoire dans l'invocation pytest descripts-tests.yml:271, pas une liste explicite — aucun câblage à toucher).See #15666(contribution partielle à l'epic : T5a livré, T5b résiduel documenté, T4 est feat(ci,#15666): T4 garde CI anti-invocation-directe lake (AST, allowlist, TRANCHE15) #16196).check_lake_direct_invocation.py,lake_direct_allowlist.json) — pas de conflit attendu.gh pr list --search 15666= feat(lean,#15666): T2 admission raffinie -- tree lease, file bornee, budget min-des-sources #16098/feat(lean,#15666): T3 backend epingle par lake -- premier-ecrivain proprietaire #16160/feat(ci,#15666): T4 garde CI anti-invocation-directe lake (AST, allowlist, TRANCHE15) #16196 (T2/T3/T4, aucun sur T5a) ; seul claim T5 = le mien (c.5679738618) ; lane sœur vérifiée.🤖 Generated with Claude Code