[DTP-Worker 20260805_181325] Auto exec · session 20260805_181325
CI / Contraintes NON-NÉGOCIABLES (CLAUDE.md) (push) Has been cancelled
CI / Validation JSON (schémas Faisabilité) (push) Has been cancelled
CI / Qualité documentaire (liens + 4Big) (push) Has been cancelled
CI / Reproductibilité des artefacts out/ (build == commité) (push) Has been cancelled
CI / Fraîcheur matrice de régression (run == commité) (push) Has been cancelled
CI / Intégrité du câblage CI (gate agrège tout · gates statiques verrouillés) (push) Has been cancelled
CI / Intégrité des chiffres du README (valeur == artefact cité · (push) Has been cancelled
CI / Intégrité mobile-build.yml (gating portable · activation différée · (push) Has been cancelled
CI / Publiciste · parser + schéma + generator (unittest) (push) Has been cancelled
CI / RBAC · 50 rôles + schéma (unittest) (push) Has been cancelled
CI / Faisabilité · générateur 4 volets + round-trip (unittest) (push) Has been cancelled
CI / RBAC · fixtures ERPNext (Role + Custom DocPerm) (push) Has been cancelled
CI / RBAC · plan User Permission (row-level) (push) Has been cancelled
CI / RBAC · Role Profile (bundles par portail) (push) Has been cancelled
CI / RBAC · run-book d'application unifié (agrégat 3 volets) (push) Has been cancelled
CI / Faisabilité · dossier bancable trilingue FR/EN/ES (push) Has been cancelled
CI / CRM · workflow vente ERPNext (lead → CONFOTUR) (push) Has been cancelled
CI / CRM · DocType porteur OTO Dossier Vente (push) Has been cancelled
CI / CRM · barème commissions vendeurs (push) Has been cancelled
CI / CRM · Financement Bancaire (gate hypothécaire RD) (push) Has been cancelled
CI / Fiscal · e-CF DGII (Compupar) (push) Has been cancelled
CI / Frontend · Workspaces 5 portails rôle (push) Has been cancelled
CI / Legal · DocType CONFOTUR Application (push) Has been cancelled
CI / QA · Audit 5D conformité (push) Has been cancelled
CI / SEO · mots-clés trilingues + schema.org + hreflang (push) Has been cancelled
CI / Chat OTOIA · montage par portail (Custom Block) (push) Has been cancelled
CI / QA · Audit 4Big (95+/100 sur 100% deliverables) (push) Has been cancelled
CI / Démo · Scénarios (run-sheet P07 banquier / P05 client) (push) Has been cancelled
CI / QA · Matrice de régression exhaustive (Sprint 8) (push) Has been cancelled
CI / DevOps · Run-book de déploiement VPS unifié (Sprint 8) (push) Has been cancelled
CI / QA · Matrice d'acceptation / traçabilité MVP (Sprint 8) (push) Has been cancelled
CI / Mobile · config app Expo/EAS (navigation par rôle) (push) Has been cancelled
CI / PIE · manifest de dépendances (Annexe 12 · V10.1) (push) Has been cancelled
CI / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
CI / Contraintes NON-NÉGOCIABLES (CLAUDE.md) (push) Has been cancelled
CI / Validation JSON (schémas Faisabilité) (push) Has been cancelled
CI / Qualité documentaire (liens + 4Big) (push) Has been cancelled
CI / Reproductibilité des artefacts out/ (build == commité) (push) Has been cancelled
CI / Fraîcheur matrice de régression (run == commité) (push) Has been cancelled
CI / Intégrité du câblage CI (gate agrège tout · gates statiques verrouillés) (push) Has been cancelled
CI / Intégrité des chiffres du README (valeur == artefact cité · (push) Has been cancelled
CI / Intégrité mobile-build.yml (gating portable · activation différée · (push) Has been cancelled
CI / Publiciste · parser + schéma + generator (unittest) (push) Has been cancelled
CI / RBAC · 50 rôles + schéma (unittest) (push) Has been cancelled
CI / Faisabilité · générateur 4 volets + round-trip (unittest) (push) Has been cancelled
CI / RBAC · fixtures ERPNext (Role + Custom DocPerm) (push) Has been cancelled
CI / RBAC · plan User Permission (row-level) (push) Has been cancelled
CI / RBAC · Role Profile (bundles par portail) (push) Has been cancelled
CI / RBAC · run-book d'application unifié (agrégat 3 volets) (push) Has been cancelled
CI / Faisabilité · dossier bancable trilingue FR/EN/ES (push) Has been cancelled
CI / CRM · workflow vente ERPNext (lead → CONFOTUR) (push) Has been cancelled
CI / CRM · DocType porteur OTO Dossier Vente (push) Has been cancelled
CI / CRM · barème commissions vendeurs (push) Has been cancelled
CI / CRM · Financement Bancaire (gate hypothécaire RD) (push) Has been cancelled
CI / Fiscal · e-CF DGII (Compupar) (push) Has been cancelled
CI / Frontend · Workspaces 5 portails rôle (push) Has been cancelled
CI / Legal · DocType CONFOTUR Application (push) Has been cancelled
CI / QA · Audit 5D conformité (push) Has been cancelled
CI / SEO · mots-clés trilingues + schema.org + hreflang (push) Has been cancelled
CI / Chat OTOIA · montage par portail (Custom Block) (push) Has been cancelled
CI / QA · Audit 4Big (95+/100 sur 100% deliverables) (push) Has been cancelled
CI / Démo · Scénarios (run-sheet P07 banquier / P05 client) (push) Has been cancelled
CI / QA · Matrice de régression exhaustive (Sprint 8) (push) Has been cancelled
CI / DevOps · Run-book de déploiement VPS unifié (Sprint 8) (push) Has been cancelled
CI / QA · Matrice d'acceptation / traçabilité MVP (Sprint 8) (push) Has been cancelled
CI / Mobile · config app Expo/EAS (navigation par rôle) (push) Has been cancelled
CI / PIE · manifest de dépendances (Annexe 12 · V10.1) (push) Has been cancelled
CI / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
This commit is contained in:
@@ -9,6 +9,21 @@
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
|
# Mode UTF-8 forcé pour TOUS les jobs (builds + suites + gates) — indépendance
|
||||||
|
# LOCALE du runner. Chaque générateur clôt son `build` par un print(✅ / accents
|
||||||
|
# français) vers stdout, dont l'encodage suit la locale. Sur un runner à locale
|
||||||
|
# ASCII (image minimale : LC_ALL=C sans coercition PEP 538, PYTHONUTF8 non posé),
|
||||||
|
# ce print lève UnicodeEncodeError APRÈS écriture des fichiers → `check-artifacts`
|
||||||
|
# voit un exit non-nul (« build a échoué ») et les 25 suites plantent : tout le
|
||||||
|
# gate passe ROUGE en silence le jour où l'image runner change, alors qu'il est
|
||||||
|
# VERT sur le poste dev (UTF-8) — classe « le runner n'est pas ton poste ».
|
||||||
|
# PYTHONUTF8=1 (PEP 540) impose stdout/stdin/défaut-fichier en UTF-8 partout,
|
||||||
|
# indépendamment de LANG/LC_ALL → tous les jobs deviennent locale-robustes.
|
||||||
|
# Verrouillé par ci/check_ci_integrity.sh (INV-C) pour ne pas disparaître en
|
||||||
|
# silence. Miroir local : run_ci.sh exporte la même variable.
|
||||||
|
env:
|
||||||
|
PYTHONUTF8: "1"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|||||||
@@ -1,5 +1,60 @@
|
|||||||
# Activity Log · 2026-08-05 · Claude Code DTP Worker
|
# Activity Log · 2026-08-05 · Claude Code DTP Worker
|
||||||
|
|
||||||
|
## Session 181325 · FIX RÉEL défaut locale-runner : le gate est ROUGE en silence sous locale ASCII → **VERROUILLÉ UTF-8**
|
||||||
|
|
||||||
|
**Choix de tâche.** `./run_ci.sh` au démarrage = **33 PASS**, arbre propre, roadmap
|
||||||
|
`ROADMAP_8_WEEKS_OR_LESS.md` **intégralement livrée/gatée in-repo** : les 15 promesses de
|
||||||
|
l'`acceptance_matrix` sont **toutes `status=in_repo`**, chaque reste (BIM runtime, builds EAS,
|
||||||
|
dépôts ONAPI, déploiement prod) explicitement `out_of_scope` VPS (#8). Un fan-out Explore
|
||||||
|
docstring-vs-code / prose-vs-numérique sur les livrables → **0 dérive** (repo propre). J'ai donc
|
||||||
|
attaqué un **axe de robustesse absent de la mémoire** et, contrairement aux 3 sweeps déterministes
|
||||||
|
précédents (hash-seed / locale-TZ / forward-compat, tous **CLEAN → attestation**), celui-ci a
|
||||||
|
révélé un **défaut RÉEL présent**.
|
||||||
|
|
||||||
|
**La faille — la coercition PEP 538 masquait le vrai cas.** Le sweep locale-TZ (`154314`) a rejoué
|
||||||
|
les builds sous `LANG=C`, mais Python **coerce silencieusement `C` → `C.UTF-8`** (PEP 538) : sous
|
||||||
|
`LANG=C` seul, `getpreferredencoding()` = **UTF-8** → le mode d'échec ASCII n'a **jamais été
|
||||||
|
exercé**. En neutralisant la coercition (`PYTHONUTF8=0 PYTHONCOERCECLOCALE=0 LC_ALL=C`),
|
||||||
|
l'encodage par défaut redevient **`ANSI_X3.4-1968` (ASCII)** — la config d'un **runner minimal**.
|
||||||
|
|
||||||
|
**Constat — 20 des 21 générateurs `build` PLANTENT.** Réplique de la boucle `check_artifacts` sous
|
||||||
|
locale ASCII neutralisée : **20/21 builds crashent** (`UnicodeEncodeError`), les 25 suites
|
||||||
|
échouent aussi. Cause : chaque générateur clôt `cmd_build` par un `print("✅ Bundle … généré" /
|
||||||
|
accents)` vers **stdout**, dont l'encodage suit la locale. Les fichiers sont écrits sans souci
|
||||||
|
(`encoding='utf-8'` explicite partout : 37 writes annotés, 0 write nu), mais le **print cosmétique
|
||||||
|
final** lève `UnicodeEncodeError` **après** écriture → exit non-nul → `check-artifacts` voit
|
||||||
|
« build a échoué » **ROUGE**. Vert aujourd'hui (runner UTF-8), **rouge en silence** le jour où
|
||||||
|
l'image runner change = classe « le runner n'est pas ton poste », mais **défaut, pas attestation**.
|
||||||
|
|
||||||
|
**Correctif — single-source à la frontière d'invocation, 0 fichier de production.** `PYTHONUTF8=1`
|
||||||
|
(PEP 540) impose stdout/stdin/défaut-fichier en UTF-8 **quelle que soit la locale**. Posé **une
|
||||||
|
fois** en `env:` **au niveau workflow** de `ci.yml` → s'applique à **tous les jobs** (21 builds +
|
||||||
|
25 suites + gates statiques). Miroir local : `run_ci.sh` `export PYTHONUTF8=1`. **Aucun des 20
|
||||||
|
modules touché** (anti-churn #5 — la fragilité est un contrat d'environnement d'invocation, pas 20
|
||||||
|
bugs à patcher un par un ; le fix vit là où le runner est configuré, comme le gate `cd`-ait déjà
|
||||||
|
dans le module pour fixer le contrat de CWD).
|
||||||
|
|
||||||
|
**Verrou — l'absence du fix est INVISIBLE sur runner UTF-8** (retirer l'`env:` reste vert
|
||||||
|
aujourd'hui) : classe de « vert trompeur » exactement traquée par ce dépôt. J'ancre donc le fix dans
|
||||||
|
le gate **existant** `check_ci_integrity.sh` (**INV-C**, pas de nouveau fichier gate #5) : il lit
|
||||||
|
l'`env:` top-level de `ci.yml` et exige `PYTHONUTF8: "1"`. **Teeth mutation-vérifié** : retrait de
|
||||||
|
la ligne `env:` → INV-C **mord** (exit 1) ; restauré → vert. INV-A/INV-B intacts (l'`env:` est
|
||||||
|
avant `jobs:` → hors du parseur de jobs).
|
||||||
|
|
||||||
|
**Preuve end-to-end.** `run_ci.sh` sous `env -u PYTHONUTF8 PYTHONCOERCECLOCALE=0 LC_ALL=C` (config
|
||||||
|
qui était **totalement ROUGE** avant) = **33 PASS · 0 FAIL** grâce au `export` miroir. Build-loop
|
||||||
|
sous `PYTHONUTF8=1 + LC_ALL=C` = **21 artefacts byte-identiques** (0 dérive, le fix ne change aucun
|
||||||
|
octet de sortie). `run_ci.sh` normal = **33 PASS**.
|
||||||
|
|
||||||
|
**Portée / anti-churn.** 4 fichiers : `ci.yml` (env), `run_ci.sh` (miroir), `check_ci_integrity.sh`
|
||||||
|
(INV-C verrou), `ci/README.md` (§2 détail INV-C + « Deux → Trois invariants »). **0 fichier de
|
||||||
|
production**, **0 artefact rebuild** (aucun `out/` touché → pas de rebuild `quality_report`, cf.
|
||||||
|
[[audit4big-rebuild-after-doc-edits]]), **0 chiffre inventé** (#6 — 20/21 dérivés de la boucle),
|
||||||
|
**0 commande VPS** (#8). run_ci = **33 PASS · 0 FAIL · 0 SKIP**. Mémoire neuve
|
||||||
|
*utf8-locale-runner-fix* (sœur de [[locale-tz-determinism-sweep]] dont elle **corrige l'angle mort**).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Session 164319 · FIX régression RED : `quality_report.json` périmé après édition de doc → **VERT**
|
## Session 164319 · FIX régression RED : `quality_report.json` périmé après édition de doc → **VERT**
|
||||||
|
|
||||||
**Constat au démarrage.** `./run_ci.sh` = **32 PASS · 1 FAIL** — `check-artifacts` RED sur
|
**Constat au démarrage.** `./run_ci.sh` = **32 PASS · 1 FAIL** — `check-artifacts` RED sur
|
||||||
|
|||||||
+16
-1
@@ -181,7 +181,7 @@ puis commit.
|
|||||||
### `check_ci_integrity.sh`
|
### `check_ci_integrity.sh`
|
||||||
Prouve, en lisant `.gitea/workflows/ci.yml`, que le **câblage** du workflow tient —
|
Prouve, en lisant `.gitea/workflows/ci.yml`, que le **câblage** du workflow tient —
|
||||||
car le job `gate` est le **seul verrou de merge** : un check absent de son `needs:`
|
car le job `gate` est le **seul verrou de merge** : un check absent de son `needs:`
|
||||||
ne bloque **rien**, même rouge. Deux invariants :
|
ne bloque **rien**, même rouge. Trois invariants :
|
||||||
- **INV-A** — `gate.needs` == { tous les jobs définis } − { `gate` } − { jobs manuels }
|
- **INV-A** — `gate.needs` == { tous les jobs définis } − { `gate` } − { jobs manuels }
|
||||||
(un job manuel = gardé par `if: … workflow_dispatch …`, ex. `e2e-baseline`,
|
(un job manuel = gardé par `if: … workflow_dispatch …`, ex. `e2e-baseline`,
|
||||||
légitimement hors du gate push/PR car il exige un serveur live). Détecte un job
|
légitimement hors du gate push/PR car il exige un serveur live). Détecte un job
|
||||||
@@ -193,6 +193,21 @@ ne bloque **rien**, même rouge. Deux invariants :
|
|||||||
script (lib partagée `ci/lib.sh` — jamais un job propre). Un nouveau gate statique
|
script (lib partagée `ci/lib.sh` — jamais un job propre). Un nouveau gate statique
|
||||||
**non câblé** (script mort) ou **décâblé**, ou une **lib morte** (sourcée par
|
**non câblé** (script mort) ou **décâblé**, ou une **lib morte** (sourcée par
|
||||||
personne), casse le check.
|
personne), casse le check.
|
||||||
|
- **INV-C** — le workflow force le **mode UTF-8 de Python** (`env: PYTHONUTF8: "1"`
|
||||||
|
au niveau workflow → tous les jobs). Motif : chaque générateur clôt son `build`
|
||||||
|
par un `print("✅ …" / accents français)` vers stdout, dont l'encodage suit la
|
||||||
|
**locale du runner**. Sur une image runner ASCII (`LC_ALL=C` sans coercition
|
||||||
|
PEP 538, `PYTHONUTF8` non posé), ce print lève `UnicodeEncodeError` **après**
|
||||||
|
écriture des fichiers → `check-artifacts` voit un exit non-nul et les 25 suites
|
||||||
|
plantent : **tout le gate passe ROUGE le jour où l'image runner change**, alors
|
||||||
|
qu'il est VERT sur le poste dev (UTF-8) — classe « le runner n'est pas ton poste »
|
||||||
|
(sœur des sweeps hash-seed / locale-TZ / forward-compat, mais ici un **défaut
|
||||||
|
réel présent**, pas une simple attestation). `PYTHONUTF8=1` (PEP 540) impose
|
||||||
|
stdout/stdin/défaut-fichier en UTF-8 **partout** → 20 builds qui crashaient +
|
||||||
|
les suites redeviennent locale-robustes (prouvé : `run_ci.sh` sous
|
||||||
|
`LC_ALL=C` neutralisé = 33 PASS). Comme l'absence de cet `env:` est **invisible**
|
||||||
|
sur un runner UTF-8, INV-C l'**ancre** : le retirer casse ce gate au lieu de
|
||||||
|
dériver en silence. `run_ci.sh` **exporte la même variable** (miroir fidèle).
|
||||||
|
|
||||||
Ferme le trou laissé par les couvertures existantes (`audit_4big/registry`,
|
Ferme le trou laissé par les couvertures existantes (`audit_4big/registry`,
|
||||||
`qa/regression/discovery`) qui ne prouvent l'appartenance au gate que des jobs de
|
`qa/regression/discovery`) qui ne prouvent l'appartenance au gate que des jobs de
|
||||||
|
|||||||
@@ -148,6 +148,28 @@ while IFS= read -r script; do
|
|||||||
fi
|
fi
|
||||||
done < <(git ls-files 'ci/*.sh' | grep -vx 'ci/check_ci_integrity.sh')
|
done < <(git ls-files 'ci/*.sh' | grep -vx 'ci/check_ci_integrity.sh')
|
||||||
|
|
||||||
|
# --- INV-C : le workflow force le mode UTF-8 de Python (indépendance locale) --
|
||||||
|
# Chaque générateur clôt son `build` par un print(✅/accents) vers stdout ; sous
|
||||||
|
# une locale ASCII (runner minimal : LC_ALL=C, sans coercition PEP 538), ce print
|
||||||
|
# lève UnicodeEncodeError → `check-artifacts` ROUGE et les 25 suites plantent,
|
||||||
|
# EN SILENCE le jour où l'image runner change (VERT aujourd'hui car UTF-8). Le
|
||||||
|
# correctif est un `env: PYTHONUTF8: "1"` au niveau WORKFLOW (s'applique à tous
|
||||||
|
# les jobs). Comme son absence est invisible sur un runner UTF-8, on l'ancre ici :
|
||||||
|
# le retirer casse ce gate au lieu de dériver silencieusement. On lit l'`env:`
|
||||||
|
# top-level (indenté 2 espaces, AVANT `jobs:` → hors du parseur de jobs).
|
||||||
|
echo "== INV-C · le workflow force PYTHONUTF8 (I/O UTF-8 · indépendance locale runner) =="
|
||||||
|
utf8_mode="$(awk '
|
||||||
|
/^jobs:[[:space:]]*$/ { exit } # ne considérer que l’en-tête (avant jobs:)
|
||||||
|
/^env:[[:space:]]*$/ { inenv=1; next }
|
||||||
|
inenv && /^[^[:space:]]/ { inenv=0 } # fin du bloc env: (clé non indentée)
|
||||||
|
inenv && match($0, /^[[:space:]]+PYTHONUTF8:[[:space:]]*["'\'']?1["'\'']?[[:space:]]*$/) { print "1" }
|
||||||
|
' "$CI")"
|
||||||
|
if [[ "$utf8_mode" == "1" ]]; then
|
||||||
|
ok "workflow env: PYTHONUTF8=\"1\" → stdout/défaut-fichier UTF-8 sur tout runner (builds + suites locale-robustes)"
|
||||||
|
else
|
||||||
|
report "workflow SANS \`env: PYTHONUTF8: \"1\"\` top-level → gate locale-fragile (RED silencieux sur runner ASCII · cf. print ✅ en fin de build)"
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
if [[ "$FAIL" -eq 0 ]]; then
|
if [[ "$FAIL" -eq 0 ]]; then
|
||||||
echo -e "\033[32m✅ Câblage CI intègre (gate agrège tout job non-manuel · gates statiques verrouillés).\033[0m"
|
echo -e "\033[32m✅ Câblage CI intègre (gate agrège tout job non-manuel · gates statiques verrouillés).\033[0m"
|
||||||
|
|||||||
@@ -73,6 +73,13 @@ cd "$ROOT" || exit 3
|
|||||||
CI_YML=".gitea/workflows/ci.yml"
|
CI_YML=".gitea/workflows/ci.yml"
|
||||||
[ -f "$CI_YML" ] || { echo "run_ci.sh : $CI_YML introuvable." >&2; exit 3; }
|
[ -f "$CI_YML" ] || { echo "run_ci.sh : $CI_YML introuvable." >&2; exit 3; }
|
||||||
|
|
||||||
|
# Miroir de l'`env:` workflow de ci.yml — force le mode UTF-8 de Python pour
|
||||||
|
# tous les jobs rejoués ici, de sorte que ce miroir local reproduise fidèlement
|
||||||
|
# le gate même si le poste tourne sous une locale ASCII (LC_ALL=C). Sans cela,
|
||||||
|
# les générateurs (print ✅/accents en fin de `build`) et les suites planteraient
|
||||||
|
# ici alors qu'ils passent en CI (cf. ci.yml env PYTHONUTF8 · check_ci_integrity INV-C).
|
||||||
|
export PYTHONUTF8=1
|
||||||
|
|
||||||
MODE="all"
|
MODE="all"
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
--static) MODE="static" ;;
|
--static) MODE="static" ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user