agent-stocktake — Audit de qualité des définitions d'agents

Auditer les définitions d'agents dans un environnement Claude Code (~/.claude/agents ou le .claude/agents d'un dépôt) et attribuer à chacune un verdict.

Qu'est-ce que agent-stocktake — Audit de qualité des définitions d'agents ?

**agent-stocktake** est un outil d'audit spécialisé conçu pour les environnements Claude Code. Il évalue chaque définition d'agent sous `<harness>/agents/*.md` et attribue un verdict parmi huit catégories : `Keep`, `Improve`, `Update`, `Merge`, `Demote to skill`, `Dissolve`, `Retire`. L'audit est unique car il opère sur deux couches de coût : la résidence (le `description` est toujours chargé dans la liste des types d'agents disponibles, comme une règle) et l'invocation (le corps n'est chargé que lors de l'appel, comme une compétence, mais déclenché par le jugement de délégation de Claude). Cela justifie son existence comme troisième compétence sœur à côté de skill-stocktake et rules-stocktake. L'outil prend en charge un mode `full` (audit complet) et un mode `changed` (réévaluation incrémentielle basée sur la date de modification), tout en effectuant toujours des vérifications d'intégrité sur l'ensemble complet. Il génère des preuves via un script Python (`agent_evidence.py`), vérifie les métadonnées (frontmatter, nom, liens Markdown), résout les chemins nus, et intègre les statistiques d'utilisation à partir d'un éventuel journal d'utilisation (`agent-usage.jsonl`). L'évaluation est holistique, avec une première phase de criblage binaire (8 questions) et une seconde phase de test de verdict qui tente de réfuter les verdicts non-Keep. Le résultat est un rapport structuré pouvant être appliqué via une branche dédiée (`apply`). Le code source, les commandes, les chemins de fichiers et les noms de variables d'environnement sont conservés dans leur forme originale pour garantir l'interopérabilité technique.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/shimo4228/harness-stocktake/tree/HEAD/skills/agent-stocktake

Installed? Explore more Productivité et collaboration skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · 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

Que fait agent-stocktake — Audit de qualité des définitions d'agents ?

Évaluez chaque définition d'agent sous <harness>/agents/*.md et attribuez à chacune un verdict : Keep / Improve / Update / Merge / Demote to skill / Dissolve / Retire. L'unité d'audit est le fichier, mais l'unité de coût est répartie sur deux couches — cette répartition est la raison pour laquelle cette compétence existe comme un troisième frère à côté de skill-stocktake et rules-stocktake.

Note de conception — le modèle de coût hybride. Le coût d'une compétence est la pollution du déclencheur (un déclenchement probabiliste dégrade la sélection) ; le coût d'une règle est la résidence (toujours chargée). Un agent a les deux à la fois : sa description est injectée dans chaque session via la liste des « Types d'agents disponibles » (résidence, comme une règle), tandis que son corps se charge uniquement lorsque l'agent est invoqué (invocation, comme une compétence — mais déclenché par le jugement de délégation de Claude, pas par la correspondance avec les mots de l'utilisateur). Ainsi, la description est audité sur la densité de résidence et le corps sur la qualité de l'invocation, avec des questions différentes pour chaque couche.

Note de conception 2 — les modifications approuvées sont appliquées par cette compétence elle-même, sur la branche apply. Même raisonnement que rules-stocktake : aucun moteur d'amélioration n'existe pour les définitions d'agents, et le corpus est suffisamment petit pour être lu dans un seul contexte — la délégation serait une sur-ingénierie. L'exception de transfert est Demote to skill (créer une compétence est le travail du skill-writer).

Racines. <harness> ci-dessous est l'environnement que cet audit couvre : ~/.claude par défaut, ou le .claude/ d'un dépôt lorsque la compétence harness-stocktake s'exécute en mode projet (sa section Racines mappe les chemins, nomme les preuves qui sont n/a là-bas, et indique quelles vérifications de convention s'appliquent). Le registre <ledger> appartient à cet environnement : ${CLAUDE_SKILL_DIR}/results.json lorsque le répertoire de cette compétence se trouve à l'intérieur de <harness> (l'environnement porte sa propre copie de la compétence), sinon <harness>/stocktake/agent-stocktake.json (un plugin installé, ou mode projet). Dans les deux cas, il est validé avec les autres modifications de l'environnement sur la branche apply.

Modes ($ARGUMENTS)

ArgumentComportement
aucun / fullLire et évaluer chaque définition d'agent (par défaut)
changedRéévaluer uniquement les fichiers dont la date de modification est plus récente que evaluated_at dans <ledger> ; reporter le reste du registre

