muxso/Shepherd

Shepherd est une plateforme de développement native Rust qui supervise les agents de codage IA (Claude Code, Codex) et vérifie l'exhaustivité des exigences —» HumainDansLaBoucle

Qu'est-ce que Shepherd ?

Shepherd est une plateforme de développement écrite en Rust qui agit comme superviseur et orchestrateur pour les agents de codage IA comme Claude Code et Codex. Elle offre des capacités de test automatisé via une API REST, permettant de valider le comportement des systèmes sans intervention humaine sur des scénarios complexes de type CRUD. La fonctionnalité clé est le test en chaîne réelle qui utilise des cas d'API référencés (kind=CASE) avec extraction de variables, assertions et substitution dynamique, le tout exécuté en mémoire sans nécessiter de pool de ressources. Shepherd est conçu pour fonctionner avec des backends existants et fournit des rapports détaillés par étape. Il utilise un mécanisme d'import idempotent de spécifications OpenAPI et génère automatiquement des cas de test par défaut pour les nouvelles interfaces, assurant ainsi une couverture de test maintenue à jour. Actuellement, les tests de bout en bout couvrent 20 modules avec 114 étapes, toutes vertes.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add muxso/Shepherd

Installed? Explore more Recherche et analyse de données skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · 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

Auto-démarrage OpenAPI

Testez l'API HTTP de Shepherd avec ses propres capacités : définitions d'API + cas + orchestration de scénarios + exécution.

Exécution

# A. Démarrage en chaîne unique (connexion → extraction → chaîne authentifiée + négative 401) :
#    vérifie le mécanisme d'exécution de la chaîne réelle
python3 .claude/skills/openapi-bootstrap/selftest.py

# B. Couverture de scénarios complète par module : un scénario CRUD/cycle de vie par balise OpenAPI,
#    exécuté avec un rapport par module
python3 .claude/skills/openapi-bootstrap/scenarios_all.py

# C. Auto-vérification des opérations de plan de test (CRUD de plan, document de planification, liens de cas,
#    exécution de plan, ré-exécution d'un seul cas, planification)
python3 .claude/skills/openapi-bootstrap/plans_selftest.py

scenarios_all.py construit un scénario chaîné réel par module métier (20 modules), en référençant des cas d'API (kind=CASE, avec en-têtes d'authentification / extraction de variables / assertions), ordonnés en chaînes CRUD/cycle de vie et exécutés en mémoire avec un environnement. Stratégie d'échec CONTINUE → une exécution produit succès/échec par étape + raisons pour chaque module. Actuellement tout vert : 20/20 modules, 114/114 étapes. Il n'y a pas de point de terminaison « mise à jour de cas » → chaque exécution supprime l'ancienne définition de conteneur (en cascade sur ses cas) et la reconstruit. Les ressources persistantes (projet/utilisateur/exigence) portent un suffixe unique par exécution afin que les exécutions répétées ne heurtent pas les contraintes d'unicité.

Contraintes réelles confirmées lors de la construction (intégrées dans les chaînes ; à maintenir synchronisées si les énumérations du backend changent) :

  • Pool de ressources poolType ∈ {Node,Kubernetes} (pas de LOCAL) ; avec allOrg=false, orgIds doit être non vide.
  • Création de tâche POST /decomposition/{id}/task retourne {"taskId": <slug>} (pas id) ; les points de terminaison points/statut utilisent ce taskId.
  • Les exécuteurs de livraison CLAUDE_CODE/CODEX sont des souches synchrones : POST /delivery se termine en une étape, créé directement en DELIVERED (pas de transitions asynchrones running/complete).
  • /runner/probe et /runner-agent/{id}/run nécessitent un agent d'exécution en ligne (502 sinon) ; la chaîne locale ne couvre que le plan de gestion.
  • Plusieurs points de terminaison de liste nécessitent ?projectId= (exigence / compétence / cas fonctionnel / révision de cas).
  • Les créations retournent 201, les suppressions/mises à jour partielles retournent 204 → utiliser l'assertion générique ResponseCode < 400 au lieu d'un StatusIs(200) exact.
Variable d'envDéfautDescription
SHEPHERD_BASEhttp://127.0.0.1:9180Adresse du backend
SHEPHERD_USER / SHEPHERD_PASSadmin / s3cretIdentifiants de connexion (SHEPHERD_ADMIN_PASSWORD)
SHEPHERD_PROJECT_IDauto-résoluProjet cible ; par défaut le premier projet de la première organisation, créé si manquant

