ADR-0014 — Le programme partenaire echange de la distribution, pas une commission
/network/agencies vendait publiquement, dans les six locales et depuis des mois : « Lifetime 20% revenue share on every BoostEcom store you implement (no 12-month cap) ». Le metaTitle de la page le repetait, ses Stats…
Statut
Accepté · 2026-09-12
Piliers : billing, growth-web, marketplace
Contexte
/network/agencies vendait publiquement, dans les six locales et depuis
des mois : « Lifetime 20% revenue share on every BoostEcom store you
implement (no 12-month cap) ». Le metaTitle de la page le repetait, ses
Stats l'affichaient comme un terme contractuel, et sa FAQ
stackWithReferral s'en servait comme preuve d'elle-meme (« the agency
share is for life »).
Aucun chemin de code ne payait cela, et aucun ne pouvait le payer. Le seul
ledger de commission du depot est AffiliateCommission
(src/config/affiliate.ts) :
| Taux | AFFILIATE_COMMISSION_PCT = 30, plafond dur (Math.min(asked, 30)) |
| Duree | AFFILIATE_COMMISSION_MONTHS = 12, comptees en factures payees |
| Cle | un code par affilie (AffiliateCode.code @unique) |
Il n'existe ni agencyShare, ni taux a vie, ni attribution
store → partenaire, ni aucune table qui rattacherait une agence aux
abonnements qu'elle deploie.
La page portait quatre autres promesses sans implementation, verifiees une par une :
| Promesse | Etat reel |
|---|---|
| « Private Slack channel » | zero Slack dans le depot. La communaute est Discord, et ecosystem-alerts.ts ecrit « no Slack » |
| Annuaire « filterable by region, vertical, language and technical expertise » | AGENCY_FIELDS porte services, location, hourlyRateCents. Aucun filtre sur /marketplace/[type] |
| « Early access 3-4 weeks before public release » | aucun feature-flag, aucun gating par partenaire |
| « Pass the technical assessment » + « 30-minute onboarding call » | le parcours reel est un formulaire de trois champs, une ligne NetworkApplication, un e-mail best-effort vers MARKETPLACE_ADMIN_EMAIL et un tri manuel dans /admin/revenue/network-applications |
Et une cinquieme, ailleurs : la FAQ de la home et de /pricing
(home.faq.groups.network.items.agencies) promettait en plus de
revendre BoostEcom en white-label avec un vetting en 2-3 jours,
quand la page annonce deux semaines. Le white_label du depot est une
option de plan Custom / Max 20x pour le CLIENT
(src/types/billing-enterprise.ts),
pas un mecanisme de revente.
L'ecart etait deja compte, pas decouvert :
backlog/billing/0369
(type: "decision", P1) le nommait, et
src/test/affiliate-terms-match-the-ledger.test.ts tenait
marketingPages.network.agencies dans PENDING_OWNER_DECISION pour
l'empecher de se repandre. Ce qui manquait etait une reponse du
proprietaire, qu'aucun agent n'a le droit d'inventer : c'est un prix et un
contrat client.
Décision
Le programme partenaire ne verse aucune commission. Il echange une fiche dans l'annuaire public, les demandes entrantes qui arrivent dessus, et un acces delegue dans l'organisation du client. Le partenaire facture ses propres clients, et rien ne passe par nous.
Le chemin paye pour une introduction reste le parrainage, inchange : 30 % sur 12 factures payees, un seul ledger, ouvert a tout compte sans revue.
Corollaire d'URL : /network/agencies devient /network/partners en 308.
L'ancienne URL excluait les freelances seniors que sa propre copie, sa FAQ
et son formulaire invitaient a candidater, alors que le marketplace porte
deja agencies et freelancers comme deux annuaires distincts.
Repondu le 2026-09-12, apres verification qu'aucune candidature agence n'avait ete acceptee : la reecriture ne laisse donc personne engage sur les anciennes conditions.
Alternatives écartées
| Option | Pourquoi non |
|---|---|
Construire un vrai ledger agence a 20 % a vie (sortie 2 de billing/0369) | Une feature complete : table de commission, attribution store → partenaire, payouts Connect, et la reouverture du calcul de liability. config/affiliate.ts chiffre deja le prix d'un taux a vie : « 30 % pour toujours sur un Max 20x, c'est 90 $/mois indefiniment pour une acquisition faite une fois ». Pas un chantier a lancer avant d'avoir le volume qui le justifie |
| Aligner le partenaire sur le parrainage : 30 % / 12 factures (sortie 3, celle que le registre recommandait) | Un seul ledger et zero mensonge, mais ca fait payer deux fois le meme client : l'agence facture son implementation ET touche une commission sur l'abonnement qu'elle a elle-meme vendu. Et ca plafonne a 12 mois une relation qui, cote agence, est censee durer |
Fermer le programme, 308 vers /network/referral (sortie 1) | Honnete en quelques heures, mais on perd un funnel d'acquisition deja construit et indexe (sitemap 0.75, llms.txt, nav), et la capacite de recruter des agences, qui sont le canal de distribution le moins cher d'une plateforme e-commerce |
Garder /network/agencies comme URL | L'URL aurait continue d'exclure les freelances que la page invite explicitement a postuler, pendant que le marketplace leur reserve son propre annuaire |
Conséquences
Ce que ca rend facile. La page devient verifiable ligne par ligne :
chaque promesse restante correspond a une surface qui existe
(listing-types.ts pour la fiche, POST /api/marketplace/leads pour les
demandes, OrganizationMember + le namespace studio.* pour l'acces
delegue, le Store Graph pour l'audit de prospect). Et le programme ne
cree aucune dette financiere : il n'y a rien a verser, donc rien a
reconcilier, rien a clawbacker, aucun modele de liability a rouvrir.
Ce que ca coute. Un programme partenaire sans revenue share est moins attractif a la lecture qu'un programme qui en promet un, et Shopify Partners, la reference du marche, en verse un. On echange une promesse forte et fausse contre une offre plus petite et tenue. La page l'assume explicitement : une section « Ce que ce programme n'est pas » enumere les cinq absences, pour que personne ne rebatisse un plan d'affaires dessus.
La dette qu'on accepte sciemment. L'annuaire contient une fiche,
boostecom-agency.json, ownedByBoostecom: true. Un partenaire qui clique
« Parcourir les agences » nous voit nous. La FAQ le dit au lieu de le
cacher, sans chiffre qui puisse pourrir, mais ca reste le point faible de
l'offre : la valeur d'un annuaire croit avec son remplissage, et celui-ci
demarre a un.
Le signal qui indiquerait de revisiter. Des agences qui candidatent, deploient, puis demandent une part de l'abonnement. Si ca revient trois fois, la sortie 2 redevient une question ouverte, avec cette fois du volume pour la chiffrer.
Ce qui reste ouvert. billing/0369 ne se ferme pas : sa moitie
affiliation (/network/affiliate, « 20 % a vie », liens par asset,
dashboard de clics) n'est pas tranchee et reste dans
PENDING_OWNER_DECISION.
Comment c'est appliqué
src/test/affiliate-terms-match-the-ledger.test.ts lit les six
catalogues et refuse tout pourcentage ou toute duree que
config/affiliate.ts ne porte pas. Le sous-arbre
marketingPages.network.partners n'est pas exempte : il ne peut donc
contenir aucun pourcentage, et les deux chiffres qui s'affichent sur la
page sont interpoles depuis AFFILIATE_COMMISSION_PCT et
AFFILIATE_COMMISSION_MONTHS parce qu'ils decrivent le parrainage.
Reintroduire « 20 % a vie » sur cette page fait echouer la suite dans les
six langues.
L'entree marketingPages.network.agencies a quitte
PENDING_OWNER_DECISION, une liste qui ne peut que retrecir : c'est la
dette, comptee, et cette decision en solde une entree sur six.
marketingPages.network.compare y reste, et c'est deliberé. Le comparatif
est partage par trois pages et garde une colonne affiliation qui lit
« 20 % » et « Lifetime ». /network/partners n'affiche simplement pas
cette colonne : il rend la tranche partenaire + parrainage. Le chiffre
pendant reste donc hors de la page faite pour ne plus en imprimer, et
l'exemption continue de pointer des chaines qui contredisent reellement le
ledger, ce qui est la condition que la garde verifie.
src/test/claude-md-marketing-routes.test.ts derive le tableau des routes
de CLAUDE.md du disque, donc /network/partners et le 308 y figurent ou
la garde echoue.