Skip to content

test(dimred): audit SpectralAutoencoder contracts and add missing tests (M2.5) - #87

Merged
PhD-Brown merged 13 commits into
mainfrom
audit/43-dimred-autoencoder
Nov 9, 2026
Merged

PhD-Brown merged 13 commits into
mainfrom
audit/43-dimred-autoencoder

Conversation

@PhD-Brown

@PhD-Brown PhD-Brown commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

Refs #43 — R1–R8 traitées après la première revue Claude, pour seconde revue indépendante sur cette même Draft PR.

Tête finale : audit/43-dimred-autoencoder@047e2c79048b0df47245bebbf5544d439a9acdcf.
Base : main@795af2c8fbe61432dda44480013d86f34ed43e02.
Entrées du rejeu complet et des suites : 05d94d327028627e7b8d38e74be47b5550c21537.
Checker R8 final : 2dc41b5b22d1bc457fdd076988dcdf21a3c30e33.
Dernier commit : documents/résultats uniquement. Matrice révisée.

Aucun changement de production, dépendances, CI, notebooks, données ou modèles. Blob AE inchangé : b06bfa75a2e0a8b132d0a0fb8e0a899b6afed0ad. Worktree principal intact ; travail dans le worktree M2.5. Checkpoints poussés et SHA distants vérifiés après chaque bloc : A046e78d, B0374bf3, Cd944ca5, R69a7dab4, D05d94d3, puis sauvegarde des preuves 2dc41b5 et tête ci-dessus.

Révision des contrats

Fil Correction et preuve
R1 Oracle du bloc caché à poids/statistiques BN fixés : sorties latentes −2 et 0 ; C03 ReLU supprimée et C04 ReLU avant BN détectées par assertion. Commentaire du gradient analytique corrigé.
R2 Amélioration tardive 5,6,4,7,8,9 : arrêt à 5 et poids3 ; buffer enregistré restauré à2 avec les poids2. C02 et C01b (strict=False) détectées par assertion. Politique d'égalité non figée.
R3 Norme réellement consommée par Adam.step ≤1+1e−5 ; pré-clipping >1.001 ; poids mis à jour ; comparaison exacte avec entraînement sans spies. C05 détectée par assertion.
R4 Votes distincts à k20/50/60, avec permutation appariée des lignes. C06/C07 détectées ; aucun départage d'égalité imposé.
R5 Deux STAR Teff4500/logg3.0 et5.5, latents éloignés : exclusion numérique des bornes supérieures. C08 détectée.
R6 A01 validation triée, A02 sortie flottante float64, A03 RNG indépendant par population et A09 autre patience du scheduler acceptées. Protections remplacées par identités/valeurs, sous-ensembles observés, barycentres fsum, répétabilité et réduction fonctionnelle du LR.
R7 Matrice AP/PA corrigée ; nouveaux mutants ajoutés ; distinction assertions, exceptions de runtime, refus attendus, erreurs de collecte et skips. Provenance et résultats historiques séparés.
R8 Archive immuable ; six contrôles temporaires montrent les limites des oracles #80/#81 et la politique ouverte #82. Critères renforcés publiés sur les trois issues.

Mutations et admissibilité

Rejeu révisé : 41 incorrectes KILLED, 0 SURVIVED/INCONCLUSIVE ; 13 contrôles admissibles + 2 équivalents + baseline PASS, 60 tests par essai. Aucun skip ni erreur de collecte/fixture.

Rejeu des anciens tests, avec --tests-ref ae1e2be : les 8 anciens survivants SURVIVED et les 4 variantes admissibles FAIL sont reproduits ; baseline56 PASS. L'exit1 est attendu pour cette comparaison historique.

Les huit nouveaux contre-exemples sont détectés par assertions. Les détections de checkpoints corrompus sont des exceptions de chargement (2 chacune), pas des oracles numériques ; validation_train_mode donne 8 assertions de frontière/état et 1 exception BN. L'ancien artefact IndexError est remplacé par un contrôle explicite du mode d'évaluation. Messages/types/tracebacks, versions, SHA256 effectifs et états Git réels sont enregistrés.

Archive et qualifications

