8.7 KiB
Delta 0.3.14-pre.009 — health policy multi-source
Base requise
0.3.14-pre.008-fix.002
workspace.package.version = 0.3.14-pre.8.fix.2
deltas/0.3.14/pre.008-fix.002.md présent
Gate de la base
Le gate opérateur de 0.3.14-pre.008-fix.002 est validé avant ouverture de cette tranche :
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 :
139 unit tests : PASS
cross_layer_completeness : 8 PASS
dependency_boundary : 19 PASS
hardening : 33 PASS
public_api : 20 PASS
release_completeness : 10 PASS
Objectif
Implémenter strictement la tranche pre.009 du plan 035 :
projeter Healthy / Degraded / Unhealthy depuis des preuves de coverage présentes et futures
conserver Faulted comme état lifecycle terminal du Worker
ne jamais rendre Healthy sur le seul fait qu'un Transport ait reconnecté
rendre Healthy uniquement lorsque toutes les sources attendues sont Active et que les gaps sont fermés
rendre Degraded lorsqu'une source reste perdue mais que le présent est réconcilié et TargetCoverage reste couvert pour la suite
rendre Unhealthy pendant une réconciliation non prouvée, avec gap ouvert ou coverage future insuffisante
ne créer aucune health source/provider spécifique publique
Projection de health fondée sur la continuité
Le ledger de pre.008 expose maintenant une projection privée et source-neutral :
continuity_frontier
has_open_gaps
future_target_coverage
failed_source_losses_reconciled
Pour chaque source projetée Failed, failed_source_losses_reconciled exige un gap SourceFailure effectivement enregistré puis fermé par une preuve run-local. Une source simplement marquée Failed dans l'inventaire ne suffit donc jamais à autoriser Degraded.
future_target_coverage est calculé uniquement depuis les sources réellement Active et les relations Exact / Superset déjà validées par TargetCoverage.
La configuration d'une source ne constitue toujours pas une preuve historique. Le présent reste gouverné par :
aucun gap ouvert
continuity frontier == processing frontier
Les deux dimensions sont volontairement distinctes :
coverage future disponible != gap historique réparé
gap historique réparé != coverage future encore disponible
Pont Inventory -> Continuity -> Snapshot
Chaque publication agrégée de l'inventaire multi-source calcule désormais, après libération du lock Inventory :
ensemble exact des sources Active
processing frontier agrégé
projection continuity/TargetCoverage sous le lock continuity séparé
projection health privée ajoutée au message latest-value
Aucun MutexGuard n'est conservé à travers un await et aucun client Transport/Store n'est exposé dans la snapshot publique.
La source HTTP full-ledger republie sa projection après l'enregistrement d'un coverage epoch afin qu'une fermeture de gap puisse mettre à jour la health sans attendre une transaction ou un slot produit supplémentaire.
Politique Running
Lorsque la projection de continuité est disponible, la health suit la politique conservative suivante :
source Reconnecting
-> Unhealthy tant que la continuité de l'incident n'est pas explicitement réconciliée
gap ouvert
ou continuity frontier != processing frontier
ou TargetCoverage future non couverte par les sources Active
-> Unhealthy
toutes les sources attendues Active
+ aucun gap ouvert
+ continuity frontier rattrapé
+ TargetCoverage future couverte
-> Healthy
une source reste perdue/Failed
+ son gap SourceFailure a été enregistré et réconcilié
+ aucune source Reconnecting
+ aucun gap ouvert
+ continuity frontier rattrapé
+ TargetCoverage future couverte
-> Degraded
Une source perdue n'est donc jamais transformée en source optionnelle. Degraded indique uniquement que le service du run reste couvert malgré son absence ; les observations spécifiques que cette source aurait produites ne sont pas inventées.
Faulted reste un état lifecycle
ksp-worker-api::WorkerHealth reste inchangé et conserve :
Unknown
Healthy
Degraded
Unhealthy
La quatrième politique terminale du plan est représentée par :
WorkerState::Faulted(error_code)
WorkerHealth::Unhealthy
Aucune nouvelle variante WorkerHealth::Faulted ni extension de l'API générique Worker n'est introduite.
Retour à Healthy
Le retour à Healthy exige simultanément :
toutes les sources attendues projetées Active
aucune source projetée Reconnecting
aucun gap run-local ouvert
continuity frontier == processing frontier
TargetCoverage future couverte par les sources Active
Le simple passage Transport Reconnecting -> Active ne constitue pas une preuve suffisante si le continuity ledger n'est pas réconcilié.
Tests ajoutés
Les unit tests couvrent notamment :
projection health séparant future TargetCoverage et gap historique ouvert
rejet des ensembles Active dupliqués ou inconnus
pont Inventory -> continuity health avec gap puis coverage epoch de réconciliation
Reconnecting -> Unhealthy tant que la preuve de continuité manque
sources Active + gap ouvert -> Unhealthy
sources Active + gaps fermés + coverage future -> Healthy
source Failed sans gap SourceFailure réconcilié -> Unhealthy
source Failed avec gap SourceFailure réconcilié et présent/futur couverts -> Degraded
publication supervisor immédiate après réconciliation réussie de la perte de source
coverage future insuffisante -> Unhealthy
WorkerState::Faulted -> WorkerHealth::Unhealthy
Les canaris hardening et release_completeness vérifient en plus :
health fondée sur continuity frontier + gaps + TargetCoverage
aucune health provider/source-key spécifique publique
aucune variante WorkerHealth::Faulted ajoutée
aucune croissance de la surface publique TargetCoverage
Hors périmètre inchangé
aucune fairness spécifique nominal/repair de pre.010
aucune observabilité publique détaillée des gaps/repair de pre.011
aucun nouveau mécanisme de replay/reconnect Worker
aucun respawn de source
aucun EARLY/shred
aucun Job Backfill depuis Worker
aucun nouveau provider ou SDK
Fichiers ajoutés
deltas/0.3.14/pre.009.md
Fichiers modifiés
Cargo.toml
crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/snapshot.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
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/snapshot.rs
Fichiers supprimés
aucun
Version Cargo
Conformément à VER-ID-009 :
header Cargo.toml : 578 -> 579
workspace.package.version : 0.3.14-pre.8.fix.2 -> 0.3.14-pre.9
Versions des fichiers modifiés :
continuity.rs : 8 -> 9
runtime_resources.rs : 36 -> 37
snapshot.rs : 5 -> 6
unit_tests/continuity.rs : 6 -> 7
unit_tests/runtime_resources.rs : 30 -> 31
unit_tests/snapshot.rs : 5 -> 6
tests/hardening.rs : 32 -> 33
tests/release_completeness.rs : 27 -> 28
Validation exécutée dans l'environnement de préparation
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.008-fix.002 -> pre.009 : 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.010.
Décisions prises
la health est une projection de preuves run-local, pas un statut provider
le futur est prouvé par TargetCoverage sur les sources Active
le présent est prouvé par continuity frontier + absence de gap ouvert
Reconnecting reste Unhealthy tant que l'incident n'est pas réconcilié
Failed ne devient Degraded qu'après enregistrement et fermeture effective de son gap SourceFailure
une source perdue mais réellement redondante maintient Degraded, jamais Healthy
Faulted reste un WorkerState terminal avec WorkerHealth::Unhealthy