v0.3.9-pre.002-fix.001

This commit is contained in:
2026-09-04 14:23:54 +02:00
parent 7d0710a1e6
commit 156d237460
9 changed files with 210 additions and 28 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 477
# version: 478
[workspace]
resolver = "3"
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api"]
[workspace.package]
version = "0.3.9-pre.2"
version = "0.3.9-pre.2.fix.1"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-api/src/identity.rs
// version: 1
// version: 2
/// Maximum UTF-8 byte length admitted for one Worker identifier.
pub const MAX_WORKER_ID_BYTES: usize = 128;
@@ -10,7 +10,7 @@ pub const MAX_WORKER_KIND_CODE_BYTES: usize = 128;
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WorkerId(std::string::String);
impl WorkerId {
impl crate::WorkerId {
/// Creates one non-empty Worker identifier using the KSP safe-code alphabet.
pub fn new(value: impl std::convert::Into<std::string::String>) -> crate::Result<Self> {
let value = value.into();
@@ -27,7 +27,7 @@ impl WorkerId {
}
}
impl std::fmt::Debug for WorkerId {
impl std::fmt::Debug for crate::WorkerId {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str("WorkerId(..)");
}
@@ -37,7 +37,7 @@ impl std::fmt::Debug for WorkerId {
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WorkerKindCode(std::string::String);
impl WorkerKindCode {
impl crate::WorkerKindCode {
/// Creates one non-empty Worker kind using the KSP safe-code alphabet.
pub fn new(value: impl std::convert::Into<std::string::String>) -> crate::Result<Self> {
let value = value.into();
@@ -54,7 +54,7 @@ impl WorkerKindCode {
}
}
impl std::fmt::Debug for WorkerKindCode {
impl std::fmt::Debug for crate::WorkerKindCode {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.debug_tuple("WorkerKindCode").field(&self.0).finish();
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-api/src/lifecycle.rs
// version: 1
// version: 2
/// Current lifecycle state of one continuous Worker.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
@@ -19,7 +19,7 @@ pub enum WorkerState {
Faulted(crate::ErrorCode),
}
impl WorkerState {
impl crate::WorkerState {
/// Returns the stable safe lifecycle code without rendering Worker data.
#[must_use]
pub const fn code(&self) -> &'static str {
@@ -63,7 +63,7 @@ pub enum WorkerHealth {
Unhealthy,
}
impl WorkerHealth {
impl crate::WorkerHealth {
/// Returns the stable safe code for this health classification.
#[must_use]
pub const fn code(&self) -> &'static str {
@@ -88,7 +88,7 @@ pub enum WorkerActivity {
Active,
}
impl WorkerActivity {
impl crate::WorkerActivity {
/// Returns the stable safe code for this activity classification.
#[must_use]
pub const fn code(&self) -> &'static str {
@@ -108,7 +108,7 @@ pub struct WorkerLifecycle {
state: crate::WorkerState,
}
impl WorkerLifecycle {
impl crate::WorkerLifecycle {
/// Creates one lifecycle in [`WorkerState::Created`] state.
#[must_use]
pub const fn new(id: crate::WorkerId, kind: crate::WorkerKindCode) -> Self {
@@ -167,7 +167,7 @@ impl WorkerLifecycle {
}
}
impl std::fmt::Debug for WorkerLifecycle {
impl std::fmt::Debug for crate::WorkerLifecycle {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.debug_struct("WorkerLifecycle").field("id", &self.id).field("kind", &self.kind).field("state", &self.state).finish();
}

View File

@@ -1,11 +1,11 @@
// file: crates/ksp-worker-api/src/snapshot.rs
// version: 1
// version: 2
/// Monotone sequence attached to one latest-value Worker snapshot stream.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WorkerSnapshotSequence(u64);
impl WorkerSnapshotSequence {
impl crate::WorkerSnapshotSequence {
/// Creates the initial sequence position for one Worker snapshot stream.
#[must_use]
pub const fn initial() -> Self {
@@ -50,7 +50,7 @@ pub struct WorkerSnapshot {
activity: crate::WorkerActivity,
}
impl WorkerSnapshot {
impl crate::WorkerSnapshot {
/// Creates one immutable common Worker snapshot from already validated values.
#[must_use]
pub const fn new(
@@ -101,7 +101,7 @@ impl WorkerSnapshot {
}
}
impl std::fmt::Debug for WorkerSnapshot {
impl std::fmt::Debug for crate::WorkerSnapshot {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter
.debug_struct("WorkerSnapshot")
@@ -130,7 +130,7 @@ pub trait WorkerSnapshotSource: std::marker::Send + std::marker::Sync {
#[cfg(test)]
fn exhausted_snapshot_sequence() -> crate::WorkerSnapshotSequence {
return WorkerSnapshotSequence(u64::MAX);
return crate::WorkerSnapshotSequence(u64::MAX);
}
#[cfg(test)]

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-api/src/stop.rs
// version: 1
// version: 2
/// Runtime-neutral cloneable token carrying cooperative Worker stop intent.
#[derive(Clone)]
@@ -7,7 +7,7 @@ pub struct WorkerStopToken {
requested: std::sync::Arc<std::sync::atomic::AtomicBool>,
}
impl WorkerStopToken {
impl crate::WorkerStopToken {
/// Creates a token with no stop request.
#[must_use]
pub fn new() -> Self {
@@ -27,13 +27,13 @@ impl WorkerStopToken {
}
}
impl std::default::Default for WorkerStopToken {
impl std::default::Default for crate::WorkerStopToken {
fn default() -> Self {
return Self::new();
}
}
impl std::fmt::Debug for WorkerStopToken {
impl std::fmt::Debug for crate::WorkerStopToken {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.debug_struct("WorkerStopToken").field("stop_requested", &self.is_stop_requested()).finish();
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-api/tests/dependency_boundary.rs
// version: 1
// version: 2
//! Dependency and runtime-neutrality canaries for the Worker API foundation.
@@ -59,6 +59,47 @@ fn pre_002_production_sources_forbid_job_runtime_domain_and_wire_dependencies()
return;
}
#[test]
fn pre_002_fix_001_shared_visible_items_use_crate_root_facade_inside_owner_modules() {
let identity = include_str!("../src/identity.rs");
let lifecycle = include_str!("../src/lifecycle.rs");
let snapshot = include_str!("../src/snapshot.rs");
let stop = include_str!("../src/stop.rs");
for expected in [
"impl crate::WorkerId {",
"impl std::fmt::Debug for crate::WorkerId {",
"impl crate::WorkerKindCode {",
"impl std::fmt::Debug for crate::WorkerKindCode {",
] {
assert!(identity.contains(expected), "missing crate-root Worker identity impl target: {expected}");
}
for expected in [
"impl crate::WorkerActivity {",
"impl crate::WorkerHealth {",
"impl crate::WorkerLifecycle {",
"impl crate::WorkerState {",
"impl std::fmt::Debug for crate::WorkerLifecycle {",
] {
assert!(lifecycle.contains(expected), "missing crate-root Worker lifecycle impl target: {expected}");
}
for expected in [
"impl crate::WorkerSnapshotSequence {",
"impl crate::WorkerSnapshot {",
"impl std::fmt::Debug for crate::WorkerSnapshot {",
"return crate::WorkerSnapshotSequence(u64::MAX);",
] {
assert!(snapshot.contains(expected), "missing crate-root Worker snapshot reference: {expected}");
}
for expected in [
"impl crate::WorkerStopToken {",
"impl std::default::Default for crate::WorkerStopToken {",
"impl std::fmt::Debug for crate::WorkerStopToken {",
] {
assert!(stop.contains(expected), "missing crate-root Worker stop impl target: {expected}");
}
return;
}
fn manifest_dependency_names(section: &str) -> std::vec::Vec<&str> {
let mut names = std::vec::Vec::new();
for line in section.lines() {

View File

@@ -0,0 +1,114 @@
<!-- file: deltas/0.3.9/pre.002-fix.001.md -->
<!-- version: 1 -->
# Delta `0.3.9-pre.002-fix.001` — conformité crate-root de `ksp-worker-api`
## Base requise
```text
0.3.9-pre.002
workspace.package.version = 0.3.9-pre.2
```
Le gate opérateur de `pre.002` est vert : format et audits propres, `cargo check --workspace` PASS, Clippy workspace `--all-targets --all-features -- -D warnings` PASS, `cargo test -p ksp-worker-api` PASS avec 17 tests, et les deux `cargo tree` ciblés confirment la frontière Core-only.
## Défaut corrigé
La nouvelle crate respectait les réexports crate-root dans ses signatures inter-types, mais les modules propriétaires implémentaient encore les types partagés par nom local nu, par exemple :
```rust
impl WorkerId {
```
`RUST-IMPORT-009` impose qu'un élément `pub` ou `pub(crate)` partagé soit appelé via `crate::Item`, y compris depuis son module de déclaration lorsque le contrat est crate-wide. La forme canonique est donc :
```rust
impl crate::WorkerId {
```
Le même défaut existait pour les autres targets d'`impl` de `identity.rs`, `lifecycle.rs`, `snapshot.rs` et `stop.rs`.
## Corrections Rust
Les targets sont normalisées sans modifier la surface ni le comportement :
```text
identity.rs
WorkerId
Debug for WorkerId
WorkerKindCode
Debug for WorkerKindCode
lifecycle.rs
WorkerState
WorkerHealth
WorkerActivity
WorkerLifecycle
Debug for WorkerLifecycle
snapshot.rs
WorkerSnapshotSequence
WorkerSnapshot
Debug for WorkerSnapshot
stop.rs
WorkerStopToken
Default for WorkerStopToken
Debug for WorkerStopToken
```
Le helper `exhausted_snapshot_sequence()` construit aussi explicitement `crate::WorkerSnapshotSequence(u64::MAX)`.
Une troisième canarie `dependency_boundary` vérifie les références crate-root attendues dans les quatre modules propriétaires afin d'éviter une régression locale lors de `pre.003`.
## Version
Ce correctif modifie du code Rust :
```text
workspace.package.version = 0.3.9-pre.2.fix.1
```
Le header du `Cargo.toml` racine passe de `477` à `478`.
## Hors scope
Aucun changement de lifecycle, identity bounds, snapshot shape, stop semantics, ErrorCode, dépendance, feature ou API publique. Aucun travail `pre.003` n'est anticipé.
L'auditeur Python global n'est pas étendu dans ce fix : une généralisation immédiate ferait remonter la dette historique de crates antérieures et élargirait artificiellement cette correction locale. La canarie Worker ferme le défaut nouveau sans masquer cette distinction.
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-worker-api/src/identity.rs
crates/ksp-worker-api/src/lifecycle.rs
crates/ksp-worker-api/src/snapshot.rs
crates/ksp-worker-api/src/stop.rs
crates/ksp-worker-api/tests/dependency_boundary.rs
docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md
docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md
```
## Fichier ajouté
```text
deltas/0.3.9/pre.002-fix.001.md
```
## Fichiers supprimés
Aucun.
## Gate opérateur demandé
```bash
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
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p ksp-worker-api
cargo tree -p ksp-worker-api --edges normal
cargo tree -p ksp-worker-api -e features
```

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Plan v0.3.9 — Worker API générique + audit RAW Transaction
@@ -561,6 +561,12 @@ reexports Error / ErrorCode / ErrorContext / Result
La crate dépend uniquement de `ksp-core-lib`, ne possède aucune feature/dev/build dependency et n'ouvre ni runtime, ni Job, ni Transport/Store/Config, ni contrat Solana. Le snapshot commun reste fixe et sans payload métier. Les preuves adversariales, object-safety, implémentation externe et latest-value multi-listener restent volontairement dans `pre.003`.
#### `pre.002-fix.001` — chemins crate-root dans les modules propriétaires
**Statut : réalisé ; correctif de conformité Rust.**
Correction de la nouvelle crate Worker selon `RUST-IMPORT-009` : tout `impl` d'un type partagé/exporté cible désormais explicitement `crate::Type`, y compris les implémentations de traits `Debug`/`Default`. Le helper de test de séquence emploie également `crate::WorkerSnapshotSequence`. Une canarie dependency-boundary dédiée verrouille ces références sans élargir la surface fonctionnelle de `pre.002`. `workspace.package.version` devient `0.3.9-pre.2.fix.1`.
### `pre.003` — hardening, races, object-safety, impl externe et freeze
**Statut : prévu.**

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Validation v0.3.9 — Worker API + audit RAW Transaction
@@ -95,6 +95,27 @@ Les cases cochées de cette sous-section attestent la matérialisation de la sur
- [X] Public API consumer depuis crate root testée.
- [X] Dependency firewall initial testée.
#### Gate opérateur de `pre.002` avant fix
- [X] `cargo fmt --all` exécuté.
- [X] audits Rust complets propres.
- [X] audit Markdown propre : 320 tables / 731 fichiers.
- [X] `cargo check --workspace` PASS.
- [X] `cargo clippy --workspace --all-targets --all-features -- -D warnings` PASS.
- [X] `cargo test -p ksp-worker-api` PASS : 13 unitaires + 2 dependency boundary + 2 public API.
- [X] `cargo tree -p ksp-worker-api --edges normal` confirme `ksp-worker-api -> ksp-core-lib` uniquement côté KSP.
- [X] `cargo tree -p ksp-worker-api -e features` ne révèle aucune feature Worker propre ni dépendance runtime/domain ajoutée.
#### `pre.002-fix.001`
- [X] Violation `RUST-IMPORT-009` identifiée sur les targets d'`impl` des types Worker exportés.
- [X] `identity.rs` utilise `impl crate::WorkerId` et `impl crate::WorkerKindCode`, y compris pour `Debug`.
- [X] `lifecycle.rs` utilise la façade crate-root pour les cinq targets d'`impl` visibles.
- [X] `snapshot.rs` utilise la façade crate-root pour les trois targets d'`impl` visibles et le helper de séquence.
- [X] `stop.rs` utilise la façade crate-root pour l'impl inhérent, `Default` et `Debug`.
- [X] Canarie dependency-boundary ajoutée contre cette régression.
- [ ] Gate Cargo du fix exécuté par l'opérateur.
### `pre.003`
- [ ] Stop-vs-fault ordres adversariaux couverts.
@@ -213,10 +234,10 @@ Aucun item ci-dessous nest déclaré exécuté en `pre.001`.
La livraison initiale `pre.001` avait conservé `workspace.package.version = 0.3.8` en suivant lexception du prompt 028. Cette exception est supplantée par la règle normative `VER-ID-009`.
Après `pre.002`, létat courant est :
Après `pre.002-fix.001`, létat courant est :
```text
workspace.package.version = 0.3.9-pre.2
workspace.package.version = 0.3.9-pre.2.fix.1
```
`pre.002` est une nouvelle tranche non-fix et synchronise donc Cargo conformément à `VER-ID-006` et `VER-ID-009`. L'état précédent `0.3.9-pre.1.fix.2` reste documenté dans `pre.001-fix.002`.
`pre.002` reste la tranche non-fix `0.3.9-pre.2`. Son correctif de conformité Rust porte `0.3.9-pre.2.fix.1` conformément à `VER-ID-007` et `VER-ID-010`. L'état précédent `0.3.9-pre.1.fix.2` reste documenté dans `pre.001-fix.002`.