증거 보고서 (Rapport de Preuve)

Génère un rapport HTML d'une seule page répondant à une question précise, en utilisant des captures d'écran réelles et des valeurs extraites comme preuves. Idéal pour les comptes-rendus de fonctionnalités visuelles, les comparaisons avant/après, et les décisions à prendre.

Qu'est-ce que 증거 보고서 (Rapport de Preuve) ?

Ce skill transforme des résultats d'implémentation visuels en un rapport HTML unique, centré sur une question claire (ex : « Qu'est-ce qui a changé ? », « Est-ce conforme au cahier des charges ? », « Quel est l'état actuel ? »). Il capture des écrans réels (non des simulations), ajoute des annotations, des valeurs de données et des marqueurs de décision. Le rapport est conçu pour être lu sur mobile et imprimé en PDF A4. Il prend en charge les workflows d'inspection (code review, bug hunting) et de décision (choix parmi plusieurs options). Le skill utilise des scripts Node/Python (Playwright, Pillow) pour automatiser les captures, le marquage et l'assemblage. Les principes clés sont : ne pas se fier à la mémoire, ne pas couvrir le contenu avec des annotations, et toujours vérifier visuellement le résultat final. Il s'active par des phrases comme « montre-moi en HTML », « capture et explique », « compare avant/après », « vérifie par rapport au cahier des charges », « résumé d'inspection », etc.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/kimjisub/agent-skills/tree/HEAD/skills/evidence-report

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Rapport de Preuve (증거 보고서)

Moment de déclenchement - Quand tu dois montrer un résultat à quelqu'un, mais qu'une simple description textuelle ne suffit pas, et que la preuve est un écran réel. Si tu as implémenté ou modifié une fonctionnalité majeure visible à l'écran, commence le rapport de fin ici, même sans demande explicite. Ce skill ne couvre pas les documents sans écran ni les cartes de navigation entre documents et écrans.

Objectif

Créer un document qui répond à une seule question en utilisant des captures d'écran réelles. Le destinataire ne lit ni le code ni les logs de commit. Il ne connaît que l'écran ; le poids du document repose entièrement sur le fait que ces écrans sont le résultat réel du fonctionnement. Dix puces de description d'une découverte sont moins rapidement comprises et moins difficilement contestables que deux photos côte à côte du même enregistrement dans deux écrans différents. Si tu termines une grosse fonctionnalité et que tu passes à autre chose sans ce rapport, le coût de vérification se déplace vers le destinataire, qui devra ouvrir l'écran lui-même.

Le livrable est une seule page HTML. Le destinataire peut l'ouvrir sur son téléphone ou l'imprimer en PDF via le navigateur. Le template est donc adapté à la fois aux petits écrans et à l'impression A4. Pas de PDF ou Markdown séparé.

Il n'y a pas de table des matières fixe dans ce skill. On commence par déterminer la phrase unique à laquelle ce document répond, puis les axes de comparaison et la structure des sections en découlent.

QuestionAxe de comparaisonCe que fait le document
Qu'est-ce qui a changé ?Code précédent <-> Code actuelMet deux écrans côte à côte pour prouver l'amélioration
Est-ce conforme au cahier des charges ? Que reste-t-il ?Cahier des charges, spécifications <-> Écran actuelAttribue un verdict à chaque clause ; ne conserve que les écarts
Est-ce conforme à nos principes ?Principes, checklist <-> Produit actuelRegroupe les découvertes par cause sur l'ensemble du produit ; capture ce qui peut être montré à l'écran pour preuve
Qu'est-ce qui change si la condition change ?État A <-> État BModifie réellement les flags, les dates, les permissions et capture chaque état
Quel est l'état actuel ?Aucun axeParcourt l'ensemble avec l'écran actuel uniquement
Que faut-il décider ?Option A <-> Option BAssocie à chaque élément l'écran actuel, les options et les entrées nécessaires

