Livello di registrazione
Ambito della versione: questa pagina riformula il livello di registrazione normativo v6 su cui si basa lo standard attuale, DWP 7.0.0. Fonti canoniche alla release
v7.9.0:V6_CONTRACT.mdeV6_LIFECYCLE.md. Dove questa pagina e quei file divergono, prevalgono i file. I piani v5 mantengono il livello di stato del piano e non vengono mai migrati implicitamente.
Versione 6.0.0, estesa nella 7.0.0. Stato: Stabile. Il livello di registrazione sostituisce il completamento narrativo con dei record: il contratto è l’autorità, il journal è la memoria, gli helper si occupano della scrittura e ogni file generato è una proiezione. Le parole chiave MUST, MUST NOT, SHOULD, SHOULD NOT e MAY devono essere interpretate come descritto nella RFC 2119.
Il modello in una riga
Un piano è composto da due artefatti redatti e da una sequenza protetta. Il markdown del piano (README.md e i file delle attività) dice cosa verrà fatto. Il contratto di risultato (contract.json) dice cosa conta come completato e cosa il piano è autorizzato a fare. Il journal (journal.ndjson) registra cosa è effettivamente accaduto. state.json e views/ vengono rigenerati dal journal e NON DEVONO essere modificati a mano; quando un file generato e il journal sono in disaccordo, prevale il journal e il file viene rigenerato.
Rilevamento della generazione
Una cartella di piano è un piano della linea v6 se e solo se contiene un manifest.json il cui puntatore contract si risolve, un contract.json o una catena di revisioni contracts/. Il rilevamento DEVE usare questi artefatti, mai la versione del pack installato: un pack attuale può contenere piani v5 e un pack più vecchio può trovarsi davanti a un piano v6.
L’URL schema del contratto ne indica la generazione, e il manifest e ogni evento del journal la rispecchiano:
| Generazione | Contratto | Eventi del journal | Manifest | Aggiunge |
|---|---|---|---|---|
| v6 | plan-contract/v6 |
journal-event/v6 |
plan-manifest/v6 |
— |
| v7 | plan-contract/v7 |
journal-event/v7 |
plan-manifest/v7 |
parallel_safe e l’evento delegation (Delega) |
I nuovi piani creati dal pack 7.x sono v7 per impostazione predefinita; una richiesta esplicita di v6 materializza comunque un contratto v6. Un piano non cambia mai generazione, e un journal che mescola generazioni DEVE essere rifiutato. Entrambe le generazioni si proiettano nella stessa forma plan-snapshot/v6.
Il contratto di risultato
Un contratto per piano, conforme allo schema della sua generazione. Contiene la dichiarazione del risultato e la definizione di successo, i criteri di accettazione, le attività con i loro prerequisiti, la superficie toccata e l’intento di gate, le invarianti con ambito di piano, l’ambito (percorsi consentiti, classi di comandi, operazioni vietate), l’envelope delle risorse, i limiti di scheduling, i permessi e il record di autorizzazione.
- Identità. Il
contract_idè lo SHA-256 dei byte canonici del contratto senza il campo id. Ogni record prodotto sotto il contratto lo cita. - Immutabilità. Una volta avviata l’esecuzione, il contratto NON DEVE cambiare. Un contratto modificato è una nuova revisione sotto
contracts/, che cita la revisione madre, con numeri di revisione contigui e un’autorità registrata nuova. - Id stabili. Criteri (
AC-*), invarianti (INV-*) e attività (T-*) DEVONO essere univoci, e i record citano gli id, mai le posizioni in un elenco. Il grafo delle attività DEVE essere aciclico e ogni intento di gate DEVE fare riferimento a un criterio dichiarato. - Permessi. Le capacità concesse e non concesse DEVONO essere sottoinsiemi disgiunti di un insieme chiuso:
gate_command_exec,fs_write_plan_scope,fs_write_repo_scope,git_operations,network_access,host_adapter_metering,agent_delegation,context_export. - Autorizzazione. Il meccanismo è esattamente
plan_authorship(la persona ha redatto o revisionato il piano prima dell’esecuzione) oppurepre_authorization(una concessione permanente con un envelope dichiarato, come nella modalità trust). Entrambi funzionano in modo identico come gate; cambia solo l’autorità registrata. - Chiudibilità. Ogni criterio DEVE essere chiudibile: un criterio presidiato da un’attività viene chiuso da un’evidenza
observeddel suo gate o da un sign-off umanoasserted, secondo le classi di evidenza che accetta. Una bozza di criterio che non ne accetta nessuna viene rifiutata.
Materializzazione
Un piano viene materializzato dall’helper fornito (ledger.py materialize), mai a mano, esattamente in quest’ordine, con ogni passaggio idempotente e riprendibile:
manifest.jsoncon il puntatore al contratto, scritto per primo affinché la generazione del piano sia individuabile anche se la materializzazione viene interrotta.contract.json, validato e indirizzato per contenuto.- L’evento del journal
approval, che cita l’id del contratto e il digest del markdown del piano.
Solo quell’evento di approvazione apre il gate di avvio delle attività. Un contratto copiato a mano senza di esso viene rifiutato all’avvio dell’attività, e un manifest il cui puntatore non corrisponde al contratto in materializzazione viene rifiutato anziché riscritto.
Il journal
journal.ndjson è append-only: un oggetto JSON chiuso per riga, mai modificato o cancellato. Una correzione è un evento successivo. Ogni evento riporta il proprio schema, il tipo, un seq strettamente crescente, un timestamp, il piano, il contract_id e l’attore (helper, agent, host_adapter o human). Il catalogo degli eventi copre avvii di attività, approvazioni, esecuzioni di gate, osservazioni, adattamenti, emendamenti, interventi, campioni di risorse, coppie di controllo, selezioni dello scheduler, rifiuti, rendering delle viste, riconciliazioni e riparazioni del journal; la v7 aggiunge gli eventi di delega. Ogni rifiuto è a sua volta registrato.
Classi di evidenza
Gli eventi che portano evidenza registrano un’etichetta di fiducia:
- observed — un helper fornito ha eseguito personalmente il controllo, con directory di lavoro, ambiente, timeout e output catturato dichiarati. Solo il gate runner (
ledger.py gate) conia evidenza di gate observed; un agente che si limita a trascrivere un risultato che riferisce non può farlo. - imported — ricavata da una fonte esterna corrispondente con provenienza, per esempio un gate record v5 migrato il cui puntatore di evidenza si risolve.
- asserted — dichiarata senza una verifica indipendente.
Ogni criterio dichiara quali classi accetta, così un criterio solo observed non può mai chiudersi su una semplice affermazione. I checksum stabiliscono l’identità dei byte, non la verità semantica; il livello di registrazione verifica struttura e provenienza e non dimostra la semantica del prodotto.
Sign-off umano
Un criterio che deve essere giudicato da una persona si chiude tramite ledger.py signoff --criterion <AC> --evidence-path <artifact> --authority <who>. Il sign-off viene registrato come asserted, cita l’artefatto su cui si fonda, conta solo all’interno della finestra di evidenza dell’attività che lo dichiara e chiude solo un criterio che accetta asserted. Un agente non firma mai al posto di una persona. I record con attore umano scritti fuori dalla materializzazione portano un marcatore di autorità esplicito (una nota scritta dalla persona, registrata per percorso e digest, oppure una conferma interattiva); il ledger non può autenticare una persona, quindi il marcatore rende l’affermazione verificabile anziché observed.
Criteri controllati
Un criterio dichiarato come controllo di regressione o di discriminazione si chiude solo su una coppia di controllo discriminante: il controllo fallisce sulla revisione di partenza e passa su quella nuova. Una coppia che passa su entrambi i rami viene registrata come non discriminante e mai arrotondata per eccesso; un punto di partenza sporco o un ramo vecchio non disponibile viene registrato come controllo non disponibile, mai sintetizzato.
Esecuzione e completamento
Il dispatch proviene dallo scheduler deterministico (scheduler.py ready), e ledger.py start rifiuta un’attività i cui prerequisiti sono incompleti. Ogni avvio di attività registra un’impronta dell’albero di lavoro, e l’evidenza viene riutilizzata solo per la stessa attività e lo stesso criterio su un’impronta equivalente.
Le invarianti hanno ambito di piano. Ogni invariante dichiarata vale per l’intero piano e viene valutata a ogni confine come osservazione (INV-<id>: pass oppure INV-<id>: fail: <reason>). Una proprietà che solo alcune attività devono rispettare è un criterio di accettazione di quelle attività, mai un’invariante.
Il completamento è derivato, mai dichiarato. ledger.py complete rifiuta, e registra il rifiuto, finché un criterio manca di evidenza accettata entro la finestra o un’invariante manca di una valutazione recente superata. Lo snapshot mostra un’attività come completata esattamente quando i record lo supportano.
Adattamenti ed emendamenti
Le modifiche a esecuzione in corso sono proposte allo scheduler, limitate a un insieme chiuso: split, reorder, insert, change_strategy e retry. Un adattamento NON DEVE eliminare un requisito, indebolire o sostituire l’accettazione, ampliare ambito o permessi, spendere oltre l’envelope o segnare come completo uno scenario non eseguito.
Una modifica ad ambito, criteri di accettazione, permessi o envelope è un emendamento del contratto: ledger.py amend prepara il contratto rivisto come revisione successiva, registra l’emendamento con i criteri di cui invalida l’evidenza precedente, richiede una nuova approvazione con un marcatore di autorità umana e solo allora sostituisce il contratto attivo. Un emendamento interrotto riprende dal primo passaggio mancante; la paternità del piano non si trasferisce mai a una revisione.
Ricevute, viste ed esportazione
outcomes.py receipt ricalcola il risultato del piano a partire dai record, quindi cambia quando cambiano i record; non viene mai scritto a mano. views.py render rigenera le viste leggibili dalle persone; una vista modificata da una persona viene segnalata, mai sovrascritta in silenzio, e la riconciliazione è a sua volta registrata. Poiché .dwp/ è in gitignore, ledger.py export --dest <dir> raccoglie journal, snapshot, catena dei contratti e ogni artefatto di evidenza citato, per durabilità o per un altro host.
Superfici di sola lettura e ripresa
status e verify non scrivono mai su un piano della linea v6; riferiscono tramite comandi puri e le proiezioni generate. Un host che riprende recupera in un ordine fisso (ispezionare, validare, proiettare, eseguire il rendering con l’autorità registrata) e tratta un’impronta obsoleta come evidenza invalidata da rieseguire, mai come risultato riutilizzabile. Il journal non viene mai riprodotto come contesto di conversazione: il lavoro riprende attraverso il ciclo di execute con un manifest di contesto per attività.
Coesistenza e migrazione
I piani v5 e della linea v6 POSSONO coesistere in una stessa .dwp/plans/, e ciascuno opera sotto la propria generazione per tutta la sua vita. L’unico percorso da v5 a v6 è una migrazione esplicita e con anteprima (migrate_v6.py, eseguita tramite refine) con un backup verificato e un rollback; la cronologia v5 migrata è imported quando la sua evidenza si risolve e asserted altrimenti, mai observed. Non esiste una migrazione inversa.
Correlati
- Risorse e capacità — il manifest di contesto, l’envelope delle risorse, le capacità dell’host e il registro degli addon.
- Delega — cosa aggiunge la v7 a questo livello.
- Stato del piano — il livello di stato v5 mantenuto.