> ## 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.

# Servizi di programma

> Servizi che derivano lo stato dei conti dallo storico di negoziazione consolidato, fuori dal blocco, e ne riscrivono il risultato sulla catena con transazioni di protocollo.

Alcune cose che una piattaforma deve sapere su un conto non si possono calcolare mentre un blocco viene eseguito. Un livello commissionale per volume dipende da trenta giorni di operazioni. Una ricompensa dipende da una finestra che non si è ancora chiusa. Un'attribuzione di referral dipende da un rapporto nato mesi fa.

Mettere quel lavoro dentro l'esecuzione del blocco sarebbe sbagliato due volte: farebbe pagare a ogni blocco un calcolo di cui quasi nessun blocco ha bisogno, e costringerebbe il kernel a portarsi dietro uno storico che non avrebbe altra ragione di conservare.

I servizi di programma lo risolvono invertendo la direzione. Il calcolo viene eseguito **fuori** dal blocco, sul registro consolidato. Il *risultato* viene poi riscritto **sulla catena** come stato di protocollo, dove l'esecuzione può leggerlo in tempo costante come qualsiasi altra configurazione.

<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">Storico consolidato</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">Servizio di programma</span><span className="dg-s">calcolo su finestra, fuori dal blocco</span><span className="dg-n">legge la tabella dei livelli dalla catena</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">Cambiato dall'ultima volta?</span></div>
    <div className="dg-b" style={{left:"79.1667%",top:"2.8736%",width:"20.8333%",height:"13.7931%"}}><span className="dg-t">Nessuna scrittura</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">Transazione di protocollo</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">Stato della catena</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">Letto durante l'esecuzione</span><span className="dg-s">in tempo costante</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">Confronto sulle aliquote, non sui livelli</span><span className="dg-s">Una soglia che si sposta, o un livello riprezzato, cambia quanto paga un conto senza cambiarne l'indice di livello.</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 catena risolve l'aliquota finale</span><span className="dg-s">Un periodo risulta applicato solo dopo che ogni lotto è stato scritto; un crash fa il replay dell'intero periodo, sicuro perché il calcolo è idempotente.</span></div>
  </div>
</div>

La catena resta l'autorità. Un servizio non custodisce stato da cui la rete dipende: propone un valore, e reale è solo ciò che la catena ha accettato.

<h2 id="what-runs-today">
  Che cosa è in funzione oggi
</h2>

**Livelli commissionali per volume.** Il servizio consuma lo storico delle operazioni trasmesso in streaming da un nodo, accumula il volume per conto e ne salva istantanee a intervalli regolari. Alla chiusura di un periodo calcola il volume di ogni conto sulla finestra mobile, lo mappa sulla configurazione delle commissioni **letta in tempo reale dalla catena**, e riscrive a lotti i conti che sono cambiati.

In quella frase diversi dettagli sono portanti:

* **La tabella dei livelli si legge dalla catena, non si scrive fissa nel codice.** Un servizio che ne tenesse una copia propria continuerebbe ad applicare il tariffario di ieri dopo che la rete lo ha cambiato.
* **Il confronto si fa sulle aliquote, non sulla posizione nella tabella.** Confrontare gli *indici* di livello non coglie due casi reali: una soglia che si sposta e fa finire in un livello diverso un conto rimasto uguale, e un livello che viene riprezzato mantenendo lo stesso indice. Entrambi cambiano quanto paga un conto; nessuno dei due cambia l'indice.
* **È la catena a risolvere l'aliquota finale.** La transazione porta un indice di livello; l'esecuzione lo risolve sulla configurazione delle commissioni in vigore. Un indice di livello fuori dall'intervallo valido fa fallire l'intero lotto invece di applicarsi in parte.
* **Un periodo risulta applicato solo dopo che ogni lotto è stato scritto.** Un crash a metà periodo comporta il replay dell'intero periodo, operazione sicura perché il calcolo è idempotente: la stessa finestra produce lo stesso risultato.

<h2 id="the-failure-model">
  Il modello di guasto
</h2>

Questi servizi stanno fra due sistemi che ogni tanto saranno indisponibili. Il progetto lo dà per scontato invece di trattarlo come un'eccezione.

I guasti delle dipendenze — il database, lo stream del nodo, l'API del nodo — vengono riprovati con backoff. Non terminano il processo, perché un riavvio non risolve una dipendenza irraggiungibile: aggiunge solo un avvio a freddo al disservizio. Resta fatale ciò che un riavvio *può* risolvere o che un operatore deve vedere: configurazione non valida all'avvio, impossibilità di mettersi in ascolto sull'endpoint di health, e i panic.

Durante un disservizio il processo resta in esecuzione, si dichiara not-ready e conta gli errori. Il segnale operativo è quindi **«è not-ready da N minuti?»**, che è la domanda utile, e non **«il processo è vivo?»**: un processo vivo che da un'ora non riesce a ingerire dati è l'incidente vero.

L'arresto è controllato sui segnali che invia un orchestratore: il lavoro si ferma, i checkpoint vengono scritti su disco e il processo esce in modo pulito. Senza questo, ogni rilascio di routine costerebbe una finestra non salvata e un replay.

<Note>
  Un periodo calcolato ma non ancora applicato non è un periodo perso. Poiché il calcolo è idempotente e il periodo applicato viene registrato solo dopo che la scrittura è riuscita, un'esecuzione interrotta riprende rifacendo la finestra invece di saltarla.
</Note>

<h2 id="why-the-pattern-generalizes">
  Perché lo schema si generalizza
</h2>

Il percorso di riscrittura è generico. Esistono transazioni di protocollo per impostare la configurazione a livello di conto e per impostare quella globale, e un servizio di programma è qualunque processo che calcoli un valore per una delle due a partire dallo storico consolidato.

Quello dei livelli commissionali è l'unico in funzione. Programmi di incentivi, attribuzione dei referral e idoneità alle campagne avrebbero la stessa forma: un calcolo su finestra sullo storico delle operazioni, un confronto con ciò che è applicato adesso, e una riscrittura a lotti. Starebbero qui e non nel kernel per la stessa ragione dei livelli commissionali: il calcolo è periodico e storico, mentre all'esecuzione serve che la risposta sia una lettura in tempo costante. Nessuno di questi è realizzato; a generalizzarsi è lo schema, non l'impegno che lo useranno.

Le condizioni commerciali di questi programmi si trovano in [Commissioni e programmi](/it/programs/fees). Questa pagina riguarda come il risultato finisce on-chain.

<h2 id="where-to-go-next">
  Dove proseguire
</h2>

<CardGroup cols={2}>
  <Card title="Indexer" href="/it/protocol/architecture/indexer">
    Lo stream che questi servizi consumano.
  </Card>

  <Card title="Commissioni" href="/it/programs/fees">
    Il lato commerciale: quali sono i livelli e quanto costano.
  </Card>

  <Card title="IntentionKernel" href="/it/protocol/architecture/kernel">
    Come la configurazione riscritta viene letta durante l'esecuzione.
  </Card>

  <Card title="Modello di stato" href="/it/protocol/architecture/state/model">
    Perché le chiavi di configurazione sono versionate, e perché i client dovrebbero risolverle in tempo reale.
  </Card>
</CardGroup>
