Aller au contenu

Recettes Arclith CLI

Une recette CLI conserve la suite des décisions de scaffolding prises avec arclith-cli. Chaque projet créé par init ou new reçoit un fichier arclith.recipe.yaml à sa racine.

La recette répond à trois besoins :

  • relire l'ordre des commandes mutantes réussies ;
  • revoir les paramètres résolus après un wizard ou des options directes ;
  • reconstruire un projet équivalent sans rejouer des commandes shell.

Recette, Git et configuration exportée

Ces trois artefacts sont complémentaires :

Artefact Source de vérité pour Ne contient pas
Git l'historique exact du code et des modifications manuelles une intention fonctionnelle rejouable hors des commits
arclith.recipe.yaml les mutations réussies réalisées par la CLI les modifications manuelles, les échecs ou les secrets
arclith-cli export-config la configuration consolidée à déployer l'ordre de construction du projet

La recette ne remplace donc jamais Git. Elle décrit uniquement les opérations Arclith connues de la CLI.

Commandes enregistrées

La version 1 enregistre :

  • init et new ;
  • add-entity ;
  • add-blueprint ;
  • add-usecase ;
  • add-intent-interpreter ;
  • add-adapter ;
  • expose-usecase et expose-feature.

Une étape est ajoutée uniquement après le succès complet de la commande. Une confirmation refusée, une erreur de validation ou une génération échouée ne modifie pas la recette.

Les fichiers créés ou mis à jour sont détectés après la commande. Leurs chemins sont toujours relatifs à la racine du projet. Les environnements virtuels, caches, métadonnées Git et la recette elle-même ne font pas partie du résultat.

Format versionné

Le fichier est du YAML structuré, écrit atomiquement et validé au chargement. La version initiale du schéma est 1 :

YAML
version: 1
project:
  name: todo-service
  package: todo_service
created_at: "2026-09-04T10:00:00+00:00"
updated_at: "2026-09-04T10:04:00+00:00"
steps:
  - id: "0001"
    at: "2026-09-04T10:00:00+00:00"
    cli_version: "0.26.1"
    command: init
    status: success
    args:
      project_name: todo-service
      directory: .
    result:
      generated_files:
        - path: pyproject.toml
          action: created
  - id: "0002"
    at: "2026-09-04T10:04:00+00:00"
    cli_version: "0.26.1"
    command: add-entity
    status: success
    args:
      entity: Todo
      profile: minimal
    result:
      generated_files:
        - path: src/todo_service/domain/models/todo.py
          action: created

Les timestamps ISO 8601 incluent toujours leur fuseau. Les identifiants à quatre chiffres restent stables pour sélectionner une plage de replay.

Lire l'historique

Depuis la racine du projet :

Bash
arclith-cli history

Pour inspecter un autre fichier :

Bash
arclith-cli history --recipe ../service/arclith.recipe.yaml

La timeline affiche l'id, la date, la commande et un résumé sans secret.

Prévisualiser un replay

Le dry-run valide la recette et affiche les actions sans créer le dossier cible :

Bash
1
2
3
arclith-cli replay arclith.recipe.yaml \
  --dir ../todo-service-rebuilt \
  --dry-run

La valeur de --dir désigne la racine exacte du projet cible. Le nom et le package fonctionnels restent ceux de la recette, même si le dossier cible porte un autre nom.

Une plage inclusive peut être sélectionnée :

Bash
1
2
3
4
5
arclith-cli replay arclith.recipe.yaml \
  --dir ../existing-service \
  --from-step 0003 \
  --to-step 0008 \
  --dry-run

Si la plage ne contient pas init ou new, la cible doit déjà être un projet compatible. Le plan affiche chaque étape comme rejouer ou ignorer (non supportée) et compte uniquement les étapes réellement exécutables. Les secrets d'une étape ignorée ne sont pas demandés. --strict refuse au contraire toute commande que la version courante de la CLI ne sait pas rejouer.

Exécuter un replay

Retirer --dry-run pour reconstruire le projet :

Bash
arclith-cli replay arclith.recipe.yaml --dir ../todo-service-rebuilt

