286 lines
9.9 KiB
Markdown
286 lines
9.9 KiB
Markdown
<!-- 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.
|