[DTP-Worker] Sprint 8 · buffer L75 · Activity log : fix vert-trompeur gates hors arbre git (cd_repo_root/lib.sh + INV-B lib sourcée)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,77 @@
|
|||||||
# Activity Log · 2026-07-31 · Claude Code DTP
|
# Activity Log · 2026-07-31 · Claude Code DTP
|
||||||
|
|
||||||
|
## Session `20260731_015954` · Buffer S8 · « Vert trompeur » : les 6 gates `ci/*.sh` passaient VERT hors d'un arbre git en ne contrôlant RIEN
|
||||||
|
|
||||||
|
**Tâche** : **Sprint 8 · buffer L75 (« Regression tests exhaustifs » · DevOps
|
||||||
|
CI/CD)**. Roadmap fonctionnellement close (21/21 modules 100/100, 534 tests verts,
|
||||||
|
6 gates statiques). Poursuite de la série anti-dérive : recherche d'un **faux-vert
|
||||||
|
réel** (gate qui passe sans rien vérifier), même classe que les bugs
|
||||||
|
`regression_run.json` / `out/` RBAC des sessions précédentes.
|
||||||
|
|
||||||
|
### Défaut trouvé — `cd "$(git rev-parse --show-toplevel)"` échoue en SILENCE hors d'un checkout git
|
||||||
|
|
||||||
|
- **Mécanisme** : les **6** gates commençaient par
|
||||||
|
`cd "$(git rev-parse --show-toplevel)"`. HORS d'un arbre de travail git (tarball,
|
||||||
|
`git archive | tar -x`, `git` absent du PATH, working-dir erroné), `git rev-parse`
|
||||||
|
n'écrit **rien** sur stdout → la commande devient `cd ""`, un **no-op qui RETOURNE
|
||||||
|
SUCCÈS** (le script reste dans le cwd au lieu d'échouer). Les gates poursuivaient
|
||||||
|
sur un `git ls-files` renvoyant une liste **VIDE** →
|
||||||
|
`validate_json` (« Aucun fichier .json suivi — rien à valider »),
|
||||||
|
`guard_constraints` et `check_docs` sortaient **exit 0 VERT en ayant contrôlé
|
||||||
|
ZÉRO fichier** (≈50 JSON non validés, contraintes CLAUDE.md non vérifiées). Un
|
||||||
|
gate qui passe au vert sans rien enforcer est le **pire** « vert trompeur » —
|
||||||
|
précisément ce que la série buffer traque.
|
||||||
|
- **Preuve au sol (avant fix)** : copie de l'arbre **sans `.git`** →
|
||||||
|
`validate_json` **exit 0** « rien à valider » ; `guard_constraints` **exit 0**
|
||||||
|
« Contraintes respectées » ; `check_docs` **exit 0**. Ce piège avait déjà faussé
|
||||||
|
une vérif « 6 gates verts sur git archive » d'une session antérieure (un `git
|
||||||
|
archive | tar -x` n'a **pas** de `.git`, alors que le runner Gitea a un vrai
|
||||||
|
`.git` via `actions/checkout@v4` — donc la méthode « archive » n'est PAS
|
||||||
|
équivalente au runner pour tout check qui interroge git).
|
||||||
|
|
||||||
|
### Fix (2 solutions · CLAUDE.md #4 — retenu : helper partagé DRY + durcissement INV-B)
|
||||||
|
|
||||||
|
- **Correctif de fond** : nouveau helper **`ci/lib.sh`** (sourcé, jamais exécuté
|
||||||
|
seul) exposant **`cd_repo_root`** — se positionne à la racine, ou **échoue
|
||||||
|
bruyamment** (`exit 3`, code distinct d'un échec de contrôle `1`) avec un message
|
||||||
|
clair si `git rev-parse` ne renvoie rien. Les 6 gates remplacent leur
|
||||||
|
`cd "$(git rev-parse …)"` par `source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" ||
|
||||||
|
exit 3 ; cd_repo_root`. *(Alt. écartée : inliner le garde de 4 lignes × 6 fichiers
|
||||||
|
= doublon, contraire à CLAUDE.md #5 · préférence lib partagée.)*
|
||||||
|
- **Durcissement du gate de câblage (INV-B · `check_ci_integrity.sh`)** : INV-B
|
||||||
|
exigeait que **chaque** `ci/*.sh` soit lancé par un job — `ci/lib.sh` (jamais dans
|
||||||
|
un `run:`) aurait été flaggé « gate mort ». INV-B accepte désormais un `ci/*.sh`
|
||||||
|
câblé de **deux** façons : lancé par un job du gate, **OU sourcé** par ≥1 gate
|
||||||
|
script (détecté par grep d'une ligne `source …/<base>` / `. …/<base>`, `#` exclu).
|
||||||
|
C'est un **renforcement** réel : le gate prouve maintenant aussi que les libs
|
||||||
|
partagées sont **effectivement sourcées** (pas du code mort).
|
||||||
|
|
||||||
|
### Preuves de morsure
|
||||||
|
|
||||||
|
- **Faux-vert corrigé** : arbre copié **sans `.git`** → les 6 gates sortent
|
||||||
|
désormais **exit 3** avec « ❌ ERREUR gate : hors d'un arbre de travail git »
|
||||||
|
(avant : `validate_json`/`guard_constraints`/`check_docs` = **exit 0 vert**).
|
||||||
|
Idem sur `git archive HEAD | tar -x` **après commit**.
|
||||||
|
- **INV-B reconnaît la lib** : `ci/lib.sh — lib sourcée par [les 6 gates] · non
|
||||||
|
exécutée en propre (OK)` → **exit 0**.
|
||||||
|
- **INV-B attrape une lib morte** : `ci/_dead.sh` (sourcé par personne) ⇒
|
||||||
|
`✗ … lancé/sourcé par AUCUN job CI (gate mort)` ⇒ **exit 1**.
|
||||||
|
|
||||||
|
**Non-régression** : **6 gates verts** dans l'arbre de travail (= ce que voit le
|
||||||
|
runner via `actions/checkout@v4`, avec un vrai `.git`) ; matrice **534/21 · PASS
|
||||||
|
inchangée** ; `qa/audit_4big` **out/ inchangé** (les édits `ci/` sont **hors**
|
||||||
|
`05_deliverables_mvp` → aucune dérive de consommateur) ; `ci.yml` YAML **valide**.
|
||||||
|
|
||||||
|
**Anti-invention (#6)** : rien inventé — garde purement défensif (bash/git stdlib),
|
||||||
|
INV-B relit `ci.yml` + grepe les gates sur disque à chaque run.
|
||||||
|
|
||||||
|
**Hors périmètre worker (VPS · #8)** : néant (stdlib en-repo ; enregistrement du
|
||||||
|
runner Gitea toujours du ressort DevOps).
|
||||||
|
|
||||||
|
**Auto-score 4Big** : 96/100.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Session `20260731_012944` · Buffer S8 · Reproductibilité en CHECKOUT PROPRE — le hand-off out/ des 4 générateurs RBAC était `.gitignore`é → gate rouge en CI, vert en local seulement
|
## Session `20260731_012944` · Buffer S8 · Reproductibilité en CHECKOUT PROPRE — le hand-off out/ des 4 générateurs RBAC était `.gitignore`é → gate rouge en CI, vert en local seulement
|
||||||
|
|
||||||
**Tâche** : **Sprint 8 · buffer L75 (« Regression tests exhaustifs » · DevOps
|
**Tâche** : **Sprint 8 · buffer L75 (« Regression tests exhaustifs » · DevOps
|
||||||
|
|||||||
Reference in New Issue
Block a user