ADRADR-0003 · BoostEcom Creative est un process vertical de l'OS, pas un deuxieme produit

ADR-0003 — BoostEcom Creative est un process vertical de l'OS, pas un deuxieme produit

BoostEcom Creative est une offre de production de creatives publicitaires e-commerce vendue en abonnement mensuel a des marques Shopify. La question posee etait : quelle infrastructure construire pour la servir ?

Statut

Accepté · 2026-08-15

Piliers : ai-platform, data-platform, billing

Contexte

BoostEcom Creative est une offre de production de creatives publicitaires e-commerce vendue en abonnement mensuel a des marques Shopify. La question posee etait : quelle infrastructure construire pour la servir ?

La reponse naive — un service de generation autonome avec son propre modele de marque, sa propre memoire et son propre agent "Creative Director" : aurait duplique presque toute la plateforme. L'inventaire du code montre que les primitives existent deja :

  • Recherche marche : la sonde meta-ad-library recupere les pubs actives des concurrents, creative-vision-analyzer en extrait hook_text / text_overlay / ugc_or_studio / format / dominant_colors dans AdCreativeAnalysis, creative-clusterer les regroupe en familles creatives. Cout mesure : ~0,005 EUR par creative analysee, plafonne a 1 EUR par store et par passe.
  • Strategie creative : c'est deja le domaine declare de @Maya dans identity-registry.ts, sa bio couvre les briefs creatifs et la rotation des creatives gagnantes, ses boundaries excluent explicitement le pricing (@Marco) et l'email (@Otis).
  • Verite de marque : knowledgeSearch indexe voix de marque, glossaire produit, claims, decisions passees. MemoryEvent + memory/rag.ts portent l'historique.
  • Production : @Atlas Studio (generateImage + saveStudioAsset).
  • Human-in-the-loop : autonomy.ts + tool-permission-matrix.ts classent chaque tool et resolvent execute / require_approval / deny avant chaque invocation, les 4 niveaux d'autonomie existent.
  • Orchestration : Workflow / WorkflowRun avec triggers manual / scheduled / webhook et le cron workflow-tick.

Deux manques reels sont apparus, et un seul bloque la vente.

Décision

Creative est un process vertical qui consomme les primitives existantes. Aucun nouvel agent, aucun second "Brand Brain", aucune memoire separee, aucun deuxieme Studio.

Trois consequences directes appliquees par ce commit :

  1. Le modele image de Studio a une source unique, STUDIO_IMAGE_MODEL.
  2. Chaque creative produite obtient une ligne StudioAsset portant son angle, son hook, sa persona, son cout et son verdict QC.
  3. La discipline creative est un skill (creative-ads), pas sept.

Alternatives écartées

OptionPourquoi non
Un agent @CreativeDirectorLe domaine appartient deja a @Maya, qui le declare dans sa bio. Ajouter un agent par discipline amorce une inflation (@EmailGuy, @CROGuy…) alors que les Skills existent precisement pour specialiser un agent sans creer un personnage.
Un "Creative Brand Brain" dedieDupliquerait knowledgeSearch + MemoryEvent. Deux sources de verite sur la marque, donc deux verites divergentes a six mois. Creative enrichit la Knowledge existante.
Sept skills (creative-research, hook-generator, static-ad…)Le router selectionne un seul skill par message (selectSkill → un unique fragment ## Skill: injecte). Sept micro-skills se disputeraient le meme slot et le classifier trancherait au hasard. Un skill a phases est la forme que l'architecture accepte.
Stocker les assets uniquement dans Blob (statu quo)Un fichier sans angle ni cout est invisible : cout par creative approuvee — la metrique qui decide si la production est rentable — devient incalculable, et la boucle d'apprentissage n'a rien a apprendre.
Facturer le modele image annonce sans l'executermodel-pricing.ts declarait google/gemini-3-pro-image (Nano Banana Pro) pendant que le tool appelait gemini-3.1-flash-image-preview. Exposition marketing, et surtout toute metrique de cout devient fictive.
Attendre 10 clients avant d'ecrire le data model et le skillVaut pour ce qui depend de donnees reelles (workflow Learn, scoring, UI de QC client). Ne vaut pas pour l'encodage d'un process deja connu : c'est de la structure, pas de la speculation.

Conséquences

Ce que ca coute.

  • StudioAsset ajoute une table et une ecriture par asset genere. L'ecriture est best-effort : un echec DB logge et retourne quand meme l'URL Blob, parce que perdre l'asset serait pire que perdre sa metadonnee. Corollaire accepte : le ledger peut avoir des trous, il n'est pas une source comptable.
  • Les metadonnees creatives sont optionnelles en base. Un asset enregistre sans concept / angle est invisible pour l'analyse. Le prompt du skill l'impose, mais rien ne le contraint mecaniquement.

La dette acceptee.

  • perVideoSecond, perVoiceKChars, perLipsyncMinute et perVector sont affiches alors que seule l'image a un tool runtime. Video, voix, lipsync et vecteur transitent par le MCP Higgsfields, qui ne s'enregistre que si HIGGSFIELDS_MCP_URL + HIGGSFIELDS_MCP_TOKEN sont definis. Ces cles ne sont declarees ni dans env/server.ts ni en production a la date de cet ADR : la V0 est statics-only.
  • perImage reste a 0,21 USD alors que le modele reellement execute est Flash, moins cher que le Pro initialement annonce. Le markup effectif depasse donc le 1.5x documente. C'est une decision business a trancher (baisser le prix, ou basculer STUDIO_IMAGE_MODEL sur le Pro), pas une decision d'ingenierie : d'ou la constante unique qui rend la bascule triviale.

Le signal de revisite. Si un deuxieme process vertical (Lifecycle, CRO) demande les memes briques que Creative, il faut extraire un socle commun plutot que dupliquer. Et si la video devient le livrable principal, configurer Higgsfields cesse d'etre optionnel et redevient bloquant.

Note du 2026-09-05 — la dette ci-dessus est payee, la decision tient.

Cet ADR reste le compte-rendu de ce qui etait vrai le 2026-08-15 : il n'est pas reecrit. Ce qui a change depuis, et qui rend le paragraphe « dette acceptee » faux au present :

  • ai-platform/0345 a bascule la video sur experimental_generateVideo / Veo 3.1, en direct sur l'AI Gateway. Elle a un tool runtime, sans aucune cle MCP. La V0 n'est plus statics-only.
  • La voix-off est generee DANS le clip (generateAudio: true), donc facturee a la seconde de video : perVoiceKChars a ete retire, son tarif etant calibre sur ElevenLabs, un fournisseur jamais appele.
  • perLipsyncMinute a ete retire : aucune route Gateway ne fait d'avatar parlant, et il n'y en a toujours pas.
  • Le vecteur est ecrit par le modele (.svg, du texte), donc deja facture en tokens de sortie : perVector a ete retire pour ne pas facturer deux fois le meme rendu.
  • STUDIO_IMAGE_MODEL a bascule sur le Pro : le Studio livre desormais le modele qu'il facture, ce qui repond a l'arbitrage business laisse ouvert ci-dessus.

Le seul tarif au token que le Studio affichait encore a survecu jusqu'au 2026-09-05 ($3 / $180 / 1M sur une route facturee a l'unite) et a ete retire avec le meme raisonnement.

Higgsfields est desormais un add-on optionnel, offert a cote des connecteurs. Le signal de revisite ci-dessus ne se declenchera pas : la video est devenue un livrable principal ET Higgsfields est reste optionnel.

Comment c'est appliqué

  • Source unique du modele image : STUDIO_IMAGE_MODEL est exportee par src/config/model-pricing.ts et importee par handler-tools-build.ts. Aucun id de modele image en dur ailleurs.
  • Ledger : saveStudioAsset ecrit la ligne StudioAsset. La table, ses enums et ses index sont derives automatiquement dans schema-guard.generated.ts (pnpm db:guard), donc verifies par le hook pre-push et appliques au cold-start : aucun step manuel.
  • Skill unique : src/features/ai/skills/creative-ads/. Le loader refuse tout bundle sans skill.md + prompt.md, et applySkillFilter n'expose que les tools declares (plus les tools read). generateImage et saveStudioAsset etant safe_write, ils doivent y figurer explicitement : ce qui est le cas.
  • Non applique mecaniquement : rien ne force le modele a renseigner concept / angle / hook lors d'un saveStudioAsset. C'est une regle de prompt, donc une regle qui sera violee. Le gate naturel serait de rendre ces champs obligatoires quand platform est fourni : a faire quand les premiers Drops reels auront montre la forme utile.