3e7bc33fb7af0f4ec35e4e24065fd3cbbd35ae90
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
8593961683 |
[DTP-Worker] Sprint 8 · buffer · Fiches agents/citation CLAUDE.md #10 : la prose « Anti-invention » de DEUX fiches — 03_agents/erpnext_backend/AGENT.md:57 (devises **USD + DOP** · format **Letter US** · paiements **Cardnet**, pas Stripe) et 03_agents/crm/AGENT.md:37 (devises **USD + DOP** · format **Letter US**) — RECOPIE À LA MAIN les valeurs canoniques de la contrainte NON-NÉGOCIABLE CLAUDE.md #10 en AFFIRMANT « cités depuis CLAUDE.md #10, jamais réinventés », mais AUCUN gate ne liait cette citation à #10. Le bloc « paramètres canoniques » faisabilite/generator n'ancre QUE genlib/model.py CANONICAL + son README (classe claude-md-constant-anchor), AVEUGLE à ces fiches ; aucune suite tests/ (FONCTIONS, jamais l'ancre à CLAUDE.md) n'attrape la prose. Piège #6 : RENOMMER le prestataire (Cardnet→Azul) ou changer une devise/format dans CLAUDE.md #10 laisse ces citations PÉRIMÉES en silence, contredisant le mandat pendant que la prose se réclame de « CLAUDE.md #10 » — « vert trompeur ». Gate ajouté (bloc « Fiches agents · CITATION des constantes CLAUDE.md #10 ») : réutilise les valeurs exp déjà recomputées de #9/#10 (zéro duplication) + le prestataire EXCLU ((pas X)) recomputé de #10 ; config table par-fiche du SOUS-ENSEMBLE de tokens qu'elle cite (crm omet le paiement) ; exige l'ancre « CLAUDE.md #10 » + chaque token en gras **<valeur>** == #10 (casse tolérée) + l'exclusion pour erpnext. 5 morsures vérifiées (Cardnet→Azul mord erpnext SEUL · devises mord les DEUX · exclusion Stripe→PayPal · fiche crm Letter US périmé · ancre #10 supprimée → INTROUVABLE), restauré vert, 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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-tests→rbac-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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |