Skill v1.0.0
currentLLM-judged scan90/100version: "1.0.0" name: ship-check description: > Audit pré-publication d'un repo : secrets (historique git compris), dépendances, hygiène repo + légal, infra Supabase, et surface applicative vibecode (IDOR, RLS, rate limiting, SSRF, uploads…). Verdict GO/NO-GO par section, rapport SHIP-REPORT.md. Use when: l'utilisateur demande explicitement un ship-check / « peut-on publier/déployer ce repo ? » / « passe-le en public ». Uniquement sur demande explicite, avant un passage en public ou un deploy. license: MIT
Ship Check
Contexte : un repo fonctionnel qu'on s'apprête à exposer (public, deploy, vraie donnée). Le skill établit les faits et rend un verdict — il ne répare presque rien lui-même :
- Rapport d'abord :
SHIP-REPORT.md(non commité), verdict **GO /
NO-GO par section** + verdict global. Toute réparation au-delà de l'inoffensif est une décision de l'utilisateur, listée avec sa commande.
- Auto-fix limité à l'inoffensif, sur branche
ship-check/<date>:
.gitignore, licence manquante, .env.example. Rien d'autre.
- Un secret trouvé n'est JAMAIS réaffiché ni commité nulle part :
chemin + type + empreinte tronquée (4 premiers caractères) au rapport ; valeurs complètes dans un inventaire local chmod 600 hors repo, dont le chemin est donné à l'utilisateur.
Chaque section est skippable si non applicable (pas de Supabase, pas de backend…) — le rapport dit alors « N/A » avec la raison, jamais silence.
Section 1 — Secrets
gitleaks git (historique complet) + gitleaks dir (working tree) — binaire Go : brew install gitleaks, ou release GitHub décompressée dans le scratchpad (uvx ne peut pas l'installer, ce n'est pas un paquet Python). En plus du scan : secret JWT/session vérifié présent au démarrage (absent = tokens forgeables), aucune clé secrète dans du code servi au client (seules les clés publishable Supabase/Firebase y ont leur place — c'est le RLS qui protège, pas la clé), aucun token/credential codé en dur. NO-GO : tout secret actif dans l'historique d'un repo destiné au public. Tester si une clé fuitée est encore active sans jamais l'utiliser : récupérer par la voie légitime (API Management Supabase, dashboard du provider) la clé actuelle et son statut enabled/disabled, puis comparer localement — identique ET enabled = fuite active ; identique mais disabled = fuite inerte (le dire tel quel au rapport). Une requête portant la clé fuitée est hors limites, même en lecture.
Section 2 — Dépendances
npm audit / pip-audit (via uvx) par package + alertes Dependabot (gh api). NO-GO : vulnérabilité critical atteignable en prod (dépendance runtime, pas devDependency). High : listées avec l'upgrade proposé. Moderate/low : comptées, sans bloquer. Vérifier aussi qu'aucun venv/, node_modules/ ou artefact de build n'est commité.
Section 3 — Hygiène repo & légal
.gitignorecouvre env, artefacts, venvs ; variables d'env documentées
(.env.example sans valeurs) ; licence présente ; visibilité du repo cohérente avec son contenu.
- Pipeline de déploiement vivant : le dernier deploy réussi
correspond-il à HEAD ? (Vercel/CI — dates et statuts des derniers runs.) L'audit du repo ne dit rien de ce qui tourne si la prod sert un vieux build — vécu : deploys silencieusement bloqués 15 jours par une version Next vulnérable, prod figée sur un build d'avant les correctifs.
- Légal minimal si l'app a des utilisateurs : Privacy Policy présente et
sincère — mentionne la collecte de données, l'usage d'IA s'il y en a, les collecteurs tiers ; aucun faux témoignage dans le contenu.
Section 4 — Infra Supabase (si le repo y est lié)
Lecture seule stricte — jamais de modification RLS/policy automatique. Advisors sécurité via l'API Management (curl uniquement, jamais urllib — WAF ; token : trousseau macOS security find-generic-password -s "Supabase CLI" -w ; sinon dashboard). Vérifier en plus des advisors :
- tables à vraies données sans RLS, policies
USING (true), et le piège
OR user_id IS NULL (rend les lignes sans propriétaire publiques) ;
- policies trouées : jointure vers une table à policy ouverte, ou colonne
vérifiée que l'utilisateur peut définir lui-même ;
- vues
SECURITY DEFINERexposées à anon ; - buckets Storage : public ET listing autorisé = fichiers « privés »
simplement non listés.
Section 5 — Surface applicative (revue statique vibecode)
Passer la checklist de VIBECODE-CHECKS.md (à côté de ce fichier) — les 10 trous récurrents des apps vibecodées avec leurs tests concrets : IDOR, enforcement serveur, rate limiting (par user + par IP sur les endpoints pré-auth coûteux), JWT, SSRF, uploads, CORS, limites d'entrée, PII dans les logs, actions d'agent IA. Chaque item : ✅ / ⚠️ / 🕳️ avec fichier:ligne. La revue ici reste statique — les « Test : » de la checklist s'exécutent contre une stack locale via /proof-run --checks (skill voisin).
Livrable
SHIP-REPORT.md(non commité) : verdict par section, verdict global
(NO-GO si une section NO-GO), findings avec fichier:ligne et commande de correction proposée, section finale « Au-delà du ship-check » — les pratiques runtime/design non vérifiables statiquement (plafond de dépense fournisseur, effacement effectif des données, flux d'annulation, jailbreak-test du bot, matrice de permissions) en recommandations.
- Si auto-fixes inoffensifs : branche + PR draft. Sinon aucun commit.
- Commits sans Co-Authored-By ni mention d'IA.