59eb774eb618cdf639cde3c0358da319ee4bcffa inchangée, accessible et ancêtre de la tête ; 11 FAIL/14 PASS historiques non réécrits. L'ancien JSON de mutations reste inchangé également.

Checker R8 et résultats : 6 PASS / 15 cas pytest, sur copies temporaires uniquement.

  • #80 qualifiée : drop_last peut donner 0 pas et NaN tout en passant l'ancien oracle ; exiger succès fini avec un vrai pas ou refus explicite.
  • #81 qualifiée : invalidation du seul modèle insuffisante ; conservation complète ou invalidation modèle+métadonnées.
  • #82 réservée : imputation silencieuse peut passer l'oracle ; admissibilité scientifique OPEN.

Vérifications exécutées

Windows/Python3.11.9, NumPy2.4.6, pandas3.1.1, sklearn1.9.1, pytest8.4.2 ; Torch 2.10.0+cpu, cuda=None, venv isolé existant.

Commande/périmètre Résultat
Fast M2.5 -W error 31 PASS
Fast pytest -q et --import-mode=importlib 416 PASS /62 deselected /7 warnings Gaia préexistants
-m "integration and not slow" 57 PASS
CPU -m slow tests/test_dimred_autoencoder_real.py 33 PASS
Suite entière Torch, importlib et ordre inversé 449 PASS /29 SKIP optionnels /7 mêmes warnings
M2.5 ordre aléatoire seed2026 /Torch seed913 /-W error 64 PASS
RNG, threads, déterminisme et warn_only après suite inversée (seed703) restaurés exactement
Black/Ruff, deux scripts d'audit inclus ; pip check des deux venvs ; diff check PASS

CI finale 42548715421 completed/success sur 047e2c79048b0df47245bebbf5544d439a9acdcf. Journaux lus : merge de contrôle536c1e0, Linux/Python3.11.18, 413 PASS /3 SKIP Windows /62 deselected /7 avertissements Gaia préexistants ; pip check, Black35fichiers et Ruff PASS. Les33tests CPU restent exclus de la CI officielle inchangée. Aucun GPU, catalogue réel, W&B réel, notebook exécuté, mesure de couverture ou validation astrophysique générale.

Les huit réponses inline sont publiées et vérifiées : R1 · R2 · R3 · R4 · R5 · R6 · R7 · R8. Les huit fils restent ouverts pour Claude. Reprise du2026-11-09 : worktree propre, HEAD local/distant identiques,14empreintes de campagne et hashes historiques/R8 revérifiés. Aucun nouveau test/campagne ni commit inutile ; seules les vérifications de reprise et la finalisation GitHub ont été effectuées. Draft maintenue, M2.5 🟡, aucun merge ni M2.6.

@PhD-Brown PhD-Brown left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Revue scientifique indépendante — M2.5 / PR #87 — Claude (1ʳᵉ revue)

Verdict : MODIFICATIONS REQUISES

Deux problèmes bloquants (R1, R2) : la suite ne protège ni la non-linéarité du réseau, ni la restauration complète du meilleur état. Pour chacun, l'ajout est limité aux tests, a été validé localement et ne demande aucun changement de production. Les six autres points (R3–R8) sont non bloquants ; R3–R5 sont peu coûteux et souhaitables dans cette PR.

(La review est enregistrée en COMMENTED parce que le compte est partagé ; le verdict ci-dessus fait foi.)


1. SHA audité et delta

  • HEAD de PR ae1e2be0a4fd5f60ad39068b0b05ceb0ca645546 (inchangé depuis la passation), base main@795af2c8fbe61432dda44480013d86f34ed43e02.
  • Diff : exactement les 6 fichiers annoncés (+2457/−0). Blob src/dimred/autoencoder.py b06bfa75… identique sur la base et la tête : aucune modification de production, de dépendances ou de CI.
  • Snapshot 1eb0c0b : les 14 empreintes SHA256 du JSON de mutations correspondent au contenu Git du snapshot (CRLF pour les fichiers Windows, LF pour les fichiers de tests et le script). Le delta 1eb0c0b → ae1e2be ne touche que la matrice et le JSON. Archive 59eb774 accessible ; elle est le parent de la ligne d'intégration.

2. Résultats de tests reproduits (Linux, Python 3.11.18, venvs uv isolés et jetables)

