Files
oto-enterprise-os-dtp/05_activity_log/2026-08-05.md
T
Claude Code DTP Worker b7ffb6448f [DTP-Worker 20260805_001109] Nouveau gate check-mobile-workflow : la structure de mobile-build.yml devient opposable au merge (surface mutation-testée UNGATED, 1re couverture) → 32→33 jobs
- ci/check_mobile_workflow.sh (8e gate statique) · 4 invariants lus dans le fichier (#6) :
  MOB-1 bien-formé (YAML strict si PyYAML) · MOB-2 aucun secrets. en if: de job
  (portabilité act/Gitea, verrouille le correctif 234104) · MOB-3 builds gatés sur
  needs.preflight.outputs.has_token (activation différée #6/#8) · MOB-4 contrat outputs
  (déclarés==référencés==alimentés, 0 dangling).
- Preuve UNGATED avant ajout : réintroduire secrets. en if: de job → 7/7 gates statiques verts.
- Gate mutation-testé : 5 mutations toutes ROUGES, fichier propre re-VERT.
- Câblé dans ci.yml + gate.needs ; check-ci-integrity INV-A/B verts ; run_ci auto → 33 PASS.
- ci/README.md : ligne §1 + détail §2 + nuance « Second workflow ».
- 0 nouveau module · 0 chiffre inventé · 0 edition prod hors CI · aucune commande VPS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-05 00:21:58 +00:00

5.5 KiB

Activity Log · 2026-08-05 · Claude Code DTP Worker

Session 001109 · Nouveau gate check-mobile-workflow — la structure de mobile-build.yml devient opposable au merge (surface mutation-testée UNGATED, 1er contrôle) → 1 gate ajouté + câblé · 32→33 jobs

Contexte + choix de tâche. ./run_ci.sh au démarrage : 32 PASS · 0 FAIL · 0 SKIP, arbre propre. Roadmap ROADMAP_8_WEEKS_OR_LESS.md intégralement livrée/gatée (8 sprints). Les 4 sessions du 08-04 (221055, 224101, 231101, 234104) avaient saturé les surfaces d'audit read-only (inter-artefacts, dérive non-gatée, attestation stakeholder) puis durci mobile-build.yml (pattern preflight-output, portable GitHub/Gitea). Cette dernière édition a laissé une queue : son propre log notait « Aucun gate ne linte la structure de mobile-build.yml (check-ci-integrity ne verrouille QUE ci.yml) ». Autrement dit le correctif de portabilité qu'elle venait de poser pouvait régresser en silence — exactement la classe « marche dans ma tête, casse le jour où on en a besoin » (mémoire mobile-build-secrets-if-gating : « workflow HORS gate.needsrun_ci won't catch a regression »). La valeur honnête du jour : fermer cette queue en rendant la structure de mobile-build.yml opposable au merge. NON redondant (#5) : c'est le premier contrôle de ce fichier.

Preuve d'absence de couverture AVANT d'ajouter le gate (discipline verify-uncovered-before-gating). Mutation : réintroduire l'exact anti-pattern corrigé en 234104secrets.EAS_TOKEN != '' dans un if: au niveau job. Résultat : 7/7 gates statiques restent VERTS. Surface confirmée non gatée (ni check_ci_integrity — scope CI=ci.yml — ni validate_json — scope .json). Fichier byte-restauré aussitôt (cp depuis backup tmp · jamais git clean).

Livrable : ci/check_mobile_workflow.sh (8ᵉ gate statique) + câblage. Le gate lit des FAITS dans le fichier (jamais une liste à la main · #6), 4 invariants :

  • MOB-1 · bien-formé — existe · name:/on:/jobs: + 3 jobs (preflight, build-ios, build-android) ; parse YAML strict exigé si PyYAML dispo, sinon awk seul (runner sans pip → best-effort, jamais un faux vert : MOB-2/3/4 en sont indépendants).
  • MOB-2 · portabilité0 secrets. dans un if: de job (^ if:). Le contexte secrets n'est pas exposé dans jobs.<id>.if (table d'availability GitHub Actions) → sur act/Gitea il s'évaluerait vide → SKIP silencieux. C'est la régression 234104 verrouillée.
  • MOB-3 · activation différée (#6/#8) — chaque job de build (run: eas build) est gaté sur needs.preflight.outputs.has_token → SKIP tant que le token absent, donc le workflow ne rend jamais le CI rouge avant activation Michel.
  • MOB-4 · contrat d'outputspreflight déclare has_token/has_repo, chaque needs.preflight.outputs.<X> référencé est déclaré (0 dangling) et chaque output déclaré est alimenté par un echo …>>$GITHUB_OUTPUT.

Bug corrigé pendant l'écriture (auto-vérification). 1er jet : preflight était classé « job de build » car un commentaire # … eas build … (l.108, entre deux jobs) était attribué au job précédent par le parseur awk. Corrigé en exigeant run:[[:space:]]*eas build (commande réelle, pas une mention). Après correctif : gate VERT sur le fichier propre.

Mutation-testing du gate lui-même (5 mutations · toutes ROUGES, fichier propre re-VERT). (1) YAML cassé (indent) · (2) secrets. en if: de job · (3) if: du job build-ios supprimé · (4) output fantôme référencé (has_tokenX) · (5) output has_repo non alimenté. Chaque mutation → exit 1 ; cp backup → gate re-VERT.

Câblage (garde check-ci-integrity INV-A/B vert). Job check-mobile-workflow ajouté à ci.yml (steps bash ci/check_mobile_workflow.sh) et à gate.needs. check_ci_integrity reconnaît le nouveau ci/*.sh comme câblé (lancé par un job du gate + il source lib.sh) → INV-A (gate.needs == tous jobs non-manuels) et INV-B (tout ci/*.sh câblé) restent verts. run_ci.sh (dérivé de gate.needs, sans liste en dur) l'inclut automatiquement → passage **32→33 jobs (8 gates statiques

  • 25 suites)**, zéro édition de run_ci.sh (#6, exactitude structurelle).

Doc (traçabilité, pas de dérive). ci/README.md : ligne §1 pour check-mobile-workflow, sous-section §2 détaillée (4 invariants + les 5 mutations), et nuance ajoutée à « Second workflow » (les jobs restent hors gate de merge, mais la structure du fichier est désormais gatée). Convention ci-readme-table-detail-in-section2 respectée : ligne §1 courte, détail en §2. Les mentions historiques « 7 gates re-verts » (§2, records de mutations passées) restent exactes en passé ; le nouveau record dit 8ᵉ gate.

Vérifications. bash ci/check_mobile_workflow.sh → VERT (4 invariants) ; 5 mutations → ROUGE ; python3 yaml.safe_load sur ci.yml → valide ; check_ci_integrity → VERT (câblage intègre) ; ./run_ci.sh33 PASS · 0 FAIL · 0 SKIP. 1 gate ajouté (NON redondant : 1re couverture d'un fichier mutation-testé ungated · pas un doublon #5) · 1 job CI câblé · 0 nouveau module · 0 chiffre inventé (#6) · 0 édition de production hors CI · aucune commande VPS (#8) · aucun git clean.