Audits · août 2026Audit — pilier intelligence

Audit — pilier intelligence

Septieme tour de la rotation (docs/team/roster.md, @codebase-auditor). Lecture seule sur le code. Ce document et un item de backlog sont la sortie complete pour ce pilier. Perimetre…

Septieme tour de la rotation (docs/team/roster.md, @codebase-auditor).

Lecture seule sur le code. Ce document et un item de backlog sont la sortie complete pour ce pilier.

Perimetre : src/lib/intelligence|scraper|browser/**, src/services/algorithms|discovery|companies/**, src/app/(marketing)/intelligence/**, src/app/(dashboard)/[orgSlug]/intelligence/**, src/app/api/intelligence|companies/**, src/lib/anon-key.ts, docs/architecture/intelligence-*.md.

Etat du depot : origin/main a 3e23edb7, 27 aout 2026.

~53 000 lignes, dont 44 919 pour services/algorithms/ seul. Cet audit a sonde les trois invariants declares du pilier et s'arrete la, la portee est dite a la fin.

Ce qui a ete verifie

SondeResultat
Invariant 1 — page par-store en noindex,nofollowrespecte (robots: { index: false, follow: false })
… et hors sitemaprespecte, avec la raison ecrite dans sitemap.ts
Invariant 2 — liens sortants en rel="nofollow"respecte — aucun lien sortant sans
… URL propre, sans UTMrespecte — zero utm_* dans le perimetre
Invariant 3 — modeles ecrivant dans PredictionAccuracy3 (breakout, saturation, forecast_traffic)
… modeles predictifs exposes publiquement4 — opportunity en plus
Lecteurs de PredictionAccuracy hors de son propre ecrivain0
src/lib/intelligence/1 fichier, 0 ligne de code

Deux invariants sur trois tiennent sans reserve, et ce sont les deux qui protegent des tiers : les boutiques espionnees ne sont ni indexees ni creditees d'un lien suivi. C'est le meilleur resultat de la rotation sur ce genre de promesse : les six tours precedents ont trouve, a chaque fois, au moins un invariant declare que le code ne tenait pas.

Le troisieme ne tient pas.


Constat 1 — le ledger qui doit interdire une claim d'edge est ecrit chaque semaine et lu par personne

Severite : moyenne. → backlog/intelligence/0068

docs/team/roster.md, section @intelligence-engineer :

« Tout nouveau modele predictif ecrit dans PredictionAccuracy : pas de claim d'edge sans ledger de backtest. »

Le ledger existe, et il est correctement alimente

prediction/backtest-runner.ts:78 fait un upsert par (model, horizonDays), pour trois modeles × deux horizons (7 et 30 jours), et le cron /api/cron/intelligence/prediction-backtest le declenche. Rien a redire : la mecanique est la, et elle tourne.

Personne ne le lit

grep -rln "predictionAccuracy" src/ renvoie un seul fichier : backtest-runner.ts, celui qui l'ecrit.

Aucune route, aucune page, aucun document ne consulte la table. La precision mesuree de breakout a 30 jours existe en base et n'est visible de personne : ni de l'utilisateur, ni de l'operateur, ni du prochain developpeur qui se demandera si le modele vaut quelque chose.

Et une prediction publique n'a aucune ligne dans le ledger

Quatre predicteurs vivent dans prediction/. Le runner en persiste trois : breakout, saturation, forecast_traffic.

Le quatrieme est opportunity.ts, et son en-tete ne laisse aucun doute sur ce qu'il pretend :

« Opportunity scorer — the "explosive but uncrowded" signal (the Graal the audit names) »

Il retourne un OpportunityPrediction, il est servi par GET /api/intelligence/opportunities, et il est rendu sur /intelligence/radar : une page publique et indexee, dont les mots-cles declares sont "shopify breakout prediction", "shopify product opportunity", "shopify trend prediction".

Verifie : ni la page ni GET /api/intelligence/predict/[domain] ne mentionnent jamais une exactitude, une confiance ou un backtest.

Ce que ca veut dire, exactement

L'invariant existe pour empecher une chose precise : affirmer un edge sans l'avoir mesure. Aujourd'hui le depot fait les deux moities separement (il mesure (trois modeles, chaque semaine, dans une table) et il affirme (une page publique optimisee pour « prediction »)) et les deux moities ne se rencontrent nulle part.

Ce n'est pas de la malhonnetete : c'est un cablage manquant. Mais tant qu'il manque, l'invariant n'est pas verifiable, et le modele qui n'a aucune ligne de backtest est precisement celui que la page publique met en avant.


Releve, sans item

  • src/lib/intelligence/ contient un fichier et zero ligne de code. Il se declare, l'audit ai-platform l'avait note, comme « frontiere reservee, pas un module », ce qui est un placeholder assume et non un vestige. Rien a faire ; mentionne pour que la prochaine sonde qui compte les repertoires vides ne le reouvre pas.
  • Les deux invariants qui tiennent meritent d'etre dits. Sur six tours, c'est la premiere fois qu'un invariant declare est verifie sans reserve, et ici il y en a deux. sitemap.ts va jusqu'a ecrire pourquoi les pages par-store en sont exclues, avec la decision et son auteur. C'est le modele a copier ailleurs.

Ce que cet audit n'a pas couvert

La disproportion est la plus grande de la rotation : ~53 000 lignes, dont 44 919 pour services/algorithms/ seul, et j'ai sonde trois invariants.

  • services/algorithms/ (233 fichiers) — seul le sous-dossier prediction/ a ete ouvert, et seulement pour l'invariant 3. Le Store Graph, le scoring, les clusters marche : non lus.
  • services/discovery/ (2 532 lignes) : non ouvert. C'est pourtant la que se decide quels stores entrent dans l'index, donc la que se logerait un biais de selection.
  • lib/scraper et lib/browser — non ouverts. Ce sont les surfaces qui vont chercher des donnees chez des tiers : rate-limit, respect du robots.txt distant, empreinte. Rien n'a ete verifie.
  • lib/anon-key.ts — dans le perimetre, non ouvert.
  • StoreSignalIndex et StoreMetricDaily — les deux tables qui portent le graphe et les series : aucune sonde sur leur remplissage ni leur coherence.
  • La qualite des predictions elles-memes : cet audit dit que le ledger n'est pas lu, pas que les modeles sont mauvais. Il ne peut pas le dire : c'est precisement ce que la lecture du ledger permettrait.

Un auditeur qui ne borne pas sa portee laisse croire qu'il a tout vu.