Audits · septembre 2026Audit dead-code transverse, 2026-09-11

Audit dead-code transverse, 2026-09-11

Un agent, une demande directe (auditer toute la codebase et nettoyer ce qui nuit a sa comprehension), pas le protocole a 27 lecteurs de 2026-09-03-full-codebase-audit.md. Ce document decrit la methode et le perimetre…

Un agent, une demande directe (auditer toute la codebase et nettoyer ce qui nuit a sa comprehension), pas le protocole a 27 lecteurs de 2026-09-03-full-codebase-audit.md. Ce document decrit la methode et le perimetre reellement couverts : une seule piste (exports/types morts et leurs cascades), pas un audit d'organisation complet malgre la formulation large de la demande.

Pourquoi pas juste knip

pnpm deadcode (knip) seul a deja produit un faux signal dans cette codebase : l'audit du 3 septembre note qu'un lecteur avait lu knip comme une preuve suffisante sans verifier les appelants, et que son correctif aurait casse trois routes d'API. Le risque est structurel, pas une erreur de lecteur : knip resout les imports statiques, pas les unions de types exportees dans le meme fichier ni les re-exports a effet de bord.

Verifie sur ce passage : la premiere execution de knip (sans node_modules installe, donc sans le plugin Next) a rapporte 818 fichiers inutilises — faux total, corrige a 0 des pnpm install termine. Les chiffres qui suivent sont tous post-install.

Methode

  1. pnpm deadcode (knip) → 1130 exports + 1489 types "unused".
  2. Un index independant, construit une fois pour tout le repo : fichier<TAB>identifiant pour chaque mot de 4+ caracteres dans src/, scripts/, evals/. Un symbole n'est retenu comme mort que si knip et cet index s'accordent sur zero occurrence ailleurs dans le repo entier — pas seulement hors de son fichier de definition, mais hors de toute reutilisation DANS son propre fichier (le piege des types union : SSEEvent dans src/types/tracking.ts compose 26 interfaces qu'aucun import externe ne cite par leur nom, knip seul les aurait toutes marquees mortes).
  3. Verification manuelle des cas limites avant suppression : re-exports a effet de bord (SecuritySweep, qui enregistre un algo dans le registre global a l'import du barrel), symboles courts exclus par erreur du premier index (cn, 2 caracteres — revérifié a la main), commentaires qui revendiquent un consommateur inexistant (updateTaskPriority pretendait etre appele par "the Kernel drag-drop reorder UI" ; zero appelant, meme apres deux avances de main).
  4. Suppression, puis a chaque etape : pnpm typecheck et pnpm test complets avant de continuer.

Resultat

172 exports/types confirmes morts par double preuve, supprimes sur ~90 fichiers. Cascades reperees par le filet (typecheck, pas par inspection) : trois fichiers laisses sans aucun export (src/config/types.ts, src/features/ai/sdk/schemas/workflow.ts, plus le dossier sdk/schemas/ entier) et trois templates email (payment-failed.tsx, payment-success.tsx, trial-ending.tsx) orphelins une fois leurs seuls appelants retires.

src/types/index.ts (465 lignes) portait une equipe d'agents fantome — BUILTIN_SUB_AGENTS, avec code-reviewer, doc-writer, test-engineer — qui n'a jamais existe dans ce produit (Atlas + 5 specialists nommes). Zero appelant, et un commentaire du fichier voisin (features/ai/preview/subagents-team/hooks/use-subagents.ts) confirmait deja que le vrai registre vit ailleurs (features/ai/agents/identity-registry.ts). Reecrit a 155 lignes : ne garde que ChatContextItem et les re-exports que les 29 importeurs de @/types consomment reellement.

3 dependances npm mortes (katex, rehype-katex, remark-math) — deja documentees comme non utilisees dans response.tsx ("No remark-math: commerce copy is full of $ amounts, not LaTeX").

Ce qui n'a pas ete touche, et pourquoi

  • ~1050 exports/types que knip signale mais que le second index disculpe (reutilises dans leur propre fichier). Faux positifs de knip seul, laisses en l'etat.
  • src/components/patterns/ai-elements/chat/tool.tsx — un warning ESLint type vs interface preexistant (verifie sur origin/main avant toute modification), dans un fichier genere par npx ai-elements@latest que src/components/patterns/CLAUDE.md interdit explicitement d'editer a la main.
  • pnpm format:check : 3223 fichiers deja hors format, dette preexistante et documentee depuis le 3 septembre (2639 a l'epoque), hors perimetre d'un passage dead-code.

Course contre main

Ce repo fusionne toutes les 1 a 3 minutes (fleet d'une dizaine d'agents en parallele). La PR a du merger origin/main deux fois pendant son vol ; a chaque fois, les fonctions que cette PR avait supprimees comme mortes ont ete reverifiees individuellement contre le nouvel etat de main avant de trancher — deux d'entre elles (cancelTask, reviewAndApprove) avaient gagne un vrai appelant entre-temps (un nouveau test de securite sur les permissions viewer, commerce-systems/0291) et ont ete restaurees ; une troisieme (findEventBySlug) de meme, pour une nouvelle page marketing.

La seconde fusion a introduit pnpm merge:resolve (scripts/resolve-generated-conflicts.mjs), la reponse du repo au meme probleme recurrent chez plusieurs agents en parallele : un conflit sur un fichier .generated.ts (ici src/i18n/client-namespaces.generated.ts) ne se merge jamais a la main, il se regenere.

Verification finale

GardeResultat
pnpm typecheckvert
pnpm test11 335 passes, 9 skippes, 0 echec
pnpm lint --max-warnings 0vert (hors le warning tool.tsx ci-dessus)
pnpm fleet:scopevert, Cross-pillar: declare
pnpm deadcode (knip)0 fichier inutilise

La CI GitHub Actions a echoue integralement sur le head final (7 checks, 4 workflows) mais en 1 a 3 secondes chacun et sans logs telechargeables — signature d'une panne d'infrastructure (provisioning de runner) plutot que d'un defaut du code, documente en commentaire sur la PR plutot que laisse sans reponse.

Livre par PR #1044, item de backlog 0606.