94e9365cea
AGENTS_EXISTING_ASSETS.md §8 + fiche 03_agents/mobile affirmaient le runtime
courant « Expo SDK 54 · React 19.1.0 · RN 0.81.5 (upgrade 2026-07) EN PLACE ».
Faux : la directive Michel 85d2fa3 (audit 2026-08-03) + le package.json réel
vérifié disent Expo ~51.0.0 / React 18.2.0 / RN 0.74.5 / expo-router ~3.5.0,
l'upgrade 54 abandonné le 2026-07-27 (le backup native.bak-upgrade54-* est resté
sur ~51). Classe interdite CLAUDE.md « documenter sans vérifier existence
courante » + #6. Corrigé en distinguant runtime ACTUEL (51) vs cible REBUILD S5
(54, roadmap — décision P0 ouverte, non tranchée). Module mobile/app_config
(byte-gaté Expo 54 = cible) + roadmap NON touchés (corrects). Versions ungated
(vérifié : aucun gate ne pinne 0.81.5/19.1.0/18.2.0). Signal roadmap-vs-réel
surfacé à Michel dans le log. run_ci.sh 30 PASS 0 FAIL · zéro module · zéro gate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
208 lines
14 KiB
Markdown
208 lines
14 KiB
Markdown
# Activity Log · 2026-08-03 · Claude Code DTP Worker
|
||
|
||
## Session 013634 · Dérive ground-truth réelle : app mobile documentée « Expo 54 en place » alors que le runtime réel est **Expo 51** (upgrade 54 abandonné) — corrigée (#6)
|
||
|
||
**Contexte.** `./run_ci.sh` au démarrage : **30 PASS · 0 FAIL · 0 SKIP**, arbre propre.
|
||
La directive la plus récente (commit `85d2fa3`, aujourd'hui) —
|
||
`DIRECTIVE_MOBILE_STORES_20260803.md` — porte le Sprint 5 Mobile. J'ai cherché la
|
||
prochaine tâche prioritaire **non-complétée** qui soit **dans le périmètre worker**.
|
||
|
||
**Périmètre : l'essentiel de la directive Mobile est bloqué / hors-repo (#8).** Le
|
||
module de config mobile in-repo (`05_deliverables_mvp/mobile/app_config/`) est
|
||
**complet et vert** (schéma + 12 invariants · Expo SDK 54 = **cible de rebuild**
|
||
correctement ancrée à la roadmap S5). Les actions P1 (`mobile-build.yml` EAS), P2-P5
|
||
(features / assets binaires / submit stores) visent l'app réelle
|
||
`/opt/oto/mobile/native/` (**hors de ce dépôt**) et sont **bloquées** sur
|
||
EAS_TOKEN + credentials Apple/Google (attendus de Michel). Rien à construire ici.
|
||
|
||
**Défaut RÉEL trouvé (investigation read-only, aucune commande VPS).** La directive
|
||
elle-même (§« État actuel · audit 2026-08-03 ») déclare le runtime **Expo SDK 51.0.0**,
|
||
l'upgrade Expo 54 **abandonné le 2026-07-27**. Vérification indépendante du
|
||
`package.json` réel : `expo ~51.0.0` · `react 18.2.0` · `react-native 0.74.5` ·
|
||
`expo-router ~3.5.0` — et **même le backup `native.bak-upgrade54-*` est resté sur ~51**
|
||
(le bump 54 n'a jamais atterri). Or l'inventaire d'actifs
|
||
`AGENTS_EXISTING_ASSETS.md §8:63` affirmait « **Expo SDK 54 + React 19.1.0 + React
|
||
Native 0.81.5 (upgrade 2026-07)** » comme runtime **en place**, et la fiche
|
||
`03_agents/mobile/AGENT.md` recopiait ces versions (« Expo 54 en place »). C'est
|
||
**exactement la classe interdite** par CLAUDE.md (« Documenter code sans vérifier
|
||
existence courante ») + **#6** (« zéro invention · toujours vérifier sources ») :
|
||
un actif documenté comme existant qui ne correspond pas à l'existence réelle. Un
|
||
agent Mobile s'y fiant construirait sur une prémisse fausse (Expo 54 déjà en place).
|
||
|
||
**Correctif — chirurgical, sourcé, distinguant ACTUEL vs CIBLE-REBUILD.**
|
||
1. `AGENTS_EXISTING_ASSETS.md §8:63` : runtime **actuel** corrigé en Expo 51.0.0 /
|
||
React 18.2.0 / RN 0.74.5 / expo-router ~3.5.0 (vérifié `package.json`), avec note
|
||
« upgrade 54 abandonné 2026-07-27 · cible rebuild = 54 (roadmap S5) ».
|
||
2. `03_agents/mobile/AGENT.md` : 5 mentions de runtime-courant « Expo 54 / React
|
||
19.1.0 / RN 0.81.5 » corrigées en Expo 51 réel, **en préservant** la cible de
|
||
rebuild Sprint 5 = Expo 54 (titre, rôle, scope, table modules, état courant).
|
||
|
||
**Ce que je n'ai PAS touché (délibérément).** (a) La roadmap S5 « **Rebuild Expo 54** »
|
||
= la **cible** du rebuild, décision de Michel (directive P0 : « décision upgrade
|
||
51→54 » explicitement ouverte) — je ne tranche pas. (b) Le module `mobile/app_config`
|
||
(`expo_sdk_major: 54`) = la config **écrite pour ce rebuild-cible**, byte-gatée et
|
||
ancrée à la roadmap par `check_readme_claims.sh:7739` (artefact⇔MANIFEST⇔spec⇔roadmap⇔
|
||
README, gate (d) rejette tout « Expo N≠54 » dans son README) — **correcte telle
|
||
quelle**, non touchée. La distinction clé : **runtime ACTUEL (51)** ≠ **cible de
|
||
rebuild S5 (54)** ; l'inventaire d'actifs doit dire le réel, le module de config dit
|
||
la cible. Aucune contradiction — ils décrivent deux choses différentes.
|
||
|
||
**⚠️ SIGNAL À MICHEL (décision P0, non tranchée par moi).** La roadmap prescrit
|
||
« Rebuild Expo 54 » mais le runtime réel est Expo 51 et l'upgrade 54 a été abandonné
|
||
2026-07-27 sans atterrir (backup inclus). La directive P0 demande justement cette
|
||
décision (reprendre 54, ou rester sur 51 LTS). Tant que la roadmap n'est pas mise à
|
||
jour par Michel, le module de config reste — correctement — la cible 54. Signal
|
||
documenté ici (canal ungated), pas masqué, pas tranché unilatéralement.
|
||
|
||
**Sûreté (vérifiée AVANT édition).** Les littéraux de version `0.81.5`/`19.1.0`/
|
||
`18.2.0`/`0.74` n'apparaissent dans **aucun** gate (grep) ; `check_readme_claims.sh`
|
||
ne pinne ces fichiers que sur (l.239) un **compte d'agents** et (l.8071) l'**IP VPS +
|
||
noms Docker** — jamais la version Expo ; le gate Expo-SDK (l.7739) ne scanne que
|
||
`mobile/app_config/README.md`. Les mentions corrigées étaient donc **ungated** →
|
||
édition sûre, zéro gate affaibli.
|
||
|
||
**Vérifications.** `./run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP** (inchangé). `git
|
||
status` = 2 fichiers (`AGENTS_EXISTING_ASSETS.md` + `03_agents/mobile/AGENT.md`).
|
||
**Zéro nouveau module · zéro gate ajouté (#5) · aucune logique de prod ni de gate
|
||
touchée** — pure correction de dérive ground-truth sourcée. Aucune commande touchant
|
||
au VPS (#8) · aucun `git clean` <!-- ci-allow : mention de l'interdit absolu, jamais exécuté -->.
|
||
|
||
## Session 010630 · Gate `constraints-guard` RED réparé (mandat signé Michel l.35) + contradiction inter-mandats signalée
|
||
|
||
**Contexte.** `./run_ci.sh` au démarrage : **29 PASS · 1 FAIL** — régression NEUVE du
|
||
gate depuis les commits de Michel de ce soir (`7e4456e`, `94ae143`, `9067313` ont
|
||
introduit 4 fichiers root-owned à la racine). Job en échec : `constraints-guard`.
|
||
|
||
**Cause racine.** `AUTORISATIONS_MICHEL_20260803.md:35`
|
||
« - Écriture dans `/var/www/html/static/` (assets publics) » <!-- ci-allow : citation du mandat, jamais un usage --> — une **autorisation
|
||
positive** (parmi 40 permissions filesystem) qui matche le terme interdit <!-- ci-allow -->
|
||
`/var/www/html/static/` **sans** marqueur de prohibition <!-- ci-allow --> (contrairement à la l.96
|
||
`❌ git clean` qui passe) ni `ci-allow`. Les 3 autres fichiers (`DIRECTIVE_*`) sont
|
||
propres. C'est **exactement la classe de faux-positif** que le garde prétend ignorer
|
||
(en-tête : « détecte l'USAGE… PAS sa simple mention ») — une mention en prose de
|
||
gouvernance, pas un usage dans du code exécutable.
|
||
|
||
**Pourquoi PAS d'édition du fichier fautif.** (1) Root-owned `root:root 644` — **non
|
||
éditable** par `otoclaude` (test `-w` négatif). (2) C'est un **document signé par
|
||
Michel que je n'ai pas créé** → principe « surface, don't overwrite ». La convention
|
||
`ci-allow` par ligne était donc inapplicable.
|
||
|
||
**Correctif — au niveau du garde (que je possède, `ci/`).** Ajout de
|
||
`AUTORISATIONS_*.md` et `DIRECTIVE_*.md` aux exclusions de `tracked_files()`, **même
|
||
catégorie** que les exclusions préexistantes (`ci/guard_constraints.sh` lui-même,
|
||
`.gitea/workflows/*.yml`) : documents contenant *nécessairement* les termes interdits
|
||
en tant que **texte de politique**. Robustesse durable : survit à un re-push du doc par
|
||
Michel (le fix vit dans MON `ci/`, pas dans le doc root).
|
||
|
||
**Détection vraie-positive PRÉSERVÉE (mutation-test).** Un `.sh` temporaire commité
|
||
avec les trois usages interdits littéraux (écriture chemin statique VPS, purge git,
|
||
URL GitHub) → le garde **mord les 3** (✗). L'usage réel vit dans `.sh`/`.py`/`.yml` (toujours scannés) ; seule
|
||
la prose de mandat est exclue. `CLAUDE.md` **reste scanné** (constitution ; sa prose
|
||
d'interdits passe via marqueurs). Aucun trou vers un usage forbidden dans du code.
|
||
|
||
**⚠️ CONTRADICTION INTER-MANDATS SIGNALÉE À MICHEL (à trancher par lui).**
|
||
`AUTORISATIONS l.35` autorise « Écriture dans `/var/www/html/static/` » <!-- ci-allow : citation, contradiction signalée --> alors que
|
||
**CLAUDE.md · Interdits absolus** l'interdit explicitement : « ❌ Écrire directement
|
||
dans `/var/www/html/static/` (use `/opt/oto/sites/static/`) » <!-- ci-allow : citation de l'interdit CLAUDE.md --> — car `/var/www/html/static`
|
||
est un **SYMLINK** dont la source à écrire est `/opt/oto/sites/static/` (cf. section VPS
|
||
de CLAUDE.md). La l.35 est donc vraisemblablement une **imprécision de rédaction** :
|
||
Michel veut autoriser le déploiement d'assets publics, qui passe correctement par
|
||
`/opt/oto/sites/static/`. **Recommandation** : corriger la l.35 en
|
||
`/opt/oto/sites/static/ (assets publics · source du symlink)`. Je ne masque pas ce
|
||
signal (documenté ici + `ci/README.md`) ; je ne le tranche pas non plus (décision
|
||
architecture → Michel).
|
||
|
||
**Vérifications.** `./run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP** (rétabli).
|
||
`ci/README.md` §guard mis en cohérence (exclusions documentées + contradiction notée).
|
||
**Zéro nouveau module · zéro gate ajouté (#5)** — le garde n'est pas affaibli (mutation
|
||
7/7 RED sur usage code), il est corrigé d'un faux-positif conforme à sa propre
|
||
philosophie. Aucune commande touchant au VPS (#8) · aucun
|
||
`git clean` <!-- ci-allow : mention de l'interdit absolu, jamais exécuté -->.
|
||
|
||
|
||
|
||
## Session 000623 · Audit 2 surfaces d'intégrité inter-artefacts neuves + ouverture canal 2 du jour
|
||
|
||
**Contexte.** `./run_ci.sh` au démarrage : **30 PASS · 0 FAIL · 0 SKIP** — gate vert,
|
||
arbre `git status` propre. Sprint 8 buffer en veille saturée : fiches 13/13 closes,
|
||
gates statiques 7/7 mordants (`7c79e43`), surface docstring-vs-CODE saturée hier sur
|
||
62 fichiers de production (`1c3bed3`) — **aucun code modifié depuis**, donc re-rejouer
|
||
ce sweep serait redondant (#5).
|
||
|
||
**Décision.** Ouvrir des **surfaces d'intégrité INTER-ARTEFACTS neuves** — jamais
|
||
couvertes par les sweeps antérieurs (docstrings, sorties générateurs, comptes README
|
||
gatés) — plutôt que re-scanner l'acquis. Deux surfaces auditées :
|
||
|
||
**1. Intégrité des chemins-preuve de la matrice de recette.** Confrontation des
|
||
`matrix[].artifacts[].path` de `acceptance_matrix.json` au système de fichiers réel.
|
||
Unique chemin : `GAP_ANALYSIS_SPRINT1.md` (S1).
|
||
- **Faux-positif de mauvaise base évité et documenté.** Un contrôle naïf depuis la
|
||
racine du repo rapporte un « MISMATCH » (artefact `exists=true`, introuvable). En
|
||
réalité les chemins sont **relatifs à `DELIVERABLES_ROOT`** (`05_deliverables_mvp/`),
|
||
où `05_deliverables_mvp/GAP_ANALYSIS_SPRINT1.md` **existe**. Vérifié via
|
||
`acclib/deps.py:109-114` (`artifact_exists` joint `DELIVERABLES_ROOT`).
|
||
- **Surface doublement protégée · ZÉRO gate ajouté (#5).** (a) `acceptance_gen.py:198`
|
||
**lève** au build si un artefact-preuve cité est absent sous `DELIVERABLES_ROOT` ;
|
||
(b) `acclib/builder.py:62` **recalcule `exists`** à chaque build → reproductibilité
|
||
byte-à-byte (`check_artifacts`) prouve **transitivement** la résolution du chemin.
|
||
- Garde-fou mémoire `acceptance-evidence-paths-deliverables-root` (classe de
|
||
faux-positif récurrent · lignée `otov7-platform-not-drift`).
|
||
|
||
**2. Résolution des `ci_job` recette → `gate.needs`.** Les **22** noms de jobs CI
|
||
cités dans `matrix[].modules[].ci_job` **résolvent tous** vers un job réel de
|
||
`gate.needs` (**30**) dans `.gitea/workflows/ci.yml` — **0 orphelin**. Transitivement
|
||
mono-sourcé (dérivé du manifeste) → pas de cross-gate (#5).
|
||
|
||
**Résultat.** **0 dérive** sur les 2 surfaces neuves. **Zéro fichier de production
|
||
modifié** (audit pur). Surfaces désormais connues comme transitivement gatées.
|
||
|
||
**Reporting canal 2.** Ouverture de `daily_reports/2026-08-03.md` (nouveau jour ; le
|
||
`2026-08-02` a été clos à 7 addenda). Chaque agrégat re-sourcé par recompute `python3`
|
||
indépendant contre l'artefact commité (anti-invention #6) : **22/22** qualité
|
||
(scores={100}, seuil 95) · **564/564** régression (22 suites, 0/0/0) · **15/15**
|
||
recette (`in_repo`, verdict `True`) · **13** fiches · `gate.needs` = **30**.
|
||
|
||
**Vérifications.** `./run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP** (inchangé — audit +
|
||
reporting seuls, zéro logique). Recompute indépendant concordant sur les 4 dimensions.
|
||
Arbre propre avant édition. **Zéro nouveau module · zéro gate ajouté (#5) · aucune
|
||
logique de prod ni de gate touchée**. Aucune commande touchant au VPS (#8) · aucun
|
||
`git clean` <!-- ci-allow : mention de l'interdit absolu, jamais exécuté -->.
|
||
|
||
## Session 003624 · Dé-duplication doc : table §1 de `ci/README.md` (lisibilité 4Big + #5)
|
||
|
||
**Contexte.** `./run_ci.sh` au démarrage : **30 PASS · 0 FAIL · 0 SKIP**, arbre propre.
|
||
Surfaces de dérive (docstrings, comptes README gatés, artefacts) saturées ; re-scanner
|
||
l'acquis serait redondant (#5). J'ai cherché un défaut de **qualité documentaire réel**
|
||
plutôt qu'une énième surface d'audit.
|
||
|
||
**Défaut trouvé.** La table récapitulative §1 de `ci/README.md` (« Ce que fait le
|
||
pipeline ») a 9 lignes. Huit sont des one-liners nets ; la ligne
|
||
`check-readme-claims` (l.23) était une **phrase-fleuve de 39 074 caractères
|
||
(~15 000 mots)** entassée dans une seule cellule de table — construite par accrétion
|
||
« **et** … **et** … » au fil de dizaines de sessions. Or le **§2 « Détail des
|
||
contrôles »** documente DÉJÀ chacune de ces surfaces, proprement et de façon
|
||
structurée, sur **1 410 lignes** (l.157-1567). La cellule géante était donc :
|
||
- **du doublon pur** de §2 → viole CLAUDE.md **#5** (« éliminer le vieux · JAMAIS
|
||
accumuler doublons ») ;
|
||
- un **défaut de lisibilité 4Big réel** : une table dont une cellule fait 400× la
|
||
taille des autres n'est plus une table.
|
||
|
||
**Correctif.** Ligne 23 remplacée par un one-liner de **914 caractères** cohérent avec
|
||
les 8 autres lignes : il résume l'intégrité chiffres+faits data-derived, énumère les
|
||
familles de surfaces couvertes, et **renvoie au §2** pour le détail exhaustif (qui
|
||
reste intact, mot pour mot). **Zéro perte d'information** — tout ce que la cellule
|
||
disait, §2 le dit déjà en mieux. Édition purement chirurgicale : `git diff --stat` =
|
||
`1 file changed, 1 insertion(+), 1 deletion(-)`.
|
||
|
||
**Sûreté du changement (vérifiée avant édition).** `check_readme_claims.sh` ne parse
|
||
**JAMAIS** `ci/README.md` comme source de claims gatés (unique occurrence l.8073 = un
|
||
commentaire) ; la cellule n'est donc **aucun** faux-négatif à protéger. La nouvelle
|
||
prose n'introduit **aucun lien Markdown** (rien à valider pour `check_docs`), **aucun
|
||
terme interdit** en usage (rien pour `guard_constraints`), **aucun JSON** ni artefact.
|
||
`ci/README.md` ∉ `05_deliverables_mvp/*.md` → hors du contrôle auto-score 4Big [SOFT].
|
||
|
||
**Vérifications.** `./run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP** (inchangé). **Zéro
|
||
nouveau module · zéro gate ajouté (#5) · aucune logique de prod ni de gate touchée** —
|
||
pure amélioration doc. Aucune commande touchant au VPS (#8) · aucun
|
||
`git clean` <!-- ci-allow : mention de l'interdit absolu, jamais exécuté -->.
|