Limites CI OpenClaw
Utilisez cette compétence pour les modifications de capacité CI, pas pour le triage ordinaire des échecs de test. L'objectif est de maintenir OpenClaw rapide tout en distinguant l'enregistrement des runners, la disponibilité des runners, la santé du plan de contrôle Blacksmith et les vidanges de files d'attente en aval.
Faits essentiels
- L'intégralité des tests CI du niveau principal s'exécute toutes les heures ; les pushes ordinaires sur main exécutent
security-fast. Un push vert ne prouve pas que la suite complète a réussi. Les PR ordinaires diffèrent Windows, macOS Node/Swift, les builds/simulateurs iOS, l'interface utilisateur réelle de Gateway, les mises à jour de pilotes publiés, Knip et la plupart des preuves d'architecture. Les vérifications d'import-cycle et Kysely restent bloquantes. Utilisezdocs/ci/scope-and-routing/selection.mdet le manifeste actuel pour la sélection exacte des événements, propriétaires et fallbacks de version ; ne restaurez pas les voies différées lors du réglage de la capacité. Les captures d'écran Android restent réservées aux versions. - Ne présumez pas de la ressource rare. Prouvez si la pression provient des enregistrements de runners, de la disponibilité des runners éligibles, de la capacité/plan de contrôle Blacksmith, des dépendances des workflows, du temps d'exécution des tests ou d'un écrivain de file d'attente en aval.
- Les enregistrements de runners GitHub pour
openclawsignalent actuellement un quota de 10 000 par fenêtre de 5 minutes dansactions_runner_registration. Vérifiez le quota en direct avant chaque passage de réglage, car GitHub peut le modifier. L'organisationopenclawpartage un seul quota. - Le quota REST principal n'épuise pas ce quota. Vérifiez
actions_runner_registrationséparément ; le quota principal peut être sain alors que l'enregistrement des runners est limité. - Utilisez environ 60 % du quota en direct comme objectif opérationnel. Avec le quota actuel de 10 000 enregistrements, maintenez la charge de burst Blacksmith planifiée sous 6 000 enregistrements par 5 minutes et laissez le reste pour les autres dépôts, les tentatives et le chevauchement des bursts.
- Les jobs qui routent, notifient, résument, choisissent des shards ou exécutent de courtes analyses de qualité CodeQL doivent rester sur des runners hébergés par GitHub, sauf si des preuves mesurées démontrent que Blacksmith est nécessaire.
Politique de coût des runners
- Utilisez le plus petit runner qui termine la charge de travail requise de manière fiable. Gardez les jobs de contrôle courts hébergés et les preuves de développement de confiance ordinaires en local.
- Considérez les runners physiques de 8 vCPU et plus comme des exceptions, pas comme une valeur par défaut ou une tentative générique. Enregistrez la commande et le pic de mémoire mesuré, un OOM sur un runner plus petit, ou une comparaison contrôlée montrant un coût total facturé inférieur. Une faible utilisation du CPU seule ne prouve pas qu'un job à forte mémoire peut être déplacé vers un runner plus petit. Préservez les limites de workers basées sur les ressources.
- Les Testboxes OpenClaw de routine utilisent la classe 4 avec un temps de travail total par défaut de 60 minutes, y compris l'hydratation. Gardez le plafond d'inactivité à 15 minutes. Des délais plus courts sont les bienvenus pour des commandes courtes connues ; ne demandez pas quatre heures automatiquement et n'augmentez pas la taille uniquement pour obtenir plus de temps. Sélectionnez
.github/workflows/ci-check-high-memory-testbox.ymlexplicitement uniquement pour une commande nommée à forte mémoire ; voirdocs/reference/test/remote-proof.md. Ce workflow a au maximum quatre leases simultanés dans le pool partagé de 32 slots Testbox. Le profil haute mémoire utilise 8 vCPUs ; les deux profils préservent leur CPU physique et RAM d'avant novembre 3. Tous les profils Testbox limitent le temps d'inactivité à 15 minutes. - Allouez via le wrapper OpenClaw actuel avec la référence de workflow
main; la capsule source préserve le checkout testé. Ne déclenchez pas une ancienne référence de workflow pour contourner les limites de dépenses. L'âge de la file d'attente est vérifié avant le checkout ; un lease admis conserve ses délais de job et d'inactivité. - Ne promouvez pas une famille entière de workflows parce qu'une commande a besoin de plus de RAM. Gardez les lignes CI à forte mémoire prouvées limitées à leur planificateur propriétaire et à leurs preuves ; re-mesurez avant de modifier leur allocation. Un label de classe 32 ne prouve pas 32 CPUs disponibles. Comparez les ressources observées et le coût total facturé du job.
Expériences rejetées
- Checkout sparse sans UI (2026-10-16) : L'exclusion des arbres d'application mobiles/macOS natifs a supprimé 48,31 Mio de contenu logique suivi, mais ne s'est pas qualifiée comme une amélioration du coût des runners. Dans run 38866595993, le checkout UI E2E Blacksmith a pris 56s et le checkout du navigateur hébergé 58s ; les checkouts UI complets dans le même run ont pris 22 à 38s. Ce sont de petits échantillons non appariés, pas un delta de facturation mesuré. Gardez le checkout complet de la source. Reconsidérez uniquement avec un temps de checkout complet et un coût facturé inférieurs, y compris le fetch filtré, la matérialisation paresseuse et l'exportation du harness de confiance ; moins d'octets logiques seuls n'établissent pas d'économies.
- Sélection des propriétaires de fixtures de déclaration (2026-10-02) :
test/scripts/tsdown-declaration-fixture.tsdérive des copies sources réelles de ses closures de point d'entrée d'exécution, donc les PR de produit qui en modifient une ne sélectionnent pas les quatre suites de déclaration construites dessus. PR #162614 a casséwrite-unified-entry-dtsde cette façon ; la CI planifiée horaire (run 36979748808) l'a détecté environ 35 minutes après la fusion et0a188c4f038f0a réparé la fixture dans l'heure. Déclarer les propriétaires comme des littérauxnew URL(..., import.meta.url)n'atteint les suites qu'en dessous du seuil de sélection agressive du hub à 20 importateurs : le propriétaire de l'incident et sept autres sont des hubs, donc le diff rejoué de #162614 n'en a toujours sélectionné aucun. En rejouant les 92 commits principaux des 30 jours précédents qui ont touché un propriétaire via les options canoniques du planificateur de PR, les littéraux URL ont nouvellement couvert 12 (+35 lignes, +1 689 class-vCPU-minutes). La couverture complète, comme une surveillance de politique sur la même liste, sélectionne nouvellement les suites pour 81 et démarrebuild-artifacts(médiane 330s sur la classe 16 pour 12 runs de PR) pour 69, car les suites sont des propriétaires de build dansci-build-manifest.mjs: +242 lignes et +11 628 class-vCPU-minutes, une médiane de +161 (+8 %) par PR affecté. Cela achète une panne de propriétaire échappée en sept semaines, alors gardez les chemins simples ; la CI planifiée horaire, les PR de propriétaires d'outillage et la validation de version possèdent cette preuve. Reconsidérez avec un taux d'échappement sensiblement plus élevé ou une sélection qui ne démarre pas égalementbuild-artifacts. - Préparation asynchrone des entrées de frontière (2026-09-26) : L'ajout des appels existants
CompilerInputSnapshot.prepare()aux trois appelants de déclaration/frontière a augmenté la validation complète à froid de 464,21s à 544,68s sur le même Testbox 4-CPU/15,42-GiB ; la validation à chaud est passée de 12,62s à 14,63s. Les 125 vérifications de plugin et la canary ont réussi, mais l'utilisation du CPU a également augmenté. Les six ajouts d'appelants ont été supprimés. Ne répétez pas cela comme une accélération présumée ; toute utilisation différente a besoin d'un bénéfice de bout en bout mesuré. - Cache pnpm Windows (2026-09-20) : Les reçus originaux de run 35547255790 mesuraient une configuration complète médiane à 45,295s à froid contre 52,738s restaurée (+16,4 %), malgré la réutilisation des 1 453 paquets avec zéro téléchargement. L'archive de 763,8 Mio a mis 23,601–26,980s à être restaurée ; la configuration/sauvegarde du producteur a ajouté 62,527s. Les sept jobs natifs ont réussi, mais le réducteur de qualification a échoué sur une différence de RAM rapportée de 24 Kio. Aucune assertion n'a été assouplie et aucun job n'a été relancé. Le sous-ensemble exactement apparié en RAM était encore 11,3 % plus lent ; c'est une preuve descriptive, pas un remplacement qui réussit la qualification. Gardez la configuration Windows normale non mise en cache. Reconsidérez uniquement avec des économies nettes de configuration complète, y compris la restauration, l'extraction, la réconciliation figée et le travail du producteur.
- Dépendances exactes Mac hébergées (2026-09-01) : L'éditeur et le consommateur à la même tête dans run 33458856298 ont réussi à sauvegarder et restaurer une archive de dépendances de 1,66 Go, mais la configuration a pris 142s contre 86s avec le cache de store ordinaire. L'extraction a pris 82s contre 27s ; l'installation ne s'est améliorée que de 43s à 35s. Gardez les jobs Mac hébergés sur le cache de store ordinaire. Reconsidérez uniquement avec des économies de configuration totale mesurées, y compris le transfert, l'extraction et la réconciliation figée, pas un succès de cache.
- Checkout par artefact Actions (2026-08-16) : Ne recommandez pas de remplacer le fetch Git Blacksmith partagé par un espace de travail pré-produit ou un artefact
.git. PR #124818 a mesuré une référence de checkout Blacksmith à 16s contre 7s hébergé. La meilleure variante d'artefact direct a coûté 1s pour l'empaquetage, 3s pour le téléchargement et 11s médiane pour la restauration ; y compris le préfixe série, il ne restait qu'environ 1s d'amélioration médiane et a régressé les runs de fetch rapide de Blacksmith. Le client d'artefact officiel était pire : run 31971531521 a mesuré 22s de téléchargement médian plus 2s de matérialisation. Le chemin de cache rapide Actions de Blacksmith n'implique pas des téléchargements d'artefacts Actions rapides. Reconsidérez uniquement avec une preuve de bout en bout mesurée pour un transport différent, y compris son coût de production et les régressions de fetch rapide.
Premières vérifications
Avant de modifier la CI, collectez la pression actuelle :
gh api rate_limit --jq '{core:.resources.core,graphql:.resources.graphql,search:.resources.search,actions_runner_registration:.resources.actions_runner_registration}'
gh run list -R openclaw/openclaw --limit 20 --json databaseId,status,conclusion,workflowName,event,headBranch,createdAt,updatedAt,url
gh run list -R openclaw/clawsweeper --limit 20 --json databaseId,status,conclusion,workflowName,event,headBranch,createdAt,updatedAt,url
gh api repos/openclaw/clawsweeper/actions/runs/<run-id>/jobs --paginate --jq '.jobs[] | {id,name,status,conclusion,labels,created_at,started_at,completed_at,runner_name,runner_group_name}'
blacksmith testbox list --all
curl -fsS https://clawsweeper.openclaw.ai/api/status | jq '{generated_at,fleet,diagnostics:{errors:.diagnostics.errors}}'
curl -fsS https://clawsweeper.openclaw.ai/api/exact-review-queue | jq '{generated_at,review:.lanes.review,publication:.lanes.publication,state_writer,state_append}'
node scripts/ci-run-timings.mjs --latest-main
node scripts/ci-run-timings.mjs --recent 10
Pour un run suspect en file d'attente, inspectez ses jobs. Un statut queued au niveau du run ne révèle pas si le job attend des dépendances ou s'il n'a pas de runner éligible. Comparez created_at, started_at, labels et runner_name. Revérifiez les runs en file d'attente obsolètes en direct avant de les annuler ; n'annulez que les runs dont l'obsolescence est prouvée.
Le warmup de Testbox confirme la création d'un lease, pas la disponibilité du runner. Un instantané initial queued sans providerMetadata.runURL n'établit pas une pénurie de capacité. Utilisez cette URL pour inspecter le workflow exact une fois associé. Un runner check assigné effectuant la configuration est une hydratation ; une admission confirmée ou une file d'attente de capacité suit la politique existante de propriété des arrêts. Ne déduisez pas l'association du run de workflow le plus récent et n'attendez pas une file d'attente de capacité confirmée.
Le délai de démarrage de scripts/ci-run-timings.mjs peut inclure le temps d'attente des dépendances du workflow plus le temps de file d'attente du runner. C'est une preuve de tendance, pas une preuve de pression sur les runners seule.
Lisez :
.github/workflows/ci.yml.github/workflows/codeql-critical-quality.ymldocs/ci.mdtest/scripts/ci-workflow-guards.test.tstest/scripts/ci-workflow-planning.test.tstest/scripts/ci-workflow-evidence.test.ts- les fichiers de planificateur touchés sous
scripts/lib/*ci*,scripts/lib/*test-plan*, ouscripts/ci-changed-scope.mjs
Diagnostiquer le goulot d'étranglement
Classez le problème avant de modifier les plafonds :
- Limitation de l'enregistrement des runners : de nombreux jobs en file d'attente avant l'attribution du runner, Blacksmith/GitHub signale des réponses 403/429 ou 422 de type spam de la part de
generate-jitconfig, et le quota API principal est toujours sain. Traitez 422 comme ce signal uniquement lorsque la charge utile de la demande est par ailleurs valide. Corrigez le caractère bursty et le nombre de jobs Blacksmith. - Capacité Blacksmith : le tableau de bord Blacksmith montre des plafonds de concurrence réels ou une capacité indisponible. Ne résolvez pas cela avec un fanout de workflow GitHub seul.
- Plan de contrôle Blacksmith Testbox : les appels list, warm, status ou run expirent avant qu'un lease ne soit retourné. Ceci est distinct de l'enregistrement des runners Actions et de la capacité des jobs Actions. La source de confiance peut utiliser le fallback local documenté ; la source non fiable reste bloquée.
- Étiquette de runner indisponible : un job est en file d'attente avec une étiquette
runs-onpersonnalisée,started_atetrunner_namerestent vides, et aucun runner éligible n'existe. Restaurez une étiquette hébergée ou enregistrée disponible ; le fanout ne peut pas résoudre cela. - Attente de dépendance de workflow : le job est en file d'attente mais les prédécesseurs requis ne sont pas terminaux. Corrigez ou attendez la dépendance ; n'appelez pas tout le délai de file d'attente du runner pression.
- Temps d'exécution des tests OpenClaw : les jobs démarrent rapidement mais une voie domine le temps mural. Utilisez
$openclaw-test-performanceau lieu du réglage des runners. - CI qui échoue réellement : un job échoue après avoir démarré. Utilisez
$github:gh-fix-ciou$openclaw-testing, pas cette compétence. - Arriéré de revue ClawSweeper : la revue en attente/prête augmente tandis que les écrivains de publication et d'état restent sains. Réglez l'admission/les workers de revue dans
openclaw/clawsweeper. - Arriéré de publication ClawSweeper : la publication en attente/prête et l'âge le plus ancien augmentent, le drain net est nul ou négatif, ou les lettres mortes augmentent. Inspectez d'abord les lots de publication, la coordination des écrivains d'état et la latence de mutation GitHub.
- Arriéré du matérialisateur/ajout d'état :
state_append.pending_rows,pending_bytesou l'âge le plus ancien augmente tandis que le matérialisateur est en file d'attente ou absent. Récupérez ce seul drain d'abord ; plus de workers de revue aggravent la situation.
Calcul du budget d'enregistrement
Estimez le pire nombre d'enregistrements pour un changement avant de modifier :
nouvelles enregistrements Blacksmith ~= nombre de jobs Blacksmith qui peuvent être mis en file d'attente dans une fenêtre de 5 minutes
Pour les jobs matriciels, comptez chaque ligne qui peut démarrer dans la fenêtre de 5 minutes. strategy.max-parallel ne plafonne que les lignes simultanées ; les lignes courtes peuvent tourner et enregistrer plus de runners avant la réinitialisation de la fenêtre. Utilisez la durée des jobs, les tentatives et le turnover de la file d'attente pour justifier toute estimation inférieure. Ajoutez les jobs Blacksmith non matriciels tels que preflight, security-fast, build-artifacts et les voies de plateforme.
Pour répéter...