> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Services de programme

> Des services qui dérivent l’état des comptes de l’historique de trading entériné, hors du bloc, et réinscrivent le résultat sur la chaîne par des transactions de protocole.

Certaines choses qu’une plateforme doit savoir d’un compte ne peuvent pas être calculées pendant l’exécution d’un bloc. Un palier de volume dépend de trente jours de trading. Une récompense dépend d’une fenêtre qui n’est pas encore close. Une attribution de parrainage dépend d’une relation établie il y a des mois.

Placer ce travail à l’intérieur de l’exécution de bloc serait doublement faux : cela ferait payer à chaque bloc un calcul dont presque aucun bloc n’a besoin, et cela obligerait le noyau à porter un historique qu’il n’a aucune autre raison de détenir.

Les services de programme résolvent le problème en inversant le sens. Le calcul s’exécute **en dehors** du bloc, sur l’historique entériné. Son *résultat* est ensuite réinscrit **sur** la chaîne comme état de protocole, où l’exécution peut le lire en temps constant, comme n’importe quelle autre configuration.

<div className="dg" data-dg="program-writeback">
  <div className="dg-c" style={{aspectRatio:"720 / 348"}}>
    <svg className="dg-w" viewBox="0 0 720 348" aria-hidden="true">
      <path className="dg-wire" d="M 144.00 70.00 L 169.60 70.00" />

      <path className="dg-head" d="M 176.00 70.00 L 169.60 74.40 L 169.60 65.60 Z" />

      <path className="dg-wire dg--sky" d="M 344.00 70.00 L 369.60 70.00" />

      <path className="dg-head dg--sky" d="M 376.00 70.00 L 369.60 74.40 L 369.60 65.60 Z" />

      <path className="dg-wire" d="M 534.00 70.00 L 561.75 38.78" />

      <path className="dg-head" d="M 566.00 34.00 L 565.04 41.71 L 558.46 35.86 Z" />

      <path className="dg-wire dg--blue" d="M 534.00 70.00 L 561.33 95.62" />

      <path className="dg-head dg--blue" d="M 566.00 100.00 L 558.32 98.83 L 564.34 92.41 Z" />

      <path className="dg-wire dg--blue" d="M 645.00 128.00 L 645.00 136.00 L 465.00 136.00 L 465.00 142.00" />

      <path className="dg-head dg--blue" d="M 465.00 142.00 L 460.60 135.60 L 469.40 135.60 Z" />

      <path className="dg-wire dg--green" d="M 554.00 181.00 L 567.60 181.00" />

      <path className="dg-head dg--green" d="M 574.00 181.00 L 567.60 185.40 L 567.60 176.60 Z" />
    </svg>

    <div className="dg-b" style={{left:"0.0000%",top:"11.4943%",width:"19.4444%",height:"17.2414%"}}><span className="dg-t">Historique de trading entériné</span></div>
    <div className="dg-b dg--sky" style={{left:"25.0000%",top:"5.7471%",width:"22.2222%",height:"28.7356%"}}><span className="dg-t">Service de programme</span><span className="dg-s">calcul sur fenêtre, hors du bloc</span><span className="dg-n">lit la table des frais en direct</span></div>
    <div className="dg-b dg--yellow dg-round" style={{left:"52.7778%",top:"10.3448%",width:"20.8333%",height:"19.5402%"}}><span className="dg-t">Changé depuis l’application ?</span></div>
    <div className="dg-b" style={{left:"79.1667%",top:"2.8736%",width:"20.8333%",height:"13.7931%"}}><span className="dg-t">Rien n’est écrit</span></div>
    <div className="dg-b dg--blue" style={{left:"79.1667%",top:"21.8391%",width:"20.8333%",height:"13.7931%"}}><span className="dg-t">Transaction</span></div>
    <div className="dg-b dg--green" style={{left:"52.7778%",top:"41.9540%",width:"23.6111%",height:"20.1149%"}}><span className="dg-t">État de la chaîne</span></div>
    <div className="dg-b dg--green" style={{left:"80.2778%",top:"41.9540%",width:"19.7222%",height:"20.1149%"}}><span className="dg-t">Lu pendant l’exécution</span><span className="dg-s">en temps constant</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"70.1149%",width:"48.8889%",height:"24.1379%"}}><span className="dg-t">Comparaison sur les taux, pas les positions</span><span className="dg-s">Un seuil qui bouge, ou un palier retarifé, modifie ce qu’un compte paie sans modifier son index de palier.</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"51.1111%",top:"70.1149%",width:"48.8889%",height:"24.1379%"}}><span className="dg-t">La chaîne résout le taux final</span><span className="dg-s">Une période n’est réputée appliquée qu’une fois tous les lots entérinés ; un crash rejoue la période entière, sans danger puisque le calcul est idempotent.</span></div>
  </div>
</div>

La chaîne reste l’autorité. Un service ne détient pas d’état dont le réseau dépend — il propose une valeur, et seul ce que la chaîne a accepté est réel.

<h2 id="what-runs-today">
  Ce qui tourne aujourd’hui