Le replay appelle directement les opérations Python de init, add-entity, add-blueprint, add-usecase, add-intent-interpreter, add-adapter, expose-usecase et expose-feature. Il ne construit pas une ligne de commande shell, ce qui évite les différences de quoting et garde les erreurs testables. Les anciennes étapes add-entity qui n'ont pas de profile restent compatibles et rejouent le profil minimal. Les chemins HTTP absolus tels que /v1/todos sont des contrats publics portables ; seuls les chemins absolus de fichiers sont remplacés par <external-path>.

Avant de créer la cible, le préflight valide aussi les métadonnées de chaque blueprint sélectionné. Un nom de blueprint absent ou inconnu, des paramètres mal formés ou les digests obligatoires manquants d'un blueprint paramétré produisent une erreur de recette homogène, sans traceback ni projet partiel. Un ancien new ou add-entity sans profile reste interprété comme minimal uniquement s'il ne contient aucune métadonnée de blueprint. La présence de parameters, de digests, d'une version ou d'opérations est refusée au lieu de les ignorer silencieusement.

Le profil append-only est enregistré avec la version du blueprint, l'opération append et l'empreinte du template, comme le profil CRUD. Le replay de new ou add-entity recrée un ImmutableRecord ; une étape add-blueprint append-only exige que ce record existe déjà. Les modèles et règles métier personnalisés ne sont pas stockés dans la recette : les conserver dans Git. Le manifeste conserve son schéma version 1 ; voir le contrat append-only.

Le blueprint synchronization conserve aussi l'enveloppe V1 et utilise le manifeste de feature V2 lié à une entité. Sa spec normalisée inclut les modes, politiques, limites et version source. Le replay vérifie le contrat Job/Synchronization du framework avant de créer le projet ; une release incompatible produit une erreur explicite. Les digests, collisions et personnalisations suivent le même plan de génération que les autres blueprints.

Le blueprint workflow réutilise cette enveloppe de recette V1 et le manifeste de cible V3 de Job. L'ordre des étapes, leurs budgets, les noms de contexte/résultat et definition_version restent canoniques et fingerprintés. Le replay n'exécute pas les étapes métier : il génère les fichiers manquants, préserve les personnalisations et refuse une dérive de définition/template.

Le blueprint job conserve l'enveloppe de recette V1 et versionne ses arguments de cible avec target_version: 1. Il enregistre soit entity, soit no_entity: true avec un nom de feature obligatoire. Le manifeste correspondant est V3 (target.kind: entity|standalone). Les paramètres canoniques remplacent le chemin de la spec et leurs digests sont prévalidés avant toute création de projet. Les manifests V1/V2 et les anciennes recettes restent lisibles, sans réécriture implicite.

Les étapes rejouées ne sont pas enregistrées une seconde fois. Pour une cible nouvelle, la recette sélectionnée est copiée une seule fois après le succès du replay. Pour un projet existant qui possède déjà sa recette, celle-ci n'est pas modifiée implicitement.

Secrets

Une recette ne stocke jamais de secret en clair. La CLI combine :

  • les paramètres secret du catalogue d'adapters ;
  • les mappings vers les variables d'environnement déjà déclarés par les adapters ;
  • une heuristique défensive sur password, passwd, secret, token, api_key, apikey, credential et les URI/URL avec credentials.

Une valeur sensible est remplacée par <redacted> et accompagnée d'une référence :

YAML
args:
  capability: cache
  adapter: redis
  params:
    redis_url: <redacted>
secrets:
  - field_path: args.params.redis_url
    source: env
    key: REDIS_URL
    value: <redacted>

Le dry-run liste les variables nécessaires sans lire ni afficher leur valeur. Le replay réel exige leur présence dans l'environnement :

Bash
REDIS_URL='redis://redis:6379/0' \
  arclith-cli replay arclith.recipe.yaml --dir ../service-rebuilt

Une référence de secret de configuration, par exemple adapters.mongodb.uri -> MONGODB_URI, reste informative lorsque la génération produit déjà config/secrets.yaml. Seuls les champs args.* sont injectés dans les paramètres du replay.

Les chemins absolus externes ne sont pas portables : ils sont remplacés par <external-path> et doivent être corrigés avant un replay réel.

Limites de la version 1

  • les changements manuels ne sont ni détectés comme commandes ni rejoués ;
  • les échecs et annulations ne forment pas un audit log ;
  • une version de schéma inconnue est refusée plutôt que devinée ;
  • new recharge le template depuis le repo_ref enregistré : pour des reconstructions durables, utiliser un tag ou une référence Git stable.