Les Routines Claude ne sont pas un Cron de raisonnement. Elles sont un sous-ensemble centré sur les dépôts.
Une semaine après qu'Anthropic ait livré Routines, trois de mes tâches cron tournent en production. Ça m'a pris trente minutes.
L'auto-review de PR qui interrogeait GitHub toutes les demi-heures ? Morte. Le script hebdomadaire de dérive de doc qui parsait les commits en bash pourri ? Mort. Le refresh de données SEO que je repoussais depuis six mois (pas le temps, vous voyez le truc) ? En ligne en cinq minutes.
Trois jobs, trente minutes, zéro friction. Convaincu. Le soir même, je me suis attaqué au quatrième.
Et là, rien. Pas d'erreur, pas de quota, pas de YAML malformé. Le job tourne, le binaire répond, mais le service qu'il interroge vit sur une IP que Routines ne voit pas et ne verra jamais, par construction. Les quarante-sept autres jobs sur mon serveur sont dans le même cas. Pas un ne passe. Et ce n'est pas un problème à corriger (c'est mécanique).
Depuis que Routines est sorti, j'ai surtout vu des démos. Tout le monde montre les trois jobs qui marchent. Personne ne nomme la frontière. Ce qui suit, c'est comment brancher ça dans une infra de prod, y compris les parties où Routines s'arrête et où vous prenez le relais.
TLDR. Routines n'est pas un cron raisonnant universel. C'est un cron raisonnant avec un périmètre, et la plupart de l'automatisation vit hors de ce périmètre pour des raisons qu'aucune config ne peut contourner. La question n'est pas de savoir si Routines est bon. C'est de savoir où ça s'arrête, ce qui tourne à la place, et comment maintenir la moitié DIY en vie sans se reconnecter tous les matins.
Les trois jobs que j'ai migrés fonctionnent mieux dans le cloud d'Anthropic que sur mon serveur. La review de PR se déclenche sur pull_request.opened au lieu de poller. Le script de dérive de doc a maintenant le contexte complet du repo, la sortie est passée de parcourable à utile. Le refresh SEO tourne juste, tous les matins, sans taxe de setup. Cette partie est réglée.
L'article parle de tout le reste. Les quarante-sept jobs que j'ai essayé de migrer ensuite, pourquoi pas un ne marche, et le pattern DIY qui survit en 2026 une fois qu'on accepte de quel côté de la ligne se trouve son job.

Ce Que "Cron Raisonnant" Veut Vraiment Dire
Laissez-moi nommer ce dont on parle.
Un cron raisonnant est un planificateur qui appelle un LLM pour réfléchir, pas juste pour exécuter du code déterministe. Il lit du contexte, prend des décisions, génère une sortie qui dépend de ce qu'il vient de voir. n8n et Make et Zapier routent des données (ils ne réfléchissent pas). Un cron Python est rigide, il casse quand le format d'entrée change. Un cron raisonnant s'adapte.
Voilà la catégorie. Routines en fait partie. Mon pattern DIY aussi. Tout wrapper autour de claude -p ou gpt ou gemini aussi. La catégorie est réelle, la demande est réelle, et qu'Anthropic livre un produit managé pour ça, c'est le bon move.
Ce qui induit en erreur, c'est d'appeler Routines le cron raisonnant. C'est un cron raisonnant avec un périmètre fixe.
Le périmètre a trois murs. Un, Routines tourne dans le cloud d'Anthropic, pas sur votre machine. Il clone un repo Git au début de chaque run et c'est tout le système de fichiers qu'il voit. Deux, il parle au monde extérieur via des connecteurs managés (Slack, Linear, Jira, GitHub, GDrive) et une allowlist HTTP (par défaut Trusted, qui bloque la plupart des APIs externes). Trois, il repart de zéro à chaque run. Pas d'état, pas de cookies, pas de session persistante.
Le guide pratique de Nimbalyst est arrivé à la même ligne indépendamment : utilisez Routines quand le travail est centré sur le repo, tourne selon un planning, et n'a pas besoin de votre environnement local. Même périmètre, mots différents.
Une fois qu'on a ces trois murs en tête, ce qui suit n'est pas une opinion. C'est une conséquence.
Où Routines Gagne (Trois Jobs Que Je Ne Retouche Plus)
Concession d'abord, parce que l'honnêteté va plus vite que la rhétorique.
Ces trois jobs sont meilleurs dans Routines qu'ils ne l'étaient dans mon cron. Je ne les remigre pas.
Auto-review de PR. Avant : un cron Python qui pollait GitHub toutes les trente minutes, lançait une review claude -p sur toute nouvelle PR, postait un commentaire via l'API. Le cron de polling traînait derrière chaque push. Après : une Routine déclenchée sur pull_request.opened, tourne à l'instant où une PR s'ouvre, poste via le connecteur GitHub. Même prompt, même qualité de sortie. Moins de YAML, pas de gaspillage de polling.
Dérive de doc hebdomadaire. Avant : un script bash qui listait les commits depuis lundi dernier, les diffait contre le dossier docs, nourrissait les deux dans claude -p, m'envoyait un résumé par email. Le résumé était toujours légèrement à côté parce que le script ne portait pas le contexte repo-wide. Le modèle ne voyait que ce que bash sed-pipait dedans. Après : une Routine qui récupère le repo complet cloné, lit CLAUDE.md, le dossier docs, et le log de commit nativement, et écrit un doc "ce qui a changé, ce qui est périmé" qui reflète vraiment la codebase. La sortie est passée de parcourable à utile.
Refresh de données SEO. Pas d'Avant. Je voulais mettre en place un pull hebdomadaire depuis mon fournisseur d'analytics, passer un modèle sur les deltas, et poster un résumé sur Slack. Chaque fois que je m'asseyais pour le câbler, autre chose arrivait et le YAML n'était jamais écrit. Après : une Routine, quinze minutes de setup, tourne tous les matins. Le job que je n'avais jamais construit en six mois existe maintenant. C'est le cas le plus fort pour un produit managé (le travail qu'on n'arriverait jamais à faire soi-même).
Ces trois partagent quatre traits. Centrés sur le repo. La sortie va vers Slack ou GitHub. La fréquence est d'au moins une heure. Rien dans la chaîne ne touche mon réseau local.
C'est exactement le périmètre de Routines. Mes quarante-sept autres jobs ratent au moins un de ces quatre. Pas un sur quarante-sept ne touche les quatre.
Six Raisons Pour Lesquelles Routines Ne Peut Pas Remplacer Mes Jobs Cron
Six raisons mécaniques. Pas des préférences, pas des cas limites. Chacune ferme la porte avant qu'on finisse de taper le YAML.
1. Serveurs MCP locaux. Routines utilise les connecteurs managés d'Anthropic. C'est tout. Le serveur MCP que j'ai écrit moi-même, celui qui vit sur ma machine et expose mes propres données à mes sessions Claude Code, n'est pas disponible. Routines ne peut pas le voir, ne peut pas lui parler, ne peut pas s'authentifier dessus. Tout workflow où le modèle doit interroger quelque chose que j'ai construit localement est exclu.
2. Services sur IPs privées. Mesh Tailscale. NAS à la maison. Postgres sur le serveur. Dashboards de monitoring internes. Tout ce qui traîne sur une adresse 100.x ou un LAN 192.168. Routines tourne dans le cloud d'Anthropic. Il ne sait pas que mon mesh existe. Le quatrième job de l'ouverture vit là, et dix-neuf autres sur ma liste aussi.
3. Fréquence sub-horaire. L'intervalle minimum de Routines est d'une heure. Mon poller de statut tourne toutes les quinze minutes parce que c'est ce que la fenêtre d'alerte requiert. Tout job qui doit se déclencher plus vite qu'une fois par heure, mécaniquement, ne peut pas bouger.
4. Quota quotidien. Pro c'est 5 runs par jour. Max c'est 15. Team c'est 25. J'ai quarante-sept jobs qui doivent tourner la nuit, plus les quotidiens, plus ceux sub-horaires. Même si toutes les autres contraintes disparaissaient, je toucherais le quota avant minuit sur un plan Max. Le quota n'est pas une limite souple qu'on peut négocier (c'est le contrat).
5. Session navigateur persistante. Routines lance un environnement propre à chaque run. Pas de cookies, pas de localStorage, pas de report de session. Si votre job doit se logger sur un site une fois et réutiliser la session, automation Playwright contre un service qui requiert une auth, vous ne pouvez pas. Nate Herk l'a documenté sur Skool quand il a essayé de faire tourner une automation communautaire dans Routines. Le login meurt entre les runs. Le job est structurellement impossible.
6. État persistant local. Un job qui écrit dans un SQLite local entre les runs, ou maintient une queue basée sur fichier, ou ajoute à un log long-lived. Routines repart frais à chaque fois. Tout ce que votre job a écrit au run précédent a disparu. Vous pouvez utiliser les sorties des connecteurs comme état (tickets Linear, issues GitHub), mais si votre état vit sur le disque où vit le cron, ce n'est pas portable.
Un commentaire communautaire sous le post de lancement d'Anthropic sur Threads l'a dit brutalement : encore des features centrées sur github. C'est la lecture de l'extérieur, et c'est juste, mais c'est aussi incomplet. Routines n'est pas que GitHub, les connecteurs font plus que ça. Le cadrage honnête est : Routines est centré sur le repo et centré sur les connecteurs managés, et si votre travail se passe hors de ce périmètre, l'outil n'a rien à vous offrir.
Six cas. Pas six opinions.
Le Pattern DIY Qui Survit en 2026
Si votre job vit hors du périmètre Routines, vous le construisez vous-même. Ce qui suit est le pattern qui survit, les parties que personne ne documente dans la douzaine de tutoriels "Routines vient de sortir" qui saturent le feed la semaine dernière.
Utilisez la redirection shell, pas spawn-with-stdin.
claude -p "Summarize the input as JSON" < input.txt
echo "$LARGE_INPUT" | claude -p "Summarize"
Le deadlock de pipe est le tueur silencieux. Pas d'erreur, pas de timeout, juste un processus qui pend sur un stdin bufferisé qui ne se ferme jamais. J'ai perdu un weekend là-dessus avant de tracer. La redirection shell depuis un fichier est la seule façon fiable de nourrir un gros input au binaire en mode non-interactif.
Désactivez ANTHROPIC_API_KEY dans votre environnement cron.
unset ANTHROPIC_API_KEY
claude -p "..."
Si ANTHROPIC_API_KEY est définie quand vous appelez claude -p, le binaire l'utilise et facture votre compte API. Silencieusement. La précédence d'auth est documentée mais facile à rater. Vous pensez tourner sur votre abonnement, et en fait chaque run cron passe par le pay-per-token. Désactivez-la explicitement. Votre portefeuille vous remerciera.
Contraignez la sortie JSON via le prompt, pas le flag.
Ne faites pas confiance à --output-format json pour faire le gros du travail. Dites au modèle quel schéma vous voulez, dans le prompt, puis validez en aval :
claude -p 'Respond ONLY with valid JSON matching: {"status": "ok|fail", "items": [...]}. No prose, no fences.' < input.txt | jq -e .status
Si jq -e échoue, retry une fois. Si le retry échoue, alertez. Le contrat au niveau prompt tient mieux que le flag dans mon expérience, et vous obtenez des modes de failure propres quand le modèle dérive.
C'est aussi pourquoi le pattern DIY ne disparaît pas quand MCP devient plus riche. Le binaire CLI reste prévisible, déterministe au niveau shell, et il compose avec tout le reste que vous avez. J'ai fait l'argument plus long pour les CLIs plutôt que MCP dans les stacks d'agents il y a quelques semaines, et Routines ne change pas la conclusion. Les CLIs composent. Les planificateurs managés ne le font pas, par design.
Générez un token OAuth long-lived avec claude setup-token.
C'est la partie qui manque dans tous les tutoriels cron-avec-Claude que j'ai lus.
Le repo GitHub claude-code est plein de la même plainte. Les tokens OAuth expirent en 8 à 24 heures en mode --print, le refresh échoue silencieusement, l'automation meurt. Le post de la communauté DEV "Building Claudio: My Always-On Claude Code Box" traverse exactement cette douleur. V1 a duré deux semaines avant que les tokens expirent. V2 a abandonné cron entièrement et a pivoté vers un outil desktop.
Il y a une commande built-in qui résout ça. Lancez-la une fois, interactivement, sur la machine où vous vous êtes originellement loggé :
claude setup-token
Elle génère un token OAuth long-lived (un an, scope inference seulement) conçu pour CI et scripts non-attendus. Vous le mettez dans CLAUDE_CODE_OAUTH_TOKEN. Le binaire le respecte, pas de danse de refresh, pas de re-login quotidien.
Je ne colle pas le token dans mon environnement cron. Je le stocke dans un gestionnaire de secrets (j'utilise Infisical, Vault et Doppler et AWS Secrets Manager font tous le même job), et le cron le tire au run time via une identité machine scopée à ce seul serveur :
#!/usr/bin/env bash
set -euo pipefail
TOKEN=$(infisical secrets get CLAUDE_CODE_OAUTH_TOKEN --plain)
export CLAUDE_CODE_OAUTH_TOKEN="$TOKEN"
unset ANTHROPIC_API_KEY
claude -p "$(cat prompt.txt)" < input.json | jq -e . > output.json
unset CLAUDE_CODE_OAUTH_TOKEN
Le token reste en mémoire pour la durée du run, puis disparaît. Si le serveur est compromis, je révoque l'identité machine et je rotate celle-là. Le token OAuth Claude lui-même n'a pas à bouger. C'est ce qui maintient une stack cron DIY qui tourne sans re-logins quotidiens ou breakage silencieux.
Un Mot Rapide sur les Conditions d'Utilisation
Anthropic a clarifié la politique en février 2026 : utiliser le CLI Claude Code sur votre propre machine, daemon, job cron, tout va bien. Le CLI sur votre propre machine, appelant le binaire officiel, c'est bon.
Ce qui a été coupé en avril 2026 était différent. Les outils tiers qui spoofaient le client Claude Code et utilisaient l'auth d'abonnement pour alimenter des produits externes ont vu leur accès révoqué. J'ai vécu ça et reconstruit mon setup la semaine d'après. Le pattern DIY de cet article ne se trouve pas du mauvais côté de cette ligne. C'est le binaire officiel, sur ma machine, faisant ce pour quoi le binaire est conçu.
Routines est un aperçu de recherche. La lecture actuelle des ToS pourrait changer, les quotas pourraient changer, la liste des connecteurs pourrait changer. Vérifiez les docs tous les deux mois si vous construisez quelque chose qui en dépend. Ça s'applique à mon pattern aussi. Cron local avec le binaire officiel a été autorisé pendant deux ans et la position a été réaffirmée il y a trois mois, mais "actuellement autorisé" n'est pas "permanent."
Trois Questions Qui Décident Où Va Votre Job
Trois questions binaires. Réponses honnêtes. La décision en découle.
1. Le job vit-il dans un repo Git que vous poussez sur GitHub ?
Pas "pourrait-il." Le fait-il, aujourd'hui, naturellement. Si non : DIY.
2. A-t-il besoin de quelque chose hors des connecteurs d'Anthropic ?
Un MCP local, une IP privée, une base de données personnelle, une session navigateur persistante, votre propre état filesystem entre les runs. Si oui : DIY.
3. Tourne-t-il plus d'une fois par heure, ou plus que votre quota quotidien ?
Polls sub-horaires, dizaines de jobs nocturnes, tout ce qui dépasse le plafond du plan. Si oui : DIY.
Trois non : Routines, sans hésitation, sans culpabilité. Il fera tourner ce job mieux que votre cron DIY, et vous économiserez la maintenance.
Un oui : restez local. Utilisez le pattern DIY. La moitié DIY ne disparaît pas.
En fait, non, laissez-moi le dire différemment. Routines n'est pas Make, Zapier, ou n8n (ce ne sont pas le même outil). Routines est un planificateur avec un périmètre. Un repo Git, les connecteurs d'Anthropic, un minimum d'une heure entre les runs. Ce qui vit hors de ce périmètre n'est pas du Routines raté 😅
Les devs qui livrent connaissent la différence. On ne met pas un poll de quinze minutes dans un planificateur avec un minimum d'une heure. On ne met pas un job qui parle à votre mesh privé dans un cloud qui ne voit pas votre mesh privé. On ne met pas un job stateful dans un environnement clean-slate. Ce n'est pas du goût. C'est de l'arithmétique.
Adaptez l'outil au job. Routines est excellent dans son périmètre. Utile, mais pas la réponse ultime.
Sources
- Anthropic, Introducing routines in Claude Code
- Claude Code docs, Automate work with routines
- Claude Code docs, Authentication
- claude-code GitHub, issue #28827, OAuth token refresh fails in non-interactive mode
- autonomee.ai, Claude Code Terms of Service Explained
- Building Claudio, My Always-On Claude Code Box