</h2>

**Paliers de frais par volume.** Le service consomme l’historique de trading diffusé par un nœud, accumule le volume par compte et en prend un instantané à intervalles réguliers. À la clôture d’une période, il calcule le volume de chaque compte sur la fenêtre glissante, le fait passer par la configuration des frais **lue en direct sur la chaîne**, et réinscrit par lots les comptes dont la valeur a changé.

Plusieurs détails de cette phrase sont structurants :

* **La table des paliers est lue sur la chaîne, jamais codée en dur.** Un service qui garderait sa propre copie continuerait d’appliquer la grille d’hier après que le réseau l’a changée.
* **La comparaison porte sur les taux, pas sur les indices de palier.** Comparer les *indices* de palier laisse passer deux cas bien réels : un seuil qui bouge, de sorte qu’un compte inchangé se retrouve dans un autre palier, et un palier dont le tarif change alors que son indice reste le même. Les deux modifient ce qu’un compte paie ; ni l’un ni l’autre ne modifie son indice.
* **La chaîne résout le taux final.** La transaction porte un indice de palier ; l’exécution le résout à partir de la configuration des frais en vigueur. Un indice de palier hors de la plage valide fait échouer le lot entier plutôt que de s’appliquer partiellement.
* **Une période n’est enregistrée comme appliquée qu’une fois tous les lots entérinés.** Un crash en milieu de période rejoue la période entière, ce qui est sans danger puisque le calcul est idempotent — la même fenêtre produit le même résultat.

<h2 id="the-failure-model">
  Le modèle de défaillance
</h2>

Ces services se situent entre deux systèmes qui seront chacun indisponibles de temps à autre. La conception le suppose plutôt que de le traiter comme exceptionnel.

Les défaillances de dépendances — la base de données, le flux du nœud, l’API du nœud — font l’objet de nouvelles tentatives avec temporisation croissante. Elles ne mettent pas fin au processus, parce qu’un redémarrage ne répare pas une dépendance injoignable ; il ajoute simplement un démarrage à froid à la panne. Ce qui reste fatal, c’est ce qu’un redémarrage *peut* réparer ou ce qu’un opérateur doit voir : une configuration invalide au démarrage, l’impossibilité d’ouvrir l’endpoint de santé, et les panics.

Pendant une panne, le processus reste actif, se déclare non prêt et compte les erreurs. Le signal opérationnel est donc **« ce service est-il non prêt depuis N minutes »** plutôt que **« le processus est-il vivant »** — ce qui est la question utile, puisque l’incident réel, c’est un processus vivant qui n’ingère plus rien depuis une heure.

L’arrêt est gracieux sur les signaux qu’envoie un orchestrateur : le travail s’arrête, les points de reprise sont écrits, et le processus se termine proprement. Sans cela, chaque déploiement de routine coûterait une fenêtre non écrite et un rejeu.

<Note>
  Une période calculée mais pas encore appliquée n’est pas une période perdue. Comme le calcul est idempotent et que la période appliquée n’est enregistrée qu’après la réussite de l’écriture, une exécution interrompue reprend en refaisant la fenêtre plutôt qu’en la sautant.
</Note>

<h2 id="why-the-pattern-generalizes">
  Pourquoi le motif se généralise
</h2>

Le chemin de réinscription est générique. Des transactions de protocole existent pour définir la configuration au niveau d’un compte et pour définir la configuration globale, et un service de programme est n’importe quel processus qui calcule une valeur pour l’une d’elles à partir de l’historique entériné.

Les paliers de frais sont le seul service en fonctionnement. Les programmes d’incitation, l’attribution de parrainage et l’éligibilité aux campagnes auraient la même forme : un calcul sur fenêtre au-dessus de l’historique de trading, une comparaison avec ce qui est actuellement appliqué, et une réinscription par lots. Ils auraient leur place ici plutôt que dans le noyau, pour la même raison que les paliers de frais — le calcul est périodique et historique, alors que l’exécution a besoin que la réponse soit une consultation en temps constant. Aucun n’est construit ; ce qui se généralise, c’est le motif, pas l’engagement qu’ils l’utiliseront.

Les conditions commerciales de ces programmes se trouvent dans [Frais et programmes](/fr/programs/fees). Cette page porte sur la façon dont le résultat arrive sur la chaîne.

<h2 id="where-to-go-next">
  Pour aller plus loin
</h2>

<CardGroup cols={2}>
  <Card title="Indexeur" href="/fr/protocol/architecture/indexer">
    Le flux que ces services consomment.
  </Card>

  <Card title="Frais" href="/fr/programs/fees">
    Le versant commercial : quels sont les paliers et ce qu’ils coûtent.
  </Card>

  <Card title="IntentionKernel" href="/fr/protocol/architecture/kernel">
    Comment la configuration réinscrite est lue pendant l’exécution.
  </Card>

  <Card title="Modèle d’état" href="/fr/protocol/architecture/state/model">
    Pourquoi les clés de configuration sont versionnées, et pourquoi les clients devraient les résoudre en direct.
  </Card>
</CardGroup>
