[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:
Claude Code DTP Worker
2026-07-31 02:10:46 +00:00
parent 1da26db22e
commit 9403e58f67
+72
View File
@@ -1,5 +1,77 @@
# 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
**Tâche** : **Sprint 8 · buffer L75 (« Regression tests exhaustifs » · DevOps