Environnement fast : requirements/ci.txt, Torch absent (et non bloqué). Environnement torch : idem + torch==2.10.0+cpu. NumPy 2.4.6, sklearn 1.9.1, pytest 8.4.2, comme chez Codex.

Commande Résultat
pytest -q tests/test_dimred_autoencoder.py -W error (fast) 31 PASS
pytest -q / --import-mode=importlib (fast) 413 PASS / 3 SKIP / 58 deselected (les 3 skips sont Windows-only, comme en CI)
pytest -q -m "integration and not slow" 57 PASS
pytest -q -m slow tests/test_dimred_autoencoder_real.py (fast) 29 SKIP (sans Torch, ces skips n'ont aucune valeur de validation)
idem (torch), normal et importlib 29 PASS
Suite complète -m "slow or not slow" (torch) : ordre inversé, importlib inversé, pytest-randomly ×5 graines dont 2 avec --randomly-dont-reset-seed 442 PASS / 32 SKIP à chaque fois : aucune dépendance à l'ordre
black --check / ruff check (src tests scripts app.py + script d'audit) PASS / PASS
pip check, git diff --check 795af2c ae1e2be PASS
CI 42541068481 completed/success, head_sha = ae1e2be ; journal lu : 413 PASS / 3 SKIP / 58 deselected, Black 35 fichiers, Ruff, pip check

Rappel : la CI officielle n'exécute pas les 29 tests réels. Leur validation repose sur ma reproduction locale et sur celle de Codex.

3. Validité des oracles

Solides et indépendants (recalculés à la main) :

  • MSE par ligne [3, 3, 49/3] et globale ;
  • résumé (0, 1, 4, 16) : moyenne 21/4, σ population √651/4 (≠ ddof 1), médiane 5/2, q95 linéaire 14,2 (≠ max 16), classes 2 et 9 non contiguës ;
  • PCA sur axes orthogonaux : 14/9, 0, 5/9, 1/9 ;
  • interpolation affine ; vote excluant −1 ; barycentres et analogies asymétriques ;
  • comptages de paramètres (ex. 3→[4,2]→1 = 84, buffers BN exclus) ; premier pas d'Adam p = 0,1/(1+ε).

Ils distinguent bien MSE/MAE, moyenne/médiane, moyenne/somme, ddof, rang du quantile et labels décalés.

Faiblesses :

  • R1 : aucun oracle de valeur ne traverse un bloc caché (BN/ReLU/Dropout).
  • R2 : trajectoire d'early stopping non discriminante, réseau contrôlé sans buffer.
  • R3 : le premier pas d'Adam est invariant au clipping.
  • R4/R5 : frontières k = 50 et log g supérieur non fixées.
  • R6 : certains oracles rejouent l'implémentation (ordre du RNG, dtype float32, hyperparamètres du scheduler) et rejettent des variantes admissibles.

Fixture sans Torch :

  • Elle n'injecte que des noms inertes (Module = object) et ne peut construire aucun réseau ; torch.FloatTensor y lèverait AttributeError.
  • Les noms sont retirés de sys.modules dès la sortie de exec_module. Mon sondage ne montre aucune fuite de torch* ni de m25_numeric, et find_spec("torch") reste None ensuite.
  • Elle ne masque pas #21 : voir la section 5.
  • Seul effet global persistant : matplotlib.use("Agg", force=True) n'est pas restauré (déjà le cas dans test_dimred_pca_analyzer.py:736). Effet sans conséquence pour une suite headless, signalé pour mémoire.

4. Entraînement PyTorch

  • Split :
    • Ce qui est vérifié : effectifs, disjonction, couverture, cibles égales aux entrées, shuffle=True, invariance à la graine Torch externe.
    • Il s'agit d'un split de lignes, pas d'objets. L'observation des doublons, reproduite, relève de #22.
    • L'exposition de la validation interne au StandardScaler global est confirmée (data_loader.py:319-322, cellule loader.load(scale=True) avant le fit dans le notebook). La matrice la qualifie correctement : exposition de la validation interne, pas preuve d'une fuite vers un test externe (#24).
  • Optimiseur : oracle Adam correct. Reset des gradients et weight decay vérifiés par spy (zero_grad ×3, kwargs). No-grad en validation détecté indirectement par le critère contrôlé. Clipping : voir R3.
  • Scheduler : le plateau réel (12 × 0,01 puis 0,005) correspond à la sémantique num_bad_epochs > patience de Torch 2.10, stable depuis longtemps. Acceptable comme verrou de version, à documenter (R6).
  • Early stopping : le nombre d'epochs et le poids restauré (2) sont corrects. Mais voir R2 : remise à zéro de la patience et buffers BN non prouvés.

5. Preuves rouges (59eb774, rejouées dans une copie isolée)

11 FAIL / 14 PASS reproduits à l'identique, y compris 236.7083282 ≠ 228 pour #84 (même graine Torch 1729 sous Linux). Causes vérifiées :

  • #21 ×4 : NameError: nn à la l. 87, avant _check_torch. Je l'ai reproduit aussi avec Torch réellement désinstallé, pas seulement bloqué par le meta-path : import du module, import dimred, from dimred import PCAAnalyzer et même from dimred.pca_analyzer import … (via __init__). Le dispositif de blocage ne crée donc pas l'erreur.
  • #80 ×2 : ValueError: Expected more than 1 value per channel when training. Précondition confirmée : 5 lignes d'entraînement avec des batchs de 4 donnent un dernier batch de 1, et N = 2 ne laisse qu'une ligne d'entraînement.
  • #81 ×1 : sortie différente après un batch_size=0 refusé ;
  • #82 ×2 : {'train_loss': [nan], 'val_loss': [nan]} renvoyé comme succès ;
  • #83 ×1 : 4 Linear au lieu de 1 ;
  • #84 ×1 : sonde de politique.

Les 11 FAIL correspondent à 5 défauts comportementaux + 1 contrat ouvert, et non à 11 bugs. Les 14 PASS sont des observations, pas des politiques validées. Les 7 contrôles de remèdes donnent 7 PASS en direct. L'écriture finale du JSON échoue seulement parce que ma copie n'est pas un dépôt Git : c'est un artefact d'environnement.

Limites des oracles rouges : voir R8 (#80 accepte un drop_last silencieux qui produit train_loss=nan ; #81 ne contrôle pas les métadonnées).

6. Mutations de Codex

Le script est intègre :

  • chaque ancre doit exister (sinon ValueError) et le code muté est compilé ;
  • un baseline de 56 tests sert de référence ;
  • les erreurs, skips et tests manquants sont classés INCONCLUSIVE ;
  • les empreintes sont vérifiées avant et après ;
  • les 4 tests exclus via -k sont bien exécutés dans les suites normales.

Rejoué entièrement (4 min 24) : 40/40 cas identiques au JSON (statut, nombre de remplacements, nombre de tests, noms des tests en échec). Nuance : certaines mises à mort viennent de crashs ou d'artefacts de spy, et non d'oracles de valeur (R7).

7. Mutations indépendantes (même harnais, 56 tests)

Mutant Erreur Oracle censé le détecter Résultat
C01b buffers BN non restaurés (named_parameters + strict=False) early stopping SURVIVED → R2
C02 patience jamais remise à 0 early stopping SURVIVED → R2
C03 ReLU → Identity (AE linéaire) architecture/forward SURVIVED → R1
C04 ReLU avant BN architecture/forward SURVIVED → R1
C05 clipping après step optimiseur SURVIVED → R3
C06 / C07 k = 60 / k = 20 voisins vote candidat SURVIVED → R4
C08 logg <= g_hi arithmétique latente SURVIVED → R5
C09 lignes 0/1 permutées dans per_sample résumé par classe KILLED
C10 quantile method='nearest' (médiane inchangée) résumé KILLED
C11 val_loss calculée sur les lignes d'entraînement split (spy) KILLED
C12 decode en mode train dropout/roundtrip KILLED
C13 load sans buffers BN roundtrip KILLED
C14 entraînement en mode eval split (spy) KILLED
C15 labels décalés (np.roll) résumé KILLED
C16 restauration de l'état de la dernière epoch early stopping KILLED
C17 MSE candidate dans l'espace brut candidat KILLED

Tous les mutants étaient actifs (ancre trouvée, compilation, baseline PASS) ; aucun n'est équivalent. Les oracles proposés dans R1–R5 ont été écrits et exécutés dans une copie jetable : 6/6 PASS sur la production, et chaque survivant tué.

8. Compatibilité avec les correctifs légitimes

Acceptés par la suite verte :

  • honorer hidden_dims=[] ;
  • invalidation complète après un échec ;
  • refus des non-finis ;
  • perte d'epoch pondérée par les effectifs (contrôle réel, pas un simple float()) ;
  • drop_last limité au batch singleton ;
  • les contrôles de Codex (métadonnées de checkpoint supplémentaires, prose prudente, refus 2D explicite).

Rejetés à tort (R6) : validation triée (même ensemble), sortie float64, RNG indépendant par population, autre patience du scheduler.

9. Qualification des issues

Issue Conclusion
#21 Confirmée (Torch réellement absent + blocage ; façade et sous-module PCA aussi touchés)
#80 Confirmée avec qualification : seulement en entraînement, avec un batch de taille 1 ; l'oracle accepte un remède silencieux (R8)
#81 Confirmée ; la preuve ne vérifie pas les métadonnées (R8)
#82 Confirmée ; l'imputation silencieuse passe l'oracle, c'est une décision humaine
#83 Confirmée (P2 adéquat)
#84 Contrat de métrique ouvert, correctement classé ; la valeur exacte dépend de la composition des batchs (RNG de shuffle), mais l'écart est structurel (batchs 4/3). Aucun test vert n'impose de choix
#85 Confirmée (documentaire) ; aucun test vert ne fige verdicts ni seuils
#86 Risque statique correctement qualifié ; aucun exploit. Je n'ai chargé que des checkpoints synthétiques générés localement par les tests
#22 / #24 Liens corrects ; portée correctement limitée

10. Limites scientifiques

Comme le dit déjà la matrice, rien ici ne valide :

  • une interpolation latente comme chemin évolutif ;
  • les seuils 0,97/3,0 comme quantiles ;
  • les analogies comme lois ;
  • une supériorité sur PCA.

Les tests verts restent compatibles avec une prose prudente. Conserver cette réserve après les corrections.

11. Corrections requises (tests et documents d'audit uniquement)

  1. R1 (bloquant) : oracle manuel en mode eval à travers un bloc caché (Linear→BN→ReLU→Dropout).
  2. R2 (bloquant) : trajectoire avec amélioration tardive et buffer contrôlé dans l'early stopping.
  3. R3 : spy sur Adam.step (norme ≤ 1). R4 : frontière k = 50. R5 : lignes log g = 3,0 et 5,5.
  4. R6 : assouplir ou documenter les verrous de reproductibilité.
  5. R7 : corriger les revendications AP de la matrice ; ajouter C01b–C08 au script de mutations.
  6. R8 : documenter les limites des oracles rouges et reporter des critères renforcés sur #80/#81 (archive inchangée).

12. Verdict

MODIFICATIONS REQUISES. M2.5 reste 🟡. Corrections par Codex sur la même branche et la même PR ; seconde revue ciblée ensuite. Aucun commit, merge, passage en Ready for review ni travail M2.6 de ma part.


Generated by Claude Code

Comment thread tests/test_dimred_autoencoder_real.py Resolved
Comment thread tests/test_dimred_autoencoder_real.py Resolved
Comment thread tests/test_dimred_autoencoder_real.py Resolved
Comment thread tests/test_dimred_autoencoder.py Resolved
Comment thread tests/test_dimred_autoencoder.py Resolved
Comment thread tests/test_dimred_autoencoder_real.py Resolved
Comment thread audit/M25_AUTOENCODER.md Resolved
Comment thread audit/M25_AUTOENCODER.md Resolved

@PhD-Brown PhD-Brown left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Seconde revue scientifique indépendante — M2.5 SpectralAutoencoder

Verdict : APPROUVER — prête pour la décision humaine de fusion

Les deux points bloquants (R1, R2) et les six autres (R3–R8) sont corrigés et vérifiés de façon indépendante. Je n'ai trouvé aucune régression. Deux réserves non bloquantes subsistent ; elles sont déjà déclarées dans la matrice (section 11). (Review enregistrée en COMMENTED parce que le compte est partagé ; le verdict ci-dessus fait foi.)


1. SHA

  • Ancien HEAD examiné : ae1e2be0a4fd5f60ad39068b0b05ceb0ca645546. Nouveau HEAD : 047e2c79048b0df47245bebbf5544d439a9acdcf, inchangé au moment de la revue.
  • Base : main@795af2c, inchangée.
  • Blob src/dimred/autoencoder.py : b06bfa75 identique sur la base, l'ancienne tête et la nouvelle.
  • Snapshot de campagne : 05d94d3. Archive rouge : 59eb774, accessible et immuable.

2. Diff examiné

3 commits (05d94d3, 2dc41b5, 047e2c7) sur 9 fichiers (+3608/−60), soit 10 fichiers par rapport à la base. Aucun fichier de production, de dépendance, de CI ni de notebook.

  • tests/ : nouvel oracle caché R1, trajectoires et buffer R2, spy au pas R3, population 20/50/60 R4, bornes log g R5, assouplissements R6. conftest.py restaure aussi warn_only.
  • audit/ : harnais mis à jour (schéma 2, types de détection, --tests-ref), deux nouveaux JSON de mutations, checker R8 et son JSON, révision de la matrice.
  • Le fichier de preuves rouges reste hors de l'arbre vert.

3. Statut R1–R8

# Statut Preuve principale
R1 VÉRIFIÉ — RÉSOLU Recalcul manuel −2,0 / 0,0. C03 → −5,5, C04 → −3,0 (assertion numérique)
R2 VÉRIFIÉ — RÉSOLU C02 → longueur 4 au lieu de 5 ; C01b → seen_batches 5 au lieu de 3 (assertion, pas une exception de clés)
R3 VÉRIFIÉ — RÉSOLU C05 → norme consommée 58,5 > 1+1e−5 ; spies passifs (référence identique bit à bit)
R4 VÉRIFIÉ — RÉSOLU Effectifs 15/5, 26/24, 34/26 ; C06/C07 → 2 == 7
R5 VÉRIFIÉ — RÉSOLU C08 → la ligne log g 5,5 rejoint K naine ; échec de l'assertion d'appartenance
R6 VÉRIFIÉ — RÉSOLU A01/A02/A03/A09 PASS ; protections intactes (réserve 11b)
R7 VÉRIFIÉ — RÉSOLU AP limités, types de détection, empreintes conformes
R8 VÉRIFIÉ — RÉSOLU Checker rejoué : 6 PASS / 15 cas ; #80–#82 fidèles

Chaque fil inline a reçu une réponse détaillée et a été résolu.

4. Rejeu des huit anciens survivants

Avec mes remplacements exacts de la première revue (même harnais, 60 tests révisés) : C01b, C02, C03, C04, C05, C06, C07 et C08 sont tous tués par une assertion pertinente, sans erreur ni exception de fixture. Mes 9 autres mutants (C09–C17) restent tués : 17/17 au total. Le JSON historique de Codex (--tests-ref ae1e2be, empreintes des tests de ae1e2be vérifiées) reproduit exactement mon constat initial : 8 SURVIVED / 4 FAIL.

5. Alternatives admissibles

  • A01 (validation triée), A02 (float64), A03 (RNG indépendant par population), A09 (patience 5) : 4 PASS. Mes autres contrôles passent aussi : [] honoré, invalidation complète, refus des non-finis, pertes pondérées réelles, drop_last limité au singleton. Total : 10/10.
  • L'assouplissement n'a pas affaibli la détection. Mutants inédits, tous tués :
    • barycentre médian ;
    • tirage avec remise (127 lignes uniques au lieu de 200) ;
    • scheduler alimenté par train_loss ;
    • factor=1.0.

6. Campagne de mutations

  • Harnais : chaque ancre composée doit exister ; la double application de C01b ne se produit qu'une fois ; type de détection assertion / runtime_exception ; tests de refus attendus comptés à part.
  • JSON révisé : 41 KILLED / 0 SURVIVED / 0 INCONCLUSIVE ; 13 admissibles + 2 équivalents + baseline PASS, 60 cas par essai, 14/14 empreintes conformes à 05d94d3, arbre propre au début et à la fin.
  • Les 5 mises à mort non fondées sur une assertion (checkpoint_*, wrong_latent_dim, reversed_rows, validation_train_mode) sont présentées comme telles dans la matrice.
  • Je n'ai pas relancé la campagne complète : entrées identiques, résultats vérifiés cas par cas, et mes candidats rejoués indépendamment.

7. Preuves rouges et leurs limites

  • Archive 59eb774 inchangée ; ses 11 FAIL / 14 PASS ont été rejoués lors de la première revue, au même SHA immuable.
  • Checker R8 rejoué sous Linux : 6 PASS / 15 cas, empreintes de l'archive et du checker identiques.
    • #80 : 0 pas d'optimisation et train_loss=[nan] refusés par le critère renforcé.
    • #81 : invalidation partielle refusée ; conservation complète et invalidation complète acceptées.
    • #82 : imputation silencieuse classée OPEN, aucune politique imposée.
  • Les commentaires sur #80, #81 et #82 sont fidèles et ne revendiquent aucun correctif.

8. Suite sans Torch (Linux, Python 3.11.18, venv uv jetable, Torch non installé)

  • pytest -q tests/test_dimred_autoencoder.py -W error : 31 PASS.
  • pytest -q et --import-mode=importlib : 413 PASS / 3 SKIP / 62 deselected. Les 3 skips sont réservés à Windows ; Codex obtient 416/62 sous Windows.
  • -m "integration and not slow" : 57 PASS.
  • Black (42 fichiers, scripts audit/ inclus), Ruff, pip check (deux environnements), git diff --check 795af2c 047e2c7 : PASS.

9. Tests PyTorch réels (Torch 2.10.0+cpu, NumPy 2.4.6, sklearn 1.9.1, pandas 3.1.1, pytest 8.4.2)

  • -m slow tests/test_dimred_autoencoder_real.py, normal et importlib : 33 PASS.
  • Suite complète -m "slow or not slow", en ordre normal, inversé et avec pytest-randomly sur 2 graines sans réinitialisation des RNG : 446 PASS / 32 SKIP à chaque fois. Le total de 478 est égal à celui de Codex (449/29 sous Windows).

10. CI au SHA final

Run 42548715421 : completed/success, head_sha = 047e2c7. Journal lu : 413 PASS / 3 SKIP / 62 deselected, Black, Ruff, pip check. Les 33 tests réels restent hors CI officielle ; leur validation repose sur les rejeux locaux de Codex (Windows) et les miens (Linux).

11. Risques encore ouverts (non bloquants)

  • a. Non-linéarité du décodeur : supprimer ReLU uniquement dans _Decoder passe toute la suite (64 PASS). La matrice le déclare en PA, et ma proposition R1 ne visait que l'encodeur. Un oracle miroir sur le décodeur est un ajout simple, à faire en suivi ou avant fusion selon la décision humaine.
  • b. Échantillonnage de l'arithmétique latente : l'observation dépend de np.random.default_rng().choice. Deux variantes admissibles restent rejetées : pas de sous-échantillonnage sous le plafond, tirage par permutation. C'est documenté dans la matrice ; la suggestion figure dans le fil R6.
  • Politiques scientifiques ouvertes, hors PR :
    • #80 batching ;
    • #81 politique transactionnelle ;
    • #82 traitement des non-finis ;
    • #84 métrique de reporting ;
    • #85 seuils et prose astrophysique ;
    • #86 confiance des checkpoints ;
    • #21 optionalité ;
    • #22 et #24 split par objet et prétraitement.
  • Aucune validation astrophysique, aucune donnée réelle, aucun GPU, aucun notebook exécuté.

12. Verdict final

APPROUVER — prête pour la décision humaine de fusion. M2.5 reste 🟡 jusqu'à la fusion effective. Je ne fusionne pas la PR et je ne la passe pas en Ready for review. Aucun commit ni travail M2.6 de ma part.


Generated by Claude Code

@PhD-Brown
PhD-Brown marked this pull request as ready for review November 9, 2026 12:30
@PhD-Brown
PhD-Brown merged commit 18302e6 into main Nov 9, 2026
1 check passed
@PhD-Brown
PhD-Brown deleted the audit/43-dimred-autoencoder branch November 9, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant