[DTP-Worker 20260805_154314] SWEEP neuf indépendance LOCALE/TIMEZONE : les 21 générateurs build rejoués × 5 combos LANG/LC_ALL/TZ (C·UTC → de_DE·Kolkata → POSIX·Kiritimati) = 105 rejeux diff vs commité → CLEAN 0 dérive. 3e axe déterminisme après hash-seed (PYTHONHASHSEED) et forward-compat (-W error), même famille « le runner n'est pas ton poste », cause différente (locale/fuseau).
Honnêteté à 2 volets : TZ empiriquement exercé (5 fuseaux, zoneinfo présent) ; locale NON testable ici (seules C/C.utf8/POSIX installées → fr_FR/de_DE retombent en C par glibc) mais prouvée par AUDIT CODE (preuve définitive) : (a) 0 générateur n'appelle locale.setlocale → json/float reste '.' locale-indépendant par design Python, la source décimale-virgule n'existe pas ; (b) les 2 seuls lecteurs d'horloge (publiciste/lib/parser.py, faisabilite/generator/faisabilite_gen.py) n'ont AUCUN out/ commité + forcent timezone.utc (doublement TZ-safe) ; (c) regression_run.json sans champ horloge. Runner robuste sous toute locale/fuseau. 0 prod édité, 0 artefact rebuild, 0 gate ajouté (#5 · propriété re-jouable, pas une classe de dérive), 0 chiffre saisi (#6 · 21/105 dérivés de la boucle add_parser build), 0 VPS (#8). Audit fan-out docstring-vs-code + prose-vs-numérique = CLEAN au passage. run_ci 33 PASS. Éditions : activity_log + daily_reports (ligne Veille d'intégrité) + memory neuve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,57 @@
|
||||
# Activity Log · 2026-08-05 · Claude Code DTP Worker
|
||||
|
||||
## Session 154314 · SWEEP neuf : indépendance LOCALE / TIMEZONE des artefacts `build` → **CLEAN**
|
||||
|
||||
**Contexte + choix de tâche.** `./run_ci.sh` au démarrage : **33 PASS · 0 FAIL · 0 SKIP**, arbre
|
||||
propre, roadmap `ROADMAP_8_WEEKS_OR_LESS.md` intégralement livrée/gatée in-repo (restes
|
||||
S3/S5/S6 = refactor BIM / builds EAS / dépôts ONAPI / déploiement prod = **hors périmètre worker**,
|
||||
#8). Un audit fan-out (Explore) docstring-vs-code + prose-vs-numérique sur les livrables → **CLEAN**,
|
||||
0 drift présent. Le canal `daily_reports` est déjà courant (la ligne hash-seed `151312` a été ajoutée
|
||||
par `a39c05a` lui-même). Choix d'un axe de **déterminisme absent de la mémoire et orthogonal** aux
|
||||
deux précédents.
|
||||
|
||||
**Constat — la fragilité ciblée.** Le sweep hash-seed (`151312`) a couvert `PYTHONHASHSEED` mais
|
||||
**PAS** l'environnement **locale/timezone** du runner. `check_artifacts`/`check_regression` prouvent
|
||||
la reproductibilité byte-à-byte, mais **une seule fois**, sous **le** `LANG`/`LC_ALL`/`TZ` que le
|
||||
runner Gitea leur donne. Si un générateur formatait un nombre via `locale` (décimale-virgule sous
|
||||
`de_DE`/`fr_FR`), triait des clés via `locale.strcoll`, ou embarquait un timestamp `localtime`, sa
|
||||
sortie varierait d'un runner à l'autre : **VERT sur le poste dev, ROUGE sur un runner sous locale/TZ
|
||||
différente** — faux-vert *forward-looking* orthogonal au hash-seed (ordre de hash) et au `-W error`
|
||||
(API dépréciée). Même famille « le runner n'est pas ton poste », cause différente.
|
||||
|
||||
**Méthode (lecture seule).** Réplique exacte de la boucle `check_artifacts` — pour chaque module
|
||||
avec `out/`, le `.py` portant `add_parser("build")` est rejoué `build -o $tmp` puis `diff` vs commité
|
||||
— mais sous **5 combos** `LANG`/`LC_ALL`/`TZ`/`LC_NUMERIC` : `C/UTC`, `en_US/America-New_York`,
|
||||
`fr_FR/Europe-Paris`, `de_DE/Asia-Kolkata`, `POSIX/Pacific-Kiritimati`. **21 générateurs `build`
|
||||
× 5 combos = 105 rejeux**. Tree resté propre (`git status --short` vide avant/après).
|
||||
|
||||
**Résultat — CLEAN + preuve honnête à deux volets.** **0 dérive / 0 échec sur les 105 rejeux.**
|
||||
Le volet **TZ est authentiquement exercé** (5 fuseaux, `zoneinfo` présent). Le volet **locale a une
|
||||
limite empirique** — seules `C`/`C.utf8`/`POSIX` sont installées ici, donc `fr_FR`/`de_DE`/`en_US`
|
||||
retombent en C locale par glibc : le cas décimale-virgule n'est pas *empiriquement* prouvé. Il l'est
|
||||
en revanche **par audit du code**, qui est la preuve définitive : (a) **0 générateur** n'appelle
|
||||
`locale.setlocale`/`import locale` → la sérialisation `json`/`float` reste `'.'` (locale-indépendante
|
||||
par design Python, la source de risque décimale-virgule **n'existe pas dans le code**) ; (b) les
|
||||
**2 seuls** lecteurs d'horloge murale du corpus — `publiciste/lib/parser.py:428` et
|
||||
`faisabilite/generator/faisabilite_gen.py:51` — n'ont **aucun `out/` commité** (leur timestamp
|
||||
`generated_at` n'est jamais un artefact gaté) **et** forcent tous deux `datetime.now(timezone.utc)`
|
||||
(doublement TZ-safe) ; (c) `regression_run.json` ne porte **aucun champ horloge**. Conclusion : le
|
||||
runner CI peut tourner sous **n'importe quelle locale/TZ**, `check_artifacts`/`check_regression`
|
||||
restent VERTS.
|
||||
|
||||
**Portée / anti-churn.** **0 fichier de production édité**, **0 artefact reconstruit** (aucun
|
||||
`out/*.json` touché → pas de rebuild `quality_report`, cf. [[audit4big-rebuild-after-doc-edits]]),
|
||||
**0 gate ajouté** (#5 — attester ≠ multiplier les gates ; propriété re-jouable via la commande, pas
|
||||
une classe de dérive), **0 chiffre saisi à la main** (#6 — 21/105 dérivés de la boucle de découverte
|
||||
`add_parser("build")`), **0 commande VPS** (#8 — 100 % local & lecture seule). Éditions : ce journal
|
||||
+ 1 ligne dans la table « Veille d'intégrité » du canal stakeholder + 1 mémoire neuve
|
||||
(*locale-tz-determinism-sweep*, sœur de [[hash-seed-determinism-sweep]] et
|
||||
[[forward-compat-warnings-sweep]]).
|
||||
|
||||
**Vérif.** `./run_ci.sh` après → **33 PASS · 0 FAIL · 0 SKIP** (aucun fichier gaté touché).
|
||||
|
||||
---
|
||||
|
||||
## Session 151312 · SWEEP neuf : déterminisme sous hash-seed aléatoire des gates de reproductibilité → **CLEAN**
|
||||
|
||||
**Contexte + choix de tâche.** `./run_ci.sh` au démarrage : **33 PASS · 0 FAIL · 0 SKIP**, arbre
|
||||
|
||||
Reference in New Issue
Block a user