Il est courant que plusieurs axes se mélangent. Lors d'une vérification de conformité, on peut tomber sur « quelque chose qui n'est pas dans le cahier des charges mais qui existe déjà ». Cela constitue un élément avec un axe différent, et il faut lui créer une section séparée. Si la question est floue, le document sera flou. Si tu n'arrives pas à l'écrire en une phrase, divise le document en deux.

Principes Fondamentaux

  1. L'écran est un résultat réel, pas une reconstitution. Créer de mémoire « à quoi cela ressemblerait » est presque toujours faux. L'écran précédent avait peut-être des éléments maintenant supprimés, ou le problème était moins grave (ou plus grave) que dans ton souvenir. « Dans cette condition, cela devrait ressembler à ceci » est également faux. Quand tu actives un flag en vrai, l'écran obtenu est souvent différent de ce que tu attendais. C'est pourquoi on crée d'abord l'état à montrer, puis on capture. Ainsi, on peut écrire dans le document : « Ceci est le résultat réel, pas une reconstitution ». Cette seule phrase détermine la crédibilité de tout le document. -> Étape 3
  2. Place les valeurs à côté des photos. La photo dit « à quoi cela ressemble ». En plaçant les valeurs stockées et les valeurs à l'écran (attributs data-*, texte de lecteur d'écran) côte à côte, on explique aussi « pourquoi cela ressemble à cela ». -> Étape 3
  3. Le marquage se fait dans l'écran. Si tu places des coordonnées à vue d'œil, tu auras presque toujours un décalage d'une colonne ou d'une ligne. Sur un écran de navigateur, trouve l'élément par son texte ou son sélecteur, dessine la bordure et le numéro à cet endroit, puis capture. -> Étape 4
  4. Ne couvre pas ce que tu expliques. Si tu places une étiquette de surbrillance directement sur l'écran, tu couvriras presque toujours quelque chose : titre, label de champ, valeur d'une colonne adjacente. Mets seulement le numéro sur l'image, et la description en légende. Le badge numéroté est petit ; où que tu le places, les pertes sont minimes. -> Étape 4
  5. Vérifie TOUJOURS visuellement ce que tu as créé. Le fait que l'outil ait renvoyé un succès signifie seulement que le fichier a été écrit. Il faut ouvrir le fichier pour savoir si la bordure entoure le mauvais élément, si le badge couvre du contenu, si l'en-tête de tableau se répète dans une jointure, si les images dans les liens sont cassées. -> Étape 5·6
  6. Sépare ce qui a été capturé de ce qui ne l'a pas été. Si tu as vérifié par code mais qu'aucun cas de test n'existe en base pour le montrer à l'écran, mets-le de côté avec la mention « (preuve par code) ». Si tu mélanges, la crédibilité des captures réelles s'en trouve affaiblie. -> Étape 1·3

Politiques

PolitiqueQuand s'applique-t-elle ?Contenu
Les données et les réglages sont en lecture seule ; demande avant de modifierÉtape 3Les requêtes pour trouver des cas sont libres. Modifier la base de développement pour créer un cas ne se fait qu'après validation de l'utilisateur, et on note les modifications pour les annuler ensuite. La base de production n'est jamais concernée
Toute modification effectuée pendant la capture est notée dans le document et le rapportÉtape 3 · Étape 6Comme la création d'une session de connexion, l'acceptation d'une connexion externe, ou la modification de la base de développement
Livrer sous une forme que le destinataire peut ouvrirÉtape 6Les chemins locaux ne s'ouvrent pas sur l'appareil du destinataire. Envoie le fichier report.html ou crée un lien. Si c'est un lien, vérifie qu'il s'ouvre bien avant de le transmettre
Toute communication vers l'extérieur est soumise à validationÉtape 6Pour Slack, email, envoi client : demande d'abord si tu laisses en brouillon ou si tu envoies directement

Prérequis