Les scripts, environnements, définitions, cas et scénarios sont tous créés-ou-réutilisés par nom — les exécutions répétées ne s'accumulent pas. (Les noms de ressources préexistants comme 自举环境 / 自举链路 sont conservés en chinois : ce sont des clés persistantes réutilisées par nom ; les renommer orphelinerait les lignes existantes.)

Flux (7 étapes)

  1. Connexion pour obtenir un jeton (appels admin uniquement pour la configuration des ressources)
  2. Résolution/création de l'organisation → projet
  3. Récupération de l'OpenAPI de ce système (GET /api-docs/openapi.json) → import idempotent (POST /api/definition/import ; même méthode+chemin écrase la spécification, pas de doublons) ; vérification par échantillon que les spécifications sont peuplées et que chaque interface possède un cas avec assertion
  4. Création ou réutilisation d'un environnement pointant vers cet hôte (baseUrl = ce serveur)
  5. Création ou réutilisation de 4 cas réels sous la définition de la chaîne de démarrage
  6. Création ou réutilisation d'un scénario référençant ces cas comme étapes (kind=CASE), alignement de l'ordre, exécution avec l'environnement
  7. Récupération du rapport ; affichage par étape ✅/❌ + variables extraites + nombre d'assertions

C'est une chaîne réelle, pas des GET codés en dur

Le scénario référence des cas d'API (kind=CASE) au lieu d'intégrer des requêtes codées en dur. Les cas couvrent POST + GET + en-têtes d'authentification + extraction de variables + chaînage entre étapes :

① connexion et extraction du jeton    POST /auth/login   assert statut 200 + contient "token"  → extraire token = $.token
② liste authentifiée des organisations  GET  /organization  en-tête Authorization: Bearer ${token} → extraire orgId = $.items[0].id
③ liste authentifiée des projets par orgId  GET /project?organizationId=${orgId}  (token et orgId substitués)
④ négatif : jeton manquant rejeté    GET /organization  assert statut 401

Mécanisme d'exécution clé (voir crates/api-test/src/adapters/{plan,local,pg}.rs, crates/api-runner/src/domain/runner.rs) :

  • Les étapes CASE s'exécutent en mémoire, chargeant la méthode/url/corps/en-têtes/authentification/assertions/processeurs complets du cas — aucun pool de ressources nécessaire (les étapes REQUEST en ligne suppriment les en-têtes, d'où CASE).
  • Les processeurs EXTRACT écrivent $.token etc. dans les variables d'exécution, transmises d'une étape à l'autre.
  • La substitution ${var} à une seule accolade s'applique à l'url / aux valeurs d'en-tête / au corps (attention : pas {{}}).
  • L'environnement baseUrl est préfixé aux urls relatives ; les en-têtes par défaut comblent les lacunes (les en-têtes de cas de même nom l'emportent).
  • Limitation connue : les assertions Variable ne peuvent pas voir les variables d'exécution à l'intérieur d'un scénario (plan.rs ne transmet pas les variables à l'évaluation des assertions), donc ce script utilise StatusIs/BodyContains au lieu d'assertions Variable.

Auto-vérification des opérations de plan de test

plans_selftest.py vérifie les opérations de plan de test de bout en bout via l'API HTTP : création/réutilisation de plan (l'identifiant du plan est conservé dans le fichier d'état local .plan_selftest_id, car il n'y a pas de point de terminaison de liste/suppression de plan), aller-retour PUT de mise à jour (description/tags/passThreshold), sauvegarde du document de planification + synchronisation des liens, liaison de cas (un scénario + un cas d'API), exécution complète du plan (toutes les lignes SUCCESS, la ligne de scénario porte un reportId dont les étapes sont tous SUCCESS), r é-exécution d'un seul cas, création/suppression de planification (201/204/404), et déliaison de cas (204 + liste réduite). Idempotent : une exécution deux fois de suite doit être entièrement verte les deux fois.

Améliorations de l'importateur backend (livrées simultanément)

POST /api/definition/import désormais :

  • analyse les parameters de chaque opération (query/header/path ; les indicateurs requis encodés dans la remarque), requestBody ($ref/allOf résolus sur components en une arborescence bodySchema + exemple) et responses (code de statut
    • exemple de schéma) → écrits dans la spec de la définition ;
  • génère un cas par défaut (code de statut + assertion métier de base) pour chaque nouvelle interface ;
  • est idempotent : un projet+méthode+chemin existant voit seulement sa spécification écrasée (les cas modifiés par l'utilisateur sont préservés) ; retourne {created, updated, skipped}.

Code : crates/api-definition/src/domain/import.rs, application/import_api_definitions.rs, domain/api_definition.rs (with_spec).

Codes de sortie

0 tout vert ; 1 une étape a échoué ; 2 le flux de démarrage lui-même a généré une erreur.

Skills associés