Files
oto-enterprise-os-dtp/03_agents/publiciste/AGENT.md
T
Claude Code DTP Worker aeb30b8311 [DTP-Worker 20260812_070054] fix correctness · rendu HTML publiciste — URL de rendu percent-encodée dans le url('…') CSS
Bug latent réel (rendu-correctness, entrée FR/ES plausible) : _hero_media
(generator.py:92) injectait le nom de fichier via html.escape dans un
background-image:url('…'). Un rendu réel « Vue d'ensemble.png » devenait
Vue d'ensemble.png → le navigateur HTML-décode l'attribut style AVANT le
CSS → l'apostrophe referme la chaîne url('…') → hero non affiché, silencieux.
html.escape est le mauvais encodeur pour un contexte CSS.

Fix : urllib.parse.quote sur le segment de fichier ('→%27, espace→%20,
accents→%XX) — valide dans URL + attribut HTML + url() CSS ; _esc conservé pour
l'attribut HTML. Zéro dérive : quote laisse les noms ASCII simples inchangés
(hero_aerien.jpg identique) → fixture + byte-repro intacts.

Test de régression à dents (test_hero_media_url_percent_encode) : prouvé FAIL
sans quote, PASS avec. Cascade régénérée (artifact-reproducibility-gate) :
suite publiciste 24→25, matrice 629/612→630/613/17 · quality_report régénéré
en DERNIER · 3 fiches AGENT.md (compteurs dérivés) réalignées.