PrérequisVérificationSi absent
Le travail est visible à l'écranLe changement apparaît-il dans l'interface utilisateur ?Un travail ne touchant que le backend ou des scripts n'est pas concerné. Fais un rapport textuel
Le produit à capturer est en cours d'exécutionLe serveur de développement local ou l'URL de staging répond-elle ?Consulte la documentation du dépôt pour le lancer. Pour le code précédent, voir axes §Axe temporel
Un outil de navigateur est disponiblenode scripts/shot.mjs fonctionne-t-il avec Playwright ?Voir capture §Manipulation du navigateur pour l'installation de Playwright et l'utilisation d'autres outils
Pouvoir se connecterL'écran nécessite-t-il une connexion ? As-tu un compte ?Voir capture §Créer un état de connexion
Python Pillowpython3 -c "import PIL"L'assemblage et le recadrage ne fonctionneront pas

Procédure

0. Question et axe     LIRE <- variants/axes - Chaque axe nécessite une préparation différente (revenir en arrière dans le code, modifier les données, lire des documents, trouver des cas). Ne suivre que la section correspondant à l'axe choisi.
1. Éléments et verdict   (si axe inspection, axes §Axe inspection 1~2 génère les éléments)
2. Structure          LIRE <- steps/20-document - Critères de regroupement des éléments en sections, vocabulaire des verdicts, résumé, emplacement des figures et tableaux
3. Capture           LIRE <- steps/30-capture - Points de blocage : connexion, événements synthétiques, longs écrans, lecture des valeurs à l'écran
4. Marquage          LIRE <- steps/30-capture §Marquage dans l'écran - Placer les coordonnées à vue d'œil décale d'une colonne
5. Vérification visuelle   (aucun document à ouvrir. La checklist est dans l'Étape 5)
6. Livraison         LIRE <- steps/60-output - Si tu casses le template, les petits écrans et l'impression sont brisés. Si tu enfreins les règles des blocs de décision, les ensembles copiés sont tronqués

Étape 0 : Question et axe

Rédige-la en une phrase. Elle doit inclure à la fois le destinataire et l'objectif, par exemple : « Expliquer au client ce qui a été modifié cette semaine », « Définir avec le chef de produit ce qui reste par rapport au cahier des charges ». Si l'objectif est différent, même pour un même écran, ce qui sera mis en avant changera. Ensuite, choisis l'axe dans le tableau de l'objectif et lis la section correspondante dans axes.

À la fin de cette étape, la question (une phrase), l'axe et le destinataire sont déterminés.

Étape 1 : Éléments et verdict

Ne commence pas par la capture. Liste d'abord ce que ce document va traiter sous forme d'éléments, et attribue à chacun un code de référence et un verdict. Cette liste devient l'ossature du document ; elle détermine aussi les écrans à capturer et les points à marquer.

Sépare les codes de référence par préfixe selon la nature de l'élément, car l'intérêt du destinataire diffère :

  • Travail demandé : R-1, R-2 ... (le destinataire veut savoir si c'est fait)
  • Découvert et corrigé en cours de route : A-1, A-2 ... (le destinataire veut savoir pourquoi ça a été touché)
  • Écart par rapport au cahier des charges : G-1, G-2 ... (le destinataire veut savoir ce qu'on va faire)
  • Découvertes d'inspection : suivre le numéro de groupe 1-1, 1-2 ... (regrouper par cause commune)

Le vocabulaire des verdicts doit être uniforme dans tout le document (exemples de vocabulaire dans document §Vocabulaire des verdicts). Compte les verdicts et affiche le total sur la première page. Une ligne comme « 35 implémentations, 3 décisions nécessaires, 1 défaut » résume tout le document. En comptant, les lacunes de la liste apparaissent aussi.

Il est facile d'oublier des corrections faites en cours de travail, donc utilise git log pour les retrouver. Pour une vérification de conformité, parcours le texte original ligne par ligne pour remplir la liste. Marque également dès maintenant si chaque élément peut être montré à l'écran (si le cas existe dans les données). -> Principe fondamental 6

À la fin de cette étape, chaque élément a un code, un verdict, et soit un écran à capturer, soit la mention « (preuve par code) ».

Étape 2 : Structure

Les sections ne sont pas choisies dans une table des matières ; elles apparaissent lorsqu'on regroupe les éléments. Les critères de regroupement sont au nombre de quatre :

  • Par écran - Plusieurs éléments sur le même écran. C'est la base des rapports d'amélioration
  • Par verdict - Quand les verdicts divergent. C'est la base des rapports de conformité ; le destinataire voit d'abord uniquement ce qui nécessite une décision
  • Par cause - Quand les découvertes sont nombreuses et dispersées sur plusieurs écrans. C'est la base des rapports d'inspection
  • Par élément - Quand chaque élément est une décision indépendante. C'est la base des documents de décision

Dans tous les cas, on place un résumé qui couvre tout en une seule page au début, et plus on avance, plus on entre dans le détail. On suppose que le destinataire lit depuis le début et s'arrête à tout moment. Le nombre de sections dépend de ce qu'il faut montrer. Ne remplis pas artificiellement, et ne crée pas de section vide. Les détails concrets et des exemples de structuration sont dans document.

Étape 3 : Capture

La préparation dépend de l'axe (axes). Voici les règles communes :

  • Capture la paire à comparer dans le même viewport, à la même position de défilement et dans la même zone. Ainsi, les deux images correspondent pixel par pixel et peuvent être visualisées avec un curseur de comparaison ou une différence (60-output §Visualisation côte à côte).
  • Utilise les mêmes données pour les écrans à comparer. Si les données sont différentes, la comparaison n'a pas de sens. Pour montrer qu'un même fait apparaît différemment selon l'écran, capture tous les écrans avec le même enregistrement.
  • Avant de capturer, vérifie par requête que les données nécessaires à la fonctionnalité existent réellement. Si tu découvres plus tard que l'écran est vide, tu devras reconstruire toute la pile.
  • Vérifie l'état de connexion avant de capturer. Une erreur réelle : capturer un élément qui nécessite une connexion alors qu'on est déconnecté, puis écrire « absent ». Avant de conclure à l'absence, distingue si l'élément est vraiment absent ou s'il n'est simplement pas visible dans la session actuelle.
  • Effectue les manipulations dans le même ordre. Si tu mets la liste des captures dans un seul fichier, tu pourras rejouer ce fichier pour tout recapturer.
  • Prends un viewport généreux. Si le bas de l'écran est coupé, tu devras tout refaire.
  • Lis les valeurs stockées et les valeurs à l'écran en même temps. -> Principe fondamental 2
  • Note comment tu es arrivé à cet écran. Pour retracer le chemin et le nombre d'étapes plus tard, tu dois y retourner. Noter pendant la capture est gratuit (document §Position et profondeur de l'écran).

Consulte capture pour les points de blocage fréquents lors des manipulations.

Étape 4 : Marquage

Si c'est un écran de navigateur, utilise scripts/shot.mjs pour dessiner les bordures et les numéros directement dans l'écran au moment de la capture (-> capture §Marquage dans l'écran). Pour les longs écrans, capture par morceaux et assemble avec scripts/stitch.py. Pour les parties hors sujet (comme une barre latérale), recadre avec le même script. Pour les écrans qui ne sont pas des navigateurs, utilise grid_overlay.py pour lire les coordonnées, puis annotate.py pour dessiner.

  • La bordure doit entourer uniquement l'élément à mettre en évidence. Une bordure trop large rend le point flou.
  • Les couleurs sont uniformisées selon le verdict. En parcourant le document, la couleur seule indique la nature. Par défaut : rouge pour l'avant et les points problématiques, vert pour l'après. Pour un rapport de conformité : rouge pour ce qui est absent, vert pour ce qui est présent, orange pour ce qui nécessite une décision.
  • Le marquage des deux écrans à comparer se fait séparément. La longueur du texte peut légèrement modifier la mise en page.
  • Regroupe toutes les captures et tous les marquages dans un seul fichier. Si tu modifies le marquage, tout sera reconstruit. Si tu veux recapturer les écrans plus tard, il suffit d'exécuter ce fichier.

Étape 5 : Vérification visuelle

Ouvre tout avec un outil de lecture. Vérifie :

  • La ligne de résultat du marquage ne contient-elle pas NOT FOUND ?
  • La bordure entoure-t-elle exactement l'élément cible ? N'a-t-elle pas attrapé un autre endroit avec le même texte (même nom de colonne dans un autre tableau) ?
  • Le badge numéroté ne couvre-t-il pas du texte ou une barre ?
  • Les en-têtes de tableau ou la table des matières ne se répètent-ils pas dans les jointures ?
  • Le titre n'est-il pas à moitié coupé en haut du recadrage ? Le rapport hauteur/largeur des deux images mises côte à côte est-il trop différent ?
  • Ce que tu as écrit comme « absent » est-il vraiment absent à l'écran ? Si ce n'était pas visible à cause de l'état de connexion ou d'une condition, le verdict doit être inversé.
  • La légende dit-elle la même chose que ce que montre la photo ? N'as-tu pas écrit « se répète trois fois » pour une colonne cachée dans la largeur ?

Corrige ce qui ne va pas et vérifie à nouveau. Il est rare que tout soit juste du premier coup.

Étape 6 : HTML et livraison

  1. Copie assets/web-report.html dans le dossier du rapport sous le nom index.html et remplis-le. La structure et l'apparence des cartes sont dans 60-output §Structure.
  2. Si le destinataire a des décisions à prendre, place le bloc de décision juste en dessous de la carte de justification. En appuyant sur Copier dans la barre, seuls les éléments choisis sont copiés en Markdown et peuvent être collés dans la conversation (60-output §Recueillir les décisions).
  3. Ouvre les trois vues : écran large, écran de 390px de large, et toutes les pages d'impression extraites par scripts/check_print.sh (60-output §Écran et impression).
  4. Utilise inline-images.py pour tout rassembler dans un seul fichier report.html. Envoie le fichier directement ou exporte-le sous forme de lien. Ouvre-le de la même manière que le destinataire pour vérifier (60-output §Transmission).

Ne modifie pas le <style> du template pour chaque rapport. Si tu fixes des largeurs en px ou si tu places des tableaux en dehors de .tw, les petits écrans seront cassés. -> Principe fondamental 5

À la fin de cette étape, report.html ne doit pas être cassé dans les trois vues, il doit s'ouvrir de la manière dont le destinataire l'ouvrira, et l'envoi dépend de la validation de l'utilisateur.

Problèmes fréquents

SymptômeCause et solution
Le serveur de développement se ferme immédiatementnext dev lit stdin. Ajoute < /dev/null pour lui envoyer EOF immédiatement. Utilise `tail -f /dev/null
Les popovers ou les menus déroulants ne s'ouvrent pasDes librairies comme Radix ne réagissent pas aux événements synthétiques. Utilise le click réel de l'outil d'automatisation, pas dispatchEvent
La capture plein écran répète le même écran ou le fixe header se superposeL'outil de capture plein écran ne fait pas défiler correctement les fenêtres ou les conteneurs internes. Utilise le mode full de shot.mjs pour capturer par morceaux et assembler
La table des matières se répète dans les photos assembléesDes éléments fixes persistent. Capture ou recadre uniquement la zone d'intérêt
Les tableaux ou les figures dépassent de l'écran sur mobileLe tableau n'est pas encapsulé dans .tw ou une largeur en px a été fixée dans un style en ligne. Utilise uniquement les classes du template
Le marquage pointe vers le mauvais tableauLe même texte apparaît plusieurs fois à l'écran. Modifie le nth, utilise exact, ou un sélecteur plus précis
L'onglet capturé est le mauvaisUne autre session partage le daemon du navigateur. Isole les sessions
Tu as écrit qu'une fonctionnalité est absente alors qu'elle existeTu l'as capturée alors que tu étais déconnecté ou dans un état de condition incorrect. Vérifie la connexion et les conditions avant le verdict
En ouvrant le lien, plusieurs images sont videsUn serveur léger a raté des requêtes concurrentes. Utilise inline-images.py pour tout rassembler dans un seul fichier
La figure apparaît trop petite dans son cadreElle a été réduite à cause d'une limitation de hauteur. Pour les images longues verticalement, passe à une disposition sur deux colonnes horizontales
Le changement est trop subtil pour être vuTu as mal choisi l'élément à comparer. Plutôt qu'un simple changement de nom de colonne dans une liste, montre l'écran de modification qui permet d'éditer cette valeur
Le tableau est trop dense à lireRemplace-le par une liste d'éléments, avec les labels à gauche et le contenu à droite. S'il y a des groupes, mets le label du groupe une seule fois à gauche de la ligne
Le document ne fait que s'allonger au fil des correctionsSi tu as créé une nouvelle section, retire les descriptions existantes qui contenaient déjà ces informations

Mécanismes communs

ScriptFonctionSortie
scripts/shot.mjsOuvre les écrans avec Playwright selon la liste de capture, dessine le marquage, et capture. Découpe les longs écransFichiers PNG dans le dossier de sortie, une ligne par résultat de marquage
scripts/mark.jsTrouve un élément dans la page par son texte ou son sélecteur, dessine la bordure et le numéro. Utilisé par shot.mjs ; peut être injecté via eval dans d'autres outilsUne ligne par résultat de marquage
scripts/stitch.pyAssemble les morceaux capturés et recadre selon les coordonnées nomméesFichiers PNG dans le dossier de sortie, une ligne par taille
scripts/inline-images.pyIntègre les images en chemin relatif et les scripts dans un seul fichier HTMLreport.html, nombre et taille des fichiers intégrés
assets/decisions.jsSauvegarde les blocs de décision et permet au bouton Copier dans la barre de copier en Markdown uniquement ce qui a été choisiBarre fixe, localStorage
assets/compare.jsAjoute au-dessus de .pair[data-compare] les modes côte à côte, curseur de comparaison et différence. Un seul état global ; le mode par défaut est le curseur. Si les deux images ont des tailles en pixels différentes, la visualisation superposée est désactivéeBarre de comparaison, ratio de différence
assets/report-nav.jsConstruit la table des matières à gauche à partir des h2·h3, affiche la taille (sections, photos, décisions, temps de lecture), les sections lues, les décisions restantes et la position actuelle. Reprend la lecture lors d'une réouvertureTable des matières à gauche (tiroir sur petit écran), localStorage
scripts/serve-tailscale.sh(Optionnel) Exporte un dossier vers une URL HTTPS dans le tailnet en utilisant Tailscale, et vérifie la réponseURL, PID, commande d'arrêt
scripts/check_print.shGénère un PDF A4 de vérification dans un dossier temporaire, en suivant le même chemin que l'impression navigateurChemin du PDF, nombre de pages, PNG par page
scripts/grid_overlay.py · scripts/annotate.pySuperpose une grille de coordonnées sur une image non-navigateur, et dessine des boîtes et des légendesImage annotée

L'utilisation et les précautions sont dans les en-têtes de commentaires de chaque script.

Livrables

Un dossier de rapport (<date>-<sujet>/) : index.html pour les modifications, images dans images/ (originaux dans images/raw/), le fichier de liste de capture et de coordonnées de recadrage, et report.html (tout en un) pour la livraison. Lors de l'envoi, mentionne le lien, les modifications apportées pendant la capture, et les éléments non visibles à l'écran.

Position dans l'écosystème des skills

  • Outils de navigateur - Ce skill décrit comment utiliser l'outil choisi pour capturer et inclure les résultats dans le document. S'il existe des règles spécifiques dans l'environnement pour choisir l'outil et isoler les sessions, suis-les.
  • Skills de documentation - Les rapports sans écran, les propositions, les diapositives relèvent des skills de documentation généraux, pas de celui-ci.
  • Révision de texte - Si l'environnement fournit des règles pour améliorer la rédaction et la composition des écrans, suis-les. Elles peuvent aussi servir de source pour les principes dans le cadre de l'axe inspection.

Skills associés