---
title: "Pipelines Kodama : CI/CD, agents et automatisation métier"
description: "Écrire des pipelines Kodama pour le CI/CD, le développement agentique, les processus avec validation humaine et les signaux métier, avec une intégration API fiable."
canonical_url: https://optimi.com/fr/docs/kodama/guide-developpeur
md_url: https://optimi.com/fr/docs/kodama/guide-developpeur.md
last_updated: 2026-10-23
---

# Pipelines et intégrations

Commencez par [le premier pipeline](/fr/docs/kodama/premiers-pas), puis adaptez
les exemples à votre projet. Un pipeline est une définition immuable ; chaque
exécution fige entrées, révision de contenu, source et configuration.

## Le contrat de pipeline

Utilisez `apiVersion: kodama/v1alpha1` et `kind: Pipeline`. Enregistrez le document
dans Kodama plutôt que de l’appliquer à Kubernetes. Les étapes forment un
graphe orienté sans cycle grâce à `needs`.

| Champ | Règle |
| --- | --- |
| `spec.inputs` | Entrées `string`, `boolean`, `integer` ou `artifact`, avec valeurs par défaut et caractère obligatoire optionnels |
| `kind` | `container`, `agent` ou `gate` |
| `image` | Image conteneur figée par empreinte |
| `workspace` | `access: none`, `read` ou `write` ; lecture/écriture sélectionnent `from: run` ou un écrivain ancêtre |
| `command`, `args`, `env` | Tableaux de commande/arguments et valeurs d’environnement explicites |
| `timeoutSeconds` | Délai positif dans les limites d’installation |
| `retry` | `maxAttempts` inclut la première tentative ; seulement les échecs infrastructure/transitoires déclarés |
| `outputs` | Sorties scalaires, artefacts ou `ociArtifact` déclarées ; fichiers sous `/kodama/outputs` |
| `when` | Une étape exécutable peut comparer une entrée du run à un scalaire ; les validations restent inconditionnelles |

Une expression occupe toute une valeur : `${{ inputs.name }}` ou
`${{ steps.test.outputs.report }}`. Les références de sortie exigent un chemin
de dépendance. Les écrivains sont totalement ordonnés. Un écrivain réussi
fournit une sortie implicite `commit`, et ses lecteurs choisissent explicitement
sa source.

Les commandes écrivent les sorties scalaires et OCI dans `/kodama/results.json` ;
le point d’entrée collecte les fichiers déclarés. Par exemple, un script
déclarant `action_required: {type: boolean}` peut écrire :

```json
{"outcome":"completed","outputs":{"action_required":true}}
```

Les exemples utilisent des images privées illustratives et des empreintes
fictives. Remplacez-les par vos images approuvées. Les scripts sous `ci/` et
`automation/` sont **des scripts applicatifs que vous fournissez** dans le dépôt
du projet, pas des commandes intégrées à Kodama. Ils doivent produire exactement
les sorties déclarées et respecter les politiques non-root, réseau et ressources.

## Exemple 1 : CI/CD classique

**Objectif :** tester un commit connu, obtenir une approbation, construire une
image vérifiée et promouvoir cette image exacte. Aucun modèle ni profil d’agent
n’est nécessaire.

Enregistrez `ci.yaml`. `ci/test.sh` lance les contrôles et écrit `tests.json` ;
`ci/build.sh` construit et publie l’image avec un builder rootless compatible,
puis écrit son descripteur OCI et sa référence figée dans le fichier résultat.

```yaml
apiVersion: kodama/v1alpha1
kind: Pipeline
metadata:
  name: ci
spec:
  inputs: {}
  steps:
    - id: test
      kind: container
      image: registry.example.com/acme/ci@sha256:1111111111111111111111111111111111111111111111111111111111111111
      workspace: {access: read, from: run}
      command: ["/bin/sh", "/workspace/ci/test.sh"]
      timeoutSeconds: 600
      outputs:
        report: {type: artifact, path: /kodama/outputs/tests.json}
    - id: review
      kind: gate
      needs: [test]
      gate:
        evidence: ["${{ steps.test.outputs.report }}"]
    - id: build
      kind: container
      needs: [review]
      image: registry.example.com/acme/builder@sha256:2222222222222222222222222222222222222222222222222222222222222222
      workspace: {access: read, from: run}
      command: ["/bin/sh", "/workspace/ci/build.sh"]
      secretFiles:
        REGISTRY_TOKEN: secret://project/registry-publisher
      timeoutSeconds: 1200
      outputs:
        image: {type: ociArtifact}
        image_ref: {type: string}
```

Le résultat du script de build suit cette forme, avec l’empreinte réellement publiée :

```json
{
  "outcome": "completed",
  "outputs": {
    "image": {
      "digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "registryRef": "registry.example.com/acme/application"
    },
    "image_ref": "registry.example.com/acme/application@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  }
}
```

L’installation doit approuver le registre et l’identifiant de publication du
projet. Kodama vérifie la provenance OCI avant d’exposer une image réussie.
La validation protège le chemin vers le build ; la retirer est un changement
explicite de politique du pipeline, pas une option de contournement du CLI.

### Promouvoir l’image vérifiée

Enregistrez séparément `promote.yaml`, puis lancez-le avec l’identifiant d’artefact
vérifié, la référence d’image et le commit candidat retournés par le CI. Cela
évite d’interpoler un objet OCI dans une chaîne shell. Configurez d’abord un
environnement de livraison et remplacez `env_staging` par son véritable ID.

L’image suivante doit contenir les scripts deployment-tools de Kodama et être
qualifiée pour le protocole apply de l’installation. Les manifests applicatifs
sous `deploy/` utilisent `@@IMAGE@@` à l’emplacement de l’image choisie.

```yaml
apiVersion: kodama/v1alpha1
kind: Pipeline
metadata:
  name: promote
spec:
  inputs:
    image_artifact_id: {type: string, required: true}
    image_ref: {type: string, required: true}
    commit: {type: string, required: true}
  steps:
    - id: deploy
      kind: container
      image: registry.example.com/acme/deployment-tools@sha256:3333333333333333333333333333333333333333333333333333333333333333
      environment: env_staging
      workspace: {access: read, from: run}
      command: ["/opt/kodama/deploy/apply.sh"]
      env:
        KODAMA_SERVER_URL: https://kodama.example.com
        DEPLOY_MANIFESTS: /workspace/deploy
        DEPLOY_REPOSITORY_URL: https://git.example.com/acme/application.git
        DEPLOY_COMMIT: ${{ inputs.commit }}
        DEPLOY_IMAGE_ARTIFACT_ID: ${{ inputs.image_artifact_id }}
        DEPLOY_IMAGE: ${{ inputs.image_ref }}
      timeoutSeconds: 600
      outputs:
        deployment_id: {type: string}
        deployment_status: {type: string}
        configuration_digest: {type: string}
        image_digest: {type: string}
        source_commit: {type: string}
        ready: {type: boolean}
        object_count: {type: integer}
```

Utilisez le même candidat pour `--source-commit` et l’entrée `commit`. Le script
apply enregistre l’identité du déploiement avant de modifier la cible. La
promotion nécessite l’action `deployment.call` et le kubeconfig limité de
l’environnement. Un résultat apply inconnu demande une réconciliation avec
cet enregistrement, pas un second déploiement inconditionnel.

## Exemple 2 : implémentation agentique et revue

**Objectif :** implémenter un travail, tester le commit produit et demander une
décision humaine sur ce candidat. Prérequis : profil `coding@1` approuvé,
paramètres modèle, outils autorisés et harness qualifié. Les instructions du
profil décrivent comment satisfaire le travail et produire le rapport de conformité.

Enregistrez `agentic-change.yaml` :

```yaml
apiVersion: kodama/v1alpha1
kind: Pipeline
metadata:
  name: agentic-change
spec:
  inputs: {}
  steps:
    - id: implement
      kind: agent
      agent: {profile: "coding@1"}
      workspace: {access: write, from: run}
      timeoutSeconds: 1800
      outputs:
        summary: {type: string}
        conformance: {type: artifact, path: /kodama/outputs/conformance.json}
    - id: test
      kind: container
      needs: [implement]
      image: registry.example.com/acme/ci@sha256:1111111111111111111111111111111111111111111111111111111111111111
      workspace: {access: read, from: implement}
      command: ["/bin/sh", "/workspace/ci/test.sh"]
      timeoutSeconds: 600
      outputs:
        report: {type: artifact, path: /kodama/outputs/tests.json}
    - id: review
      kind: gate
      needs: [test]
      gate:
        evidence:
          - ${{ steps.test.outputs.report }}
          - ${{ steps.implement.outputs.conformance }}
```

Le test utilise `from: implement` : il évalue le candidat publié par l’agent,
pas la source initiale. La validation lie candidat, exigences et preuves.
Un build ultérieur doit consommer le même candidat.

Modèles et outils sont sélectionnés dans le profil et le projet, sans embarquer
les identifiants fournisseurs. Les outils portent des noms
`<registration>/<tool>`. Si l’agent retourne `needs_input`, clarifiez la
spécification et lancez un nouveau run. Un rejet entraîne de même une reprise
avec nouvelles preuves et nouvelle validation, en conservant la décision initiale.

## Exemple 3 : processus métier avec approbation humaine

**Objectif :** valider une correction ERP, examiner la proposition et l’appliquer
une seule fois. Le dépôt contient les règles d’automatisation versionnées,
même si la demande métier est extérieure à Git. Son commit établit la référence
des règles utilisées pour le rapport et l’approbation.

`validate-correction.sh` lit la demande et écrit la proposition dans
`proposal.json`. `apply-correction.sh` revérifie la demande approuvée et écrit
un reçu. Les deux utilisent un identifiant ERP limité, fourni par fichier secret.
Le script apply doit employer l’ID stable de demande comme clé d’idempotence
ERP et vérifier que la proposition n’a pas changé depuis la revue.

Enregistrez `business-correction.yaml` :

```yaml
apiVersion: kodama/v1alpha1
kind: Pipeline
metadata:
  name: business-correction
spec:
  inputs:
    request_id: {type: string, required: true}
    request_version: {type: string, required: true}
  steps:
    - id: validate
      kind: container
      image: registry.example.com/acme/business-tools@sha256:4444444444444444444444444444444444444444444444444444444444444444
      workspace: {access: read, from: run}
      command: ["/bin/sh", "/workspace/automation/validate-correction.sh"]
      env:
        REQUEST_ID: ${{ inputs.request_id }}
        REQUEST_VERSION: ${{ inputs.request_version }}
      secretFiles:
        ERP_TOKEN: secret://project/erp-connector
      timeoutSeconds: 300
      outputs:
        proposal: {type: artifact, path: /kodama/outputs/proposal.json}
    - id: approve
      kind: gate
      needs: [validate]
      gate:
        evidence: ["${{ steps.validate.outputs.proposal }}"]
    - id: apply
      kind: container
      needs: [approve]
      image: registry.example.com/acme/business-tools@sha256:4444444444444444444444444444444444444444444444444444444444444444
      workspace: {access: read, from: run}
      command: ["/bin/sh", "/workspace/automation/apply-correction.sh"]
      env:
        REQUEST_ID: ${{ inputs.request_id }}
        REQUEST_VERSION: ${{ inputs.request_version }}
      secretFiles:
        ERP_TOKEN: secret://project/erp-connector
      timeoutSeconds: 300
      outputs:
        receipt: {type: artifact, path: /kodama/outputs/receipt.json}
```