changed détecte les modifications en ligne (pas de script) :

Les chemins ci-dessous commencent à ${CLAUDE_SKILL_DIR}, le répertoire contenant ce SKILL.md ; un agent qui ne substitue pas la variable le lit comme ce répertoire.

find <harness>/agents -name "*.md" -newermt "$(jq -r .evaluated_at \"<ledger>\")"

Comme dans rules-stocktake, les vérifications d'intégrité de la Phase 1 s'exécutent toujours sur l'ensemble complet — la suppression d'une compétence ou d'un hook casse silencieusement une référence à l'intérieur d'un corps d'agent non modifié, et mtime ne peut pas le détecter. Tout agent dont la vérification de référence (Étape 3 ci-dessous) échoue nouvellement rejoint l'ensemble de réévaluation. Le script n'a pas non plus de mode changed, pour une raison différente : les paires quasi-dupliquées et le total de résidence sont des propriétés d'ensemble, donc un corpus partiel donnerait des nombres erronés plutôt que moins de nombres.

Phase 1 — Preuves, inventaire, utilisation

Étape 1 — Exécuter le script de preuves (ne pas compter à la main)

uv run --frozen --project "${CLAUDE_SKILL_DIR}" \
       --directory "${CLAUDE_SKILL_DIR}" \
       python scripts/agent_evidence.py --root <harness>

Mode preuve : JSON sur stdout, code de sortie 0 quel que soit le nombre de constatations (code de sortie 2 uniquement lorsque le corpus est illisible). Il mesure et énumère ; il n'attribue jamais de verdict.

Transcrivez le JSON en constatations — ne mesurez jamais à l'œil. Ce qu'il vous donne :

Champ JSONRemplace
desc_words / body_lines / total_desc_wordsle passage wc -w / wc -l
tools.items[].status + registry.known_toolsbuiltin / unverified / mcp. unverified signifie « pas dans la liste datée du script », pas « n'existe pas » — vous détenez le registre des outils en direct et le script ne le fait pas, donc confirmez un unverified par rapport à votre propre liste d'outils avant de le qualifier de preuve Update. registry.known_tools.as_of est la date de cette liste (null quand --known-tools l'a remplacée)
tools.items[].server_in_config + registry.mcp_config_filesPas un verdict. Il indique uniquement si le serveur apparaît dans les fichiers de configuration locaux listés — les serveurs fournis par un connecteur n'y apparaissent jamais du tout, donc un false n'est pas « retiré ». null signifie qu'aucune source de configuration n'a été analysée. Vérifiez le status de chaque source avant d'utiliser cela ; un false à côté d'une source non ok n'est pas une preuve
unreadablefichiers que l'analyse n'a pas pu ouvrir, avec une raison. Non vide signifie que l'analyse est incomplète — nommez-les et corrigez avant de donner un total, car une instruction de suppression à l'intérieur d'un fichier illisible est maintenant certifiée absente
tools_unparsableagents dont la ligne tools: n'a pas été analysée (par exemple, style de flux YAML). Leur items est [], ce qui semble identique à un agent sans clé tools: — c'est-à-dire sans restriction. Ce n'est pas le cas ; la liste n'a simplement pas été lue
description_near_duplicatesla vérification des descriptions quasi-identiques ; les jumeaux divisent le trafic de délégation, donc chaque paire alimente la question de chevauchement de l'Étape 1
suppression_candidatescandidats numérotés pour la question de suppression de l'Étape 1 (le catalogue est bilingue car le corpus l'est)
always_never_candidatescandidats numérotés pour la question de sur-contrainte, corps uniquement — une description est un déclencheur de délégation, pas une instruction pour l'agent

