Files
oto-enterprise-os-dtp/05_activity_log/2026-07-31.md
T
Claude Code DTP Worker 76fb0e768d [DTP-Worker] Sprint 8 · buffer L75 · Intégrité matrice régression : fix gate check_regression cassé en CI (run baseline commité) + invariant disque→CI (INV4 orphan_tests_dirs)
Défaut #1 (bug CI réel) : ci/check_regression.sh exigeait regression_run.json
commité comme baseline, mais le fichier était .gitignore → absent en checkout
propre → le job Gitea check-regression échouait sur CHAQUE run CI (ne passait
qu'en local via un fichier non suivi). L'artefact run est byte-déterministe
(aucun horodatage/hôte/durée · path relatif) → committer est licite. Fix :
run désormais commité (baseline), .gitignore + README réécrits.

Défaut #2 (invariant manquant) : coverage_report prouvait CI→disque mais pas
l'inverse. Nouveau disk_test_modules() + orphan_tests_dirs dans INV4 : un module
gagnant un tests/ sans job CI fait chuter la couverture (fini la sous-comptée
silencieuse de la matrice). Schéma + 2 tests de morsure.

Consommateur régénéré : qa/audit_4big/quality_report.json (README 3710→4236 o,
24→26 méthodes). Matrice 534/21/PASS inchangée (harnais self-exclu, INV3).
5 gates verts · 26+34 tests OK · YAML valide.
2026-07-31 00:41:16 +00:00

4.9 KiB
Raw Blame History

Activity Log · 2026-07-31 · Claude Code DTP

Session 20260731_002924 · Buffer S8 · Intégrité de la matrice de régression (bug CI réel + invariant disque→CI)

Tâche : Sprint 8 · buffer L75 (« Regression tests exhaustifs » · DevOps CI/CD) — roadmap fonctionnellement close (21/21 modules gated à 100/100, 534 tests verts, 5 gates statiques). Recherche d'une incohérence de reproductibilité réelle plutôt qu'un correctif doc cosmétique. Deux défauts réels trouvés et corrigés, tous deux dans qa/regression.

Défaut #1 (PRIORITAIRE · bug CI réel) — le gate check-regression était cassé en checkout propre

  • Symptôme : ci/check_regression.sh (l.52-53) exige que qa/regression/out/regression_run.json existe dans le dépôt, puis compare un run frais à ce fichier commité (baseline byte-identique).
  • Contradiction : ce même fichier était .gitignoreé (« non déterministe (temps machine) → jamais commitée ») → jamais présent dans un checkout propre. Le job Gitea check-regression ne fait que checkout + bash check_regression.sh, aucune étape ne génère le fichier. Conséquence : le gate échouait sur CHAQUE run CI propre (artefact absent du dépôt). Il ne « passait » qu'en local, par la présence d'un regression_run.json non suivi laissé par un run manuel. Le commentaire de ci.yml disait déjà « le regression_run.json commité » — intention claire du commit précédent, jamais concrétisée (fichier resté ignoré).
  • Vérif de faisabilité (#1 analyser) : l'artefact run est byte-déterministe — clés {ran,passed,failures,...} + path relatif, aucun horodatage/hôte/ durée. Deux run successifs byte-identiques (vérifié). Le committer est donc licite et complète l'intention du gate.
  • Fix : run est désormais commité (baseline du gate) →
    • .gitignore : retrait de out/regression_run.json + note expliquant qu'il est commité parce que déterministe ;
    • README.md : section run réécrite (byte-déterministe · commité · baseline check_regression · distinction d'avec check_artifacts qui ne rejoue que build) ;
    • out/regression_run.json : ajouté au suivi (21 suites · 534 tests · PASS).
  • Preuve de morsure : fichier retiré (simule checkout propre) ⇒ gate exit 1 (artefact absent) — l'état exact en CI ; restauré ⇒ exit 0 (run == commité).

Défaut #2 (invariant manquant) — dérive silencieuse disque→CI non gardée

  • Gap : discovery.coverage_report prouvait le sens CI→disque (tout module gated a un tests/) mais pas l'inverse : un module gagnant un tests/ sur disque sans job CI n'entrait jamais dans la matrice, ses tests ne tournaient jamais, et la couverture ne le voyait pas (elle n'itère que les suites dérivées du CI) — la matrice restait « PASS » en sous-comptant en silence. Même classe de dérive que « demo 18→21 », direction opposée.
  • Fix : nouvel invariant INV4
    • discovery.disk_test_modules() : marche disque pure listant tout module portant un tests/ (POSIX, trié, déterministe) ;
    • coverage_report : champ orphan_tests_dirs = disk ci_paths ; ok exige désormais not orphan_tests_dirs ;
    • regression.schema.json : orphan_tests_dirs ajouté (required · strict) ;
    • regression_gen.py : message INV4 surface les orphelins ;
    • tests/test_regression.py : +2 tests (sous-ensemble disque⊆CI sur le dépôt réel ; preuve de morsure monkeypatch d'un orphelin ⇒ ok=False).
  • Preuve de morsure end-to-end : mkdir zz_orphan/tests + buildbuild refusé INV4 … orphan_tests_dirs=['zz_orphan'] ; répertoire retiré ⇒ build OK.

Anti-invention (#6) : rien inventé — les deux gates régénèrent la vérité (run frais / couverture recomputée) au lieu de figer un compteur.

Régénération des consommateurs (mémoire projet) : l'édition des tests + du README de qa/regression a fait dériver qa/audit_4big/out/quality_report.json (evidence « README.md 3710→4236 octets » et « 24→26 méthodes test_* ») — régénéré, verdict PASS · 21/21 · min 100. Totaux matrice 534/21 inchangés : le harnais qa/regression est self-exclu (INV3) → +2 méthodes test_* n'affectent pas la matrice.

Vérifs : 5 gates locaux verts (guard_constraints/validate_json/check_docs/ check_artifacts/check_regression) ; ci.yml YAML valide ; tests harnais 26/26 OK (régression) + 34/34 OK (audit_4big) ; matrice 534/534 · 21/21 · PASS ; artefacts out/ reproductibles à l'identique.

Hors périmètre worker (VPS · #8) : néant (stdlib pur en-repo ; enregistrement du runner Gitea toujours du ressort DevOps).

Auto-score 4Big : 96/100.