`request_version` immuable empêche un enregistrement externe modifiable de
changer silencieusement l’action approuvée. Si l’ERP ne sait pas appliquer des
mises à jour conditionnelles/idempotentes, fournissez un registre d’actions et
une réconciliation dans votre connecteur. La clé de soumission Kodama ne
déduplique pas un effet ERP arbitraire. Aucun réessai automatique de commande
n’est déclaré pour `apply`.

## Exemple 4 : signaux métier

**Objectif :** un CRM, ERP, système analytique ou règle de supervision signale
un changement significatif, par exemple un nombre d’exceptions dépassant un
seuil, et Kodama l’évalue avec des règles versionnées. Votre adaptateur de
signaux authentifie l’émetteur, résout tenant/projet et soumet des entrées typées
à l’API publique d’exécution.

Enregistrez `assess-signal.yaml`. `assess-signal.sh` produit un rapport et un
booléen structuré `action_required` dans `/kodama/results.json` :

```yaml
apiVersion: kodama/v1alpha1
kind: Pipeline
metadata:
  name: assess-signal
spec:
  inputs:
    event_id: {type: string, required: true}
    source_system: {type: string, required: true}
    observed_count: {type: integer, required: true}
    threshold: {type: integer, default: 100}
  steps:
    - id: assess
      kind: container
      image: registry.example.com/acme/business-tools@sha256:4444444444444444444444444444444444444444444444444444444444444444
      workspace: {access: read, from: run}
      command: ["/bin/sh", "/workspace/automation/assess-signal.sh"]
      env:
        EVENT_ID: ${{ inputs.event_id }}
        SOURCE_SYSTEM: ${{ inputs.source_system }}
        OBSERVED_COUNT: ${{ inputs.observed_count }}
        THRESHOLD: ${{ inputs.threshold }}
      timeoutSeconds: 120
      outputs:
        report: {type: artifact, path: /kodama/outputs/signal.json}
        action_required: {type: boolean}
```

L’adaptateur soumet par exemple :

```json
{
  "workItemId": "wi_signal_1843",
  "definitionId": "pd_assess_signal",
  "contentRevision": 1,
  "sourceCommit": "1111111111111111111111111111111111111111",
  "inputs": {
    "event_id": "evt_1843",
    "source_system": "erp",
    "observed_count": 147,
    "threshold": 100
  }
}
```

```sh
curl --fail-with-body -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: erp:evt_1843:assess-v1' \
  --data-binary @signal-run.json \
  "$FACTORY/api/v1/tenants/$TENANT_ID/projects/$PROJECT_ID/runs"
```

Remplacez les IDs et enregistrez le JSON dans `signal-run.json`. L’adaptateur
crée ou associe le travail et son espace avant soumission, puis conserve la
correspondance avec l’événement. Une livraison répétée utilise le même principal,
la même requête et la même clé. Pour dédupliquer au-delà de la fenêtre
d’idempotence de Kodama, gardez un registre durable des événements dans l’adaptateur.

Après succès, lisez `action_required`. S’il est vrai, soumettez un pipeline de
réponse autorisé distinct, comme la correction métier, avec sa propre clé
stable et la demande identifiée. Analyse et mutation restent ainsi séparées.
Les conditions sur entrées ne permettent pas un branchement arbitraire sur la
sortie précédente ; l’adaptateur prend explicitement cette décision.

Planifiez les analyses récurrentes avec votre ordonnanceur ou un CronJob
Kubernetes appelant l’API. Authentifiez les webhooks métier dans l’adaptateur ;
le hook Git natif traite les notifications Git, pas des événements métier
génériques non authentifiés. Les destinations ChatOps sortantes peuvent
notifier les équipes et fournir un lien authentifié vers la revue.

## Enregistrer, lancer et suivre un exemple

