Public : creative ops et ingénieurs UI Android qui reçoivent des drops .9.png depuis Figma ou des pipelines texture et veulent la même acceptation binaire chaque nuit sur un Mac distant. Objectif : traiter les exports comme un mini service de CI — surveillance de dossier debouncée, jobs single-flight, contrôle des pixels de jupe (marqueurs noir pur), gabarits de nommage par densité, plafonds octets et disque, retry classés et JSONL archivables en froid. Croisez les règles géométriques avec la checklist livraison nine-patch 2026 ; croisez l’orchestration avec surveillance PNG, retry et archives de logs et contrôle qualité PNG par lot.
Sommaire
Modèle mental « daemon » et rôle d’OpenClaw
Un chien de garde fichiers n’est pas une « IA qui dessine des nine-patch » : c’est une machine à états sur le disque — événements bruyants que vous repliez en un job par lot, validateurs déterministes, promotion ou quarantine. OpenClaw orchestre des outils allowlist à arguments figés ; macOS apporte launchd, SSH et un raster Apple Silicon stable. Le cron seul rate les rafales sub-minute ; écoute debouncée + file colle aux exports réels.
Arborescence & règles de debounce
Racine de job sur NVMe, par exemple ~/nine_jobs/<CAMPAIGN_ID>/, avec inbox, work, out, failed, quarantine, logs, archive. Ne pointez jamais un watcher vers des chemins résolus iCloud. Valeurs par défaut qui survivent aux passations :
- Fenêtre de calme : après la dernière écriture qualifiée, attendre environ 30 à 45 secondes avant de déplacer un lot de
inboxverswork(à ajuster par exporteur). - Probe de taille stable : deux résultats
statidentiques espacés d’au moins 400 ms avant de parser les pixels. - Verrou single-flight : un mutex par
campaign_id; journalisercoalesced_eventsquand des sauvegardes rapides fusionnent. - Liste d’ignorés : sauter
.DS_Store,*.tmp,*~et stubs à zéro octet.
Installez et validez l’hôte via le guide d’installation OpenClaw (toutes plateformes) avant de dépendre d’appels Gateway depuis des shells non interactifs.
Étapes reproductibles (squelette exécutable)
Remplacez les segments entre chevrons par vos valeurs de campagne ; gardez les scripts sous contrôle de version à côté du manifeste de compétences OpenClaw afin que le diff raconte ce qui a tourné en production.
- Initialiser l’arborescence
export NINE_ROOT="${HOME}/nine_jobs/<CAMPAIGN_ID>" mkdir -p "${NINE_ROOT}"/{inbox,work,out,failed,quarantine,logs,archive} - Démarrer une surveillance debouncée (motif seulement — épinglez l’implémentation dans votre dépôt) :
fswatch -l 2.0 -o "${NINE_ROOT}/inbox" | while read -r _; do "${NINE_ROOT}/bin/debounced_enqueue.sh" done - Vider la file avec un worker (processus séparé pour borner concurrence Gateway/outils) :
"${NINE_ROOT}/bin/worker_once.sh" --max-files 32 --trace-id "$(uuidgen)" - Valider la jupe pour chaque candidat (votre script décode RGBA et balaie l’anneau extérieur) :
python3 "${NINE_ROOT}/bin/validate_patch_skirt.py" \ --path "${NINE_ROOT}/work/<ASSET>.9.png" \ --require-srgb-icc true \ --jsonl-out "${NINE_ROOT}/logs/validate.jsonl" - Renommer en cas de succès selon le gabarit studio (voir tableau des noms) :
mv "${NINE_ROOT}/work/<ASSET>.9.png" \ "${NINE_ROOT}/out/ui__<SLUG>__<DENSITY>.9.png" - Appendre une ligne d’audit (un objet JSON par ligne ; rotation quotidienne) :
printf '%s\n' "{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"event\":\"promote\",\"asset\":\"<SLUG>\",\"bytes\":<N>,\"trace_id\":\"<UUID>\"}" \ >> "${NINE_ROOT}/logs/audit-$(date -u +%Y-%m-%d).jsonl" - Archiver les lots promus :
tar -czf "${NINE_ROOT}/archive/$(date -u +%Y-%m-%d)_<BATCH_ID>.tar.gz" -C "${NINE_ROOT}/out" .
Pour la discipline de nommage sur d’autres classes PNG, réutilisez les champs décrits dans workflow PNG : auto-nommage et validation par lot.
Tableau des seuils d’acceptation
Contrat pass/fail entre design et build ; ajustez les chiffres par jeu ou appli, mais gardez les colonnes pour que la CI puisse diff un YAML de politique.
| Portillon | Mesure | Exemple de seuil « OK » | Si échec |
|---|---|---|---|
| Pureté jupe (anneau de contrôle) | Échantillons RGBA sur la première rangée et colonne extérieures | Marqueurs exactement #000000 opaques ; autres cellules de l’anneau alpha = 0 |
quarantine/ + classe données (pas de retry aveugle) |
| Poussière anticrénelage | Tout gris avec 0 < alpha < 255 sur l’anneau | 0 pixel fautif | Classe données ; chemin PNG dans JSONL |
| Transparence des coins | Quatre coins de l’anneau | Entièrement transparents | Classe données |
| Plafond octets par fichier | Taille disque | Exemple : mdpi ≤ 256 Kio ; xxhdpi ≤ 1,5 Mio | Quarantaine + notification |
| Volume de lot | Somme des octets du dequeue courant | Exemple : ≤ 120 Mio par lot | Pause file ; reprise opérateur |
| Eau libre disque | df sur le volume de job |
≥ 15 % libre et ≥ 25 Gio plancher absolu | Pause globale du dequeue |
| ICC / couleur | Profil embarqué | sRGB IEC61966-2.1 sauf dérogation P3 signée | Playbook ICC ou quarantaine |
Contrat de gabarit de nommage
Des noms prévisibles rendent les merges Gradle et les clés CDN ennuyeux — positivement. Standardisez des jetons analysables par machine et refusez la dérive humaine au moment de la promotion.
| Jeton | Sens | Exemple |
|---|---|---|
ui__<slug>__<density>.9.png |
Module + slug d’asset + mdpi/hdpi/xhdpi/xxhdpi | ui__hud_frame__xxhdpi.9.png |
<slug>_@<scale>x.9.png |
Style studio alternatif | hud_frame_@3x.9.png |
sha256 (sidecar) |
Ligne de manifeste par promotion | manifest.jsonl à côté de out/ |
Échecs, retry et archive des journaux
Reproduire une fiabilité de type API dans le worker :
- Transitoire : fichier occupé, lecture courte, volume SMB capricieux → backoff exponentiel avec jitter, nombre max de tentatives (par exemple cinq), chaque tentative append dans JSONL avec
next_eligible_at. - Données : pureté jupe, violation ICC, gabarit de nom incorrect → pas de retry automatique ; déplacement vers
quarantineavecreason_codeet drapeau manifeste humain avant ré-enfilage. - Opérationnel : seuil disque, environnement Python manquant, Gateway 401 → pause globale du dequeue jusqu’à
resumeaprès correctif ; journaliserpause_reason.
Champs JSONL typiques : trace_id, batch_id, asset, class, exit_code, duration_ms, stderr_tail, bytes_in, bytes_out. Rotation quotidienne de logs/*.jsonl ; gzip > 7 jours vers archive/logs/. Alignez le vocabulaire sur watchdog Lottie → PNG.
Périmètre Gateway (moindre privilège)
OpenClaw orchestre, pas un shell root : Gateway sur 127.0.0.1, jetons lisibles uniquement par l’utilisateur worker, allowlist ~/nine_jobs/<CAMPAIGN_ID>/** et scripts git épinglés. Préférez des outils déclaratifs (argv YAML) aux chaînes shell libres ; même trace_id pour chaque invocation.
Checklist opérateur
- Racine de job sur disque local rapide ; pas de sync Bureau/Documents sur le chemin surveillé.
- PID du watcher unique enregistré au boot ; pas de double
fswatch+ sync GUI sur le même arbre. - Fenêtre de calme + probe de taille active ; règle
.doneou manifeste documentée dans le README. - Validateur jupe épinglé dans
requirements.txtou lockfile ; même version sur CI et Mac distant. - YAML de seuils versionné ; alertes sur
pause_reason(mailhook, Slack, Grafana). - Rotation JSONL + tâche
gzip(cron ou LaunchAgent) installée ; drill de restauration trimestriel. - Revues d’allowlist Gateway quand les chemins de campagne changent.
FAQ
On relit déjà les nine-patch dans Figma — pourquoi automatiser l’anneau ?
La relecture humaine rate des gris d’un pixel qui décalent le padding d’un dip sur certains panneaux. Un scan aligné décodeur est rejouable à 2 h du matin et laisse une trace JSONL.
OpenClaw renvoie 401 sous launchd mais pas en shell interactif — pourquoi ?
Les sessions non interactives n’ont souvent ni les mêmes fichiers d’environnement ni les mêmes trousseaux. Reproduisez avec la même commande ssh que Jenkins, vérifiez les permissions du chemin du jeton, alignez HOME sur l’utilisateur worker.
Le watcher doit-il appeler ImageMagick pour chaque test pixel ?
Utilisez le décodeur auquel votre build Android fait confiance (souvent Pillow ou équivalent épinglé). ImageMagick convient si les versions matchent la CI ; l’important est de décoder RGBA comme les validateurs et les appareils, pas le CLI le plus court à taper.
Peut-on fusionner cette file avec des pipelines HEIC ou Lottie ?
Partagez journaux et schémas d’archive, mais gardez des racines inbox séparées pour que les règles géométriques nine-patch n’héritent pas de budgets d’octets ou de politiques de retry étrangers.
Synthèse : figer l’arbre, debouncer les exports bruyants en jobs single-flight, valider la jupe noire avec seuils machine, imposer gabarits de noms et portillons octets / disque, classifier les échecs pour des retry sains, et traiter JSONL + gzip comme boîte noire. Pour un worker Apple Silicon toujours branché plutôt que des portables qu’on empêche de dormir, parcourez sur MacPng les pages options de location et d’achat, tarifs et nœuds et le guide SSH / VNC : aucune connexion n’est obligatoire pour comparer les offres. Poursuivez depuis le blog pour d’autres automatisations PNG OpenClaw.
Exécuter la QA nine-patch sur un Mac distant dédié
Gardez l’acceptation .9.png hors portable design, épinglez les validateurs sur Apple Silicon, partagez les runbooks file + JSONL entre fuseaux.