v0.3.6-pre.008
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md -->
|
||||
<!-- version: 13 -->
|
||||
<!-- version: 14 -->
|
||||
|
||||
# Plan v0.3.6 — Job API et premier backfill RAW
|
||||
|
||||
@@ -472,19 +472,23 @@ Le gate opérateur de `pre.006-fix.001` confirme les audits, `cargo check`, les
|
||||
|
||||
### `pre.007` — Persistance Store et idempotence
|
||||
|
||||
**Statut : matérialisé ; gate opérateur à rejouer.**
|
||||
**Statut : réalisé ; gate opérateur vert.**
|
||||
|
||||
Budget cible : **15-20 min**. Entrée : RAW v1 figé et gate `pre.006-fix.002` vert. La tranche ajoute `persist_backfill_hydration` et une projection Backfill explicite des outcomes Store sans créer de second contrat de persistance. Une acquisition disponible est consommée par l'unique capacité atomique `RawTransactionWrite::persist_raw_transaction_acquisition` via `ksp-store-lib`, toujours en `RawTransactionAcquisitionMode::Normal`; aucune prélecture Store, écriture d'observation séparée ou `ForceRehydrate` n'est introduite.
|
||||
|
||||
Le réseau du Store est comparé à l'identité `(RawNetworkId, signature)` avant toute écriture. `Missing` n'effectue aucune écriture. Les outcomes Store valides sont projetés en dispositions entité/observation distinctes : `Inserted/Inserted`, `AlreadyPresent/Inserted`, `AlreadyPresent/AlreadyPresent` et `SkippedPurged/NotRecorded`. `ERROR_CODE_RAW_CONFLICT` devient un outcome Backfill `Conflict/NotRecorded`, distinct d'un succès idempotent ; les autres erreurs Store restent des erreurs. Les combinaisons impossibles en mode normal, dont `Rehydrated`, sont rejetées par `ERROR_CODE_BACKFILL_PERSISTENCE_INVALID`.
|
||||
|
||||
La tranche matérialise 29 tests unitaires et 8 canaries d'intégration au total. Les doubles Store restent privés et déterministes ; ils couvrent insert, nouvelle observation sur entité existante, relance idempotente, purge normale, conflit, erreur Store, mismatch réseau et incohérence de référence. La frontière contiguë, la concurrence et le checkpoint restent fermés jusqu'à `pre.008`.
|
||||
La tranche matérialise 29 tests unitaires et 8 canaries d'intégration au total. Les doubles Store restent privés et déterministes ; ils couvrent insert, nouvelle observation sur entité existante, relance idempotente, purge normale, conflit, erreur Store, mismatch réseau et incohérence de référence. Le gate opérateur est intégralement vert : audits Rust/Markdown, `cargo check`, Clippy sans warning, 29 unitaires, 8 canaries et arbres Cargo passent sur `0.3.6-pre.7`. La frontière contiguë, la concurrence et le checkpoint restent fermés jusqu'à `pre.008`.
|
||||
|
||||
### `pre.008` — Concurrence, frontier et checkpoint
|
||||
|
||||
**Statut : planifié.**
|
||||
**Statut : matérialisé ; gate opérateur à rejouer.**
|
||||
|
||||
Budget cible : **15-20 min**. Entrée : résultats Store typés. Ajouter admissions bornées, réconciliation hors ordre et reprise. Sortie : frontière contiguë, trous, bornes et checkpoints des quatre scopes prouvés.
|
||||
Budget cible : **15-20 min**. Entrée : résultats Store typés et gate `pre.007` vert. La tranche ajoute `BackfillCheckpoint`, `BackfillExecutionBatch` et `execute_backfill_discovery`. Le checkpoint est opaque, caller-owned et validé contre `JobId` + fingerprint de scope ; aucune table ou persistance durable de Job n'est créée. `BackfillRequest::with_checkpoint` reste additif afin de préserver les constructeurs existants.
|
||||
|
||||
L'exécution utilise un `FuturesUnordered` privé et maintient au plus `hydration_concurrency` candidats actifs, sans `tokio::spawn`, temporisation Job, retry Job ni file non bornée. Les résultats Store durables `Inserted`, `AlreadyPresent` et `SkippedPurged` avancent une bitmap bornée de complétion ; `Missing`, conflit ou erreur laissent un trou. Un conflit ou toute erreur Transport/conversion/Store arrête immédiatement les nouvelles admissions, puis le batch draine les futures déjà admises avant de publier son checkpoint.
|
||||
|
||||
La reprise suit les quatre sémantiques figées : Latest repart de la vue courante et s'appuie sur l'idempotence Store ; Before reprend via le dernier curseur contigu et cumule le préfixe durable ; After et Explicit rejouent le scope et sautent uniquement le préfixe validé. Si une découverte After finit sur `AfterAnchorNotReached`, aucun progrès nouveau de checkpoint n'est publié ; le checkpoint précédent est conservé s'il existe. La tranche matérialise 39 tests unitaires et 9 canaries d'intégration. L'annulation coopérative, le snapshot latest-value complet et les courses terminales restent fermés jusqu'à `pre.009`.
|
||||
|
||||
### `pre.009` — Annulation et snapshots concrets
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/023-V0_3_6_JOB_API_BACKFILL.md -->
|
||||
<!-- version: 13 -->
|
||||
<!-- version: 14 -->
|
||||
|
||||
# Validation v0.3.6 — Job API et premier backfill RAW
|
||||
|
||||
@@ -113,7 +113,7 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
- [X] Nombre de candidats entre 1 et 10 000.
|
||||
- [X] Concurrence d'hydratation entre 1 et 64.
|
||||
- [X] `min_context_slot` transmis sans en changer le sens.
|
||||
- [ ] Checkpoint rejeté si son JobId ou son fingerprint de scope diffère.
|
||||
- [ ] Checkpoint rejeté si son JobId ou son fingerprint de scope diffère ; test `pre.008` matérialisé, gate opérateur à rejouer.
|
||||
- [X] Aucun défaut d'application silencieux dans la bibliothèque.
|
||||
|
||||
## 8. Pagination, ordre et déduplication
|
||||
@@ -129,13 +129,13 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
|
||||
## 9. Acquisition Transport et retry
|
||||
|
||||
- [ ] Les wrappers typés officiels restent l'unique chemin RPC.
|
||||
- [X] Les wrappers typés officiels restent l'unique chemin RPC, confirmé par audit de source jusqu'à `pre.008`.
|
||||
- [X] Retour observé additif de `getTransaction` matérialisé et gate opérateur vert.
|
||||
- [X] Canarie déterministe : un `429` sur le premier endpoint reroute et rapporte le second provider/endpoint victorieux ; gate opérateur vert.
|
||||
- [X] `HttpObservedValue<T>` ne contient que valeur typée, endpoint sûr et provider ; URL, headers et body HTTP brut restent privés.
|
||||
- [ ] Aucun retry, pacing ou sélection d'endpoint dans Job.
|
||||
- [ ] Aucune détection d'erreur par chaîne.
|
||||
- [ ] Une erreur Transport finale arrête les admissions avec un code Job sûr.
|
||||
- [X] Aucun retry, pacing ou sélection d'endpoint dans Job, confirmé par audit de source `pre.008`.
|
||||
- [X] Aucune détection d'erreur par chaîne dans la composition Backfill `pre.008`.
|
||||
- [ ] Une erreur Transport finale arrête les admissions avec un code Job sûr ; exécuteur et test `pre.008` matérialisés, gate opérateur à rejouer.
|
||||
|
||||
## 10. RAW v1 et provenance
|
||||
|
||||
@@ -161,20 +161,22 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
|
||||
## 11. Persistance Store
|
||||
|
||||
`pre.007` matérialise la composition Store normale sans élargir les responsabilités. Le chemin public consomme un `BackfillHydrationOutcome`, contrôle d'abord le réseau logique du Store, puis utilise exclusivement l'écriture atomique transaction + observation de `ksp-store-lib`. `Missing` ne déclenche aucune écriture. Un conflit de contenu Store est converti en outcome Backfill explicite afin que les tranches de frontier/snapshot puissent le compter puis le traiter comme trou/échec, sans le confondre avec l'idempotence. Les tests Rust de cette tranche sont matérialisés mais restent à exécuter dans le gate opérateur.
|
||||
`pre.007` matérialise la composition Store normale sans élargir les responsabilités. Le chemin public consomme un `BackfillHydrationOutcome`, contrôle d'abord le réseau logique du Store, puis utilise exclusivement l'écriture atomique transaction + observation de `ksp-store-lib`. `Missing` ne déclenche aucune écriture. Un conflit de contenu Store est converti en outcome Backfill explicite afin que les tranches de frontier/snapshot puissent le compter puis le traiter comme trou/échec, sans le confondre avec l'idempotence. Le gate opérateur `pre.007` est intégralement vert : audits, `cargo check`, Clippy sans warning, 29 unitaires, 8 canaries et arbres Cargo passent.
|
||||
|
||||
- [X] Dépendance unique vers `ksp-store-lib`, jamais vers backend ou API directement, confirmée par audit de manifeste/source.
|
||||
- [X] Écriture atomique transaction plus observation composée en mode `Normal` dans l'unique chemin de persistance.
|
||||
- [X] Aucune prélecture de présence avant hydratation ou persistance.
|
||||
- [ ] Entités insérée, déjà présente et purgée distinguées au gate Rust `pre.007`.
|
||||
- [ ] Observations insérée, déjà présente et non enregistrée distinguées au gate Rust `pre.007`.
|
||||
- [ ] `getTransaction = null` ne produit aucune écriture fabriquée au gate Rust `pre.007`.
|
||||
- [ ] Conflit Store reste un outcome terminal visible, distinct d'un succès idempotent, au gate Rust `pre.007`.
|
||||
- [ ] Même JobId et même endpoint donnent une relance idempotente au gate Rust `pre.007`.
|
||||
- [X] Entités insérée, déjà présente et purgée distinguées au gate Rust `pre.007`.
|
||||
- [X] Observations insérée, déjà présente et non enregistrée distinguées au gate Rust `pre.007`.
|
||||
- [X] `getTransaction = null` ne produit aucune écriture fabriquée au gate Rust `pre.007`.
|
||||
- [X] Conflit Store reste un outcome terminal visible, distinct d'un succès idempotent, au gate Rust `pre.007`.
|
||||
- [X] Même JobId et même endpoint donnent une relance idempotente au gate Rust `pre.007`.
|
||||
- [X] `ForceRehydrate` absent du chemin normal `pre.007` par audit de source.
|
||||
|
||||
## 12. Concurrence, frontière et checkpoint
|
||||
|
||||
`pre.008` matérialise un checkpoint opaque caller-owned, sans table Store ni promesse de reprise crash-safe. `BackfillRequest::with_checkpoint` valide `JobId` et fingerprint avant usage. L'exécuteur utilise une collection `FuturesUnordered` strictement bornée par `hydration_concurrency`, réconcilie les fins hors ordre par index stable et draine les futures déjà admises après la première erreur fatale. Les tests couvrent frontier contiguë, Missing, conflit, reprise Before/Latest/Explicit et protection After lorsque l'ancre n'est pas atteinte ; ils restent à exécuter dans le gate opérateur.
|
||||
|
||||
- [ ] Nombre d'hydratations en vol borné par la requête.
|
||||
- [ ] Aucune file de candidats ou notifications non bornée.
|
||||
- [ ] Résultats hors ordre réconciliés par index stable.
|
||||
@@ -202,10 +204,10 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
- [X] `ksp-job-api` dépend exactement de Core et n'a aucune feature, dev-dependency ou build-dependency.
|
||||
- [X] `ksp-job-backfill-lib` ne dépend pas de Config, App, Wallet, Program, Interface ou backend Store ; `ksp-store-lib` est consommée avec `default-features = false`.
|
||||
- [ ] Aucun retour de dépendance vers Job depuis les couches basses.
|
||||
- [X] Versions/features auditées : aucune nouvelle version externe ; `sha2` et `tokio` réutilisent les entrées workspace existantes, Tokio étant dev-only en `pre.005`.
|
||||
- [X] Versions/features auditées : aucune nouvelle version externe ; `sha2`, `futures-util` et `tokio` réutilisent les entrées workspace existantes. `futures-util` devient un détail normal privé de `pre.008`, Tokio reste dev-only.
|
||||
- [X] `pre.005` matérialise 11 tests unitaires et 6 canaries d’intégration ; le gate opérateur les exécute tous avec succès.
|
||||
- [X] `pre.006` matérialise 19 tests unitaires et 7 canaries d’intégration ; le gate opérateur les exécute tous avec succès, avec uniquement le warning Clippy corrigé par `pre.006-fix.001`.
|
||||
- [X] `cargo clippy --workspace --all-targets` warning-free sur `pre.006-fix.002`.
|
||||
- [X] `cargo clippy --workspace --all-targets` warning-free sur `pre.007` ; le gate `pre.008` reste à rejouer.
|
||||
- [ ] `cargo fmt --all -- --check` vert.
|
||||
- [X] `scripts/audit_rust_workspace_rules.py` vert sur `pre.005` dans l'environnement d'assemblage et dans le gate opérateur.
|
||||
- [X] `scripts/audit_markdown_tables.py` vert sur `pre.005` dans le gate opérateur (264 tables / 147 fichiers, delta inclus).
|
||||
@@ -217,7 +219,7 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
|
||||
## 15. Preuves d'intégration et fermeture
|
||||
|
||||
- [X] Fake Transport et fake Store déterministes sans backend direct matérialisés ; exécution du fake Store `pre.007` à confirmer au gate opérateur.
|
||||
- [X] Fake Transport et fake Store déterministes sans backend direct exécutés avec succès au gate `pre.007`; fake processor concurrent `pre.008` matérialisé, gate à rejouer.
|
||||
- [ ] Vertical découverte, hydratation, conversion, persistance et observation couvert.
|
||||
- [ ] Smoke Devnet plus PostgreSQL configuré exécuté si l'environnement explicite est disponible.
|
||||
- [ ] Aucun endpoint payant, credential ou donnée sensible requis par les tests normaux.
|
||||
|
||||
Reference in New Issue
Block a user