Commit Graph

90 Commits

Author SHA1 Message Date
Claude Code DTP Worker d2ab269684 [DTP-Worker 20260802_173603] Sprint 8 · buffer · ci/README.md : retrait des comptes CI figés « 7 gates / 23 suites »
Même fix que dcb463e, un cran plus haut. dcb463e avait dérivé le décompte 30/23/7
du COMMENTAIRE de run_ci.sh (il se périme à chaque module ajouté/retiré de ci.yml) ;
mais la DOC du lanceur (ci/README.md §« Rejouer le gate EN LOCAL ») re-transcrivait
encore les mêmes nombres à la main : bloc d'usage L34-35 (« 7 gates statiques + 23
suites de module » / « 7 gates ci/*.sh ») + checklist L1601 (« 7 gates statiques »).

Vérif d'exposition (verify-uncovered-before-gating) : mutation 23→24 / 7→8 →
check_readme_claims ET check_docs restent VERTS → surface réellement NON gatée.

Décision FIXER pas gater (fix-vs-gate + local-ci-runner) : ci/README.md:51-54 déclare
lui-même que run_ci.sh « n'a pas à être re-gaté (#5) » (exactitude structurelle) —
gater la prose qui le décrit trahirait cette posture. On retire donc les nombres
figés et on laisse run_ci.sh seul propriétaire du décompte (dérivé de gate.needs,
imprimé à l'exécution + --list). Ajout d'un paragraphe l'explicitant (même raison #6).

Intactes : les « 7 gates re-verts » du CHANGELOG (narratif historique d'états passés
VRAIS, pas une composition vive). Zéro module · zéro gate (#5) · zéro chiffre inventé
(#6) · run_ci.sh 30 PASS · guards verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 17:41:25 +00:00
Claude Code DTP Worker 68f8c1a718 [DTP-Worker 20260802_170601] Sprint 8 · buffer · run_ci.sh : -h|--help + en-tête --static honnête (UX du lanceur, PAS un gate #5)
Deux vraies aspérités d'UX sur le lanceur run_ci.sh (miroir local du gate),
reproduites avant fix :
- `--help`/`-h` échouait « option inconnue » exit 2 alors qu'un bloc d'usage
  riche dormait dans l'en-tête → ajout usage() branché AVANT résolution git
  (aide marche hors checkout : exit 0 ; vrai run hors git reste exit 3),
  codes de sortie documentés (0/1/2/3).
- en mode --static l'en-tête annonçait « 30 jobs = 7 gates + 23 suites »
  alors que seuls 7 gates tournent → récap « 7 PASS » contredisait l'en-tête ;
  en-tête rendu mode-conscient (« 7 gates seuls, 23 suites ignorées »).
- message d'option inconnue + ci/README.md alignés (ajout --help).

Toutes les valeurs restent DÉRIVÉES de gate.needs (#6, zéro compte figé).
Zéro nouveau module · zéro gate ajouté (#5) : run_ci.sh reste un lanceur
(racine ∉ ci/*.sh, hors gate.needs, INV-B). Vérif : --help exit 0 in+hors git ·
--bogus exit 2 · check_docs/check_readme_claims/guard_constraints verts ·
run_ci.sh plein → 30 PASS · 0 FAIL · 0 SKIP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 17:11:19 +00:00
Claude Code DTP Worker 49123ecba3 [DTP-Worker 20260802_150601] Sprint 8 · buffer · DevOps outillage : run_ci.sh — miroir LOCAL du gate CI dérivé de gate.needs (zéro liste en dur), reproduit les 30 jobs (7 gates ci/*.sh + 23 suites module) en une commande · anti-dérive par construction (suit ci.yml) · PAS un gate (#5), root ∉ ci/*.sh donc hors INV-B · parseur awk anti-commentaire · chemin d'échec prouvé (EXIT=1 + dump) · doc README + ci/README · 7/7 gates statiques verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 15:16:29 +00:00
Claude Code DTP Worker 576e78b6a9 [DTP-Worker 20260802_133549] Sprint 8 · buffer · roles_couverts (« 44 ») : enquête anti-dérive → NON-surface prouvée (3 manifestes importent la même fonction roles_by_portail sur l'unique contrat rbac_50_roles.json → transitivement mono-sourcé, un cross-gate serait redondant #5, contra le cross-check RBAC-50 qui re-dérive) + documentation du garde-fou dans ci/README.md pour prévenir un gate N+1 redondant 2026-08-02 13:45:38 +00:00
Claude Code DTP Worker 8dcedb092c [DTP-Worker 20260802_130548] Sprint 8 · buffer · Compte d'agents : ancrage des 3 surfaces vives de GAP_ANALYSIS_SPRINT1 (dont coche couverture DoD) sur n_agents
Balayage de complétude après cb8d931 (qui a ancré « 13 agents » aux 2 docs de
mandat de tête) : 3ᵉ surface HORS gate = le livrable Sprint 1 GAP_ANALYSIS_SPRINT1.md
(Definition of Done). Retranscrit le compte à 3 endroits vifs — périmètre d'audit
(l.12) · constat global total (l.53, le « 12 » analytique EXCLU) · coche de
couverture DoD (l.214). Prouvé ungate (grep ci/=0 ; mutation 13→14 laissait exit 0)
et à dérive prouvée (publiciste 12→13). Extension de la boucle head-docs existante
(3 tuples réutilisant n_agents = git ls-files 03_agents/*/AGENT.md · zéro nouvelle
machinerie · #5) ; on n'ancre que le total ; INTROUVABLE = échec (#6). ci/README.md
documente désormais 7 surfaces vives. 6 morsures (M5 no-false-positive sur le « 12 » ·
M6 SILENT-GREEN via git rm --cached prouvant l'autorité git-index). 7 gates exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 13:11:37 +00:00
Claude Code DTP Worker 7e674f2f09 [DTP-Worker 20260801_233454] Sprint 8 · buffer · RBAC SPEC §5 : gate de la LIGNE D'AUTO-CONTRÔLE du « résumé »
La SPEC RBAC a déjà 3 gates (§3 ventilation par portail · §4 colonne Entité · §7
run-book) mais son §5 « Les N rôles (résumé) » restait AVEUGLE. Ce §5 restitue le
total de rôles sur 3 surfaces prose : le compte-titre « ## 5. Les 50 rôles », NEUF
comptes parenthétiques de regroupement (`**Ventes (8)**` …) et une ligne
d'auto-contrôle arithmétique `_(6+8+4+7+5+8+4+2+6 = 50.)_`. AJOUTER un rôle au
contrat (|rôles| 50→51) laisse titre/somme/`= 50` périmés en silence ; ÉDITER
`Ventes (8)→(7)` sans toucher la ligne casse la cohérence titre↔somme — ni les
suites tests/ (FONCTIONS RBAC, jamais la prose) ni le byte-gate d'artefact ne
l'attrapent.

Subtilité (memory rbac-spec-portail-count-gate : « §5 by-family is editorial ») :
les 9 regroupements sont ÉDITORIAUX (« Direction / Gouvernance » agrège des rôles
de familles direction+finance ≠ colonne `famille`) ⇒ AUCUN mapping groupe↔famille
(dérive fausse). On gate UNIQUEMENT ce qui est data-derived sans ce mapping.

Nouveau bloc « 1septies) §5 » : on recompute N = |rôles| du contrat
(rbac_50_roles.json, byte-gaté) et on exige (a) compte-titre == N ; (b) les 9
comptes de regroupement == EXACTEMENT dans l'ordre les termes de la ligne
(comparaison de LISTES ⇒ mord valeur ET position) ; (c) Σ termes == membre droit ;
(d) membre droit == N. Section/titre/ligne/comptes absents = échec (#6).

5 morsures vérifiées (working tree byte-restauré via git checkout -- <fichier>,
gate rc=1 sous mutation · rc=0 restauré) : titre 50→51 (a) · Ventes (8)→(9) (b) ·
= 50.→= 49. (c+d double) · terme 6+→7+ (b+c double) · suppression ligne (absence).
ci/README.md : row check-readme-claims étendue de la clause §5. 7 gates re-verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 23:46:27 +00:00
Claude Code DTP Worker 15812c1dff [DTP-Worker 20260801_230453] Sprint 8 · buffer · QA/Audit 5D : gate d'IDENTITÉ du VERDICT GLOBAL — le LABEL de conclusion de l'audit (PASS / PASS_WITH_OPEN_ITEMS / FAIL), la HEADLINE du livrable, était HORS de tout gate : le bloc audit_5d existant recompute la ventilation chiffrée (13 PASS · 0 FAIL · 4 à confirmer), les open items, les 5 dimensions et les livrables audités — jamais le label lui-même. Or il est data-derived (audit_report.json[verdict] == MANIFEST.json[verdict], byte-gatés), recalculé par builder.py (FAIL si ≥1 FAIL · sinon PASS_WITH_OPEN_ITEMS si ≥1 A_CONFIRMER · sinon PASS) et transcrit à la main à 2 endroits du README (la RÈGLE l.39 + le VERDICT COURANT l.49). Nouveau bloc : on MIROITE la règle et on exige (a) HONNÊTETÉ interne audit_report.verdict == verdict(triplet) — un PASS forcé pendant que 4 params restent a_confirmer (CŒUR #6 : ne jamais forcer un PASS) est mordu ; (b) MANIFEST.verdict == audit_report.verdict ; (c) label « Verdict courant » README == artefact ; (d) la règle « Verdict global » énumère EXACTEMENT le codomaine {FAIL, PASS_WITH_OPEN_ITEMS, PASS} du générateur. 5 morsures vérifiées (2 README · 2 artefact + M3 cascade a+b+c · 1 disparition), 7 gates re-verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 23:13:00 +00:00
Claude Code DTP Worker a40bfc51c1 [DTP-Worker 20260801_223450] Sprint 8 · buffer · SEO : gate d'IDENTITÉ du COMPTE d'INVARIANTS CI — le compte de contrôles de validation (annoncé « ## Garanties (N invariants) » du README + toutes ses mentions + les 5 self-reports du seo_gen.py : docstrings/aides/succès CLI) recomputé du SEUL registre-source = le LEDGER numéroté « # N · » de la fonction _validate (analogue du registre # Invariant N de Chat OTOIA · source d'autorité NON-artefact, invisible à check_artifacts). Exige : (a) ledger CONTIGU 1..N (comparaison LISTE triée ⇒ mord lacune ET doublon) ; (b) toute mention « N invariants » du .py == |ledger| ; (c) compte annoncé README == |ledger| ; (d) toute mention README == |ledger|. Prose du README RÉSUME (11 puces ≠ énumération 1:1) ⇒ gate du COMPTE, pas set-diff. 5 morsures vérifiées (2 README · 3 source ; doublon ledger attrapé là où l'approche set aurait raté), 7 gates re-verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 22:41:56 +00:00
Claude Code DTP Worker 64b635073a [DTP-Worker 20260801_220449] Sprint 8 · buffer · Chat OTOIA : gate d'IDENTITÉ de la LISTE D'INVARIANTS CI — la section « ## Invariants (N) — garantis en CI » du README (compte annoncé + énumération numérotée en prose + self-report CLI « N invariants verts » du générateur, 3 transcriptions) recomputée du REGISTRE-source = marqueurs # Invariant N de chat_otoia_gen.py : (a) registre code contigu 1..N, (b) self-report CLI == |registre|, (c) compte annoncé == |registre|, (d) énumération prose == registre EXACT (set-diff absent/fantôme) ; surface aveugle aux blocs Chat OTOIA préexistants (comptes d'artefact + identité persona/langues) ; 5 morsures vérifiées, 7 gates re-verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 22:13:26 +00:00
Claude Code DTP Worker d20d37607d [DTP-Worker 20260801_213444] Sprint 8 · buffer · Fiche ONAPI/Legal : gate de la 2ᵉ SURFACE PROSE des ENTITÉS PORTEUSES
Surface ungatée fermée : `03_agents/onapi_legal/AGENT.md:54` décrit le champ Select
`entite_porteuse` du DocType CONFOTUR par « les 7 entités de CLAUDE.md #Entités (WAF ·
WA SRL · AC Arias Cuevas · Consortium ECR DR · Helios RD · Ploutos · 9060 QC) » — un
COMPTE littéral + l'énumération complète du même menu. Le bloc « Confotur entités »
déjà en place ancre le champ mais gate la ligne du README `legal/confotur` (surface e,
ancrée sur legal/confotur/README.md) ; le motif ne vise PAS 03_agents/ ⇒ la fiche
restait hors de tout gate. Dérive #6 : ajouter/retirer/renommer une entité dans
CLAUDE.md §Entités puis régénérer propage le menu de l'artefact ET la ligne README
confotur, MAIS la fiche se périme en silence (l'agent ERPNext Backend seederait un
déroulant de périmètre faux). Aucune suite tests/ (FONCTIONS de build, pas la prose)
ne l'attrape.

Gate ajouté (ci/check_readme_claims.sh) : re-dérive la liste depuis les tokens gras de
« ## Entités » de CLAUDE.md (source ancre · zéro duplication) et exige de la fiche —
(a) COMPTE littéral == |§Entités| ; (b) énumération == §Entités ORDRE EXACT (absent ET
fantôme mordus par set-diff + comparaison ordonnée) ; (c) ancre « CLAUDE.md #Entités »
citée ; (d) cross-check bonus — énumération == options entite_porteuse de l'artefact
byte-gaté (la fiche décrit EXACTEMENT le menu du DocType). Ligne absente = échec (#6).

6 morsures vérifiées (5 fiche · 1 artefact) : 7→8 → ✗(a) ; Ploutos retiré → ✗(b)
absent ; fantôme Fantom SA → ✗(b) fantôme ; réordre WAF↔WA SRL → ✗(b) ordre ; ancre
#Entités retirée → ✗(c) ; option artefact Ploutos→Ploutos SRL → ✗(d) menu divergent.
Restauré = green (a/b/c/d ✓ · exit 0). Working tree byte-restauré via
git checkout -- <fichier précis> (JAMAIS git checkout . / git clean). 7 gates re-verts.
ci/README.md étendu (clause « 2ᵉ surface prose (fiche ONAPI/Legal) »).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 21:43:11 +00:00
Claude Code DTP Worker d587b446b9 [DTP-Worker 20260801_210434] Sprint 8 · buffer · CRM/commissions : gate d'IDENTITÉ du CHAMP DEVISE — la clause devise_field = le champ devise (Select USD/DOP · #10) du DocType Dossier Vente (crm/commissions/README.md:54), invariant CLI #8, transcrite en prose hors de tout gate (grep devise_field dans ci/ = 0)
4e surface distincte du même livrable crm/commissions (après états/champs, anti-taux #6, rôles payés) : le « sur quelle devise » du calcul base×taux. Re-dérivée de 3 sources byte-gatées/constitutionnelles : plan.devise_field (out/commission_plan.json) == champ `devise` du DocType (dossier_vente/doctype_spec.json, fieldtype Select) == options ORDONNÉES == devises canoniques CLAUDE.md #10 (« USD + DOP »). Ancrage vivant (#10) : (0) 2 devises depuis le segment gras de #10 ; (a) cross-artefact plan==DocType==#10 ; (b) prose README:54 == artefacts + #10 + tag #10. Distincte du bloc Fiches #10 (prose ERPNext/CRM) et du bloc e-CF TipoMoneda (spec fiscal).

7 morsures vérifiées (4 README · 1 DocType · 1 CLAUDE.md · 1 plan), 7 gates re-verts, working tree byte-restauré (git checkout --, JAMAIS git clean). ci/README.md (récap + paragraphe détaillé) et 05_activity_log mis à jour. Auto-score 4Big 96/100.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 21:15:36 +00:00
Claude Code DTP Worker f91a22f458 [DTP-Worker 20260801_203424] Sprint 8 · buffer · Audit 5D (4e surface du même README) : gate d'IDENTITÉ des LIVRABLES AUDITÉS — la liste des 5 hand-off out/*.json que l'audit de second niveau LIT (README qa/audit_5d §« Livrables audités »), énumérée à la main hors de tout gate ; recomputée par ENSEMBLE de MANIFEST.audited_artifacts (byte-gaté · = sorted(ARTIFACT_PATHS.values())), ordre README ≠ ordre MANIFEST trié ⇒ set-diff absent/fantôme ; cross-anchors : chaque chemin résout un fichier commité (a) + |audités| == |alias distincts des controls[].artifacts du spec| (b) ; 6 morsures vérifiées (4 README · 2 source), 7 gates re-verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 20:46:10 +00:00
Claude Code DTP Worker 17c3d2b104 [DTP-Worker 20260801_200419] Sprint 8 · buffer · Fiche DevOps : gate du COMPTE de suites gated (« 22 suites gated », cellule Tests de la row pipeline CI) — classe DISTINCTE des comptes de MÉTHODES test_ : recomputé de regression_plan.totals.suites (reg[suites], byte-gaté) + cohérence croisée == regression_run len(suites) ; surface non atteinte par row_re (ancre ci.yml/ci · suffixe 'suites gated') ni par l'agrégat de la fiche QA ; 5 morsures vérifiées, 7 gates re-verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 20:09:27 +00:00
Claude Code DTP Worker 861260462f [DTP-Worker 20260801_190412] Sprint 8 · buffer · Fiches agents/RBAC : gate d'APPARTENANCE à roles_allowed du chat OTOIA — 3e surface d'appartenance (DISTINCTE du contrat rbac_50_roles.json ET du Has Role workspace.json) : QUI peut INVOQUER l'assistant OTOIA d'un portail — asserée en prose par rendu:36 (∈ roles_allowed construction, triple ancrage) + mobile:41 (∉ tout, assertion négative #6), recomputée de chat_otoia/out/chat_mount.json (byte-gaté) ; 6 morsures vérifiées, 7 gates re-verts 2026-08-01 19:12:16 +00:00
Claude Code DTP Worker 47ef210910 [DTP-Worker 20260801_183412] Sprint 8 · buffer · Legal/CONFOTUR : gate d'IDENTITÉ des 2 champs DÉRIVÉS du workflow vente — dossier_vente (Link → workflow.document_type = OTO Dossier Vente) + estado (Select → états confotur_* du pipeline) — transcrits en prose (legal/confotur/README.md:33-36) hors de tout gate ; source = crm/workflow_vente/workflow_vente_spec.json (workflow_source du MANIFEST)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 18:43:45 +00:00
Claude Code DTP Worker e874717f0f [DTP-Worker] Sprint 8 · buffer · Fiches agents/voix : gate d'ANCRAGE du pied de page « Voix Amélie QC (multilingual_v2) pour toute interaction OTOIA » — répété dans 11 des 13 fiches 03_agents/*/AGENT.md (hors faisabilite/publiciste) — sur CLAUDE.md §Architecture cible
Le triplet persona/qualif/voix (Amélie · QC · multilingual_v2) recopié à la main
dans chaque pied de page était HORS de tout gate : le bloc persona Chat OTOIA
(063234) ne confronte que le module chat_otoia, aveugle aux 11 fiches ; le bloc
configs runtime note même que le « QC » est « gardé en littéral — non gaté ici ».

Bloc ajouté (check_readme_claims.sh) : RE-DÉRIVATION INDÉPENDANTE du triplet de
§Architecture cible (regex qui ne fige PAS le qualificatif en dur ⇒ QC→… mord ici,
pas seulement via l'INTROUVABLE du bloc persona) · 3 tokens == CLAUDE.md exigés sur
chaque fiche portant le pied de page · pied de page malformé & évaporation totale du
recensement échouent AUSSI (#6). 6 morsures vérifiées (CLAUDE.md voix v2→v3 : 11
fiches + cascade persona · CLAUDE.md qualif QC→BC : 11 fiches, bloc indépendant ·
seo voix · crm persona · bim malformé · surface évaporée) · restauré green · 7 gates
re-verts. ci/README.md (récap + paragraphe détaillé) mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 17:44:15 +00:00
Claude Code DTP Worker b9e333ceef [DTP-Worker] Sprint 8 · buffer · QA/audit_4big : gate des SEUILS STRUCTURELS de la colonne « Fait vérifié »
3e surface du MÊME README audit_4big, jamais gatée : les deux seuils que le
scorer applique (DOC « ≥ 400 octets » · TESTS « ≥ 8 méthodes def test_* »),
transcrits à la main. Le bloc BARÈME ne capture que le POIDS voisin (regex
`| `DOC` | 20 |`), aveugle à la 3e cellule. Ces nombres sont DATA-DERIVED de
quality_spec.json[thresholds] (min_doc_bytes/min_test_methods) — l'INPUT
byte-gaté par check_artifacts (report rebuild depuis lui).

Gate ajouté (check_readme_claims.sh) : (1) cross-check d'ANCRAGE — le seuil
TESTS APPLIQUÉ, lu de l'evidence « (seuil N) » de CHAQUE module du report ==
spec.min_test_methods pour tous (mord une divergence spec↔report) ; (2) prose
DOC « ≥ N octets » == spec ; (3) prose TESTS « ≥ N méthodes » == spec ; claim
absent échoue AUSSI (traçabilité #6). Élever min_test_methods (8→12 : module de
8-11 tests sous FAIL) ou changer min_doc_bytes rebuild le report SANS toucher au
README → prose périmée en silence, désormais interdite.

5 morsures vérifiées (README 400→450 · README 8→10 · ligne DOC vidée · spec
min_test_methods 8→12 rebuild : README+cross-check · spec min_doc_bytes 400→500
rebuild) ; restauré = green · 7 gates re-verts. ci/README.md (récap + paragraphe
détaillé) mis à jour. Hors périmètre VPS : néant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 17:12:01 +00:00
Claude Code DTP Worker a52daa056f [DTP-Worker] Sprint 8 · buffer · QA/audit_5d : gate d'IDENTITÉ des 5 DIMENSIONS du cadre
3e surface du MÊME README `qa/audit_5d` : la table « ## Les 5 dimensions »
(README:15-19) transcrit par ligne le triplet (id · titre · reference) de chaque
dimension. Jusqu'ici gatée seulement sur son COMPTE agrégé (« 5 dimensions ») — un
WILDCARD aveugle à QUELLE dimension. Une norme de référence permutée (D3 fiscal
`Ley 32-23`, D1 probatoire `ISA 500`) est une affirmation de conformité fausse
(l'invention même que #6 interdit) sur l'audit de second niveau que le banquier lit.

Gate ajouté (`ci/check_readme_claims.sh`) : liste ORDONNÉE {id:(titre,reference)}
recomputée de `qa/audit_5d/out/audit_report.json[dimensions]` (byte-gaté) — identité
par ensemble d'id (absent/en trop), ordre préservé (D1→D5), (titre,reference) par
ligne. Cohérence croisée bonus : rapport == audit_spec.json[dimensions] (l'INPUT dont
il dérive). Table disparue = échec (traçabilité #6).

8 morsures vérifiées (README rename titre/permute norme ISA/Ley/supprime ligne/
réordonne · artefact & spec renommés · table supprimée) ; restauré green · 7 gates
re-verts. Édition hors `05_deliverables_mvp/*/out` ⇒ 0 dérive d'artefact.
ci/README.md (recap + paragraphe détaillé) mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 16:41:34 +00:00
Claude Code DTP Worker 85a9ba7fca [DTP-Worker 20260801_160354] Auto exec · session 20260801_160354
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 / 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 / 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 / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
2026-08-01 16:18:55 +00:00
Claude Code DTP Worker 28e5e2145b [DTP-Worker] Sprint 8 · buffer · CRM/Commissions : gate d'IDENTITÉ des RÔLES PAYÉS — le « à quel rôle » du barème vendeurs — appartenance SINGLETON au portail ventes (séparation des pouvoirs · invariant #5) double-ancrée contrat rbac_50_roles.json ⨯ littéral README ⨯ portails_business · nom Frappe erpnext_role_name RÉSOLU == contrat (invariant #6, jamais figé en dur) · role_id ∈ contrat (jamais fantôme) · MANIFEST.roles_rbac_utilises recoupé — recomputés de commission_plan.json + contrat + MANIFEST byte-gatés 2026-08-01 15:44:53 +00:00
Claude Code DTP Worker 290bd2ec02 [DTP-Worker] Sprint 8 · buffer · DevOps/CI : gate d'IDENTITÉ des identifiants d'infrastructure VPS (IP 153.75.250.214 + conteneurs Docker erpnext-backend-1/erpnext-frontend-1) — recomputés de CLAUDE.md §VPS · direction copie→source sur toute doc .md du mandat (hors journaux) · enveloppe conteneur DÉRIVÉE des stems service (backend/frontend) et non du préfixe compose ⇒ un renommage erpnext-*→oto-* mord · migration serveur cascade sur les 10 copies
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 15:15:24 +00:00
Claude Code DTP Worker 9963279879 [DTP-Worker] Sprint 8 · buffer · Faisabilité/generator : ANCRAGE des 3 copies aval des 6 marqueurs canoniques (#9/#10) — l'oracle d'enforcement renderer._CANONICAL_MARKERS (que check_canonical parcourt) ⨯ les 2 docstrings scorer.py ⨯ l'oracle du test test_generator.py, recomputés de CLAUDE.md #9/#10 (réutilise exp)
Le bloc « paramètres canoniques » n'ancrait que model.py::CANONICAL + le README ;
son propre commentaire nommait pourtant le défaut (« marqueurs hardcodés dans le
test, une copie de plus jamais comparée à CLAUDE.md ») sans le fermer. Nouveau bloc :
helper _list_vs_want6 (set-diff EXACT absent/en-trop) pour les copies-LISTES
renderer._CANONICAL_MARKERS + oracle du test ; substring normalisé (USD+DOP==USD + DOP)
pour les 2 docstrings scorer. 4 morsures vérifiées dont CLAUDE.md #10 Cardnet→Azul
mordant SIMULTANÉMENT model+renderer+test+2 docstrings (valeur de l'ancrage) ;
restauré vert · 7 gates re-verts. ci/README.md + activity log mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 14:42:30 +00:00
Claude Code DTP Worker 8667cdf4de [DTP-Worker] Sprint 8 · buffer · Fiscal/e-CF DGII : gate d'IDENTITÉ des ÉVÈNEMENTS D'ÉMISSION (« le cœur du livrable ») — ENSEMBLE émetteurs {réservation,contrat} ⨯ DISJONCTION des brouillons (jamais de facture sur brouillon) ⨯ base_field ⨯ rôle unique compta-fiscaliste-ecf double-ancré RBAC portail compta ⨯ FormaPago défaut 3/Tarjeta/Cardnet #10, recomputés d'ecf_plan.json
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 14:14:18 +00:00
Claude Code DTP Worker 915be3cb77 [DTP-Worker] Sprint 8 · buffer · CRM/Commissions : gate de la PROMESSE ANTI-INVENTION (#6) — la raison d'être du barème vendeurs
Aucun taux de commission n'étant documenté dans CLAUDE.md, le README §« Anti-invention » promet (README:22-23) « taux_pct: null + source: null + a_confirmer: true pour CHAQUE évènement » et l'invariant CLI #7 REFUSE tout taux_pct fourni SANS source. Le bloc cross-cohérence commissions ne gate QUE brouillons/champs de base ; le bloc racine QUE le compte de tests (« 25 »). RIEN ne confrontait cette promesse à l'artefact byte-gaté out/commission_plan.json.

Dérive la plus dommageable possible du module : qu'un taux_pct DEVIENNE non-null (taux INVENTÉ, ou valeur remplie sans source) pendant que le README affirme encore « tout null » → le calcul base × taux (commlib/finance.py) émettrait une commission fondée sur un chiffre inventé — l'invention EXACTE que le module promet d'écarter. Aucune suite tests/ (FONCTIONS de calcul, jamais la promesse README vs artefact) ne l'attrape.

Gate ajouté (bloc « CRM/Commissions · ANTI-INVENTION (#6) ») : recompute de l'état null/confirmé depuis l'artefact + (a) invariant #7 permanent (aucun taux_pct sans source) · (b) a_confirmer ⟺ taux_pct is null · (c) MANIFEST.counts recoupe le plan (taux_a_confirmer / evenements) · (d) la promesse #6 du README REFLÈTE l'artefact dans les DEUX SENS (tout-null ⇒ promesse présente ; taux confirmé ⇒ promesse retirée) — zéro faux négatif quand la Direction remplira les taux · (e) note_taux du MANIFEST cohérente.

5 morsures vérifiées (taux sans source · taux avec source mais a_confirmer stale + README périmé · a_confirmer=false sur null · counts périmé 5→4 · promesse retirée INTROUVABLE), restauré vert, 7 gates re-verts. Working tree byte-restauré via git checkout -- (JAMAIS git clean). Édition hors 05_deliverables_mvp/*/out ⇒ 0 dérive d'artefact. ci/README.md (récap + paragraphe détaillé) mis à jour. Auto-score 4Big 96/100.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 13:41:28 +00:00
Claude Code DTP Worker 2e627a6a3b [DTP-Worker] Sprint 8 · buffer · Fiches agents/master prompt : gate d'IDENTITÉ de l'endpoint GPU RunPod ComfyUI (pod t68akvx80wv092 + tag « Flux dev fp8 » · 6 citations BIM/Rendu/master prompt) ancré sur le bullet §1 de AGENTS_EXISTING_ASSETS.md
Surface data-derived jusqu'ici hors de tout gate : l'ID du pod RunPod ComfyUI
et le tag modèle Flux, recopiés à la main en 6 endroits, dont la source de
vérité in-repo est le fichier maître AGENTS_EXISTING_ASSETS.md (que les fiches
citent explicitement). Un pod re-créé (nouvel id) ou un modèle bumpé péримait
les citations en silence → batch Flux câblé vers un endpoint GPU mort (#6).

Gate « RunPod endpoint » (ci/check_readme_claims.sh, avant sys.exit) : id+tag
recomputés du bullet §1 (garde : bullet unique) ; direction fiche→inventaire —
toute fiche/master prompt mentionnant RunPod doit citer l'id EXACT (token
backtické de forme pod == canonique) + le tag EXACT ; disparition totale échoue.
6 morsures vérifiées (id change → 3 fiches cascade · tag bump → 3 · mistype → 1
· tag drop → 1 · id drop → incomplet · bullet supprimé → ancre morte) ; restauré
green · 7 gates re-verts.

ci/README.md (clause récap + paragraphe détaillé) + 05_activity_log mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 13:11:39 +00:00
Claude Code DTP Worker c6428533a0 [DTP-Worker] Sprint 8 · buffer · Fiches agents/colonne « Entrée CLI » : gate d'IDENTITÉ des 16 jeux de sous-commandes documentés (03_agents/*/AGENT.md) recomputés PAR AST des subparsers.add_parser() réels des scripts
Classe fermée `agent-fiche-role-attrs-ungated` (sous-classe colonne CLI). La colonne
« Entrée CLI » des tables de livrables cite à la main le jeu de verbes de chaque module
(`publiciste.py parse|validate|generate|run`, `faisabilite_gen.py
score|scaffold|generate|batch`, …). Les blocs amont gatent déjà génériquement — pour
TOUTES les fiches — les colonnes « Tests » (vs regression_plan) et « Job CI » (vs
ci.yml), mais RIEN ne liait les VERBES écrits aux sous-commandes que le CLI EXPOSE.

Piège #6 : renommer/ajouter/retirer/réordonner un add_parser dans le .py (ou le mal
recopier dans la fiche) laisse la fiche documenter une surface d'invocation FANTÔME —
la doc d'identité qui dit à l'agent COMMENT lancer son livrable ment en silence, le CI
reste vert (le module tourne sous le vrai verbe), aucune suite tests/ ne l'attrape.

Gate ajoutée (ci/check_readme_claims.sh, bloc « colonne Entrée CLI ») : _cli_subcommands()
recompute via AST l'ensemble ORDONNÉ des subparsers.add_parser("<verbe>") ; script résolu
par le chemin de module de la MÊME ligne de table (lien …/<path>/README.md) + basename ;
égalité EXACTE ensemble ET ordre exigée ; `|` markdown échappés `\|` dé-échappés avant
découpe. 16 cellules gatées (6 fiches ; regex [a-z0-9_] capte audit_5d/4big_gen.py).

7 morsures vérifiées, restaurées vert : fiche renomme/ajoute/retire/réordonne un verbe
(4) · le vrai « vert trompeur » add_parser renommé dans le .py fiche inchangée (5) ·
nouveau add_parser non documenté (6) · script déplacé => INTROUVABLE (7). 6 gates
re-verts. ci/README.md catalogue mis à jour. Incident : un git checkout large a reverté
l'edit non-commité du gate ; ré-appliqué (git clean JAMAIS utilisé · ci-allow sur le log).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 12:44:43 +00:00
Claude Code DTP Worker 64238f6833 [DTP-Worker] Sprint 8 · buffer · Frontend Console/AGENT.md : gate d'IDENTITÉ de l'ENSEMBLE des portails métier (énumération L11 · double ancrage workspaces frontend ⨯ rbac portails_business) + exclusion nommée de la console technique plateforme (6ᵉ portail RBAC hors métier, L46)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 12:12:10 +00:00
Claude Code DTP Worker dce409f0f6 [DTP-Worker] Sprint 8 · buffer · RBAC/SPEC §4 : gate d'IDENTITÉ de la colonne « Entité » de la « Cartographie rôles ↔ entités » (7 entités nommées + Groupe consolidé) doublement ancré sur CLAUDE.md §Entités (descripteurs) ⨯ rbac_50_roles.json (ENSEMBLE des entite_principale)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 11:43:06 +00:00
Claude Code DTP Worker c4487fdcf7 [DTP-Worker] Sprint 8 · buffer · SEO/fiche agent : gate d'IDENTITÉ des 2 métriques data-derived (schema.org 10 nœuds · hreflang 10 pages FR/EN/ES) de 03_agents/seo/AGENT.md ancré sur seo_schema_org.json ⨯ seo_hreflang.json
Les blocs SEO schema.org/hreflang ne gataient que seo/README.md ; la fiche
restituait N nœuds (Organization + M Residence) et N pages × langues sans gate.
Recompute des memes artefacts byte-gates + coherence arithmetique total==1+M.
8 morsures verifiees, working tree byte-restaure, 7 gates re-verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 11:10:08 +00:00
Claude Code DTP Worker 71999e04c4 [DTP-Worker] Sprint 8 · buffer · Frontend Console/AGENT.md : gate d'IDENTITÉ des configs runtime Chat OTOIA (persona · langues · endpoint:null #6/#8) ancré sur chat_mount.json ⨯ MANIFEST.json
Bloc anti-dérive #6 dans ci/check_readme_claims.sh : la cellule « Métrique
vérifiée » de 03_agents/frontend_console/AGENT.md:29 restituait 3 attributs
data-derived du montage OTOIA (persona Amélie · langues FR/EN/ES ·
`endpoint: null`) ; le bloc chat_otoia amont ne gate que le COMPTE
blocks/mounts/portails, et le gate persona/capabilities ancré sur CLAUDE.md
vise spec/mounts/MANIFEST/README/oracle, jamais cette fiche. Le nouveau bloc
recompute les 3 depuis out/chat_mount.json (5 configs) + out/MANIFEST.json
byte-gatés : persona==MANIFEST.persona.nom, langues==MANIFEST.langues majuscule,
endpoint:null == affirmation d'honnêteté exigeant all(mount.endpoint is None)
— un endpoint fabriqué mord. Cohérences croisées MANIFEST⇔chaque mount +
endpoint_statut=='a_confirmer'⇔endpoints tous null. 6 morsures vérifiées ·
7 gates verts · aucune écriture out/ (0 dérive artefact).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 10:40:20 +00:00
Claude Code DTP Worker 7e8bb9a0de [DTP-Worker] Sprint 8 · buffer · RBAC/SPEC §7 : gate d'IDENTITÉ des comptes du run-book d'application (28 UP templates · 6 Role Profiles / 5 métier · 50 rôles bijectifs) ancrés sur rbac_50_roles.json
Surface data-derived non gatée : la NOTE §7 «  … livré en-repo » de
RBAC_50_ROLES_SPEC.md restitue 3 comptes du run-book (28 templates Company /
6 profils (5 métier + plateforme technique) / 50 rôles bijectifs) sur une
surface DISTINCTE des READMEs userperm_gen/roleprofile_gen déjà gatés et du
§3 (per-portail). Nouveau bloc 1quinquies dans check_readme_claims.sh :
recompute depuis le contrat byte-gaté (|scope==entite|, |portails distincts|,
|métier hors plateforme|, |roles|), blockquote « > » neutralisé avant match.
6 morsures vérifiées (dont contrat entite→groupe = silent green), restauré
vert, 7 gates PASS. ci/README.md (récap + paragraphe détaillé) mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 10:11:39 +00:00
Claude Code DTP Worker 5677082965 [DTP-Worker 20260801_090301] Auto exec · session 20260801_090301
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 / 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 / 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 / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
2026-08-01 09:18:02 +00:00
Claude Code DTP Worker 51e447605f [DTP-Worker] Sprint 8 · buffer · DevOps/deploy_runbook : IMPUTABILITÉ des CONFIRMATIONS préalables VPS (owner · réf-contrôle) ancrée sur out/deploy_runbook.json ⨯ qa/audit_5d
La ligne « Confirmations préalables VPS » du README `devops/deploy_runbook` annote
CHAQUE confirmation réglementaire d'un COUPLE data-derived `nom` (OWNER · RÉF-CONTRÔLE)
— ex. `taux_commission` (Direction · audit_5d D1.1) : QUI doit confirmer le paramètre
avant déploiement + QUEL contrôle qa/audit_5d le trace. Sources faisant autorité
(double, byte-gatées) : les `confirmations` de out/deploy_runbook.json (owner + source)
CROISÉES avec qa/audit_5d/out/audit_report.json (chaque control D#.# porte son propre
owner). Les blocs DevOps amont ne gataient que le COMPTE (2) et l'ENSEMBLE des noms —
AVEUGLES à QUI porte chaque confirmation et à QUEL contrôle la trace. Piège #6 :
réaffecter `taux_commission` de Direction à Ventes (mauvais responsable escaladé),
misattribuer le contrôle (D1.1→D2.1) ou citer un contrôle FANTÔME (D9.9) laisse la
prose périmée en silence pendant que l'artefact/l'audit disent autre chose → l'agent
DevOps escaladerait le mauvais owner / contrôle ; aucune suite tests/ (FONCTIONS de
graphe) n'attrape ce « vert trompeur ». État courant : aucune annotation périmée
(anti-invention #6), le défaut est la surface ungated.

Gate ajouté (ci/check_readme_claims.sh, bloc « 2ter ») : cross-anchor à trois — owner
run-book ⊆ owner du contrôle audit_5d cité (tolère le suffixe « / UAF ») · owner
README ⊆ owner run-book (tolère l'abréviation « Fiscaliste eCF » ⊂ « Compta Fiscaliste
eCF ») · réf README == contrôle réel présent DANS audit_5d ET dans la source. Une
confirmation tracée DOIT rester annotée (traçabilité #6) ; une annotation d'un nom
fantôme échoue AUSSI.

9 morsures vérifiées (README réaffecte owner · misattribue D1.1→D2.1 · contrôle
fantôme D9.9 · annotation retirée · artefact réaffecte owner = silent green · audit_5d
owner divergent · source cite contrôle fantôme · annotation nom fantôme · réf textuelle
absente de la source), restauré vert, 7 gates re-verts. ci/README.md (récap + paragraphe
« 3ᵉ surface deploy_runbook — imputabilité des confirmations ») mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 08:41:43 +00:00
Claude Code DTP Worker ee421add1d [DTP-Worker] Sprint 8 · buffer · Fiscal/ecf_dgii : le JEU DE DEVISES moneda (USD/DOP) ANCRÉ sur CLAUDE.md #10
Le champ que `Encabezado.TipoMoneda` porte dans chaque e-CF DGII —
`moneda.options = ["USD","DOP"]` — vit dans `ecf_spec.json` ET, byte-gaté par
check_artifacts, dans `out/ecf_plan.json`. C'est une valeur CANONIQUE de CLAUDE.md
#10 (« **USD + DOP** devises ») dont le README se réclame « #10 » (README:37/57/77).
Or byte-gater une constante prouve la REPRODUCTIBILITÉ, PAS l'ANCRAGE :
check_artifacts prouve ecf_plan==build depuis le spec, JAMAIS que spec[moneda]==#10.
Les blocs fiscaux amont gatent le FormaPago (Cardnet · #10) + états/champs
émetteurs, AVEUGLES au jeu de devises ; le bloc « Fiches #10 » ancre les fiches
ERPNext/CRM, AVEUGLE au module fiscal.

Piège #6 : RENOMMER/ÉTENDRE les devises dans CLAUDE.md #10 (`USD + DOP`→`USD + EUR`,
ou +`EUR`) ET dans le spec de façon cohérente reste byte-VERT tout en faisant
émettre à l'e-CF un `TipoMoneda` d'une devise qui CONTREDIT le mandat — « vert
trompeur » de la classe de la marque SEO §Entités, la persona Chat OTOIA ou les
tokens branding #4, qu'aucune suite tests/ (FONCTIONS de génération, jamais l'ancre
à CLAUDE.md) n'attrape. L'agent ERPNext Backend câblerait TipoMoneda hors mandat.

Correctif de déclaration : nouveau champ `moneda.options_source` (ecf_spec.json +
requis dans ecf.schema.json) citant « CLAUDE.md #10 — devises **USD + DOP** »,
DISTINCT de `source` (taux TipoCambio, reste null/a_confirmer côté VPS · #8).
Artefact régénéré (byte-gate re-verte · 39 tests module verts).

Gate ajouté (ci/check_readme_claims.sh, bloc « Fiscal · ecf_dgii — le JEU DE
DEVISES `moneda` … ANCRÉ sur CLAUDE.md #10 ») : RÉUTILISE exp["devises"] déjà
recomputé depuis #10 (zéro duplication) ; (a) spec[moneda].options == devises #10
ORDRE exact ; (b) artefact byte-gaté idem ; (c) options_source cite CLAUDE.md #10 +
chaque devise ; (d) prose README qui se réclame de #10 == jeu exact + toute mention
moneda/devise d'une paire concordante (scan ancré sur contexte, évite le faux
positif `RNC / ITBIS`). 7 morsures vérifiées (CLAUDE.md #10 rename = 4 bites en
cascade · spec options régénéré = le vrai silent green · artefact seul · reorder ·
options_source sans ancre · README ligne #10 · README table), restauré vert, 7
gates re-verts.

ci/README.md (clause récap + paragraphe « 4e surface du MÊME README ») mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 07:43:29 +00:00
Claude Code DTP Worker 30892dfecb [DTP-Worker] Sprint 8 · buffer · Mobile/app_config : le SDK MAJEUR Expo (« Expo 54 ») ANCRÉ sur la roadmap Sprint 5 l.56 « Rebuild Expo 54 »
La version MAJEURE du SDK Expo que l'app compagnon cible (`expoSdkMajor`) est data-derived : `out/app_config.json.expo.extra.expoSdkMajor = 54` (byte-gaté par check_artifacts ⇒ faisant autorité), recopié dans `out/MANIFEST.json.app.expo_sdk_major`, dérivé de `mobile_spec.json[app].expo_sdk_major` dont la SOURCE FAISANT AUTORITÉ est la roadmap Sprint 5 l.56 « Rebuild Expo 54 » (le spec le DÉCLARE via `expo_sdk_source`). Le README:4/19/35/72 recopie « Expo 54 » CINQ fois À LA MAIN — dont la ligne de source « Expo SDK **54** | roadmap Sprint 5 l.56 ». Le bloc « Mobile · récap de l'app Expo » amont ne gate QUE le quadruplet onglets/rôles/langues/identifiants a_confirmer (comptes de MANIFEST.counts), AVEUGLE au majeur du SDK. Piège #6 : BUMPER le SDK (Expo 55 sort · eas build cible 55) dans le spec/artefact SANS toucher au README (ou l'inverse), ou DÉRIVER la roadmap de l'artefact, laisse la prose PÉRIMÉE en silence pendant que le graphe byte-gaté dit autre chose → l'agent Mobile lancerait `eas build` sur le MAUVAIS SDK (le rebuild même que la ligne roadmap prescrit) — « vert trompeur » qu'aucune suite tests/ (FONCTIONS de génération, jamais la prose ni l'ancre à la roadmap) n'attrape. Même patron d'ANCRAGE que la marque SEO §Entités (Helios RD ancrée sur CLAUDE.md) ou les roadmap_line de la recette, mais sur une valeur dont la roadmap — non CLAUDE.md — est l'INPUT faisant autorité.

Gate ajouté (bloc « Mobile · le SDK MAJEUR Expo … ANCRÉ sur la roadmap Sprint 5 l.56 ») : le majeur re-dérivé de app_config.json byte-gaté, puis (a) cohérence interne artefact ⇔ MANIFEST ⇔ spec ; (b) ancrage roadmap `Rebuild Expo <N>` == artefact (ancre vive) ; (c) le spec DÉCLARE l'ancrage (expo_sdk_source cite roadmap + Expo N) ; (d) TOUTE mention prose « Expo [SDK] N » == artefact (aucune périmée) ; (e) la ligne de source du tableau cite l'ancre roadmap. Un claim absent échoue AUSSI.

7 morsures vérifiées (README 54→55 prose périmée · artefact 54→55 README+roadmap périmés = le vrai silent green · roadmap Rebuild Expo 54→55 artefact périmé · MANIFEST 54→55 chaîne incohérente · spec expo_sdk_source sans roadmap · README ligne source sans roadmap · README retire toute mention Expo N), restauré vert (git checkout --, JAMAIS git clean), 7 gates re-verts. ci/README.md (table récap + paragraphe détaillé) mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 07:14:31 +00:00
Claude Code DTP Worker 5de6b23c02 [DTP-Worker] Sprint 8 · buffer · Chat OTOIA : IDENTITÉ persona (Amélie/voix multilingual_v2) + 4 CAPABILITIES OTOIA (aec.py+knowledge.py+prompt_engine.py+chat.py) du montage Chat par portail frontend/chat_otoia ANCRÉE sur CLAUDE.md §Architecture cible
Les artefacts `out/chat_mount.json` (5 configs runtime, une par portail) +
`out/MANIFEST.json` portent la persona + les capabilities, BYTE-GATÉS pour la
REPRODUCTIBILITÉ par check_artifacts (reconstruction depuis `chat_spec.json`) mais
JAMAIS ANCRÉS à CLAUDE.md §Architecture cible (l.30 « Voix Amélie QC (multilingual_v2) »
· l.28 « OTOIA capabilities : aec.py + knowledge.py + prompt_engine.py + chat.py »),
leur source faisant autorité. Le bloc chat_otoia amont ne gate que la COMPOSITION
(portails métier · 1 block⇔1 mount) ; le SEUL contrôle d'identité vit dans tests/
(`test_persona_amelie_sourcee`/`test_capabilities_sourcees_sans_ajout`) mais son ORACLE
est HARDCODÉ (`"Amélie"`, `["aec.py",…]`) — une copie de plus, jamais comparée à
CLAUDE.md. Piège #6 : renommer la persona (`Amélie`→`Sophie`), changer la voix, ou
renommer/RETIRER une capability dans `chat_spec.json` (ou dans CLAUDE.md) reconstruit
l'artefact fidèlement (byte-gate VERTE) sans toucher l'oracle (tests VERTS) → le chat
monté dans CHAQUE portail annoncerait une persona/voix/capabilities CONTREDISANT le
mandat — « vert trompeur » de la classe des tokens branding ancrés sur #4 et de la
marque SEO §Entités. Aucune suite tests/ (FONCTIONS de génération, jamais l'ancre à
CLAUDE.md) ne l'attrape.

Gate ajouté (bloc « Chat OTOIA · persona + capabilities ancrées CLAUDE.md ») :
persona+capabilities re-dérivées de §Architecture cible (regex `Voix … QC (…)` +
`OTOIA capabilities : …` split `+`, NFC), puis (a) `chat_spec.json`
persona/capabilities == CLAUDE.md (ordre exact) · (b) le spec DÉCLARE l'ancrage
(`persona.source` + chaque `capability.source` citent CLAUDE.md) · (c) CHACUN des 5
mounts + le MANIFEST == CLAUDE.md · (d) README cite l'ancre §Architecture cible + nomme
persona + chaque capability (notation compacte matchée par radical) · (e) l'ORACLE du
test == CLAUDE.md (set-diff). Un claim absent échoue AUSSI.

8 morsures vérifiées : CLAUDE.md `Amélie→Sophie` (mord SIMULTANÉMENT
spec/mount/README/oracle — l'ancre est vive) · CLAUDE.md retire `chat.py` · spec
`aec.py→exfil.py` (capability injectée) · spec `persona.source` sans CLAUDE.md · UN
SEUL mount à voix altérée (byte-gate aveugle) · README retire le radical
`prompt_engine` · oracle du test persona `Amélie→Bob` · oracle du test capabilities
réordonné/tronqué ; restauré = green, exit 0. Working tree byte-restauré
(`git checkout --`, JAMAIS `git clean`) · 7 gates re-verts · unittest module re-vert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 06:41:19 +00:00
Claude Code DTP Worker 6f88383939 [DTP-Worker] Sprint 8 · buffer · Legal/CONFOTUR : cross-cohérence PERMISSIONS répliquée dans la FICHE AGENT 03_agents/onapi_legal/AGENT.md:43-45 — la MÊME table role→portail→actions que le README du module (ventes-confotur (Ventes)→read/write/create/print · legal-onapi (Direction)→read/write/create · legal-directeur (Direction)→read/write/**submit**/report), annoncée « **mot pour mot** les permissions_cibles RBAC des 3 rôles », mais sous une convention DIFFÉRENTE ( / espacé · **submit** en gras) et gatée par RIEN. Le bloc « Legal confotur perms · cross-cohérence » existant ne gate QUE la §Permissions du README du MODULE (legal/confotur/README.md), AVEUGLE à la fiche. Piège #6 : PROMOUVOIR ventes-confotur à submit (élévation de privilège · casse la séparation des pouvoirs dont is_submittable est déduit), RETIRER une action, RÉAFFECTER un portail, RENOMMER un rôle ou AJOUTER une ligne fantôme dans la FICHE la laisse périmée pendant que l'artefact (et le README, lui gaté) disent autre chose → l'agent ONAPI/Legal lirait sa PROPRE doc d'identité mentant sur le jeu de permissions qu'il porte (le risque même que « mot pour mot » promet d'écarter) — « vert trompeur » qu'aucune suite tests/ (FONCTIONS de mapping RBAC, jamais la prose de fiche) n'attrape. Classe explicitement notée en mémoire (agent-fiche-role-attrs-ungated) : une fiche peut restituer la MÊME donnée data-derived qu'un README déjà gaté, sur une surface distincte. Gate ajouté (bloc « cross-cohérence PERMISSIONS répliquée dans la FICHE AGENT ») : RÉUTILISE conf_perm_by_id/conf_portail_by_id déjà dérivés du MANIFEST par le bloc README (ZÉRO duplication du contrat #6) ; regex tolérant / et ** ; par rôle portail (casse normalisée) ET jeu d'actions exigés EXACTS (set-diff absent ET en trop) ; identité d'ensemble fiche⇔MANIFEST (aucun rôle fantôme/manquant). 6 morsures vérifiées (fiche promeut ventes-confotur→submit · fiche retire create de legal-onapi · fiche réaffecte portail Ventes→Direction · fiche renomme legal-directeur→legal-boss ligne INTROUVABLE+fantôme · sous-liste entière supprimée · artefact promeut submit fiche stale = le vrai silent green), restauré vert, 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 06:07:34 +00:00
Claude Code DTP Worker e53d60fc0b [DTP-Worker] Sprint 8 · buffer · Legal/CONFOTUR : IDENTITÉ des ENTITÉS porteuses du DocType CONFOTUR Application ANCRÉE sur CLAUDE.md §Entités — le champ Select entite_porteuse (le MENU DÉROULANT qui fixe QUELLE entité juridique porte chaque dossier d'incitation touristique) offre pour options les 7 entités canoniques du mandat (WAF·WA SRL·AC Arias Cuevas·Consortium ECR DR·Helios RD·Ploutos·9060 QC), DÉRIVÉES via options_source de confotur_spec.json[entites] et BYTE-GATÉES pour la REPRODUCTIBILITÉ par check_artifacts (l'artefact se reconstruit depuis le spec) mais JAMAIS ANCRÉES à CLAUDE.md §Entités, leur source faisant autorité. Les blocs CONFOTUR amont ne gatent que le COMPTE de champs/rôles et la cross-cohérence des PERMISSIONS, aveugles à l'IDENTITÉ de cette liste. Piège #6 : RENOMMER une entité dans CLAUDE.md §Entités (9060 QC9061 QC) ou dans confotur_spec.json[entites] puis régénérer laisse le DocType offrir un menu qui CONTREDIT/omet une entité canonique pendant que la byte-gate reste VERTE (l'artefact se reconstruit fidèlement… depuis un spec dérivé) — « vert trompeur » de la MÊME classe que la marque SEO org (§Entités) et les tokens branding (#4). L'agent ERPNext Backend importerait un DocType dont le déroulant liste une entité FANTÔME ou en omet une (la restriction même que reqd pose). Aucune suite tests/ (FONCTIONS de génération, jamais l'ancre à CLAUDE.md) ne l'attrape. Gate ajouté (bloc « Legal · CONFOTUR — IDENTITÉ des ENTITÉS porteuses ») : les 7 entités re-dérivées des tokens en gras de la section « ## Entités » de CLAUDE.md, puis (a) options de l'artefact == CLAUDE.md ORDRE exact · (b) spec[entites] == CLAUDE.md l'INPUT ancré · (c) le spec DÉCLARE l'ancrage (entites_source cite CLAUDE.md + chaque entité) · (d) wiring intact options_source == "entites" · (e) README cite l'ancre CLAUDE.md + nomme chaque entité (nom complet OU 1er token · abréviation « AC » tolérée · #6). 7 morsures vérifiées (CLAUDE.md rename → 4 bites a/b/c/e simultanées, l'ancre est vive · artefact drop option · artefact reorder · spec entites renommé · spec source sans CLAUDE.md · spec options_source hardcoded · README retire une entité), restauré vert, 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 05:41:06 +00:00
Claude Code DTP Worker 3e7bc33fb7 [DTP-Worker] Sprint 8 · buffer · SEO/schema.org : IDENTITÉ du nœud racine Organization ANCRÉE sur CLAUDE.md §Entités — le nom de marque Helios RD (marque publique · « **Helios RD** (marque publique) sous WAG ») et son url == base_url, portés par le nœud racine du graphe JSON-LD seo/out/seo_schema_org.json, étaient byte-gatés pour la REPRODUCTIBILITÉ (check_artifacts prouve la reconstruction depuis seo_spec.json) mais JAMAIS ANCRÉS à CLAUDE.md. Le bloc SEO schema.org amont gate la COMPOSITION (@type + bijection un-listing-par-projet), aveugle à l'IDENTITÉ de la marque que Google indexe. Piège #6 : renommer la marque dans seo_spec.json[schema_org.organization.name] (ou dans CLAUDE.md §Entités) puis régénérer laisse le JSON-LD PUBLIC de vente.otov7.com émettre un nom qui CONTREDIT le mandat pendant que la byte-gate reste VERTE (l'artefact se reconstruit fidèlement… depuis un spec dérivé) — « vert trompeur » de la classe des tokens branding ancrés sur #4. Aucune suite tests/ (FONCTIONS de génération, jamais l'ancrage à CLAUDE.md) ne l'attrape.
Gate ajouté (bloc « SEO org » après la composition schema.org) : marque re-dérivée de la parenthèse « (marque publique) » de CLAUDE.md §Entités (1× exactement · zéro duplication), puis (a) `Organization.name` == marque CLAUDE.md ; (b) `Organization.url` == `MANIFEST.base_url` & `@id` sous base_url ; (c) chaque listing rattaché à CETTE Organization (`brand.@id` == `org.@id`) sous base_url ; (d) `addressCountry` UNIFORME == `country_code` du spec (ISO 2 lettres, géo-ciblage à l'identique) ; (e) le spec DÉCLARE l'ancrage (`organization.name` == marque + `source` cite CLAUDE.md). Racine `Organization` exigée singleton en pré-requis.

6 morsures vérifiées (restauré vert après chacune) : artefact `name`→Helios DR (a) · CLAUDE.md §Entités rename Helios RD→Helios Dominicana → mord SIMULTANÉMENT artefact (a) ET spec (e), l'ancre est vive · artefact `url` divergent (b) · un `addressCountry` DO→US (d) · spec `source` supprime l'ancre CLAUDE.md (e) · un listing `brand.@id`→#phantom (c). Restauré = green, exit 0. Working tree byte-restauré (`git checkout --`, JAMAIS `git clean`). 7 gates re-verts (check_readme_claims/check_ci_integrity/check_docs/guard_constraints/check_artifacts/check_regression/validate_json). ci/README.md (clause table récap + paragraphe détaillé) mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 05:11:46 +00:00
Claude Code DTP Worker f5c7642cbf [DTP-Worker] Sprint 8 · buffer · CRM/DocType porteur : le NOM OTO Dossier Vente — le POINT D'ATTACHE du pipeline vente (le Workflow s'y branche via son document_type) — était RECOPIÉ À LA MAIN à ≥4 endroits (titre + ligne « Nom du DocType » du README crm/dossier_vente, fiche 03_agents/crm/AGENT.md:25, fiche 03_agents/onapi_legal/AGENT.md:50) et ASSERTÉ EN PROSE égal à workflow.document_type, mais AUCUN gate ne couvrait le NOM. Le bloc CRM pipeline ne recompute que le COMPTE d'états (9), aveugle à l'identité ; aucune suite tests/ (FONCTIONS de graphe) n'attrape la prose. Piège : RENOMMER le DocType dans doctype_spec.json reconstruit les DEUX artefacts de façon COHÉRENTE (le document_type du workflow suit, les tests restent verts) mais périme les mentions en prose EN SILENCE → l'agent ERPNext Backend importerait un DocType sous un nom pendant que la fiche/le README en nomment un autre, et le Workflow s'attacherait à un DocType FANTÔME. Gate ajouté (bloc « CRM · IDENTITÉ du DocType porteur ») : nom recomputé de doctype_oto_dossier_vente.json[name] byte-gaté, chaque prose exigée EXACTE + cohérences croisées DocType.name == MANIFEST.doctype_name (interne) & == workflow.document_type (attache porteur↔workflow). 7 morsures vérifiées (nom artefact renommé → 6 lignes en cascade · document_type divergent → attache rompue · doctype_name divergent → incohérence interne · les 4 mentions périmées), restauré vert, 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 04:09:01 +00:00
Claude Code DTP Worker d7f727203c [DTP-Worker] Sprint 8 · buffer · Fiches agents/colonne « Job CI » : chaque table de livrables de 03_agents/*/AGENT.md NOMME entre backticks le job Gitea Actions qui exécute la suite du module (rbac-tests · fiscal-ecf-tests · frontend-portails-tests…) — nom SAISI À LA MAIN dont la source de vérité est la clé jobs: de .gitea/workflows/ci.yml — mais AUCUN gate ne liait le NOM écrit dans la fiche au job réel. check_ci_integrity.sh prouve que chaque job est CÂBLÉ dans gate.needs (INV-A/B) et les blocs amont de check_readme_claims recomputent les COMPTES de tests par suite ; RIEN ne vérifiait que le token DÉSIGNE un job existant. Renommer un job dans ci.yml (rbac-testsrbac-role-tests) ou mal recopier demo-scenario-tests en demo-scenarios-tests laissait la fiche pointer un job FANTÔME pendant que le CI reste VERT (le vrai job tourne sous son nouveau nom) — la doc d'identité de l'agent ment en silence.
Gate ajouté (bloc « Fiches agents · colonne Job CI ») : on RECOMPUTE l'ensemble des jobs depuis la clé `jobs:` de ci.yml (la section `on:` push/pull_request/workflow_dispatch est AVANT `jobs:` et donc exclue ; jamais une liste à la main) et on exige que chaque token `*-tests` cité dans une fiche y figure. Direction fiche→ci.yml (le consommateur) : ci.yml peut définir des jobs non cités (légitime), une fiche ne peut pas citer un job absent ; la disparition totale de la colonne échoue AUSSI. 33 références vérifiées == jobs ci.yml ; 2 morsures (token de fiche `seo-tests`→`seo-suite-tests` fantôme · job ci.yml `rbac-tests` renommé → mord SIMULTANÉMENT les 4 fiches qui le citent : erpnext_backend/ifc_speckle/mobile/rendu), restauré vert, 7 gates re-verts. ci/README.md + activity log MAJ.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 03:38:42 +00:00
Claude Code DTP Worker e62ecfd61e [DTP-Worker] Sprint 8 · buffer · Fiscal/e-CF DGII : l'IDENTITÉ du RÔLE émetteur e-CF — le SEUL rôle habilité à ÉMETTRE un comprobante fiscal électronique, nommé en prose par le bullet role_id du README (fiscal/ecf_dgii/README.md:51-54) via TROIS attributs data-derived (role_id compta-fiscaliste-ecf · erpnext_role_name OTO Compta Fiscaliste eCF · portail compta) — était HORS de tout gate d'IDENTITÉ.
Le bloc e-NCF gate le FORMAT de l'identifiant ; le bloc cross-cohérence (2e surface) gate états émetteurs/champs de base/FormaPago ; mais AUCUN ne comparait l'IDENTITÉ de ce rôle à ses DEUX sources faisant autorité : (a) out/ecf_plan.json (byte-gaté) — chaque emission_events[] porte role_id + erpnext_role_name ; (b) rbac_50_roles.json (contrat) — le rôle porte portail:"compta". Le `portail` n'est PAS dans l'artefact ; il n'est vérifiable QUE contre le contrat.

Même classe d'IDENTITÉ que la Fiche Mobile / les Fiches Faisabilité ou les gardes CRM/workflow_vente, appliquée à une 3e surface distincte du MÊME README fiscal. Piège : la seule vérification existante (tests/) teste des FONCTIONS (ncf/résolution), jamais la prose. RÉAFFECTER l'émission à un autre rôle, le RENOMMER, ou DÉPLACER le rôle hors du portail compta (e-CF émis HORS Compta — séparation cassée) laisse la prose périmée pendant que l'artefact/contrat disent autre chose → l'agent ERPNext Backend câblerait le mauvais rôle émetteur.

Gate ajouté (ci/check_readme_claims.sh, bloc « Fiscal rôle émetteur ») : role_id/erpnext_role_name recomputés de emission_events + portail/nom Frappe du contrat, prose EXACTE ; cohérences croisées : tous les emission_events pointent UN SEUL rôle (fonction · non vide) · role_id unique au contrat · nom artefact == contrat (zéro-dup) · portail == compta. Un claim absent échoue AUSSI. 6 morsures vérifiées (README renomme role_id/nom/portail · artefact réaffecte les 2 events à ventes-directeur (5 mords cascade) · contrat déplace le rôle vers ventes · artefact diverge du contrat sur le nom), restauré vert, 7 gates re-verts. ci/README.md mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 03:10:11 +00:00
Claude Code DTP Worker 68004265d6 [DTP-Worker] Sprint 8 · buffer · Publiciste/branding : les 4 TOKENS DESIGN CANONIQUES de la marque luxury — fond dark #0a0a12 + accent doré #f0b429, titres Fraunces + corps Cormorant Garamond (contrainte NON-NÉGOCIABLE CLAUDE.md #4) — étaient RECOPIÉS à QUATRE endroits tous NON gatés : (a) les CONSTANTES lib/branding.py (COLOR_BG/COLOR_ACCENT/FONT_DISPLAY/FONT_BODY), source unique importée par le générateur & substituée dans le gabarit {{COLOR_BG}}…, hors out/ donc INVISIBLE à check_artifacts ; (b) le docstring du fichier ; (c) le README ; (d) le tuple d'oracle HARDCODÉ de tests/test_publiciste.py. Le seul contrôle existant (test_marque_luxury) assert que le RENDU contient ces marqueurs mais ils sont une copie de plus JAMAIS comparée à CLAUDE.md — même patron EXACT que les paramètres canoniques faisabilite/generator (CANONICAL↔CLAUDE.md #9/#10). Gate ajouté : les 4 tokens recomputés de la ligne #4 de CLAUDE.md (zéro duplication) ; (a) branding.py CONSTANTES == #4 (hex insensible casse, fontes exact), (b) docstring cite les 4, (c) README cite les 2 fontes, (d) oracle du test == #4 (set-diff). 6 morsures vérifiées (constante accent/display · CLAUDE.md #4 accent → mord SIMULTANÉMENT les 3 copies aval · docstring · README · oracle), restauré vert, 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 02:41:10 +00:00
Claude Code DTP Worker 3a91c9d52f [DTP-Worker] Sprint 8 · buffer · Fiches agents/rattachement Workspace : les ASSERTIONS D'APPARTENANCE Has Role des trois fiches 03_agents/{rendu,ifc_speckle,mobile}/AGENT.md — QUELLE CONSOLE (Workspace ERPNext natif v15) le rôle peut atteindre — étaient une surface data-derived DISTINCTE du contrat rbac_50_roles.json (la membership vit dans frontend/portails/out/workspace.json, byte-gaté par check_artifacts) et HORS de tout gate.
Les blocs Fiches Faisabilité / Fiche Mobile ne gataient que les attributs du CONTRAT ; le bloc « triplets par workspace » ne gate que le COMPTE de rôles par Workspace (`nb_roles`), AVEUGLE à QUEL rôle. Rattacher le rôle mobile à `OTO Ventes` (SUR-EXPOSITION console : le dev mobile gagnerait l'accès au portail Ventes — la restriction même que la note #6 pose), retirer/déplacer le rôle rendu de `OTO Construction`, laissait la fiche périmée en silence pendant que l'artefact dit autre chose ⇒ l'agent ERPNext Backend câblerait le mauvais accès console.

Gate ajouté (nouveau bloc « Fiches agents · rattachement Workspace ») : index recomputé `erpnext_role_name → {titres de Workspace le portant}` depuis workspace.json (nom résolu du contrat par id, zéro duplication). 3 formes d'assertion : in_named (rendu — prose cite CE Workspace ET membership == {lui seul}) · in_any (ifc — membership ≥1) · not_in_named (mobile — assertion NÉGATIVE #6, rôle ABSENT du Has Role du Workspace nommé). Garde anti-typo : Workspace nommé absent de l'artefact ⇒ ROUGE. Claim absent ⇒ ROUGE (traçabilité).

9 morsures vérifiées (4 artefact + 5 fiche/bord) ; restauré vert ; 7 gates re-verts. ci/README.md (récap + paragraphe détaillé) + activity log + mémoire mis à jour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 02:10:19 +00:00
Claude Code DTP Worker bc58809e7d [DTP-Worker] Sprint 8 · buffer · Faisabilité/fiches agents : les DEUX FICHES D'IDENTITÉ des rôles RBAC faisabilite-rendu-3d (03_agents/rendu/AGENT.md:34) et faisabilite-ifc-speckle (03_agents/ifc_speckle/AGENT.md:34) — la carte que l'agent ERPNext Backend lit pour SEEDER le rôle porteur des rendus / de l'export IFC→GLB — recopiaient EN PROSE, DEPUIS le contrat rbac_50_roles.json, les attributs data-derived du rôle (erpnext_role_name · nom_fr/modules côté rendu · portail · entite_principale · niveau · les DEUX permissions_cibles File R/W/create + Faisabilité R ou R/W) SANS AUCUN gate d'IDENTITÉ. Le README frontend/portails n'est gaté que sur des COMPTES de rôles par Workspace, aveugles à l'identité de CE rôle.
Même classe que la Fiche Mobile (session précédente) — surface 03_agents/*/AGENT.md transcrivant à la main les attributs d'un rôle depuis le contrat, gatée (si tant est) seulement sur des comptes agrégés. Gate ajouté (bloc « Fiches Faisabilité », config-table par fiche : fichier · role_id · attributs restitués) : par attribut recomputé du contrat, prose EXACTE exigée ; permissions rendues en ORDRE CANONIQUE (read→R · write→W · create/delete/… en toutes lettres — élargir/rétrécir change la chaîne, `R/W/create` ne satisfait plus `R/W/create/delete`) ; verbe inconnu ⇒ ROUGE ; claim absent échoue AUSSI.

#6 (honnêteté) vérifié AVANT édition : la DESCRIPTION de ces deux fiches est une PARAPHRASE éditoriale (le contrat porte « (… — CLAUDE.md) » / « les modèles » que la fiche condense) — donc NON gatée verbatim (ne rien réécrire de correct pour un gate), seuls les attributs structurés (transcrits à l'exact) sont contraints. État courant : aucun attribut structuré périmé (12 recomputes == contrat).

11 morsures vérifiées (5 contrat + 6 fiche) : rendu Faisabilité +write (R→R/W) · rendu niveau 2→3 · rendu WA SRL→WAF · rendu rôle renommé · ifc Faisabilité R/W→R · fiche rendu File R/W/create→…/delete · fiche ifc R/W→R/W/create · fiche rendu module Faisabilité→Selling · fiche ifc WA SRL→WAF · fiche rendu nom_fr retiré (absent) · ligne contact ifc supprimée (INTROUVABLE) ; restauré vert, 7 gates re-verts. ci/README.md + activity log MAJ.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 01:38:49 +00:00
Claude Code DTP Worker 3bce40ea80 [DTP-Worker] Sprint 8 · buffer · Mobile/fiche agent : la FICHE D'IDENTITÉ du rôle RBAC plateforme-mobile (03_agents/mobile/AGENT.md:36) — le SEUL ancrage in-repo réellement vérifiable de l'agent mobile (builds/stores hors-repo #8) — recopiait EN PROSE, DEPUIS le contrat rbac_50_roles.json, TOUS les attributs data-derived du rôle (erpnext_role_name · nom_fr · famille/portail · entite_principale · niveau · scope_donnees · modules · perm API Access custom R/W · description) SANS AUCUN gate d'IDENTITÉ. Le README mobile/app_config n'est gaté que sur des COMPTES agrégés (« 5 onglets · 44 rôles »), aveugles à l'identité de CE rôle — la carte que l'agent ERPNext Backend lit pour seeder le rôle. Gate ajouté : chaque attribut recomputé du contrat, prose EXACTE par attribut (sigle de perm canonique ordonné C/R/W/D/S/X/A — élargir/rétrécir change le sigle), description verbatim (emphase/point neutralisés), cohérences croisées famille==portail · perm custom · role_id singleton ; 12 morsures (6 contrat + 6 fiche) vérifiées, restauré vert, 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 01:13:06 +00:00
Claude Code DTP Worker e8b30d7147 [DTP-Worker] Sprint 8 · buffer · Faisabilité/bancable : les 4 figures « Génération réelle (fixture) » du README (40 unités · USD 8,560,000 / DOP 505,040,000 · point d'équilibre 21 unités ⌈52 % × 40⌉) — les chiffres DATA-DERIVED du dossier bancable que voit le banquier — étaient HORS de tout gate. Le module n'écrit son out/ que sur disque (« out/ non commité ») ⇒ check_artifacts est aveugle (aucun artefact byte-gaté) et AUCUN gate ne le touchait.
Ces 4 figures sont Σ quantités · Σ(qté×prix_usd) · Σ(qté×prix_dop) · ⌈point_equilibre_pct × Σ unités⌉ calculées sur la fixture COMMITÉE fixtures/brief_bancable.json, le 52 % ancré sur CLAUDE.md #9 (« Point équilibre 52% pré-vente »). PIÈGE : la seule vérification existante (tests/) teste des FONCTIONS (l'arithmétique de recoupement _check_derived_arithmetic) avec des oracles HARDCODÉS dans le test — une copie de plus, jamais comparée à la PROSE du README. Éditer une typologie de la fixture (quantité/prix), en ajouter/retirer une, ou déplacer le point d'équilibre de CLAUDE.md #9, laisse les 4 chiffres du README périmés pendant que le générateur produit autre chose → le banquier lit un dossier faux (l'invention même que #6 interdit) — « vert trompeur » qu'aucune suite tests/ n'attrape.

Nouveau bloc « Faisabilité/bancable figures » dans ci/check_readme_claims.sh (avant sys.exit), même esprit que le bloc faisabilite/generator ancré sur CLAUDE.md #9/#10 mais appliqué à une surface dont la source de vérité n'est PAS un out/*.json : (1) recompute indépendant des 4 figures depuis la fixture commitée ; (2) cohérence croisée — le manifeste GÉNÉRÉ (bancable_gen validate, exécuté via subprocess stdlib pur, encoding utf-8) == le recompute (mord un générateur/fixture incohérents) ; (3) prose — un seul pattern d'identité exige les 4 valeurs EXACTES avec séparateur de milliers pour USD/DOP + la formule ⌈pct × Σ unités⌉ dont le pct == CLAUDE.md #9 et le total == Σ unités. Un claim absent échoue AUSSI (traçabilité).

État courant : aucun chiffre périmé (anti-invention #6, rien à réécrire) — le défaut est la surface ungated (module entièrement hors CI). 7 morsures vérifiées : README USD 8,560,000→9,560,000 (figure périmée) · README retire le séparateur de milliers (8,560,000→8560000) · README breakeven 21→20 (formule périmée) · README formule 52 %→55 % (dérive CLAUDE.md #9) · README supprime la ligne entière (INTROUVABLE) · fixture Studio qté 12→13 (5 morsures : units/USD/DOP/breakeven README périmés + manifeste) · fixture 2 Chambres prix_usd 320000→300000 (catalogue USD périmé) ; restauré = green : 4 figures == génération réelle · manifeste == recompute · pct 52 % == CLAUDE.md #9 · exit 0. Working tree byte-restauré via git checkout -- (JAMAIS git clean) · 7 gates re-verts. ci/README.md (ligne récap check-readme-claims) mis à jour · log 05_activity_log/2026-08-01.md. Auto-score 4Big 96/100.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 00:41:00 +00:00
Claude Code DTP Worker 37903685c0 [DTP-Worker] Sprint 8 · buffer · RBAC/userperm_gen : la TABLE « Mapping scope_donnees → mécanisme » — la FONCTION d'enforcement ROW-LEVEL (quel mécanisme Frappe natif applique CHAQUE portée + si un User Permission template est émis), CŒUR sécurité du module — était transcrite EN PROSE (README:33-38) SANS AUCUN gate d'IDENTITÉ. Le bloc RBAC « 3 volets » ne gate QUE la ventilation par mécanisme (« 28/16/2/4 »), aveugle à QUEL mécanisme applique QUELLE portée.
Gate ajouté (check_readme_claims.sh) : par portée le mechanism (1er token backtické) + le verdict « Template émis ? » recomputés de out/user_permission_plan.json byte-gaté, exacts ; identité d'ensemble portées table == portées artefact (ni fantôme ni manquante) ; cohérences croisées : chaque portée mappe UN SEUL mécanisme (fonction) · verdict uniforme par portée · template émis SSI user_permission_company (invariant « template SSI entite »).

7 morsures vérifiées (README réaffecte entite→none_consolidated = row-level enforcement abandonné · bascule verdict oui→non · échange portée = fantôme+manquant · retrait ligne · table supprimée · artefact réaffecte entite · artefact non-uniforme casse SSI) ; restauré = green · exit 0. Working tree byte-restauré (git checkout --, JAMAIS git clean) · 7 gates re-verts. ci/README.md (récap + détail 2e surface userperm_gen) mis à jour.
2026-08-01 00:10:13 +00:00
Claude Code DTP Worker e5f6459e85 [DTP-Worker] Sprint 8 · buffer · DevOps/deploy_runbook (2e surface) : la TABLE « Plan de phases généré » — le GRAPHE de portage VPS ordonné (# · Responsable · Modules · Dépend de) — était un WILDCARD et avait DÉRIVÉ : elle omettait mobile/app_config (phase 5) ET qa/acceptance (phase 7), 20/22 modules listés pendant que la couverture prouvée était bijective 22/22. README corrigé sur l'artefact byte-gaté + gate d'identité par phase (8 morsures).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-31 23:40:44 +00:00
Claude Code DTP Worker 082b057639 [DTP-Worker] Sprint 8 · buffer · CRM/workflow_vente (3e surface) : la TABLE « Rôles = contrat RBAC » — le RÔLE RBAC qui GARDE chaque transition du pipeline vente, CŒUR sécurité du workflow — était transcrite EN PROSE (README:55-62) SANS AUCUN gate d'IDENTITÉ.
Les deux blocs CRM/workflow existants gatent le COMPTE (« 9 états · 11 transitions ») ET l'énumération des transitions à séparation des pouvoirs (allow_self_approval=0), jamais l'identité des GARDES. Sources faisant autorité (byte-gatées par check_artifacts) : out/workflow.json (chaque transition porte `allowed` = le rôle gardien) + out/MANIFEST.json.roles_rbac_utilises[].erpnext_role_name (recomputé du contrat rbac_50_roles.json à chaque build). PIÈGE : les blocs COMPTE/séparation sont AVEUGLES à l'identité des gardes → RÉAFFECTER un pas monétaire (« Confirmer réservation » Réservations→Conseiller = élévation de privilège) · RENOMMER un rôle · AJOUTER un fantôme · en OUBLIER un laissait le README périmé pendant que l'artefact dit autre chose → l'agent ERPNext Backend câblerait le mauvais garde (le risque même que la table veut prévenir) — « vert trompeur » qu'aucune suite tests/ (qui teste des FONCTIONS de graphe/résolution RBAC, pas la prose) n'attrape. Même patron d'IDENTITÉ que la cross-cohérence PERMISSIONS Legal/CONFOTUR déjà gatée.

Nouveau bloc « CRM gardes » dans ci/check_readme_claims.sh (après le bloc Démo scénarios) : (1) identité d'ensemble — colonne « Rôle » de la table == {allowed} de workflow.json (set-diff · NFKD/casefold) ; (2) cohérence artefacts — {allowed} == roles_rbac_utilises du MANIFEST (aucun garde hors manifeste ni l'inverse) · ensemble NON VIDE ; (3) cross-cohérence par pas — les gardes des étapes SENSIBLES et uniques Confirmer réservation/Signer contrat/Approuver CONFOTUR (recomputés `allowed`, jamais figés) nommés EXACTEMENT dans leur ligne. Le (3) mord la RÉAFFECTATION vers un rôle DÉJÀ présent (rôle servant deux transitions) que le set-diff seul manquerait. Un claim absent échoue AUSSI.

7 morsures vérifiées : README réaffecte Confirmer réservation→Conseiller (absents=[réservations] + pas mordu) · artefact réaffecte Signer contrat→Conseiller (en trop=[contrats] + incohérence MANIFEST + pas mordu) · README rôle fantôme (en trop=[oto fantome]) · README retire un rôle (absents=[direction commerciale]) · artefact MANIFEST perd un garde (garde pas dans MANIFEST=[réservations]) · table supprimée (INTROUVABLE) · artefact réaffecte Approuver CONFOTUR→Directeur (rôle déjà présent, set INCHANGÉ, captée UNIQUEMENT par la cross-cohérence par pas) ; restauré = green : 7 rôles · colonne == {allowed} == roles_rbac_utilises · 3 étapes sensibles pinnées · exit 0. État courant : aucun garde périmé (anti-invention #6, rien à réécrire) — le défaut était la surface ungated. ci/README.md (table + détail « 3e surface workflow_vente ») mis à jour · working tree byte-restauré (git checkout --, JAMAIS git clean) · 7 gates re-verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-31 23:11:18 +00:00