Les deux derniers sont des candidats, pas des constatations — lisez chaque ligne citée avant de la rédiger. Le catalogue est aussi un plancher, pas un recensement : il contient cinq formulations tirées d'un corpus, donc une suppression écrite d'une autre manière (« ignorez tout ce dont vous n'êtes pas sûr », « évitez les constatations qui ne seraient que du bruit ») n'apparaît dans aucun champ JSON. Continuez à lire pour celles-ci ; une liste vide n'est pas un bilan vierge.

Les ratios de faux positifs mesurés vivent en dehors de ce fichier, donc cette étape ne contient pas de nombres qui deviennent obsolètes.

Étape 2 — Lire les portes qui possèdent déjà le reste

Trois vérifications restent en dehors du script car, dans un environnement qui a une porte de lint (<harness>/scripts/hooks/harness_lint.py), cette porte les possède. Lisez sa sortie lorsqu'elle existe ; sans elle, effectuez les trois vérifications avec Read / Grep :

  • Le frontmatter s'analyse et contient name, description, origin, model, et model est un alias → le lint_agents du script de lint (dans l'environnement de l'auteur, il s'exécute dans .claude/verify.sh et le hook pre-commit). Un origin manquant, lorsque l'environnement indique la convention origin, est toujours une constatation d'intégrité, alimentant Improve.
  • name est égal à la tige du nom de fichier → le même lint_agents. Il n'admet aucun jugement et le registre de délégation s'appuie dessus, donc il appartient à une porte qui arrête un commit — pas à une preuve qu'un lecteur peut ou non transcrire. Une constatation ici est un commit bloqué, pas un verdict de stocktake.
  • Les liens Markdown à l'intérieur des corps d'agents résolvent → le même script lint_markdown_links (ses portées incluent agents).

