Audit — les quatre piliers de distribution (2026-09-12)
Lecture seule sur le code. Demande : auditer la surface extension Chrome, le bridge, puis audit/scan, pour definir ce qui va, ce qui ne va pas et ce qui manque, croise avec l'etat de l'art 2026. Recadre : ce sont quatre…
Lecture seule sur le code. Demande : auditer la surface extension Chrome, le bridge, puis audit/scan, pour definir ce qui va, ce qui ne va pas et ce qui manque, croise avec l'etat de l'art 2026. Recadre : ce sont quatre piliers de distribution, le quatrieme etant le wizard de creation / connexion d'une boutique Shopify, et l'objectif est que chacun soit « 100 % pret, plus besoin de revenir dessus ».
Etat au demarrage :
origin/mainaaa257dcc(PR #1157 mergee).
Ce que cet audit n'a pas pu verifier
A lire avant le reste, pour ne pas prendre un compte derive pour une mesure :
- la suite de tests n'a pas ete executee. Les dependances ne sont pas
installees dans cette session distante (
node_modules/.bin/vitestabsent). Tous les comptes de couverture ci-dessous sont derives des fichiers presents sur disque, pas d'un run ; - le code de l'extension n'a pas ete relu. Il vit dans
BoostEcom/Ecosystem, branchePrivate/Extensions/@BoostEcom. Les constats du pilier 01 portent sur la surface plateforme et sur les contrats documentes ; - l'etat reel de la fiche Chrome Web Store n'est pas lisible depuis un agent. Les dates et politiques Chrome et Shopify viennent des sources listees en fin de document.
Verdict
Aucun des quatre moteurs n'a besoin d'etre reecrit. Ce qui bloque est ailleurs, et c'est la bonne nouvelle : trois des quatre bloqueurs sont des decisions ou des actions ops, pas des chantiers d'ingenierie. Le quatrieme est un sprint sur un socle deja en production.
| Pilier | Bloqueurs | Ce qui bloque |
|---|---|---|
| 01 — Extension Chrome | 2 | le build publie sur le CWS, et le panel de navigation |
| 02 — Bridge MCP | 0 | rien ; retard de spec a planifier |
| 03 — Audit & Scan | 1 | le job durable n'a jamais ete ecrit |
| 04 — Wizard Shopify | 1 | on decrit au marchand un ecran supprime en janvier |
01 — Extension Chrome
Ce qui va
Le contrat de presence est le bon design, et il est teste. Une page web
ne peut pas detecter une extension installee : Chrome ne l'expose pas,
deliberement, parce que ce serait un vecteur de fingerprinting. La
plateforme lit donc trois signaux independants en OU — marqueur DOM,
handshake postMessage, ping runtime legacy — dont un seul coute quelque
chose a l'extension. Le handshake exige event.source === window et une
origine same-origin, donc un iframe tiers ne peut pas pretendre que
l'operateur a notre extension.
src/features/store-runtime/extension/presence.test.ts (7 cas) epingle la
separation des dialectes ; docs/architecture/extension-presence-contract.md
donne une procedure de diagnostic en dix secondes. C'est la reference de
qualite a viser sur les trois autres piliers.
Le funnel d'install est mesure. src/modules/analytics/spy-funnel.ts
nomme les goals en un seul endroit et documente explicitement les deux
diagnostics que le couple extension_click / extension_install_view
permet de trancher.
Ce qui ne va pas
Le build publie sur le Chrome Web Store n'est pas celui qui ouvre notre
page — deja suivi par backlog/growth-web/0620, aucun item ouvert
ici. La source est correcte depuis le commit 6c4d482 (2026-09-10). Le
package n'a pas ete re-uploade. Deux cases ops, ouvertes depuis deux items
consecutifs. Tant qu'elles le restent, tout le funnel construit derriere
mesure zero.
Le panel de navigation collecte sans lecteur, sous une politique qui
l'interdit. → backlog/intelligence/0598 (type: decision).
IntelligencePanelEvent est ecrit par /api/intelligence/panel/ingest et
lu par personne : timeSeries.query({ series: "panel" }) n'a aucun
appelant, la « Phase 2 » du contrat (panel-rollup) n'existe pas, et le
cron de purge qualifie lui-meme la table de « currently dormant ». En face,
la politique CWS applicable depuis le 1er aout 2026 interdit la
collecte d'activite de navigation hors fonctionnalite user-facing decrite
en evidence. Risque maximal, valeur produit nulle, pendant une review.
Deux defauts mineurs a corriger avec la sortie choisie : la branche panel
de timeSeries.query ignore storeIntelligenceId dans son where (elle
rendrait tous les domaines), et la retention de 180 jours est calibree sur
des courbes que rien ne rend.
Trois noms morts, dont un qui est un contrat vivant.
→ backlog/app-shell/0610 et backlog/integrations/0598.
-
data-contextiqest le marqueur de presence que le build publie ecrit. Le renommer d'un cote seulement casse la detection pour tous les installes. Migration en deux temps obligatoire.Suite, 2026-09-13. Etape 1 livree (
app-shell/0610, PR #1173) : le lecteur accepte les deux noms. Le nom canonique a ensuite ete renomme une seconde fois,data-boostecom-spy→data-boostecom-extension, pendant qu'il etait encore gratuit : aucun build publie ne l'avait jamais ecrit, donc aucun parc a migrer. La source de l'extension ecrit desormais les DEUX noms (section[Unreleased], sans bump : un bump signifie qu'un package a ete uploade). Il ne manque plus de code pour l'etape 2, il manque une publication CWS puis une mesure d'adoption. -
/api/sidekick/*: deux endpoints publics authentifies par HMAC, sans aucun client. Trois sources du depot se contredisent sur qui les appelle (docstring : « Theme Copilot AI » ;agentic-stack.md: « a creer / a wirer » ;shared-secrets.test.ts: « BoostEcom Spy envoie deja »). Tranche le 2026-09-12 : aucune n'est plus vraie. Le secret annonce dans les docstrings (SIDEKICK_SHARED_SECRET) n'existe pas dans le schema env ; le code litVITALS_BEACON_SECRET, qui signe aussi les beacons vitals et l'identite acheteur inter-commandes.
02 — Bridge MCP
Le bridge est le serveur MCP consomme par les clients LLM externes — Claude, ChatGPT, Cursor, Claude Code. Transport distinct de l'extension, mais meme cerveau : les deux lisent la meme projection.
Ce qui va
La surface OAuth est au niveau de la spec, sans etape proprietaire.
BoostEcom est son propre serveur d'autorisation, multi-tenant par audience :
le storeId voyage dans resource (RFC 8707), se fige sur le code puis sur
le token, et /api/mcp/[storeId] refuse un token emis pour un autre store.
RFC 9728, RFC 8414, RFC 7591 (DCR), rotation de refresh obligatoire,
RFC 7009 (revoke). La step-up authorization de MCP 2026-07-28 est
implementee. Un client qui parle OAuth 2.1 + MCP se connecte en decouvrant
tout depuis un 401. C'est le meilleur actif technique des quatre piliers.
Le MCP Intelligence public repond deja au coup joue par la concurrence.
Dix outils (searchStoreIntelligence, searchSimilarStores,
predictStoreTrajectory, findEmergingNiches, getWinningAngles,
getSupplierIntel…), quotas par tier (60 req/min anonyme, 6 000 avec cle
bei_, bucket par organisation et non par cle). Quatorze outils cote
store MCP, gates par scope OAuth + scope Custom App. Un outil du marche
vend aujourd'hui son MCP comme differenciateur a partir de 49 $/mois : nous
avons la meme surface, publique. A traiter comme un canal d'acquisition,
pas comme de la plomberie.
Ce qui ne va pas
Le contrat que deux piliers partagent n'est epingle par aucun test.
→ backlog/intelligence/0599. L'extension lit l'Intelligence en REST
(lookup?rich=1, hub/scan, similar?enrich=1), les clients MCP la
lisent en outils : les deux passent par hub-projection.ts → HubStore.
Ce contrat est documente dans un audit date (2026-09-10 §D), pas dans
une garde. Le cout d'une derive est asymetrique : cote MCP un client se
plaint, cote extension le build est deploye separement, affiche un vide, et
personne ne relie ce vide a une PR mergee des semaines plus tot.
Retard sur la revision 2026-07-28, sans consequence immediate.
→ backlog/integrations/0600. Mcp-Method / Mcp-Name (SEP-2243) absents,
donc notre propre rate limit doit parser le corps pour savoir ce qu'il
limite. ttlMs / cacheScope (SEP-2549) absents, donc un client ne sait
pas combien de temps un tools/list reste frais. Extension Tasks
absente — et c'est exactement le besoin du pilier 03, donc les deux se
concoivent ensemble. Roots, Sampling et Logging sont deprecies par cette
revision : ne rien construire dessus.
03 — Audit & Scan depuis le chat
Ce qui va
Le moteur de scan tracking est un vrai produit. 41 checks — 7 infrastructure, 14 fondations, 12 destinations, 8 conformite — chacun dans son fichier, plus des detecteurs par vendeur, des validateurs croises, cinq phases et quatre analyseurs qui transforment le constat en plan d'action. La retention est pensee en deux etages (redaction du payload a 30 jours, suppression de la coquille jamais avant 62), avec plafond de depense sur le scan public et hash d'IP du soumetteur. C'est rare et c'est correct.
Ce qui ne va pas
Le job durable a ete livre comme document, jamais comme code.
→ backlog/ai-platform/2642. docs/architecture/durable-audit-jobs.md
decrit precisement la cible. L'item qui l'a produit (ai-platform/0592,
PR #1011) porte type: "docs", status: "done". Le document est bon ; le
job n'existe pas : 18 types de jobs enregistres, ni store-audit ni
tracking-scan-durable, et HEAVY_JOB_TYPES ne contient toujours que
intelligence-scan-store. Donc runFullStoreAudit et runTrackingScan
tournent encore inline dans le tour de chat sous maxDuration = 300 :
coupe nette, pas de reprise, pas d'idempotence produit. Les quatre
consequences que le document annonce sont toutes encore vraies.
Correction du 2026-09-12, en preparant l'implementation. Ce rapport a d'abord qualifie l'item de « sprint, pas un chantier : deux handlers, deux entrees de registre ». C'est faux, et la raison est une fourche d'architecture que ni le document de design ni l'item n'avaient vue.
Les deux fonctions dependent de
ctx.requestOrigin+ctx.requestCookie— un saut HTTP vers/api/tracking/scanportant le cookie de session de l'utilisateur (tools/tracking-scan.ts:180,store-audit/engines/tracking-pillar.ts:104). Ce saut existe pour deux bonnes raisons documentees : importer le scanner directement a casse le build Vercel (Playwright + Browserbase + chromium-bidi tires par Turbopack), et la route fait son propre controle de session.Or le design §3.4 interdit explicitement de rejouer ce cookie dans QStash. Les deux sont justes separement et incompatibles ensemble.
Un worker qui reconstruit le contexte sans ces champs n'echoue pas bruyamment : le pilier tracking se degrade proprement et rend quatre piliers a
covered: false. Un audit durable livre en l'etat serait donc systematiquement plus faible que l'audit inline, sans que l'operateur sache pourquoi — exactement la degradation silencieuse que ce rapport reproche ailleurs.La fourche, la recommandation et son chiffrage sont dans
backlog/ai-platform/2642, qui passe de taille M a L et porte desormais unblocked_by.
Le verdict que le scan facture n'est garde par aucun test.
→ backlog/commerce-systems/0603. checks/ 45 fichiers → 1 test (sur les
URLs de guide, pas sur la logique) ; detectors/ 9 → 0 ; validators/
4 → 0 ; phases/ 5 → 0 ; analyzers/ 4 → 0 ; clients/ 4 → 0 ; cmp/
4 → 0 ; scoring.ts, orchestrator.ts, runner.ts → aucun. Les dix tests
qui existent couvrent la peripherie, et la couvrent bien. Rien ne couvre le
calcul. Une regression silencieuse dans un check transforme un « tout va
bien » en mensonge facture.
La file de rapports hebdomadaires n'a toujours pas de consommateur —
deja suivi par backlog/platform-ops/0257 et la decision
backlog/platform-ops/0368, aucun item ouvert ici. Le confinement est
bien fait : la moitie qui empilait des StoreReport en pending est
coupee par un drapeau, et un test a double sens echoue le jour ou un
consommateur apparait sans que le drapeau bouge.
04 — Wizard store Shopify
Ce qui va
Le moteur d'execution autonome n'a rien a envier a un orchestrateur
commercial. Playbook type de 29 jalons en DAG (13 auto + 16 human,
chacun avec dependsOn), 13 executeurs cables — un par jalon automatique,
aucun jalon auto sans executeur —, un runner avec cycle de vie complet,
claim atomique anti-double-execution et retries exponentiels stampes. Le
cron launch-tick (739 lignes) parcourt le graphe, dispatche ce qui est
pret, re-queue ce qui a expire, et detecte l'acceptation du transfert de
boutique en sondant shop.json. DevStorePool fait le reste : claim
atomique, token chiffre AES-256-GCM au repos, machine a etats du transfert,
et une absence de FK volontaire pour qu'une boutique transferee puis
supprimee ne resurgisse jamais comme AVAILABLE.
Ce qui ne va pas
On envoie le marchand sur un ecran que Shopify a supprime en janvier.
→ backlog/integrations/0597. La copie affichee dit litteralement
« Settings → Apps and sales channels → Develop apps → Create an app », en
six locales, et le bouton CTA deep-linke sur
admin.shopify.com/store/<shop>/settings/apps/development. Depuis le
1er janvier 2026, Shopify n'autorise plus la creation de custom apps
depuis l'admin : elles passent par le Dev Dashboard. Les apps creees avant
continuent de fonctionner — c'est exactement ce qui a rendu le defaut
invisible : ca marche pour nous et pour tous les marchands deja
connectes, et seulement pour eux.
Correction du 2026-09-12, apres lecture du code. La premiere version de ce paragraphe ajoutait « le token colle reste valide, c'est l'itineraire qui a change ». C'est faux pour un nouveau marchand : une app du Dev Dashboard ne delivre jamais de
shpat_collable, elle donne un Client ID + secretshpss_et un tokenclient_credentialsde 24 h.Ce que cette erreur cachait est une bonne nouvelle : le chemin moderne existe deja et fonctionne.
/api/integrations/shopify/custom-appfait leclient_credentials, rafraichit le token 24 h (features/shopify/sdk/token.ts), et c'est lui que le panneau Settings → Connecteurs utilise — avec la bonne copie. Le dialogue d'onboarding l'appelle aussi, et le marque « Recommended ». Seul le secret permet de verifier la signature des webhooks, donc seul ce chemin allume la sync live.Le defaut est donc strictement de la copie, et il est plus etroit que l'item ne le disait : le wizard envoie le marchand chercher la mauvaise chose au mauvais endroit, alors que les champs qui l'attendent juste en dessous sont les bons.
Treize executeurs ecrivent chez le marchand, un seul fichier de test.
→ backlog/ai-platform/2643. Meme defaut que le pilier 03, sur une surface
plus sensible : ces executeurs ne lisent pas, ils ecrivent — theme,
produits, pages legales, JSON-LD — dans la boutique d'un marchand payant,
sans relecture humaine sur les jalons auto. Le seul test porte sur la
couche de transport. Trois d'entre eux ecrivent du contenu public et
indexable : une erreur y est visible par Google avant de l'etre par nous.
Erratum du 2026-09-22 — l'echeance 2027 ne vise pas la Custom App merchant-owned
La suite integrations/0599 ouverte par cet audit reposait sur une premisse
fausse : l'obligation Shopify du 1er janvier 2027 sur les offline tokens
expirants concerne les public apps. Shopify exclut explicitement les custom
apps et les apps creees par les marchands.
Le chemin merchant-owned moderne mesure ici reste valide : Dev Dashboard du
marchand → scopes → release/install → Client ID + Client Secret →
client_credentials (token 24 h, renouvelable). Le runtime BoostEcom le fait
deja.
L'architecture retenue depuis cet erratum est l'ADR 0033. 0599 est archive
sans implementation et remplace par integrations/2951, dont le probleme est
l'onboarding et la couverture de permissions du chemin merchant-owned — pas une
migration OAuth publique imposee par 2027.
Sources Shopify :
- https://shopify.dev/changelog/expiring-offline-access-tokens-required-for-all-public-apps-as-of-january-1-2027
- https://shopify.dev/docs/apps/build/dev-dashboard/create-apps-using-dev-dashboard
- https://shopify.dev/docs/apps/build/authentication-authorization/client-credentials-grant
- https://shopify.dev/docs/apps/launch/protected-customer-data
Les items ouverts
| Pri | Item | Ce que c'est |
|---|---|---|
| P2 | backlog/intelligence/0598 | decision — couper le panel de navigation, ou le declarer. Etait P0 : la premisse (une collecte en cours, sous review CWS) a ete mesuree FAUSSE le 2026-09-13, l'extension publiee n'envoie rien. Decision intacte, urgence tombee |
backlog/integrations/0597 | la copie de connexion Shopify, 6 locales — fait, archive | |
| P0 | backlog/ai-platform/2642 | les deux handlers de job durable |
backlog/commerce-systems/0603 | tests du moteur de scan — fait, archive | |
backlog/integrations/0598 | supprimer /api/sidekick/* — fait le 2026-09-13, archive | |
| P1 | backlog/intelligence/0599 | epingler le contrat HubStore |
backlog/ai-platform/2643 | tests des executeurs publics — fait, archive | |
| P1 | backlog/app-shell/0610 | migrer data-contextiq en deux temps — etape 1 faite, etape 2 gatee sur une publication CWS |
backlog/_archive/integrations/0599-porter-la-connexion-shopify-sur-oauth-avant-l-echeance-2027.md | ||
| P1 | backlog/integrations/2951-shopify-custom-app-merchant-owned-onboarding-permissions-maximales.md | Custom App merchant-owned : onboarding guide, credentials, grant reel et permissions maximales |
| P2 | backlog/integrations/0600 | rattraper la revision MCP 2026-07-28 |
Ouverts apres coup, le 2026-09-13
| Pri | Item | Ce que c'est |
|---|---|---|
| P1 | backlog/commerce-systems/2651 | les quatre distorsions de la note du scan : un warn coute autant qu'un fail, un skip reste au denominateur, une categorie absente vaut 0 en se declarant couverte a 100, et requiredPhase est declare 41 fois pour n'etre lu nulle part. Les quatre etaient epingles par les gardes de 0603 et aucun n'etait corrige |
| P1 | backlog/ai-platform/2645 | (minimal)/scan/tracking, 7504 lignes et 45 composants, seconde surface de rendu du meme rapport |
| P2 | backlog/commerce-systems/2650 | deux chips, deux intentions, trois skills pour une question |
Et un livre le meme jour : ai-platform/2644, une seule porte d'audit dans
le chat (ADR 0016).
Deja suivis ailleurs, volontairement pas rouverts : le re-upload CWS
(growth-web/0620) et l'orchestrateur de rapports (platform-ops/0257,
decision platform-ops/0368).
Sources de la veille 2026
- Chrome Web Store policy updates — Chrome for Developers
- Limited Use — Chrome Web Store Program Policies
- Chrome extensions must meet new privacy standards by August 1 — CyberInsider
- The 2026-07-28 MCP Specification Release Candidate
- MCP Authorization specification
- Shopify App Development Changes in 2026 — Blueant Solutions
- OAuth2 Token Exchange & managed install — Shopify developer changelog