Sélectionnez un travail existant et un espace disponible. Relevez sa
`contentRevision` et son commit accepté, puis enregistrez la définition :

```sh
kodama pipeline register --file business-correction.yaml --output json
kodama run start --work "$WORK_ID" --definition "$DEFINITION_ID" \
  --content-revision "$CONTENT_REVISION" --source-commit "$SOURCE_COMMIT" \
  --input request_id=correction-42 --input request_version=7 \
  --idempotency-key correction-42-v7 --output json
kodama run watch "$RUN_ID" --exit-on-terminal --timeout 30m
kodama run steps "$RUN_ID" --output json
kodama run logs "$RUN_ID" --step validate --tail 100
```

Utilisez les IDs retournés dans les commandes suivantes. `--input` fournit une
chaîne ; `--input-json observed_count=147` un entier et
`--input-json enabled=true` un booléen. La validation hors ligne vérifie les
définitions autonomes ; secrets, environnements et profils sont validés de
façon autoritative à l’enregistrement serveur.

`run watch` reprend avec des curseurs SSE et retourne un résultat final unique.
Son délai termine l’observation, pas le run. `run cancel` demande l’annulation ;
continuez à observer jusqu’à résolution. Les journaux identifient une tentative
et leur exhaustivité est distincte du succès. Précisez `--attempt` si une étape
comporte plusieurs tentatives.

## Examiner un sujet identifié

Lisez la validation et ses preuves avec une identité reviewer. Utilisez
exactement la version et l’empreinte examinées :

```sh
kodama gate get "$GATE_ID" --output json
kodama gate decide "$GATE_ID" --decision approve \
  --subject-digest "$SUBJECT_DIGEST" --if-version "$GATE_VERSION" \
  --idempotency-key correction-42-review-v7 \
  --reason "Proposition de correction et preuves vérifiées."
```

Une validation en attente ne consomme pas de calcul. Sa décision est immuable ;
un changement d’exigences, de code ou de déploiement peut périmer son sujet.
Relisez et examinez délibérément le nouveau sujet plutôt que d’actualiser les
versions automatiquement. Un administrateur ou ingénieur n’est pas
automatiquement reviewer.

## Intégration API fiable

Le [document OpenAPI](https://github.com/optimiware/kodama/blob/main/api/openapi.yaml)
définit requêtes et réponses publiques. Les routes projet commencent par
`/api/v1/tenants/{tenantId}/projects/{projectId}`. Utilisez jetons d’accès bearer
et JSON. Le client Go généré prend une URL de base **incluant `/api/v1`**, alors
que `--factory` du CLI prend seulement l’origine.

| Situation | Comportement attendu |
| --- | --- |
| Édition ou transition versionnée | Envoyer `If-Match: "N"` observé ; équivalent CLI : `--if-version N` |
| Réponse perdue d’une soumission avec clé | Répéter requête et clé identiques après vérification de l’autorité courante |
| `409 idempotency_conflict` | Examiner l’opération antérieure ; une autre requête ne réutilise pas sa clé |
| `412 version_conflict` / `428 version_required` | Relire l’état et effectuer une modification versionnée délibérée |
| Pagination | Conserver `nextCursor` ; 50 éléments par défaut, 200 maximum |
| Reconnexion SSE | Envoyer `Last-Event-ID` ; sur `410 cursor_expired`, reprendre depuis le curseur d’un instantané |
| `429` | Respecter `Retry-After` avec des limites de reprise bornées |
| Mutation sans clé à réponse perdue | Lire ressource et historique avant de resoumettre |

Les erreurs suivent `{error: {code, message, requestId, details}}`. Conservez
les IDs de requête avec ceux des événements/actions de votre intégration.
Exécution réussie, approbation et finalisation métier sont des résultats distincts.

Suite : **[exploiter et diagnostiquer l’installation](/fr/docs/kodama/exploitation)**.