Étape 3 — Résoudre les références de chemin nu (la seule vérification que rien d'autre ne possède)

lint_markdown_links ne voit que la syntaxe de lien, et scan_refs.py de skill-health analyse l'arbre des compétences. Un chemin écrit en prose à l'intérieur d'un corps d'agent (<harness>/hooks/foo.sh, skills/foo/SKILL.md) n'est couvert par aucun des deux. Grep le corpus pour eux et ls chacun.

Étape 4 — Inventaire

Énumérez avec Glob : <harness>/agents/*.md. Lisez chaque fichier dans un seul contexte (le corpus est petit). Les colonnes de résidence et de corps proviennent du JSON de l'Étape 1 — ne faites jamais confiance aux chiffres écrits dans la documentation, y compris celle-ci.

Étape 5 — Compteurs d'utilisation

Entrée de preuve : une faible utilisation nomme un candidat, et le contenu décide du verdict. Lorsque la configuration conserve un journal d'utilisation des agents (<harness>/metrics/agent-usage.jsonl ; absent = utilisation n/a), lisez-le en ligne (un hook de journalisation des utilisations tel que log-agent-usage.sh ajoute un événement invoke par lancement d'outil Agent, clé par son champ agent, dont la valeur est le subagent_type) et comptez les événements par agent sur 7 / 30 / 90 jours. Agrégez avec une commande python3/jq jetable.

  • Si le journal est manquant ou son premier événement est plus jeune que 90 jours, affichez l'utilisation comme — (non mesurée). Ne l'affichez jamais comme 0 — non mesuré et non utilisé sont des faits différents.
  • Les compteurs sont des limites inférieures : seuls les lancements d'outil Agent (Task) sont capturés. Les travailleurs agent() de Workflow, la distribution interne de plugin, et les mécanismes intégrés qui contournent l'appel d'outil n'atteignent pas le hook. Un agent à faible utilisation entre à l'Étape 1 comme candidat Retire/Dissolve ; sa valeur peut être épisodique (par exemple, les relecteurs de papiers ne se déclenchent que près d'un dépôt), donc le contenu décide.
  • Le journal existe depuis le 2026-07-27 ; avant cette date, il n'y a aucune mesure.

Indiquez le résultat de l'analyse upfront, en prenant les compteurs du JSON de l'Étape 1 : agents_total moins tout ce qui se trouve dans unreadable, qui doit être nommé, total_desc_words (la taxe de résidence par session de la liste), les échecs d'intégrité, et si l'utilisation est mesurable. Transférez les échecs à l'Étape 1 en tant que preuves pré-calculées.

Phase 2 — Évaluation (entièrement en ligne, holistique)

Lisez chaque corps tout en voyant l'ensemble complet.

Étape 1 — Criblage binaire (chaque agent). Oui/Non explicite par élément ; ne faites apparaître que les réponses Non. Les deux premières questions auditent la couche de description (résidence), les suivantes la couche du corps (invocation) :

  • La description mérite-t-elle sa résidence ? — dense, distincte et permettant la sélection dans la liste toujours chargée ; indique quand déléguer ET quand ne pas déléguer
  • La description est-elle véridique par rapport au corps ? — ce qu'elle promet est ce que le corps fait (une description dérivée détourne la délégation à chaque session, même si le corps est bien)
  • Le corps est-il exempt d'instructions de suppression ? — commencez par les suppression_candidates de cet agent dans le JSON de la Phase 1, traitées selon l'Étape 1. Ce qui compte : les seuils de confiance (« ne rapportez que les constatations dont vous êtes sûr à ≥N % », « attribuez à chaque constatation une confiance et éliminez les faibles »), les planchers de gravité (« uniquement haute gravité »), les cadres de type « soyez prudent ». La directive de la génération actuelle est : rapportez tout, filtrez dans un passage séparé — une instruction de suppression est suivie littéralement et supprime silencieusement les constatations. Un Non ici est un candidat Amélioration par inversion : réécrivez l'instruction dans la direction opposée, ne supprimez jamais simplement la section (la suppression laisse le cadre de suppression ; l'inversion le remplace)
  • La copie d'origine externe est-elle à jour ? — pour un agent dont l'origin est un dépôt externe et dont le corps est une copie textuelle (par exemple, une redéfinition intégrée telle que Explore), la version source nommée dans le commentaire d'en-tête du corps correspond à l'outil installé (claude --version) ; une discordance est une Update (diff par rapport au bundle et re-copie). Les questions de suppression et de sur-contrainte sont ignorées pour ces copies — le corps est celui du fournisseur, pas le nôtre
  • Le corps est-il exempt de sur-contrainte de génération précédente ? — procédures pas à pas exhaustives pour un jugement que le modèle actuel détient nativement, emphase répétée, paires ALWAYS/NEVER que le jugement du contexte environnant devrait posséder. Les always_never_candidates de la Phase 1 localise les jetons ; décider si un résultat est une directive ou si elle ne fait que citer les mots est le travail de cette question
  • Non absorbé par le substrat ? — l'environnement couvre-t-il maintenant le travail de cet agent nativement (mécanisme de révision natif, mode plan, commandes slash intégrées) ? L'absorption → candidat Dissolve ; la revendication doit nommer son absorbeur concrètement. Jugez avec l' axe de contexte frais/riche : les rôles qui bénéficient d'un contexte frais (révision, vérification antagoniste, évaluation de l'essence — décorrélation du coût irrécupérable du proposant) vivent légitimement dans un sous-agent ; les rôles qui bénéficient d'un contexte riche (planification, génération, implémentation — intention de l'utilisateur, contraintes en cours de conversation) sont un travail de boucle principale, donc pour eux la boucle principale elle-même compte comme un absorbeur. Deux justifications auxiliaires peuvent légitimement remplacer l'attrait du contexte riche : un contrat de rendu avec entrée figée — l'appelant fige un paquet autonome avant l'invocation, donc le contexte de la conversation n'est pas nécessaire par conception (prompt-forager, qui obtient une ligne exprès) — et l'isolement de contexte en vrac — le travail lit ou produit un volume qui polluerait le contexte principal (chercheur, un angle de recherche web par exécution)
  • Les références techniques sont-elles à jour ? — vérifiez inconditionnellement chaque artefact que le corps nomme : ls chaque chemin référencé, exécutez --help / vérifications de version pour les commandes, drapeaux, noms de modèles et listes d'outils nommés. « Vérifier si cela semble obsolète » est une formulation interdite — la condition est ce qui dilue ; les affirmations vérifiables de manière déterministe obtiennent des vérifications déterministes, à chaque fois
  • Unique dans l'ensemble ? — aucun autre agent (ou compétence) ne possède le même travail ; une division orchestrateur→sous-agent documentée n'est PAS un chevauchement

Huit questions et pas plus — une décomposition supplémentaire dégrade le jugement holistique (voir Références).

Étape 2 — Test de pression du verdict (candidats non-Keep uniquement). Générez 1–3 questions atomiques oui/non spécifiques à l'agent qui tentent de réfuter le verdict provisoire, chacune répondue avec une ligne de preuve (lecture de fichier, vérification de chemin, --help, WebSearch, vérification de la documentation de l'environnement). Pour les candidats Dissolve, une question est obligatoire : « La fonctionnalité de l'environnement absorbante peut-elle être nommée concrètement — Oui/Non » — une revendication d'absorption qui ne peut pas nommer son absorbeur est réfutée. Et lorsqu'un Dissolve est sur le point d'être réfuté par une capacité que la contrepartie du substrat n'a pas (un outil, un sous-agent câblé), une contre-question est obligatoire avant d'accepter la réfutation : « Le sous-agent est-il le bon endroit pour utiliser cette capacité — ou la boucle principale la détient-elle de toute façon ? » L'existence d'une capacité est nécessaire mais pas suffisante ; l'axe de contexte frais/riche décide où la capacité appartient (précédent : la réfutation du planificateur s'est effondrée parce que la boucle principale contient l'outil Agent complet). Les agents liés à Keep n'obtiennent pas de questions dynamiques.

L'évaluation est

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills associés