v0.3.14-pre.008

This commit is contained in:
2026-09-12 09:00:36 +02:00
parent 9fc30d3ab9
commit 505cc8c3f6
9 changed files with 1184 additions and 127 deletions

285
deltas/0.3.14/pre.008.md Normal file
View File

@@ -0,0 +1,285 @@
<!-- file: deltas/0.3.14/pre.008.md -->
<!-- version: 1 -->
# Delta `0.3.14-pre.008` — réconciliation et supervisor source-loss
## Base requise
```text
0.3.14-pre.007-fix.001
workspace.package.version = 0.3.14-pre.7.fix.1
deltas/0.3.14/pre.007-fix.001.md présent
```
## Gate de la base
Le gate opérateur de `0.3.14-pre.007-fix.001` est validé avant ouverture de cette tranche :
```text
cargo fmt --all : PASS
cargo fmt --all -- --check : PASS
audit Rust workspace rules : PASS
audit Markdown tables : PASS
cargo check --workspace : PASS
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features : PASS
```
Le gate Worker comprend notamment :
```text
133 unit tests : PASS
cross_layer_completeness : 8 PASS
dependency_boundary : 19 PASS
hardening : 32 PASS
public_api : 20 PASS
release_completeness : 9 PASS
```
## Objectif
Implémenter strictement la tranche `pre.008` du plan `035` :
```text
unifier les preuves replay/redondance/discovery HTTP/hydration autour du ledger de continuité
maintenir un continuity frontier distinct du processing frontier
conserver les Missing known-reference comme gaps single-slot après libération du processing frontier
réconcilier les gaps uniquement depuis des coverage epochs réellement prouvés
remplacer la terminalité « first source failure » uniquement lorsqu'une TargetCoverage présente et future est explicitement prouvée
ne jamais respawn une source Transport depuis le Worker
rester fail-closed lorsque la plage de perte est non bornée ou qu'une preuve manque
```
## Continuity frontier distinct du processing frontier
Le gap ledger calcule désormais un `continuity_frontier` à partir du processing frontier courant :
```text
aucun gap ouvert <= processing frontier
-> continuity frontier = processing frontier
gap ouvert commençant à S <= processing frontier
-> continuity frontier = S - 1
gap ouvert commençant à 0
-> aucun continuity frontier
```
Le processing frontier reste donc un indicateur de traitement et ne peut jamais, à lui seul, fermer une discontinuité historique.
## Coverage epochs réellement prouvés
Le ledger `pre.005` reçoit désormais les epochs produits pendant l'exécution.
La source HTTP Block Polling full-ledger enregistre un epoch uniquement lorsqu'une fenêtre bornée de `pre.006` a été effectivement prouvée :
```text
fenêtre discovery bornée
+ tous les blocs produits de la partie prouvée effectivement matérialisés
+ aucun getBlock observed = null bloquant la fenêtre
= coverage epoch admissible
```
Un epoch adjacent ou chevauchant du même source/scope/commitment est fusionné. L'enregistrement d'un nouvel epoch déclenche immédiatement une tentative de réconciliation des gaps déjà ouverts.
Aucune source filtrée n'obtient un epoch par sa simple présence ou sa configuration.
## Missing known-reference raccordé au ledger
Le résultat `Missing` introduit en `pre.007` devient un gap de continuité single-slot :
```text
source_key exact
commitment exact
scope configuré exact de la source
range = [slot, slot]
reason = KnownReferenceMissing
```
Le pending de processing peut ensuite être soldé normalement. Le gap reste toutefois ouvert dans le ledger jusqu'à une preuve de coverage distincte.
Un epoch full-ledger d'une autre source couvrant ce slot peut donc réconcilier cette obligation sans inventer une observation de transaction et sans assimiler `getTransaction = null` à une absence prouvée.
Aucun second registre d'hydration, scheduler, semaphore ou pipeline n'est ajouté.
## Source-loss bornée et supervisor
Les tâches source supervisées retournent désormais leur `source_key` avec leur résultat terminal. Les projections source existantes restent l'autorité pour déterminer les sources réellement `Active` au moment de la décision.
Les incidents WS déjà bornés en `pre.003` transportent leurs bornes inclusives jusqu'au supervisor. Une perte classifiée et bornée est enregistrée comme gap selon le scope/commitment exacts de la source perdue.
Le supervisor peut continuer sans cette source uniquement si, après réconciliation :
```text
aucun gap connu ne reste ouvert
continuity frontier == processing frontier
chaque requirement de TargetCoverage est couvert par au moins une source encore Active
la source perdue n'est pas utilisée comme source active de remplacement
les relations de scope restent celles de pre.005 : Exact ou Superset explicitement démontré
le commitment reste strictement identique
```
Sinon, la politique précédente reste fail-closed et les sources sœurs sont arrêtées puis jointes comme auparavant.
## Pertes qui restent terminales
Cette tranche ne fabrique aucune plage lorsqu'elle n'est pas connue.
Restent donc terminales, entre autres :
```text
source transport perdue sans borne de continuité sûre
replay Yellowstone dont la coverage reste non prouvée sans range sûr
fermeture configurée sans range historique démontré
join failure / task-set invariant
content conflict
persistence failure
counter/invariant exhaustion
```
Le simple fait qu'une autre source soit configurée ou `Active` ne constitue jamais une preuve historique de l'intervalle perdu.
## Aucun respawn Worker
Le Worker ne recrée aucune source terminale. Transport conserve l'ownership de ses propres reconnect/replay mechanisms.
Après une décision `Continue`, le supervisor conserve uniquement les tâches sœurs déjà vivantes. La source perdue reste absente du run.
Les frontières historiques restent inchangées :
```text
aucun set_from_slot dans Worker
aucun SubscribeReplayInfo dans Worker
aucun socket WebSocket/gRPC créé par Worker
aucun retry loop réseau Worker
aucun accès Config
aucun Job Backfill
aucun backend Store physique
```
## Tests ajoutés
Les unit tests couvrent notamment :
```text
continuity frontier bloqué par un gap puis rétabli après coverage epoch redondant
source-loss refusée si les sources actives ne couvrent plus toute TargetCoverage
source-loss refusée tant qu'un gap reste ouvert malgré une source future-capable
source HTTP full-ledger prouvée permettant la survie d'une source filtrée perdue sans respawn
seules les pertes classifiées entrent dans la décision de coverage
Missing known-reference transféré au continuity ledger sans bloquer le processing frontier
Missing single-slot réconcilié seulement après epoch full-ledger réellement prouvé par une autre source
```
Les canaris `hardening` et `release_completeness` vérifient en plus :
```text
présence du continuity frontier privé
présence du gate TargetCoverage dans la décision source-loss
présence de record_known_reference_gap sur le chemin runtime Missing
aucune croissance de surface publique
aucun respawn source Worker
aucun ownership replay Transport déplacé vers Worker
```
## Hors périmètre inchangé
```text
aucune health policy Healthy/Degraded/Unhealthy/Faulted de pre.009
aucune fairness spécifique pendant réconciliation de pre.010
aucune observabilité publique détaillée des gaps de pre.011
aucun mécanisme EARLY/shred
aucun backfill historique caller-driven
aucune nouvelle source/provider
```
## Fichiers ajoutés
```text
deltas/0.3.14/pre.008.md
```
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/lib.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
```
## Fichiers supprimés
```text
aucun
```
## Version Cargo
Conformément à `VER-ID-009` :
```text
header Cargo.toml : 575 -> 576
workspace.package.version : 0.3.14-pre.7.fix.1 -> 0.3.14-pre.8
```
Versions des fichiers modifiés :
```text
continuity.rs : 7 -> 8
lib.rs : 31 -> 32
runtime_resources.rs : 34 -> 35
unit_tests/continuity.rs : 5 -> 6
unit_tests/runtime_resources.rs : 28 -> 29
tests/hardening.rs : 31 -> 32
tests/release_completeness.rs : 26 -> 27
```
## Validation exécutée dans l'environnement de préparation
```text
python3 scripts/audit_rust_workspace_rules.py : PASS
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas : PASS
scan des frontières Worker/Transport/Backfill/Store : PASS
scan de la crate-root historique : PASS
comparaison exacte pre.007-fix.001 -> pre.008 : PASS
```
Les gates Cargo ne sont pas déclarés PASS dans l'environnement de préparation lorsqu'ils ne peuvent pas y être exécutés. Ils restent obligatoires côté opérateur avant `pre.009`.
## Décisions prises
```text
une source active n'est pas une preuve historique de coverage
les coverage epochs doivent provenir d'une observation réellement prouvée pendant le run
le processing frontier peut avancer avec un Missing, mais le continuity frontier reste bloqué par son gap
la continuation source-loss exige à la fois réconciliation historique et TargetCoverage future par les sources encore Active
les pertes sans range sûr restent fail-closed
aucun respawn Worker
```
## Questions ouvertes
```text
aucune pour cette tranche
```
## Gate opérateur après application
```bash
cargo fmt --all
cargo fmt --all -- --check
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
```
## Prochaine tranche
`pre.009` : appliquer la health policy multi-source `Healthy / Degraded / Unhealthy / Faulted` selon coverage présente et future, avec retour à Healthy seulement après source active et gaps fermés.