7.7 KiB
Delta 0.3.6-pre.003 — notifications Job latest-value génériques
Base requise
0.3.6-pre.002-fix.001
workspace.package.version = 0.3.6-pre.2.fix.1
SHA-256 archive = 0b6640155786b92e27508637af2bcc7a0a34e5e8e4185d76ac4dd6d71aa7a869
Le gate opérateur fourni pour cette base confirme cargo fmt, audits Rust/Markdown, cargo check --workspace, Clippy, les dix tests unitaires et onze canaries ksp-job-api, les suites individuelles, cargo test --workspace, les arbres Cargo Job API et l'examen des doublons.
Objectif
Matérialiser la tranche pre.003 du plan 027 : observation Job latest-value runtime-neutral avec séquence monotone, snapshot complet courant, attente abstraite d'une valeur plus récente et resynchronisation multi-listeners, sans ouvrir encore ksp-job-backfill-lib ni imposer Tokio à l'API.
Audit des archives et des règles
Les deux archives fournies ont été testées avant modification :
KSP 0.3.6-pre.002-fix.001
SHA-256 = 0b6640155786b92e27508637af2bcc7a0a34e5e8e4185d76ac4dd6d71aa7a869
1541 entrées / aucune duplication / aucune traversée / aucun chemin absolu / aucun lien symbolique ZIP
unzip -t = propre
kbot3 v0.5.3-pre.005-fix010
SHA-256 = ee47643b9f8b582ee8db97b2381ec107e45aef8c009fee44757531514615d318
2501 entrées / aucune duplication / aucune traversée / aucun chemin absolu / aucun lien symbolique ZIP
unzip -t = propre
La base KSP ne contient ni Cargo.lock, ni .env, ni target, ni node_modules, ni secret ou artefact de build détecté par l'inventaire statique. L'archive kbot3 reste une référence historique et contient notamment un scripts/__pycache__; ce contenu n'est ni copié ni livré.
Les autorités relues incluent RULES.md, docs/000-README.md, les règles sous docs/rules/, les architectures Layers/Dependencies, Component Contracts, Dependency Graph et Acquisition/Workers/Jobs, le prompt 025, le plan 027, la validation 023 et les deltas pre.001 à pre.002-fix.001.
Pour cette tranche, kbot3 confirme uniquement le besoin fonctionnel historique : BackfillObserver::on_progress appelait directement le consumer applicatif et exposait timestamp, niveau, message libre et compteurs optionnels. KSP conserve l'observabilité mais rejette cette forme callback/producteur ; aucun code, DTO, ID, message ou runtime kbot3 n'est repris.
Surface ajoutée
JobNotificationSequence :
- position initiale contrôlée par l'API ;
- progression unitaire par
checked_add; - ordre total et test
is_after; - erreur stable
job_api.job_notification_sequence_exhaustedavant tout wrap.
JobNotification<S> :
JobId,JobKindCode, séquence,JobStateet snapshot complet ;- champs privés et valeur immutable ;
Debugstructurel qui masque toujours le snapshot générique.
JobSnapshotFuture<'a, S> et JobSnapshotSource :
- futur abstrait fondé uniquement sur
std::future::Future,PinetBox; - lecture du snapshot courant ;
- attente d'une valeur plus récente après une séquence observée ;
- coalescence autorisée des progressions intermédiaires, avec resynchronisation sur le snapshot complet courant ;
- aucun callback producteur, channel Tokio, event log, Tauri ou historique public.
La source runtime concrète n'est pas créée dans Job API. Elle restera possédée par ksp-job-backfill-lib lorsque cette crate ouvrira ; les canaries de pre.003 prouvent le contrat externe, sans annoncer comme acquises les propriétés runtime O(1), wake-up ou isolation du producteur avant ce consumer réel.
Tests ajoutés
Trois unitaires :
- progression stricte et ordre de séquence ;
- épuisement
u64::MAXexplicite sans wrap ; - conservation de la valeur et redaction du snapshot en
Debug.
Trois canaries externes :
- consommation de l'enveloppe depuis le crate-root ;
- deux listeners indépendants resynchronisés vers la dernière valeur après séquences anciennes différentes ;
- snapshot terminal encore lisible depuis un handle partagé.
Les canaries de dépendances et de complétude existantes sont étendues pour couvrir notification.rs, les nouveaux exports et l'absence de fuite Backfill/Worker/runtime.
Fichiers ajoutés
crates/ksp-job-api/src/notification.rs
crates/ksp-job-api/tests/notifications.rs
crates/ksp-job-api/unit_tests/notification.rs
deltas/0.3.6/pre.003.md
Fichiers modifiés
Cargo.toml
crates/ksp-job-api/src/error.rs
crates/ksp-job-api/src/lib.rs
crates/ksp-job-api/tests/dependency_boundary.rs
crates/ksp-job-api/tests/release_completeness.rs
docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md
docs/validation/023-V0_3_6_JOB_API_BACKFILL.md
Mécanique Cargo :
header version: 396 -> 397
workspace.package.version: 0.3.6-pre.2.fix.1 -> 0.3.6-pre.3
workspace members: inchangés
workspace dependencies: inchangées
Fichiers supprimés
Aucun.
Décisions prises
- une séquence publique ne se construit pas depuis un entier arbitraire ; elle part de
initial()puis progresse vianext(); JobNotification<S>reste générique afin que Job API ne possède aucun snapshot Backfill prématuré ;- le
Debugde l'enveloppe ne demande pasS: Debuget ne rend jamais le snapshot ; - le contrat d'attente expose un futur
stdboxed plutôt qu'un type Tokio ou un callback ; - la sémantique publique est latest-value, pas une queue et pas un event log durable ;
- une séquence manquée n'exige aucun replay : le listener reprend le snapshot complet le plus récent ;
- la source concrète et son wake-up ne sont pas simulés comme fonctionnalité de production dans Job API ; ils seront prouvés avec le premier consumer réel ;
ksp-job-apiconserve exactement sa dépendance normale Core-only et aucune feature/dev-dependency/build-dependency n'est ajoutée ;- aucun README/USAGE intermédiaire n'est créé avant la surface consommable réconciliée prévue par le plan.
Validations exécutées
unzip -tq des deux archives
-> propre
inventaire ZIP
-> KSP: 1541 entrées, 0 duplicate, 0 traversal, 0 absolute, 0 symlink
-> kbot3: 2501 entrées, 0 duplicate, 0 traversal, 0 absolute, 0 symlink
python3 scripts/audit_rust_workspace_rules.py
-> General Rust rule audit: clean
-> Rust export completeness audit: 0 candidate(s)
-> KSP workspace Rust rule audit: clean
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.6
-> Markdown table audit: clean (264 tables / 144 fichiers)
python3 -m unittest scripts/tests/test_audit_markdown_tables.py
-> 5 tests / OK
inventaire statique ksp-job-api
-> 13 tests unitaires
-> 14 canaries d'intégration
L'inventaire différentiel base/travail confirme que seuls les fichiers listés par ce delta sont ajoutés ou modifiés, hors caches Python temporaires supprimés avant assemblage.
Validations non exécutées
L'environnement d'assemblage ne fournit ni cargo ni rustfmt. Les commandes Rust de pre.003 ne sont donc pas annoncées comme réussies localement.
Le smoke réseau et PostgreSQL ne concernent pas cette tranche API-only.
Gate opérateur demandé
cargo fmt --all
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/0.3.6
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-job-api
cargo tree -p ksp-job-api --edges normal
cargo tree -p ksp-job-api -e features
Le résultat attendu pour ksp-job-api après cette tranche est treize tests unitaires et quatorze canaries d'intégration, sans nouvelle dépendance normale ou feature.
Questions ouvertes
Aucune question ne bloque pre.004 après un gate opérateur vert de pre.003.