Maintenir le package
La procédure de régénération des dépendances pour les auteurs, l’organisation des sources de la squad, les paramètres de personnalisation et le processus de publication fondé sur les tags.
Structure du dépôt#
apm.yml: métadonnées du package, liste des dépendances et scriptsapm.lock.yaml: fichier de verrouillage des dépendances résoluesscripts/Update-ApmDependencies.ps1: générateur de dépendancesscripts/Get-HveCoreCastDelta.ps1: compare les agents déployables entre deux références hve-corescripts/New-ChangeFragment.ps1: écrit un fragment de changement pour une pull requestscripts/Invoke-ReleasePrep.ps1: assemble les fragments en attente dans une section CHANGELOG et incrémenteapm.yml.changes/unreleased/: fragments de changement en attente ; vide entre les publicationssquad-src/.github/: sources de la squad rédigées localement (agents, prompts, instructions, skills)apm_modules/: dépendances installées (ignorées par git).github/: ressources locales générées ou déployées (ignorées par git, sauf.github/workflows/si ce dossier est suivi)-
.copilot-tracking/: état de travail des agents. Ignoré par défaut — vos recherches, plans et exécutions interactives de la squad restent locaux sans intervention de votre part. L’exception est la piste d’audit d’une exécution sans surveillance en Watch Mode, que.gitignoreréinclut aux deux niveaux, car la preuve de délégation comporte deux niveaux :squad/members/issue-*/etsquad/members/pr-*/(l’exécution interne), plussquad/history/issue-*.mdetsquad/history/pr-*.md(la méta-transition au niveau de la fédération). Les fichiers d’état scalaires à la racine de la fédération (federation.md,meta-routing.md,state.jsonet les registres agrégés) restent locaux : ils fonctionnent par remplacement, donc les inclure dans des commits provoquerait immanquablement des conflits entre exécutions simultanées, et l’amorçage les reconstruit. docs/: ce site de documentation (servi par GitHub Pages)
Scripts#
Site de documentation#
Eleventy construit le site publié à partir des sources anglaises dans docs/ et françaises dans docs/fr/, avec les mêmes noms de fichiers et des identifiants d'ancre communs. Les pages et index de recherche générés sont placés dans _site/ ; ouvrir une page source d'origine n'affiche pas les encarts de version ni les commandes d'installation versionnées générés.
Mettez à jour les deux langues dans le même changement. Conservez les noms et paramètres des commandes, et signalez les liens vers les guides externes, rapports historiques et vidéos disponibles uniquement en anglais. Le cadre publié, les traductions et l'apparence se trouvent dans site/pages.njk, site/locales.json et site/assets/site.css. Les onglets d'environnement appartiennent à chaque exemple de commande et partagent l'environnement sélectionné entre les exemples et les pages ; le changement de langue conserve la page courante.
Marquez chaque nouveau comportement documenté non encore publié avec data-release-change="20261005-routing-economy", en utilisant le nom de son propre fragment en attente sans .md, dans les deux langues. Placez l'attribut sur le titre, le paragraphe, l'élément de liste, l'identifiant en ligne ou le bloc de code entier de la fonctionnalité, jamais dans un lien ni dans un bloc de code copiable. Ne marquez pas comme indisponibles les options déjà stables ni les simples corrections documentaires. scripts/docs-release.mjs lit la dernière version stable dans apm.yml et détermine le tag glissant à partir de l'incrémentation en attente la plus élevée. Les badges disparaissent lorsque leur fragment est consommé, même si un mainteneur remplace le numéro de version à publier.
Rédigez les exemples Squad exécutables dans des blocs pre > code avec la syntaxe canonique des commandes slash. Le moteur de rendu partagé utilise cette source pour créer des requêtes sans préfixe pour VS Code, la CLI et l’application avec l’agent correspondant, en préservant les arguments et le texte multiligne. Séparez les commandes shell et les déclencheurs par commentaire GitHub ; marquez les références qui comparent explicitement les environnements avec data-host-reference. Sans JavaScript, les exemples canoniques d’origine restent lisibles.
npm ci
npm run docs:test
npm run docs:build
npm run docs:devLa compilation préserve le texte et les exemples sources, insère les versions actuelles et vérifie les traductions, liens, ressources et index de recherche. Les tests couvrent aussi les onglets au clavier, les préférences enregistrées, le contenu sans script et la promotion d'une version. Le workflow Pages reconstruit le site lors des changements de fragments en attente comme lors des changements documentaires, pour que l'encart suive les renommages du tag de préversion. Vérifiez les mises en page pour ordinateur et mobile après toute modification visuelle.
Scripts du package#
Définis dans apm.yml :
sync-deps— régénèredependencies.apmà partir du contenu HVE Core.install-sync— régénèredependencies.apmet exécuteapm install.change— crée un fragment de changement dans.changes/unreleased/pour la pull request en cours.release-prep— assemble les fragments en attente pour une publication : section CHANGELOG, incrémentation de version, suppression des fragments.
Procédure de maintenance#
-
Régénérez les dépendances :
apm run sync-deps -
Installez les dépendances localement :
apm install # or apm run install-sync -
Actualisez le fichier de verrouillage :
apm lock -
[FACULTATIF] Construisez l’artefact du package (nécessaire uniquement pour construire un plugin) :
apm pack -
[FACULTATIF] Publiez (le cas échéant) :
apm publish
Séquence recommandée avant une publication :
apm run sync-depsapm lockapm pack(facultatif)apm run release-prep— ou exécutez le workflow Release Prep, qui fait la même chose et pousse les changements.
Fonctionnement de la génération des dépendances#
Le script de génération :
- Se connecte à
microsoft/hve-coresur une référence cible (par défaut : le SHA déjà épinglé dansapm.yml) - Énumère les fichiers de
.github/agents,.github/instructions,.github/promptset.github/skills - Filtre les artefacts Markdown
- Réécrit uniquement
dependencies.apmdansapm.yml
Les métadonnées du package restent ainsi stables tandis que la liste des dépendances est mise à jour de manière sûre.
Mettre hve-core à jour : les deux voies#
Le roster de la squad associe chaque rôle à un agent hve-core par la valeur exacte de name:
dans son frontmatter. Une mise à jour de hve-core recouvre donc deux opérations différentes en
apparence semblables, dont une seule peut être automatisée de bout en bout sans risque. La distinction repose sur une
question : cette révision de hve-core déplace-t-elle un agent que la squad désigne encore ?
Le schéma n’a pas pu être affiché. Sa source reste disponible ci-dessous.
Source du schéma
flowchart TD
A["Planification 06:00 UTC<br/>sync-hve-core.yml"] --> B["Get-HveCoreCastDelta.ps1<br/>SHA épinglé comparé à main de hve-core"]
B --> C{"squad-src référence-t-il encore<br/>un agent supprimé ou non invocable ?"}
C -- "non (mécanique)" --> D["Mettre à jour la version épinglée + assembler la version<br/>à partir des fragments .changes + pousser"]
D --> E["release.yml<br/>tag + version GitHub"]
C -- "oui (rupture)" --> F["Ouvrir une issue étiquetée squad/auto<br/>corps = cahier des charges complet de l’adaptation"]
F --> G["squad-watch.yml<br/>se déclenche sur l’étiquette"]
G --> H["Sous-squad issue-N<br/>autopilot, sans intervention"]
H --> I["PR BROUILLON qui clôt l’issue"]
I --> J{"Étiqueter la PR squad/review ?"}
J -- oui --> K["squad-watch.yml à nouveau<br/>sous-squad pr-N, rôle tester"]
K --> L["Commentaires de revue sur la PR"]
L --> M["Fusion par une personne"]
J -- non --> M
Notez qu’aucune tâche cron n’exécute de squad. La seule tâche planifiée est la synchronisation mécanique ; lorsqu’elle trouve une différence entraînant une rupture, elle crée une issue et s’arrête. L’issue sert à la fois de déclencheur et de cahier des charges : la description de la tâche de la squad est donc un artefact durable et révisable, plutôt qu’une chaîne enfouie dans un fichier de workflow.
Voie 1 — mécanique (aucun changement des agents fournis)#
sync-hve-core.yml déplace le SHA épinglé et enregistre ce déplacement dans un fragment de changement,
exactement comme le ferait un contributeur — la modification de la référence épinglée rejoint ainsi les contributions
fusionnées ce jour-là et est livrée avec la prochaine version préparée par quelqu’un, au lieu de produire
sa propre version chaque matin. Le workflow pousse les changements et s’arrête là. Une nouveauté par rapport au comportement antérieur : il exécute
d’abord le script de comparaison des agents comme garde-fou. Un déplacement de SHA ne peut pas réaffecter une ligne du roster,
et le publier malgré tout distribue une squad dont les rôles ne correspondent à rien — c’est exactement
ce qui s’est passé dans 0.10.11.
Voie 2 — adaptative (les agents fournis ont changé)#
Le workflow de synchronisation ne touche pas à apm.yml. Il ouvre une issue
portant le label squad/auto, dont le corps contient tout le cahier des charges : ce qui a changé et pourquoi cela
crée une rupture, huit étapes numérotées, les contraintes de modification, les critères d’acceptation et le tableau
généré des différences entre agents. Une seule issue ouverte par SHA cible — si la tâche cron retrouve une différence non résolue,
elle ajoute un commentaire plutôt que de créer un doublon.
squad-watch.yml se déclenche sur ce label, exécute la squad sans interface dans la sous-squad
issue-<N> et ouvre une PR en brouillon qui clôt l’issue.
L’ajout du label squad/review à cette PR déclenche à nouveau le même workflow dans la sous-squad
pr-<N>, avec routage vers le rôle de testeur, qui publie ses constats en commentaires de la PR.
La PR d’adaptation contient un fragment dans .changes/unreleased/ avec
bump: minor, car un changement des agents fournis signifie que le roster distribué n’est plus celui
de la version précédente. Elle ne modifie pas apm.yml version: ni
CHANGELOG.md — c’est la même règle que pour tous les contributeurs,
et pr-validation.yml l’impose ici aussi. Si une exécution l’oublie, le workflow écrit un
fragment provisoire de niveau patch pour permettre à la PR de passer les contrôles, marqué
PLACEHOLDER, rewrite before merging.
Fusionner la pull request d’adaptation suffit à mettre la version mineure en attente. Le
fragment arrive dans .changes/unreleased/ sur main, où
Rolling Preview le publie en préversion installable en quelques minutes.
Il est livré aux utilisateurs avec la prochaine version que vous préparez.
Comportement des points de validation sans surveillance#
Une exécution sans surveillance ne peut pas attendre une approbation qui n’arrivera jamais. Watch Mode déplace donc l’endroit où le point de validation est satisfait plutôt que de le supprimer. Voir Unattended Gate Disposition dans les instructions de Watch Mode.
- Transitions entre étapes — se poursuivent sur la base des preuves apportées par les artefacts, comme dans toute exécution autopilot.
- Validation du résultat final — satisfaite par la PR en brouillon. L’exécution compile son résultat dans le corps de la PR au lieu de se mettre en pause.
- Risk Gate — consigné, non bloquant. Les constats sont enregistrés dans
decisions.mdet reproduits dans le corps de la PR sous Blocking findings ; la PR reste en brouillon. -
Impactful-Action Gate — n’autorise jamais la poursuite. Aucune fusion, aucun
déploiement, aucun push forcé, aucune migration, aucune rotation de secret, aucune écriture dans un outil de suivi actif,
et aucune charge utile ne peut changer cela. Cette règle
est imposée de trois manières : le contrat, l’absence de toute information d’identification de déploiement sur le runner,
et la protection de branche sur
main.
Exécutez vous-même le contrôle des différences à tout moment :
./scripts/Get-HveCoreCastDelta.ps1
./scripts/Get-HveCoreCastDelta.ps1 -ToRef main -MarkdownPath delta.mdConfiguration requise#
-
Secrets.
COPILOT_GITHUB_TOKEN— un PAT à granularité fine avec l’autorisation Copilot Requests (le jeton Actions intégré ne peut pas authentifier Copilot).SYNC_DEPS_TOKEN— utilisé pour liremicrosoft/hve-coreet pousser le commit de publication. -
Labels. Créez
squad/autoetsquad/review. Ce sont les deux déclencheurs ; sans eux, rien ne se lance. -
Settings → Actions → General → Workflow permissions : activez
“Allow GitHub Actions to create and approve pull requests.” Sans cette autorisation,
gh pr createrenvoie 403 et l’exécution se termine avec une branche mais sans PR. -
Ensemble de règles de branche sur
main: exige une pull request, avec le rôle d’administrateur du dépôt comme seul acteur autorisé à les contourner. C’est la troisième couche d’application de l’Impactful-Action Gate, et celle dont la configuration reste le plus souvent incomplète — une règle qui interdit seulement les pushs forcés et les suppressions n’empêche pas un push direct versmain: elle en limite les dégâts. Le contournement réservé à l’administrateur sépare les deux automatisations :sync-hve-core.ymlpousse avec le PAT d’un mainteneur et passe directement, tandis que Watch Mode pousse sous l’identitégithub-actions[bot], qui ne détient aucun rôle dans le dépôt et ne peut pas du tout atteindremain. Le nombre d’approbations requises est fixé délibérément à zéro pour qu’un mainteneur seul ne soit pas empêché de fusionner sa propre pull request. -
Modèle épinglé (déjà configuré).
squad-watch.ymltransmet--modelà Copilot CLI à partir de la variableSQUAD_MODELdéfinie au niveau du workflow. Ne laissez pas ce choix àauto: le coordinateur est l’agent du système qui porte le plus d’instructions, et une sélection automatique du modèle route précisément cet agent vers ce qui coûte le moins cher — c’est ainsi qu’une exécution se retrouve à rédiger les livrables elle-même au lieu de les déléguer à ses agents. L’ordre de priorité dans la CLI est--model>COPILOT_MODEL>~/.copilot/settings.json; seul le paramètre est propre au dépôt, car lui seul réside dans le dépôt. Confirmez les identifiants disponibles avec votre offre en exécutantcopiloten mode interactif puis en saisissant/model— ce sont des identifiants en minuscules commeclaude-sonnet-5, et non les noms affichés utilisés dans le frontmatter des agents. Une exécutionworkflow_dispatchpeut remplacer le modèle épinglé pour une seule exécution. -
Surveillance des approbations (facultative) : copiez
.github/skills/squad/github-approval-watcher.workflow.ymldans.github/workflows/si vous souhaitez aussi pouvoir approuver les exécutions interactives depuis un téléphone.
Tester la boucle manuellement#
Lancez Squad Watch depuis l’onglet Actions avec le paramètre issue_number pour
tester le parcours complet sur une issue que vous avez rédigée vous-même, sans attendre de changement
en amont. Faites-le une fois avant de vous fier à la tâche cron.
Examiner une PR d’adaptation#
Le corps de la PR contient la liste de contrôle ; les deux points les plus importants sont les suivants :
- Aucun agent Primary ou Alternate du roster ne définit
disable-model-invocation: true— ces agents ne peuvent pas recevoir de délégation. -
.copilot-tracking/squad/members/<sub-squad>/history/contient une entrée par rôle auquel une tâche a été déléguée. Un historique peu fourni signifie que l’exécution a rédigé les changements elle-même au lieu de les déléguer à ses agents, et le diff ne doit pas être considéré comme fiable à lui seul.
Sources de la squad#
En plus des dépendances microsoft/hve-core, ce package fournit une « squad »
rédigée localement — un Squad Coordinator accompagné d’agents de soutien, d’instructions, d’un prompt et d’un
skill. Les sources de la squad se trouvent dans :
squad-src/.github/agents/squad/squad-src/.github/instructions/squad/squad-src/.github/prompts/squad/squad-src/.github/skills/squad/
Contrat de plafond de coût et tests#
Le contrôle d’admission fondé sur le coût couvre plusieurs types d’artefacts, mais chaque aspect a un responsable principal. Gardez l’interface des prompts, le calcul de référence, le point de contrôle du coordinateur, la validation du Scribe, le schéma d’état et les tests synchronisés lorsque le paramètre change.
| Aspect | Responsable principal |
|---|---|
| Invocation et transmission | squad.prompt.md et squad-federation.prompt.md |
| Plafond effectif, estimation, confiance, approbation et règles d’arrêt | references/consumption.md |
| Procédure au point de délégation | references/gates-and-modes.md |
| Formats des enregistrements machine et lisibles | references/entry-schemas.md et references/federation-templates.md |
| Contrôle des créneaux après admission | references/scribe-procedure.md |
| Orchestration d’une squad unique et de la fédération | squad-coordinator.agent.md et squad-federation-coordinator.agent.md |
| Taux agrégés et étalonnage de la fédération | consumption-rates.md à la racine de la fédération, initialisé à partir de references/federation-templates.md et utilisé uniquement par l’autopilot de fédération non ciblé |
| Identifiants de comportement stables | tests/squad-behavior-contract.md |
| Contrôles du package, de l’état, de la chronologie et des mutations | tests/tier0/SquadPackage.Tests.ps1 et tests/tier1/ |
Gardez la répartition des responsabilités explicite. L’initialisation est une dépense de configuration hors du contrôle d’admission. Le routage ordinaire et le routage ciblé de la fédération transmettent un plafond indépendant à chaque sous-squad sélectionnée. Seul l’autopilot de fédération non ciblé lit ou écrit l’état agrégé de Cost Preflight à la racine de la fédération. Son méta-coût déjà engagé est reconstruit sur l’ensemble des tours, pas seulement à partir du dernier manifeste, dont le périmètre diminue.
Exécutez les couches de validation locales sans risque après un changement :
# Prompt, package, reference, and body-cap conformance
./tests/tier0/Invoke-Tier0Tests.ps1 -SourceRoot .
# Valid state plus adversarial transition fixtures
./tests/tier1/Invoke-Tier1Tests.ps1 -SelfCheck -Output Normal
# Whitespace and malformed patch output
git diff --check
Les exécutions Tier 1 en conditions réelles invoquent des modèles et constituent une voie de mesure manuelle distincte. L’autocontrôle ci-dessus
est déterministe et prouve que chaque assertion du contrat peut rejeter une arborescence volontairement corrompue.
Un changement de comportement nécessite aussi un nouveau fichier dans .changes/unreleased/ ; modifier un
fragment existant ne satisfait pas le contrôle d’une pull request distincte.
Maintenance du skill squad et des références#
Les fichiers d’instructions et de référence du skill squad pilotent le roster, la sélection des modèles et le comportement du registre.
Les modifications apportées ici se propagent à tous les utilisateurs lors du prochain apm install.
Répartition du roster : squad-src/.github/instructions/squad/squad-roster.instructions.md
contient le résumé de sécurité intégré, les règles d’éligibilité à la délégation et Profiles/Packs. Le catalogue des agents (anciennement
les sections Cast Catalog, External Cast et Building a Custom Roster) se trouve désormais dans le fichier de référence
squad-src/.github/skills/squad/references/roster-catalog.md (lu à la demande). Lorsque vous ajoutez un
agent au catalogue, modifiez references/roster-catalog.md pour ajouter la ligne du rôle et lier le fichier
de l’agent dans .github/agents/.
Catalogue des modèles et routage : squad-src/.github/skills/squad/references/model-catalog.md
énumère les modèles pris en charge, les niveaux et leur disponibilité. references/model-routing.md définit
l’algorithme de sélection par classement et l’ordre de priorité. Le Scribe ne doit pas hériter du modèle de pointe de la session
(épinglé à Claude Haiku 4.5 dans son frontmatter ; la classe d’affectation bookkeeping a pour plancher le Model Tier rapide initialisé).
Lorsque l’offre de modèles GitHub Copilot change, mettez à jour la date Retrieved du catalogue ; une date
vieille de plus de 90 jours entraîne un repli sur les niveaux statiques. Gardez la date de récupération et le catalogue synchronisés.
Contrôle Tier 0 du budget en octets : tests/tier0/baselines/byte-budget-baseline.json (voir
Performance.Tests.ps1 L507) fixe des limites de taille (roster : 61 170 octets ; noyau actif du Scribe : 82 000 octets ; tolérance de 5 %). Modifiez
budgetBytes et note manuellement lors d’un changement de taille intentionnel. La référence
tests/tier0/baselines/prefill-baseline.json est régénérée avec
./scripts/Measure-SquadPerformance.ps1 -SourceRoot . -UpdateBaseline (voir Measure-SquadPerformance.ps1
L52–56) ; après la régénération, examinez le diff pour confirmer que seules les phrases normatives et les titres voulus ont changé (la suppression
d’une phrase normative fait échouer le contrôle d’inclusion dans Performance.Tests.ps1 L507, sauf s’il s’agissait d’une correction intentionnelle).
Utilitaire de registre et garde-fous : le script Measure-SquadLedger.ps1 -SquadRoot <root> -Check
valide l’arithmétique du registre, la divergence entre le registre et state.json (contrôle strict ; un state.json absent ou impossible à analyser provoque un échec ;
une racine de fédération signalée par federation.md est consignée comme non applicable), ainsi que le contrôle d’identité (les identités
ordonnées des blocs enregistrées par fichier doivent former un préfixe ordonné des identités actuelles ; les écrasements et suppressions échouent ;
les ajouts réussissent ; un simple -Check n’émet qu’un avertissement lorsqu’aucune identité n’est enregistrée — cas des anciens registres).
Le Scribe l’appelle avec
-ExpectedHistoryCounts <per-agent entry counts> (scribe-procedure.md L166), ce qui transforme
ces mêmes avertissements d’identité manquante en échecs — que les identités soient totalement absentes ou absentes seulement pour certains des fichiers modifiés
(un collage partiel) — puisque cet appel suit toujours une nouvelle écriture. Les jeux de données de test dans
tests/fixtures/ledger-* exercent chaque condition de protection.
Pourquoi les sources sont séparées de l’arborescence .github/ déployée#
apm install déploie les agents et les prompts en les aplatissant dans l’arborescence
.github/ de l’utilisateur. Si les sources de la squad se trouvaient directement dans le dossier de premier niveau
.github/agents/ (ou .github/prompts/), un apm install ultérieur
les écraserait. Conserver les sources rédigées dans squad-src/.github/... les place
hors de la zone d’aplatissement du déploiement tout en préservant le préfixe
.github/{agents,prompts,instructions,skills}/ attendu par la correspondance de déploiement.
L’état d’exécution de la squad est créé par projet dans .copilot-tracking/squad/
et n’est jamais inclus dans le package.
Génération des entrées de la squad#
Update-ApmDependencies.ps1 énumère les sources de la squad depuis le système de fichiers local
(elles ne sont pas clonées, car elles se trouvent dans cette arborescence de travail et peuvent ne pas
encore avoir été poussées). Les entrées de la squad sont produites sous forme de chemins virtuels distants
<SquadRepoSlug>/<SquadSourceRoot>/.github/..., par exemple
Peter-N91/hve-squad/squad-src/.github/agents/squad/squad-coordinator.agent.md.
Elles sont ajoutées après les entrées hve-core dans dependencies.apm.
La commande de synchronisation accepte les paramètres suivants, propres à la squad :
pwsh -File scripts/Update-ApmDependencies.ps1 `
-SquadSourceRoot squad-src `
-SquadRepoSlug Peter-N91/hve-squad `
-SquadRef vX.Y.ZSquadSourceRoot: chemin local de l’arborescence des sources de la squad (par défaut :squad-src). Si le chemin n’existe pas, l’énumération de la squad est ignorée sans erreur.SquadRepoSlug:owner/repoqui héberge les sources de la squad (par défaut :Peter-N91/hve-squad).SquadRef: référence git facultative qui épingle les autoréférences de la squad sous la forme#<ref>. En général, vous n’y touchez pas — le workflow Release les épingle automatiquement (voir Tags de version reproductibles ci-dessous). Ce paramètre reste disponible pour épingler un manifeste manuellement.
Utilisez -DryRun pour prévisualiser à la fois les entrées hve-core et celles de la squad sans écrire dans apm.yml.
Tags de version reproductibles#
Les autoréférences de la squad sont distribuées sous forme de chemins sans référence sur main, et APM résout un tel chemin
sur la branche par défaut. Sans intervention, un tag figerait la liste des dépendances, mais pas
leur contenu : il a été constaté qu’une installation de #v0.14.0 renvoyait
le coordinateur de main, alors que les entrées hve-core du même manifeste étaient résolues
correctement parce qu’elles portent #<sha>. APM le signale directement —
47 dependencies unpinned: Peter-N91/hve-squad.
release.yml corrige ce problème sans aucune étape manuelle. Avant de créer la publication, il exécute
scripts/Set-SquadSelfRefPin.ps1 -Ref vX.Y.Z, crée un commit du manifeste épinglé et pousse
ce commit directement vers refs/tags/vX.Y.Z. Un manifeste ne peut pas désigner son
propre tag avant que celui-ci n’existe ; la référence épinglée réside donc dans un commit vers lequel seul le tag pointe.
main ne le reçoit jamais et conserve le manifeste non épinglé, de sorte que les installations de développement
continuent de suivre main.
Cela s’applique à partir de v0.15.2. Chaque tag antérieur résout les fichiers de sa squad
depuis main et n’est pas reproductible. Corriger l’un d’eux rétroactivement implique de déplacer
son tag de force, ce qui change la cible de sa GitHub Release.
apm lock et apm install ne peuvent résoudre les chemins virtuels de la squad
qu’une fois l’arborescence squad-src/ poussée vers le dépôt distant SquadRepoSlug.
Les tags de version sont épinglés automatiquement par release.yml : vérifiez donc
apm install depuis un clone neuf du tag plutôt que depuis l’arborescence de travail.
Références épinglées reproductibles#
Chaque entrée microsoft/hve-core générée est épinglée au SHA exact du commit vers lequel
-Ref pointe (ajouté sous la forme #<sha>) : une version publiée continue donc
de résoudre les mêmes fichiers même après l’évolution de main dans hve-core. Sans cela,
un chemin non épinglé que hve-core renomme ou supprime par la suite fait échouer l’installation pour tous les utilisateurs
de cette version. En l’absence de -Ref, le script réutilise la référence déjà épinglée dans
apm.yml ; transmettez -Ref <hve-core-ref> pour la déplacer vers un
commit, un tag ou une branche précis.
Personnalisation#
Vous pouvez ajuster le comportement de génération dans scripts/Update-ApmDependencies.ps1 :
RepoSlug: dépôt sourceRef: branche, tag ou commit à parcourir. Par défaut, le SHA déjà épinglé dansapm.ymlest utilisé ; une régénération ordinaire ne déplace donc jamais la référence épinglée. Fournissez ce paramètre explicitement pour la déplacer.IncludeRoots: dossiers inclus dans la découverteIncludeRegex: motif de filtrage des fichiersSquadSourceRoot: chemin local de l’arborescence des sources de la squadSquadRepoSlug:owner/repohébergeant les sources de la squadSquadRef: tag de version ou commit facultatif qui épingle les autoréférences de la squad
Fragments de changement#
La version et le changelog sont des sorties de publication, pas des éléments qu’une pull request modifie.
La version occupe une seule ligne et le titre le plus récent du changelog une seule position : deux
pull requests qui les modifient entrent donc toujours en conflit — et la seconde à être fusionnée réutilise
silencieusement un numéro de version déjà pris par la première. Changer de branche cible n’aide pas : deux
pull requests incrémentant vers le même numéro sur une branche develop entrent en conflit de la même manière.
La solution est de retirer entièrement l’état partagé de la pull request.
Chaque pull request ajoute à la place un nouveau fichier dans
.changes/unreleased/, généré par apm run change. Deux pull requests
ajoutant deux fichiers de noms différents n’entrent jamais en conflit. Le format est documenté dans
.changes/README.md
et repris pour les contributeurs sur la page Contribuer.
pr-validation.yml transforme la règle en contrôle mécanique plutôt qu’en commentaire de revue :
- Modifier
CHANGELOG.mddans une pull request fait échouer le contrôle. - Modifier la ligne
version:dansapm.ymlfait échouer le contrôle. -
Déplacer la référence épinglée de
microsoft/hve-corefait échouer le contrôle, sauf si la branche est une branche d’adaptation Watch Mode (squad/issue-*). Modifierdependencies:est autrement autorisé — un contributeur qui ajoute un skill doit le faire, viaapm run sync-deps, qui conserve par défaut la référence épinglée actuelle. Le contrôle sert de dernier garde-fou face à un-Ref mainexplicite qui contourne le contrôle des différences entre agents ; son message indique le SHA à transmettre à la place. - Une pull request sans nouveau fragment échoue, sauf si elle porte le label
skip-changelog. Ce label évite aussi l’incrémentation de version, car celle-ci est calculée à partir des fragments — une pull request qui n’apporte aucun fragment n’apporte aucune incrémentation. - Chaque fragment en attente est analysé avec
Invoke-ReleasePrep.ps1 -DryRun: un fragment mal formé est ainsi détecté dans la pull request plutôt qu’au moment de la publication.
Le workflow s’exécute sur pull_request, pas sur pull_request_target : les pull requests issues de forks
reçoivent un jeton en lecture seule et aucun secret, et le contrôle n’a besoin ni d’un accès en écriture ni de secrets. Créez le
label skip-changelog avant de compter sur cette exception.
Qui décide du niveau de version#
Le niveau de version suit les idées, pas les artefacts. 0.10.0 correspondait à la
fédération et 0.11.0 au remaniement du rattachement de hve-core, car chacun introduisait
un concept qui n’existait pas auparavant. Tout agent, skill, rôle ou instruction ajouté
dans le cadre de l’une de ces idées relève d’un correctif, quel que soit le nombre de fichiers concernés. Un contributeur
qui ajoute un rôle de squad à la fédération prolonge une idée déjà distribuée.
Le bump d’un fragment est une suggestion et, puisque la fusion publie
immédiatement, c’est dans la pull request que vous le remplacez. Deux éléments
facilitent cela :
-
pr-validation.ymlécrit le résultat dans le résumé de la tâche du contrôle — Version : 0.11.12 -> 0.12.0 (minor) — de sorte qu’une version mineure ne puisse jamais passer inaperçue. -
Vous n’êtes pas d’accord ? Ouvrez le fragment dans l’onglet Files changed de la pull request, cliquez sur
le crayon, remplacez
bump: minorparbump: patch, puis créez un commit. Une ligne, sans extraction locale. Les pull requests issues de forks l’autorisent par défaut (Allow edits by maintainers).
Les substitutions au moment de la publication restent disponibles pour le lot que vous assemblez vous-même, et pour tout
ce qui a atteint main sans publication :
pwsh -File scripts/Invoke-ReleasePrep.ps1 -Bump minor -DryRun # this batch adds up to a new idea
pwsh -File scripts/Invoke-ReleasePrep.ps1 -Version 1.0.0 # exact number, overrides everything
Le workflow Release Prep propose le même choix dans une liste déroulante bump,
dont la valeur par défaut est fragments. Le script affiche “Bump override:
fragments resolved to X, releasing as Y” chaque fois que vous remplacez leur résultat, pour que la décision
soit visible dans le journal d’exécution.
Processus de publication#
Les publications suivent un processus fondé sur des tags à partir de la branche par défaut (main). Le tag est
l’artefact de version que les utilisateurs installent avec apm install "Peter-N91/hve-squad#vX.Y.Z".
Vous ne choisissez pas le numéro de version manuellement — c’est le bump le plus élevé parmi les
fragments en attente qui le détermine.
Les publications sont déclenchées manuellement. Fusionner une pull request qui contient un fragment
le pousse dans .changes/unreleased/ sur main et ne publie rien.
Aucune publication n’est non plus déclenchée par une minuterie. Lorsque le lot en attente est prêt, vous lancez
Release Prep, qui le livre en une seule version : il calcule le niveau, ajoute en tête
la section CHANGELOG avec le bloc d’installation pour les utilisateurs et la référence du lien, écrit
version: dans apm.yml, supprime les fragments consommés, crée le commit
chore(release): X.Y.Z, déclenche release.yml pour créer le tag et la
GitHub Release, puis retire la préversion.
La publication devient ainsi une décision sur l’état de préparation plutôt qu’une date. Un correctif rapide est livré dès que vous l’avez vérifié dans la préversion ; un changement plus important y reste jusqu’à ce qu’il soit prêt, et tout ce qui est fusionné entre-temps est livré avec lui.
Entre les publications, main est installable. Chaque fusion déclenche
Rolling Preview, qui regroupe les fragments en attente dans une seule préversion GitHub
portant le tag de la version qu’ils déterminent (voir la version actuelle et la commande d'installation) et déplace de force
ce tag vers la nouvelle tête de branche. Ce workflow ne fait que lire : aucun fragment n’est consommé, aucune version n’est incrémentée et
CHANGELOG.md reste intact. Une seule préversion est ouverte à la fois ; lorsqu’un
fragment minor est intégré, l’ancienne est donc supprimée et le nouveau nom prend sa place.
Une pull request sans fragment (portant le label skip-changelog) n’apporte aucune incrémentation.
Cochez dry run au lancement pour voir la version calculée et la section assemblée
sans créer de commit. Utilisez les paramètres bump et version pour
remplacer le niveau calculé à partir des fragments ou épingler un numéro exact.
Ne conservez pas de branche release de longue durée. Créez une branche éphémère
hotfix/vX.Y.Z à partir d’un tag existant uniquement lorsque main contient du travail
qui ne doit pas encore être publié et qu’un correctif ne peut pas attendre — une version livre un commit : un tag
créé depuis main emporte donc ce travail en attente avec le correctif.
git switch --detach v0.14.0
git switch -c hotfix/v0.14.1
# apply the fix, then record it
apm run change # Type: Fixed, Bump: patch
git push -u origin hotfix/v0.14.1
Déclenchez Release Prep avec ref défini sur hotfix/v0.14.1.
Il ne consomme que les fragments de cette branche, y incrémente apm.yml et crée le tag
depuis cette branche ; release.yml reçoit la même référence et attribue le tag au commit qu’il a
extrait. La préversion glissante n’est délibérément pas retirée, car le lot qu’elle
décrit reste en attente sur main.
Fusionnez ensuite la branche en retour pour que le correctif survive à la prochaine publication, et attribuez à cette pull
request le label release-merge-back. Ce label constitue la seule exception aux contrôles
de CHANGELOG.md et de version: dans pr-validation.yml,
et il existe précisément parce que Release Prep — et non une personne — a écrit les deux. Si une
version supérieure a déjà été publiée, le workflow de publication compare les versions et transmet
--latest=false pour que le correctif ne prenne pas le badge Latest à
la version qui le remplace.
Release Prep peut aussi être exécuté directement :
apm run release-prep # resolve version, assemble, write
pwsh -File scripts/Invoke-ReleasePrep.ps1 -DryRun # preview only
pwsh -File scripts/Invoke-ReleasePrep.ps1 -Bump minor # overrule the fragments
pwsh -File scripts/Invoke-ReleasePrep.ps1 -Version 1.0.0 # force an exact version
Avant une publication qui réépingle aussi hve-core, régénérez d’abord la liste :
pwsh -File scripts/Update-ApmDependencies.ps1 -Ref main épingle chaque entrée hve-core au
SHA du commit de main. Actualisez le fichier de verrouillage avec apm lock. Les autoréférences
de la squad ne nécessitent aucune intervention — release.yml les épingle dans le commit portant le tag.
Évitez une branche release de longue durée. Ne créez release/vX.Y.Z à partir d’un
tag existant que lorsque vous devez corriger une ancienne version après l’intégration de travaux plus récents sur
main.
Incidents connus lors des tests de chevauchement#
Pendant le développement et les tests du chevauchement des passages de relais au Scribe (mode autopilot), cinq incidents d’intégrité de la piste d’audit ont été observés et détectés. Ces incidents ont orienté la conception des barrières de vérification à chaque écriture et des contrôles correctifs. Ils sont consignés ici pour les mainteneurs qui travaillent sur l’état de la squad et les délégations au Scribe :
- Incident 3 (tour 15) : la délégation au Scribe en début d’exécution a réduit
history/Squad Scribe.mdde 48 blocs à 8 ; un simpleMeasure-SquadLedger.ps1 -Checka réussi parce que le registre avait été réécrit pour correspondre. Le contenu d’origine était irrécupérable, car.copilot-tracking/est ignoré par git. - Incident 4 (tour 18) : le Scribe a rédigé manuellement
consumption.mddans un format invalide, avec une cellule Attribution Agent vide qui a provoqué une exception dansMeasure-SquadLedger -Check; la comparaison avec l’instantané pris avant écriture par le coordinateur l’a détectée, et le fichier a été réécrit à partir de la sortie de l’utilitaire. Par ailleurs, un triple ajout de titre dans un fichier d’historique a fait l’objet d’une entrée corrective en ajout uniquement. - Incident 5 (tour 21) : le Scribe a modifié des octets existants parmi les 4 937 premiers octets de
history/System Architecture Reviewer.md.Measure-SquadLedger -Check -ExpectedHistoryCountsa réussi malgré la modification du préfixe ; seul le contrôle SHA-256 du préfixe effectué hors bande par le coordinateur l’a détectée. Les octets d’origine étaient irrécupérables, et cet incident a conduit à l’adoption de contrôles du préfixe du contenu par rapport à une référence au niveau de l’outil (-EmitBaseline/-BaselinePath). - Incident 6 (tour 23) : le Scribe a écrasé
plans/2026-09-28-scribe-pipelining-plan-amendment-2.md(de 99 355 à 8 659 octets), car sa charge utile n’énumérait pas explicitement l’ensemble des fichiers autorisés en écriture. Le rôle responsable (Squad Lead) a rédigé de nouveau le plan ; l’outil impose désormais un périmètre d’artefacts protégés par comparaison avec une référence de contenu. - Incident 7 (tour 25) : le Scribe a ajouté six lignes de titre par fichier d’historique du conseil (au lieu d’une), produit des corrections par annulation et nouvel ajout, inséré des entrées à l’intérieur de lignes de titre et inclus des valeurs coupées par des retours à la ligne. Une décision humaine a adopté des charges utiles Scribe prérendues (rédaction par le coordinateur, ajout uniquement par le Scribe) pour le reste de cette exécution.
Chaque incident a été détecté et corrigé par des entrées d’historique en ajout uniquement ou par une nouvelle délégation au rôle responsable. Les octets d’origine des incidents 3 et 5 n’ont pas pu être récupérés. Les contrôles correctifs sont désormais intégrés au contrat de vérification du chevauchement des tâches du Scribe : Measure-SquadLedger.ps1 -Check -ExpectedHistoryCounts -BaselinePath (et non un simple -Check), préservation et contrôle du préfixe du contenu au moyen d’instantanés de référence, et nouvelle délégation au rôle en cas d’échec de la vérification.