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>
14 KiB
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.
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) ».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 .
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) » — une autorisation
positive (parmi 40 permissions filesystem) qui matche le terme interdit
/var/www/html/static/ sans marqueur de prohibition (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/ » alors que
CLAUDE.md · Interdits absolus l'interdit explicitement : « ❌ Écrire directement
dans /var/www/html/static/ (use /opt/oto/sites/static/) » — 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 .
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.mdexiste. Vérifié viaacclib/deps.py:109-114(artifact_existsjointDELIVERABLES_ROOT). - Surface doublement protégée · ZÉRO gate ajouté (#5). (a)
acceptance_gen.py:198lève au build si un artefact-preuve cité est absent sousDELIVERABLES_ROOT; (b)acclib/builder.py:62recalculeexistsà 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éeotov7-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 .
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 .