Défaut d'abord : 12 fichiers cœur / 7 modules ré-audités CLEAN (epsilon 1e-9
gate apport = tolérance flottante correcte). run_ci 33/0/0 · NFC-clean ·
zéro code moteur V18 (bloqué D-06 #6) · zéro gate ajouté (#5) · zéro invention (#6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 07:15:47 +00:00

7.0 KiB

🎯 Publiciste Agent · Maintenance automatique site public (vente.otov7.com)

Rôle : Cet agent OTOIA maintient automatiquement à jour le site public vente.otov7.com à partir des faisabilités canoniques de chaque projet. Il élimine le besoin d'édition manuelle du site.

Mission

  1. Extraire en continu depuis les faisabilités canoniques (data_room/PXX/) :

    • Positionnement marketing
    • Typologies + surfaces
    • Prix "à partir de" par typologie
    • Grille tarifaire complète
    • Ce qui est inclus (services · équipements · CONFOTUR · Fideicomiso · etc.)
    • Rendus visuels (60_photos_site)
    • Statut (Disponible · En développement · Bientôt · En processus)
  2. Générer copy multilingue FR/EN/ES à partir du positionnement documenté

  3. Publier automatiquement sur vente.otov7.com sans intervention humaine

  4. Détecter changements dans faisabilités et déclencher rebuild du site

  5. Ajouter automatiquement les nouveaux projets dès que data_room/PXX/ créé + faisabilité complète

Sources de vérité (dans l'ordre)

  1. /opt/oto/data_room/PXX/50_financier_bancable/one_pager_banquier.pdf
  2. /opt/oto/data_room/PXX/40_llm_outputs/commercial.md
  3. /opt/oto/data_room/PXX/40_llm_outputs/marche_analyste.md
  4. /opt/oto/data_room/PXX/40_llm_outputs/directeur.md
  5. /opt/oto/data_room/PXX/00_brief/
  6. /opt/oto/data_room/PXX/60_photos_site/ (rendus)

Règles absolues (interdits)

  • Zéro invention de prix, chiffres, positionnement (source ONLY = faisabilité)
  • Jamais éditer directement vente.otov7.com/index.html — passer par le générateur
  • Ne pas publier un projet dont la faisabilité est incomplète (marquer "En développement")
  • Ne pas dupliquer rendus AI (source unique data_room/PXX/60_photos_site/)

Workflow détaillé

Trigger 1 : Faisabilité mise à jour

  • Détecte modification dans data_room/PXX/40_llm_outputs/*.md
  • Re-extrait positionnement + prix
  • Régénère section projet dans vente.otov7.com/index.html
  • Log la modification dans /opt/oto/otoia/reports/publiciste_YYYY-MM-DD.md
  • Notifie Michel via WhatsApp si prix / positionnement change

Trigger 2 : Nouveau projet créé

  • Détecte création data_room/PXX/ (nouveau code projet)
  • Attend que la faisabilité soit complète (score ≥ 95/100)
  • Ajoute automatiquement la card projet sur vente.otov7.com
  • Copie les rendus dans /opt/oto/sites/static/projets/pXX/
  • Log + WhatsApp notification

Trigger 3 : Nouveau rendu généré

  • Détecte nouveau rendu dans data_room/PXX/60_photos_site/
  • Copie vers /opt/oto/sites/static/projets/pXX/
  • Met à jour l'image hero de la card si c'est le rendu principal
  • Cache-bust Cloudflare automatique

Trigger 4 : Faisabilité incomplète

  • Détecte "prix non documenté" ou "pricing non défini"
  • Marque le projet en "En développement" avec "Prochainement · Détails à venir"
  • Log + WhatsApp à Michel pour compléter faisabilité

Architecture technique

data_room/PXX/  ────► parser.py (extraction) ────► projets_master.json
                                                          │
                                                          ▼
                                                  generator.py (rendu HTML)
                                                          │
                                                          ▼
                                                  /opt/oto/sites/vente/index.html
                                                          │
                                                          ▼
                                                  Cache-bust Cloudflare + notify Michel

Composants à créer

  1. otoia/capabilities/publiciste.py — orchestrateur agent
  2. otoia/capabilities/knowledge/site_public_template.md — template génération site
  3. Systemd timer otoia-publiciste.timer (check horaire)
  4. Watch inotify sur data_room/*/40_llm_outputs/ (temps réel)
  5. Backend Frappe DocType Publiciste Log pour audit trail

Livrable Publiciste réellement produit (05_deliverables_mvp/publiciste/)

Les « Composants à créer » ci-dessus décrivent le runtime VPS cible (otoia/capabilities/publiciste.py, systemd/inotify · hors périmètre worker · CLAUDE.md #8). Leur contrepartie commitée et testable existe déjà en-repo (périmètre worker) : le scaffold du générateur, gaté en CI. C'est le seul module net-neuf du mandat, sur le chemin critique (cf. ../../05_deliverables_mvp/GAP_ANALYSIS_SPRINT1.md §3.13).

Module Sprint Rôle Entrée CLI Job CI Tests
publiciste/ 2 (README scaffold (Sprint 2) · GAP §3.13) Pipeline site public : data_room/PXX/projets_master.jsonindex.html luxury (lib/parser.py extraction · lib/validator.py schéma · lib/generator.py + lib/branding.py rendu dark+doré #0a0a12/#f0b429 · templates/site_public.html.tmpl) publiciste.py parse|validate|generate|run publiciste-tests 25

Le contrat d'échange projets_master.json n'est pas défini ici mais par le Faisabilité Agent (../../05_deliverables_mvp/faisabilite/projets_master.schema.json, Sprint 1) — source unique, zéro duplication (#5). Le Publiciste en est le consommateur : lib/parser.py extrait, lib/validator.py valide contre ce schéma avant tout rendu.

Anti-invention (#6) : le générateur ne fabrique aucun prix ni positionnement — chaque valeur du site est extraite d'une faisabilité data_room/PXX/ réelle ; un projet dont la faisabilité est incomplète est marqué « En développement », jamais complété par invention (règles absolues ci-dessus). Aucun index.html de production n'est commité ici : seuls le générateur, le template et ses fixtures d'entrée (fixtures/data_room/P01…P02, échantillons d'entrée du parser — pas des livrables, d'où leur exclusion volontaire de l'auto-score) le sont ; la publication réelle sur vente.otov7.com s'exécute côté VPS (#8). Auto-score du livrable : 95/100 (README.md).

Livrable Sprint (mandat 8 semaines)

  • Semaine 2 : Setup base + parser faisabilité → JSON
  • Semaine 3 : Générateur HTML → vente.otov7.com
  • Semaine 4 : Triggers systemd + inotify actifs
  • Semaine 5 : Notifications WhatsApp Michel
  • Semaine 6 : Multi-langue FR/EN/ES automatique
  • Semaine 7 : Tests + validation faisabilités P01-P09
  • Semaine 8 : Production

Coordination inter-agents

  • BIM Agent : fournit rendus (Blender/Bonsai → 60_photos_site)
  • Faisabilité Agent : génère faisabilités 4 volets → 40_llm_outputs
  • Rendu Agent : batch renders → 60_photos_site
  • CRM Agent : reçoit leads/inscriptions du site public
  • SEO Agent : optimise les balises meta générées