v0.3.15-pre.001

This commit is contained in:
2026-09-13 00:27:37 +02:00
parent 002d08ba5f
commit 4ec80889c2
4 changed files with 1330 additions and 2 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 593 # version: 594
[workspace] [workspace]
resolver = "3" 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-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"] 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-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
[workspace.package] [workspace.package]
version = "0.3.14" version = "0.3.15-pre.1"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

178
deltas/0.3.15/pre.001.md Normal file
View File

@@ -0,0 +1,178 @@
<!-- file: deltas/0.3.15/pre.001.md -->
<!-- version: 2 -->
# Delta `0.3.15-pre.001` — audit / route model / sizing Raw Transaction Ingest Desk
## Base requise
```text
v0.3.14
workspace.package.version = 0.3.14
deltas/0.3.14/rel.001.md présent
```
Archive opérateur auditée :
```text
khadhroony-solana-project-v0.3.14.zip
SHA-256 897bd30b0d06c00abc120a7459250b78c11629e84825ac29adbe151d60a668ed
```
L'archive ne contient pas `.git`; l'identité interne stable est contrôlée mais l'objet du tag Git ne peut pas être comparé localement.
## Objet
Exécuter le gate `pre.001` imposé par `prompts/034-V0_3_15_START_PROMPT.md` avant tout scaffold lourd :
```text
lecture complète des règles et du handoff 0.3.14
audit archive/base stable
audit Config/Transport/Store/Worker
audit des cinq familles Worker et de leurs constructeurs
audit des Desk KSP actuelles
external re-audit Solana/Yellowstone/Helius/PublicNode/OrbitFlare pertinent
matrice route/capability/config/resource
classification des gaps
screen map / states / Start-Stop / snapshots
matrice IPC et tracing
sizing et forecast recalibré
plan 036 + validation 032
```
Aucune crate Desk, commande Tauri Start/Stop, extension Transport/Config/Worker ou logique d'acquisition n'est implémentée dans cette tranche.
## Décisions
```text
cinq routes V1 retenues : Yellowstone hydrated, Standard Logs hydrated, Standard Block direct, Helius transaction hydrated, HTTP Block Polling
route != source != endpoint
provider name != capability
catalogue route V1 app-owned
réseau dérivé d'un composite/profil app cohérent Transport+Store
1 route = 1 Worker indépendant
plusieurs Workers peuvent partager le même Arc<Store> si réseau identique
aucun partage de gaps/TargetCoverage entre Workers
composabilité calculée sans I/O réseau ; opérabilité validée au Start
Transport conserve le choix physique endpoint selon rôles/priorités
HTTP request_kinds existants suffisent à prouver les requirements HTTP
WS protocol kind seul ne suffit pas à prouver une subscription exacte
capability WS typed explicite nécessaire dans Transport puis Config
Worker devra enforce la capability WS requise avant I/O
Helius standard WS != Helius transactionSubscribe
Helius ne gagne jamais blockSubscribe par son provider name
Store et lifecycle/snapshots Worker ne nécessitent pas de nouveau contrat essentiel
aucune nouvelle crate intermédiaire
aucun bump de dépendance
release 0.3.15 maintenue ; forecast étendu jusqu'à pre.016
```
## Fichiers ajoutés
```text
docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md
docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md
deltas/0.3.15/pre.001.md
```
## Fichiers modifiés
```text
Cargo.toml
```
## Fichiers supprimés
```text
aucun
```
## Version Cargo
```text
header : 593 -> 594
workspace.package.version : 0.3.14 -> 0.3.15-pre.1
```
Aucune dépendance, feature ou autre ligne fonctionnelle du manifest racine n'est modifiée.
## Surfaces explicitement inchangées
```text
crates/**
config/**
README.md
RULES.md
ROADMAP.md
CHANGELOG.md
prompts/**
deltas/0.3.14/**
```
## Validations base exécutées
```text
unzip -t : PASS
archive safety : PASS
workspace/crate inventory : 21/21
General Rust rule audit : clean
Rust export completeness audit : 0 candidate(s)
KSP workspace Rust rule audit : clean
Markdown table audit : clean (340 tables / 886 files)
rule definitions : 489 / 489 uniques / 0 doublon
```
Le journal opérateur fourni qualifie séparément la stable `0.3.14` avec fmt/check/clippy/tests/tree. Cette preuve n'est pas revendiquée comme gate post-bump.
## Validations post-modification
Exécuté localement :
```text
General Rust rule audit : clean
Rust export completeness audit : 0 candidate(s)
KSP workspace Rust rule audit : clean
Markdown table audit : clean (354 tables / 889 files)
rule definitions : 489 / 489 uniques / 0 doublon
stable -> worktree : 3 ajouts / 1 modification / 0 suppression
```
Non exécuté localement :
```text
cargo fmt/check : NON EXÉCUTÉ — cargo absent du sandbox
cargo check --workspace : NON EXÉCUTÉ — cargo absent du sandbox
cargo clippy : NON EXÉCUTÉ — cargo absent du sandbox
cargo test : NON EXÉCUTÉ — cargo absent du sandbox
```
Ces commandes restent à exécuter par lopérateur après application du delta ; aucun faux PASS Cargo nest revendiqué.
## Archive d'échange
Livraison attendue selon `VER-ARCHIVE-004` :
```text
ksp-general-0.3.15-pre.001.zip
```
Contenu exact attendu :
```text
Cargo.toml
docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md
docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md
deltas/0.3.15/pre.001.md
```
Aucun fichier stable inchangé, secret, cache, lockfile, sortie de build ou artefact d'audit n'est inclus.
## Gate opérateur après application
```bash
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/0.3.15
cargo check --workspace
```
Après gate propre, `pre.002` commence par la capability WS typed Transport prévue par le plan `036`, et non par le scaffold UI.

View File

@@ -0,0 +1,726 @@
<!-- file: docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md -->
<!-- version: 1 -->
# Plan v0.3.15 — Raw Transaction Ingest Desk
## 1. But de la version
`0.3.15` introduit `ksp-app-raw-transaction-ingest-desk`, application Tauri KSP de **composition et supervision** des routes live `RawTransaction` déjà possédées par Config, Transport, Store et `ksp-worker-raw-transaction-ingest-lib`.
L'application ne devient jamais une nouvelle couche d'acquisition. Son rôle est strictement :
```text
Config résolue
-> inventaire déterministe des routes composables
-> sélection opérateur de 0..N routes
-> revalidation backend au Start
-> reconstruction des ressources Transport
-> 1 Worker indépendant par route sélectionnée
-> même Store logique pour les Workers du même réseau
-> snapshots Worker source-neutral vers l'UI
```
La règle structurante est :
```text
route != source != endpoint
1 route sélectionnée = 1 Worker
provider name != capability
Composable != Operational
```
## 2. Base autoritaire auditée en `pre.001`
```text
archive : khadhroony-solana-project-v0.3.14.zip
SHA-256 : 897bd30b0d06c00abc120a7459250b78c11629e84825ac29adbe151d60a668ed
bytes : 8591925
ZIP entries : 2046
ZIP files : 1851
workspace members : 21
crate manifests : 21
workspace.package.version : 0.3.14
stable delta : deltas/0.3.14/rel.001.md
prompt : prompts/034-V0_3_15_START_PROMPT.md
```
Contrôle archive :
```text
unzip -t : PASS
entrée absolue : 0
path traversal : 0
doublon d'entrée ZIP : 0
symlink ZIP : 0
target/ : 0
node_modules/ : 0
dist/ : 0
.git/ : 0
Cargo.lock : 0
package-lock.json : 0
pnpm-lock.yaml : 0
yarn.lock : 0
rust-toolchain.toml : 0
.env : 0
workspace member sans crate : 0
crate hors workspace : 0
```
L'archive ne contient pas `.git`; l'identité interne stable peut être contrôlée, mais l'objet du tag Git `v0.3.14` ne peut pas être comparé cryptographiquement depuis cette archive seule.
## 3. Audit des règles actives
Les sources normatives imposées ont été relues depuis `RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, `docs/000-README.md` et `docs/rules/`.
Contraintes qui gouvernent toute la version :
```text
Rust 2024
unsafe interdit
unwrap / expect / panic interdits selon les règles KSP
? interdit en production
retours explicites ; clippy::implicit_return deny
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
pas de pub mod
pub/pub(crate) partagés réexportés via crate root
accès partagés via crate::Item, y compris intra-crate
Config seule propriétaire des fichiers/profils/secrets/endpoints configurés
Transport seul propriétaire des clients/sessions/retry/reconnect/replay natif
Store consommé uniquement via ksp-store-lib
Worker indépendant de Config, Job Backfill et backend Store physique
Desk compose et supervise sans recoder acquisition/persistence
frontend Tauri sans URL/token/Store URI/client/handle/payload brut
tracing frontend sans valeurs sensibles
un fichier texte réellement modifié incrémente son header
une prerelease non-fix synchronise workspace.package.version
un delta publié reste immuable
archive d'échange = delta minimal
une validation non exécutée n'est jamais PASS
```
Le scan des définitions normatives donne :
```text
489 définitions
489 identifiants uniques
0 doublon de définition
```
## 4. État stable `0.3.14` à préserver
Le Worker stable expose déjà cinq familles productives :
```text
Yellowstone
Standard Logs
Standard Block
Helius Transaction
HTTP Block Polling
```
Il conserve un seul pipeline Common RAW/admission/persistence **par Worker**, ainsi que :
```text
canonical identity / idempotence / observations
content conflict explicite
hydratation/coalescence interne
processing frontier distinct de continuity frontier
gaps run-local bornés
TargetCoverage conservative
reconnect != replay_attempt != replay_covered != repaired
repair borné et fair
health source-neutral
shutdown/drain/abort+join borné
snapshots publics source-neutral avec gap observability
```
Le graphe direct du Worker reste sans Config, Job Backfill, backend Store physique ou provider SDK. `0.3.15` ne modifie pas cette direction de dépendances.
## 5. Audit Config / Transport / Store
### 5.1 Transport HTTP
La Config résolue fournit déjà des `HttpTransportSettings` typed avec :
```text
endpoint enabled/name/provider/cluster
roles
request_kinds
priority
rate/concurrency/retry settings
URL conservée backend-only
```
La composabilité HTTP peut donc être calculée côté Rust à partir de rôles + `request_kinds` sans parser le JSON dans le frontend.
### 5.2 Transport WebSocket
La Config et Transport distinguent déjà :
```text
WsProtocolKind::SolanaStandard
WsProtocolKind::HeliusLaserStream
```
Transport possède également le type public `WsSubscriptionKind` couvrant notamment `Logs`, `Block` et `HeliusTransaction`.
Gap confirmé : `WsEndpointSettings` ne porte actuellement **aucune liste explicite des subscriptions supportées**. Le seul protocol kind ne suffit pas à prouver qu'un endpoint accepte `blockSubscribe`, méthode Solana instable et optionnelle côté validator/provider.
Décision : ajouter pendant `0.3.15`, avant l'UI qui en dépend, une capability WS typed au niveau Transport, la mapper depuis Config, puis faire appliquer le requirement par les constructeurs Worker concernés. Aucune inférence par nom de provider n'est autorisée.
### 5.3 Yellowstone gRPC
Les settings gRPC Config/Transport portent endpoint/provider/cluster/metadata avec valeurs sensibles non projetées. Le Worker possède déjà un constructeur Yellowstone prenant le channel, la requête `Subscribe`, un pool HTTP et un rôle d'hydration.
Aucune nouvelle API gRPC générique n'est requise par le Desk pour V1.
### 5.4 Store
Le chemin reste :
```text
ResolvedStoreConfig
-> StoreSettings
-> ksp-store-lib::Store::open
-> Arc<Store> partagé par les Workers du même réseau
```
Aucun gap Store n'est identifié. L'application ne dépend jamais de `ksp-store-postgres-lib` et n'accède jamais au SQL.
## 6. Profils Transport réellement committed
| Profil/config | Réseau | Surfaces | Secret requis | Committed ? | Observation |
|-------------------------|------------------------------|---------------------------------------|-----------------------|----------------------|-------------------------------------------|
| `devnet_public` | devnet | HTTP + WS Solana standard | non | oui | pas de capability WS fine aujourdhui |
| `orbitflare_devnet` | devnet | HTTP + WS standard + Yellowstone gRPC | token gRPC secret | conditionnel | profil complet seulement si secret résolu |
| `mainnet_public` | mainnet | HTTP + WS Solana standard | non | oui | pas de capability WS fine aujourdhui |
| `mainnet_backfill_pool` | mainnet | plusieurs HTTP + WS standard | selon endpoint/config | oui si profil résolu | priorités/rôles restent Transport-owned |
| `publicnode_mainnet` | mainnet | HTTP + WS standard + Yellowstone gRPC | x-token secret | conditionnel | gRPC provider-gated |
| `publicnode_testnet` | testnet | HTTP + WS standard + Yellowstone gRPC | x-token secret | conditionnel | gRPC provider-gated |
| Helius exemple | mainnet/devnet selon exemple | WS `helius_laserstream` | API key secret | non committed | exemple != profil actif |
Conséquences :
```text
un fichier sous config/examples/ ne rend aucune route disponible
une capability provider documentée sur le Web ne rend aucune route disponible
un secret requis mais non résolu rend le profil concerné non composable
le Desk ne synthétise pas une capability à partir de provider == helius/publicnode/orbitflare
```
## 7. Modèle de route V1
Une route est un objet applicatif borné décrivant une stratégie complète, pas un endpoint. Son identité V1 reste app-owned car elle sert l'UX et compose des contrats lower-layer existants.
Chaque route contient conceptuellement :
```text
route_id stable
route family
network logique
commitment confirmé/finalized
essential capability set
optional capability set
resource builder backend
source family Worker
RAW-direct ou reference-bearing
selectable/unavailable reason code
```
Le frontend reçoit uniquement la projection sûre de ce modèle. Les ressources physiques restent dans le backend Rust.
## 8. Matrice route / capability / Config / Worker
| Route V1 | Network | Required capability | Optional capability | Config evidence | Worker resource | Composable aujourdhui ? | Missing contract | Live-testable ? |
|-------------------------------|------------------|----------------------------------------------------------------|-------------------------------------------------|-----------------------|-----------------------------------------------|---------------------------------------------------------|--------------------------------------------------|-----------------------------------------------|
| `yellowstone-hydrated` | réseau du profil | Yellowstone gRPC Subscribe + HTTP `getTransaction` même réseau | scan HTTP repair si rôle compatible | gRPC + HTTP role | `RawTransactionIngestYellowstoneSource` | oui sur profil complet et secrets résolus | aucun contrat essentiel | provider-gated selon profil |
| `standard-logs-hydrated` | réseau du profil | WS Solana standard `logsSubscribe` + HTTP `getTransaction` | scan HTTP repair si rôle compatible | WS + HTTP role | `RawTransactionIngestStandardLogsSource` | non prouvable strictement avant capability WS explicite | Transport + Config + enforcement Worker minimaux | oui, notamment Devnet keyless après extension |
| `standard-block-direct` | réseau du profil | WS Solana standard `blockSubscribe` explicitement déclaré | aucune hydration obligatoire | WS capability Block | `RawTransactionIngestStandardBlockSource` | non prouvable aujourdhui | Transport + Config + enforcement Worker minimaux | seulement endpoint prouvé compatible |
| `helius-transaction-hydrated` | réseau du profil | WS Helius `transactionSubscribe` + HTTP `getTransaction` | scan HTTP repair si rôle compatible | Helius WS + HTTP role | `RawTransactionIngestHeliusTransactionSource` | non dans les profils committed actuels | Config data/composite + capability WS explicite | provider-gated Helius |
| `http-block-polling` | réseau du profil | HTTP `getSlot` + `getBlocksWithLimit` + `getBlock` | `getTransaction` pour known-reference hydration | HTTP role | `RawTransactionIngestHttpBlockPollingSource` | oui lorsque le rôle résolu annonce les trois méthodes | aucun contrat essentiel | oui sur endpoint public compatible |
### 8.1 `yellowstone-hydrated`
Requirement minimal :
```text
un endpoint Yellowstone gRPC activé sur le réseau logique
une requête Subscribe transaction-bearing bornée
un rôle HTTP même réseau supportant getTransaction
commitment confirmed ou finalized
```
Le rôle HTTP peut aussi fournir `getBlock` + scan pour repair, mais ce n'est pas une obligation de construction de la route nominale.
La requête V1 sera app-owned et bornée à une acquisition transaction-bearing générale, sans laisser le frontend définir des filtres arbitraires. L'app ne passe jamais de metadata/token via IPC.
### 8.2 `standard-logs-hydrated`
Requirement minimal :
```text
WS protocol = SolanaStandard
capability WS explicite = Logs
HTTP same-network avec getTransaction
commitment confirmed ou finalized
```
Le filtre V1 est un preset backend, pas une structure libre envoyée par le navigateur.
### 8.3 `standard-block-direct`
Requirement minimal :
```text
WS protocol = SolanaStandard
capability WS explicite = Block
commitment confirmed ou finalized
```
Aucun HTTP n'est obligatoire pour le chemin nominal, car le matériau bloc est RAW-direct. Cette route reste non sélectionnable tant que la capability `Block` n'est pas explicitement déclarée dans le profil exact.
### 8.4 `helius-transaction-hydrated`
Requirement minimal :
```text
WS protocol = HeliusLaserStream
capability WS explicite = HeliusTransaction
HTTP same-network avec getTransaction
commitment confirmed ou finalized
```
Le profil committed stable n'expose actuellement pas cette ressource ; les exemples Helius ne sont pas convertis en disponibilité implicite.
### 8.5 `http-block-polling`
Requirement minimal exact du constructeur :
```text
un rôle HTTP même réseau qui, au niveau du pool, compose :
getSlot
getBlocksWithLimit
getBlock
```
`getTransaction` est optionnel et sert des chemins de known-reference hydration/repair lorsqu'il existe. Le Desk laisse le pool Transport choisir les endpoints selon rôles/priorités existants ; il ne fait pas choisir une URL physique au frontend.
## 9. Helius standard WS vs Helius provider-specific
Deux cas doivent rester distincts même si une infrastructure physique Helius peut accepter plusieurs protocoles :
```text
Helius utilisé comme endpoint Solana standard
-> WsProtocolKind::SolanaStandard
-> peut satisfaire une route Standard Logs si capability Logs déclarée
-> ne devient pas HeliusTransaction par son seul provider name
Helius transactionSubscribe
-> WsProtocolKind::HeliusLaserStream
-> capability HeliusTransaction
-> route helius-transaction-hydrated
```
La documentation Helius actuelle indique que `blockSubscribe` n'est pas supporté. Un endpoint Helius ne reçoit donc jamais une capability `Block` par inférence provider.
## 10. Classification des gaps `pre.001`
| Sujet | Classification | Owner | Décision |
|--------------------------------------------------|------------------------------|--------------------|----------------------------------------------------------------|
| Catalogue de cinq routes et IDs applicatifs | adaptation app seulement | Desk | catalogue borné, pas de nouvelle crate |
| Projection HTTP `request_kinds` / rôles / réseau | aucun gap | Config + Transport | déjà exploitable côté Rust |
| Projection gRPC Yellowstone / metadata sûre | aucun gap | Config + Transport | secrets restent Rust-only |
| Capability WS exacte par subscription | extension Transport minimale | Transport | ajouter une déclaration typed réutilisant `WsSubscriptionKind` |
| Mapping schema/config des capabilities WS | extension Config minimale | Config | Config reste propriétaire de la déclaration |
| Refus Worker si capability WS requise absente | extension Worker minimale | Worker | enforcement avant I/O, pas de logique provider dans Desk |
| Composite dédié Raw Ingest Desk | extension Config minimale | Config | profils app dédiés et cohérents Store/Transport |
| Store open / network / partage `Arc<Store>` | aucun gap | Store + app | `ksp-store-lib` suffit |
| Lifecycle / stop / snapshots Worker | aucun gap | Worker + app | handles publics existants |
| Backfill / historical repair | hors scope | Job Backfill | aucune orchestration automatique |
| Taille release | pas de split de release | plan | forecast étendu jusquà `pre.016` |
La release n'est pas rescindée. Le gap WS est petit, clairement propriétaire et testable. En revanche, le forecast doit être étendu pour ne pas fusionner Transport, Config, Worker et scaffold UI dans une même tranche.
## 11. Lieu du catalogue et projection de composabilité
### 11.1 Catalogue app-owned
Le catalogue de routes reste dans le backend de `ksp-app-raw-transaction-ingest-desk` :
```text
il exprime les produits UI V1
il n'est pas un contrat générique d'acquisition
il ne duplique pas les constructeurs Worker
il référence uniquement des capability requirements typed lower-layer
```
Aucune nouvelle crate intermédiaire n'est créée.
### 11.2 Projection backend-only
Le backend :
```text
résout un composite/profil app KSP
obtient Transport HTTP/WS/gRPC typed
obtient StoreSettings typed
calcule un inventaire route/capability déterministe sans I/O réseau
projette seulement IDs/states/reason codes sûrs
```
Le frontend ne lit ni `std.transport.json`, ni `std.store.json`, ni `.env`.
### 11.3 Profil/réseau V1
Décision V1 : le réseau est **dérivé du composite/profil app sélectionné**, dont Transport et Store doivent être cohérents. Le Desk ne combine pas arbitrairement un profil Transport d'un réseau avec un target Store d'un autre.
Invariant :
```text
route.network == Worker.settings.network == Store.network
```
Un changement de profil app est interdit tant qu'un Worker de la session est actif. Il force ensuite une nouvelle génération d'inventaire.
### 11.4 Plusieurs compositions physiques
Lorsque plusieurs endpoints/rôles satisfont une route :
```text
Transport conserve la sélection physique selon ses rôles/priorités
le Desk expose une route logique, pas N URLs
le frontend ne choisit jamais l'endpoint physique
```
Si un futur besoin exige des compositions logiques distinctes, il faudra introduire des IDs logiques sûrs ; ce besoin n'est pas prouvé pour V1.
## 12. Lifecycle multi-Worker et Store partagé
État applicatif backend :
```text
resolved app profile + inventory generation
0..N selected route IDs
0..N active route runtimes
route_id -> Worker handle + snapshot source + terminal task ownership
0 ou 1 Store partagé pour le réseau actif
```
Start d'une route :
```text
1. recevoir route_id + inventory_generation + commitment
2. re-résoudre la Config côté Rust
3. vérifier que la génération/route existe toujours
4. revalider réseau Transport/Store
5. reconstruire les ressources exactes de la route
6. ouvrir ou réutiliser le Store partagé via ksp-store-lib
7. démarrer exactement un Worker
8. installer le handle avant publication de Running
9. relayer les snapshots sûrs
```
Le Start n'accorde aucun crédit à un inventaire frontend obsolète.
Stop d'une route :
```text
request_stop()
attente terminale bornée selon le contrat Worker
publication Stopping puis Stopped/Faulted
retrait du handle de cette route uniquement
conservation du Store tant qu'au moins un Worker le référence
```
Fault d'une route : aucune autre route n'est arrêtée implicitement.
Fermeture application : demander l'arrêt de tous les Workers détenus, attendre leur terminaison bornée/join, puis laisser tomber le Store partagé. Aucun kill non coordonné n'est le chemin nominal.
## 13. UX prévue
### 13.1 Screen map
```text
Splash KSP commun
Main window
Header
application title
selected app profile / network
Store status
Routes view
profile selector lorsque aucun Worker actif
commitment selector
route list
Start selected / Stop selected comme orchestration UI bornée
Route runtime detail
lifecycle / health / activity
throughput/admission/persistence
reconnect / replay / gaps / repair
source-neutral fault code
Diagnostics/status area
safe command errors
inventory generation / resync action
```
Aucun éditeur d'URL, token, header ou Store URI n'est prévu.
### 13.2 États UI
| État UI | Sémantique | Action principale |
|-------------|----------------------------------------------------------------|-------------------------------------|
| Unavailable | requirements incomplets ou incohérents | non |
| Configured | requirements Config complètes, aucune preuve runtime | oui |
| Starting | revalidation + reconstruction + ouverture Store + start Worker | non |
| Running | Worker actif, snapshots reçus | Stop |
| Stopping | stop demandé, attente terminale bornée | non |
| Stopped | Worker terminal propre, handle retiré | Start après nouvelle revalidation |
| Faulted | échec Start/runtime avec code sûr | Start après correction/revalidation |
`Configured` signifie seulement composable depuis Config. Seul un Worker réellement démarré peut devenir `Running`.
### 13.3 Route list contract
Chaque ligne montre au maximum :
```text
label/family logique
network
selectable
availability state
safe unavailable reason
Worker lifecycle/health si actif
quelques compteurs source-neutral
Start/Stop control
```
Les raisons sûres candidates incluent :
```text
profile_unresolved
network_mismatch
missing_http_get_transaction
missing_http_block_scan
missing_ws_logs_capability
missing_ws_block_capability
missing_helius_transaction_capability
missing_yellowstone_grpc
missing_required_secret
store_unavailable_at_start
stale_inventory
route_already_running
```
Le texte détaillé des erreurs provider n'est jamais projeté tel quel.
## 14. Matrice IPC candidate
| DTO candidat | Sens | Contenu autorisé | Exclusions |
|---------------------------------|---------------------|------------------------------------------------------------------------------|------------------------------------------|
| `RawIngestDeskOptionsDto` | backend -> frontend | profils logiques sûrs, réseaux, commitments supportés, génération inventaire | URL, secret, Store URI |
| `RawIngestRouteDto` | backend -> frontend | route_id, family, label, network, state, selectable, reason code | endpoint name/URL/token/source key |
| `RawIngestRouteStartRequestDto` | frontend -> backend | route_id, inventory_generation, commitment | endpoint/credential/client |
| `RawIngestRouteStopRequestDto` | frontend -> backend | route_id | Worker handle |
| `RawIngestRouteRuntimeDto` | backend -> frontend | route_id, lifecycle/health/activity, compteurs source-neutral | payload brut, erreur provider arbitraire |
| `CommandErrorDto` | backend -> frontend | code stable + contexte whiteliste | texte remote arbitraire |
| `FrontendLogPayloadDto` | frontend -> backend | target/level/action IDs bornés | valeurs config/route sensibles |
Les noms exacts peuvent évoluer pendant le scaffold, mais la surface autorisée et les exclusions sont fixes.
## 15. Mapping snapshots -> UI
Le Desk consomme les snapshots publics Worker existants. Projection cible :
```text
lifecycle / health / activity
admission + persistence capacities
admitted / canonicalized / persisted
entity / observation outcomes
store/source failures
backpressure
hydration pending/total
processing frontier
source total/active/reconnecting/failed
reconnect/replay/gap counters
continuity frontier / open gaps / future target coverage
gap observability bornée
repair totals
```
Aucune source key privée, endpoint, signature ou transaction payload n'est nécessaire au monitoring de base.
## 16. Matrice tracing frontend
| Interaction | Trace autorisée | Interdit |
|--------------------------|---------------------------------------------|----------------------------------|
| Navigation/tab | control_id + action | aucun profil, endpoint ou secret |
| Sélection profil/réseau | action + résultat code + counts | pas de valeur de secret ni URL |
| Sélection route | route family/route_id sûr + booléen | pas de source key |
| Start/Stop | route_id sûr + lifecycle outcome code | pas de payload Worker |
| Refresh/resync snapshots | action + sequence/count | pas de transactions |
| IPC success/failure | command id + stable code + durée éventuelle | pas derreur remote brute |
Le tracing suit le socle KSP actuel : clics, tabs, contrôles, refresh/resync et IPC sont instrumentés, sans logguer les valeurs métier sensibles.
## 17. Gabarit Desktop et dépendances
Le scaffold réutilisera le gabarit courant des cinq Desk KSP : même splash, mêmes fonts, même style général et séparation backend/frontend.
Socle npm actuel à conserver sans upgrade opportuniste :
```text
@fltsci/tauri-plugin-tracing
@fortawesome/fontawesome-free
@tauri-apps/api
bootstrap
resize-observer-polyfill
simplebar
```
Les devDependencies seront alignées sur les Desk courantes au moment du scaffold. DataTables ne sera ajouté que si le route list en a réellement besoin ; cinq routes V1 ne justifient pas mécaniquement une table server-side.
Dépendances Rust candidates du Desk, à fermer pendant `pre.005` :
```text
ksp-config-lib
ksp-core-lib
ksp-logging-lib
ksp-onchain-transport-lib
ksp-store-lib
ksp-worker-raw-transaction-ingest-lib
serde
tauri
tauri-plugin-tracing
tokio
ts-rs si DTO bindings retenus
```
Exclusions fermes :
```text
ksp-store-postgres-lib
ksp-job-backfill-lib
provider SDK
client SQL
reqwest/tonic/tokio-tungstenite directs app si les façades KSP suffisent
```
Aucun bump de dépendance workspace n'est justifié en `pre.001`.
## 18. Audit externe courant
L'audit externe `pre.001` sert uniquement à qualifier des capabilities lower-layer ; il ne remplace jamais Config.
Constats :
```text
Solana blockSubscribe reste une méthode unstable, activable explicitement côté validator
Solana logsSubscribe reste une subscription standard
Helius documente les méthodes Solana standard sur son endpoint WSS et une extension transactionSubscribe
Helius documente blockSubscribe comme non supporté
Yellowstone Subscribe conserve les filtres transaction/block et from_slot/replay semantics
PublicNode annonce actuellement RPC/WS/Yellowstone sur les réseaux Solana qu'il expose
OrbitFlare annonce Yellowstone gRPC, notamment pour développement/prototypage
```
Conséquence architecture : les capabilities doivent être **déclarées dans Config et enforced dans la lower-layer**, pas déduites dynamiquement d'une page marketing ou d'un provider name.
## 19. Stratégie de validation de la release
Gates permanents après toute tranche pertinente :
```text
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/<active-version>
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
tests ciblés de la crate touchée
```
Gates Desk :
```text
npm install uniquement via la procédure autorisée par les règles
npm build/check via hooks/scripts Tauri KSP existants
cargo test ciblé app
security/dependency/public API/release completeness canaries
```
Gate live final, sans faux PASS :
```text
HTTP block polling sur endpoint public réellement accessible
Standard Logs + hydration sur WS/HTTP public si capability Config déclarée
Standard Block uniquement sur endpoint prouvé blockSubscribe-compatible
Yellowstone uniquement lorsque credential/profil provisionné
Helius transactionSubscribe uniquement lorsque credential/profil committed/provisionné
plusieurs routes simultanées -> même Store, Workers indépendants
fault d'une route -> autres routes actives intactes
app close -> tous Workers arrêtés/joints
```
Le build Tauri final reste un gate tardif et ne remplace pas les tests runtime.
## 20. Forecast recalibré
| Tranche | Objectif borné |
|-----------|------------------------------------------------------------------------------------------------------|
| `pre.001` | audit, route model, external re-audit, sizing, plan/validation |
| `pre.002` | Transport : capability WS typed par subscription + tests, sans app |
| `pre.003` | Config : schema/mapping capabilities WS + composite/profils Raw Ingest Desk |
| `pre.004` | Worker : enforcement des capabilities WS déclarées + canaris route constructors |
| `pre.005` | scaffold `ksp-app-raw-transaction-ingest-desk`, gabarit KSP, DTO/route IDs/states, sans Start Worker |
| `pre.006` | Config -> inventaire de routes composables/non composables + raisons sûres |
| `pre.007` | reconstruction/revalidation Start des ressources Transport pour les cinq routes, sans launch Worker |
| `pre.008` | Store lifecycle + Start/Stop mono-route réel |
| `pre.009` | multi-route : un Worker par route, même Store, isolation des faults |
| `pre.010` | snapshots/events/monitoring lifecycle-health-activity-backpressure-reconnect-replay-gaps-repair |
| `pre.011` | frontend fonctionnel complet + tracing TypeScript sûr |
| `pre.012` | races, shutdown app, sécurité IPC, hardening hostile/stale inventory |
| `pre.013` | cross-layer completeness + canaris système sans expansion de frontières |
| `pre.014` | gate technique/live accessible + frontend/Tauri + build final de validation technique |
| `pre.015` | réconciliation documentaire finale : plan/validation/README/USAGE |
| `pre.016` | préparation publication minimale : prompt suivant + CHANGELOG + ROADMAP |
| `rel.001` | mécanique stable uniquement, aucun rattrapage fonctionnel |
Le forecast initial `pre.002 -> pre.013` est donc étendu jusqu'à `pre.016`. La cause n'est pas une inflation UI : c'est la découverte d'un contrat WS capability manquant qui doit être fermé proprement dans Transport, Config puis Worker avant consommation par la Desk.
## 21. Hors périmètre
```text
nouvelle source Worker
nouvelle stratégie de repair Worker
Backfill automatique ou campagne historique
Worker par endpoint physique
partage de gap ledger entre Workers
failover cross-Worker global
scheduler durable / restart après reboot
éditeur frontend de Config/endpoints/secrets
persistance browser des sélections
SQL/backend Store direct
provider SDK direct
raw transaction payload dans le monitoring
```
## 22. Résultat du gate `pre.001`
Le gate est clos côté analyse/planification avec les décisions suivantes :
```text
0.3.15 maintenue comme release
cinq routes V1 retenues
catalogue route app-owned
réseau dérivé d'un composite/profil app cohérent Transport+Store
plusieurs endpoints physiques restent choisis par Transport
1 Worker par route
Store partagé seulement par réseau identique
aucun gap Store / HTTP / lifecycle Worker essentiel
capability WS fine = gap lower-layer réel à fermer avant UI
Helius standard WS != Helius transactionSubscribe
aucune route rendue disponible à partir d'un exemple Config ou du provider name
forecast recalibré jusqu'à pre.016
```
`pre.002` doit donc commencer par le contrat Transport de capabilities WS, et non par le scaffold Tauri.

View File

@@ -0,0 +1,424 @@
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
<!-- version: 2 -->
# Validation v0.3.15 — Raw Transaction Ingest Desk
## 1. Rôle
Ce document enregistre les preuves et non-claims de `0.3.15`. En `pre.001`, aucune crate Desk, aucun Start/Stop Worker et aucune extension lower-layer ne sont encore implémentés : la tranche est exclusivement le gate de lecture, audit, brainstorming, external re-audit, sizing et planification imposé par `prompts/034-V0_3_15_START_PROMPT.md`.
## 2. Archive stable contrôlée
```text
archive : khadhroony-solana-project-v0.3.14.zip
SHA-256 : 897bd30b0d06c00abc120a7459250b78c11629e84825ac29adbe151d60a668ed
bytes : 8591925
entries : 2046
files : 1851
absolute entries : 0
parent traversal entries : 0
duplicate entries : 0
symlink entries : 0
workspace members : 21
crate manifests : 21
workspace.package.version : 0.3.14
edition : 2024
stable delta : deltas/0.3.14/rel.001.md
```
Artefacts interdits recherchés :
```text
Cargo.lock : absent
package-lock.json : absent
pnpm-lock.yaml : absent
yarn.lock : absent
rust-toolchain.toml : absent
.env : absent
target/ : absent
node_modules/ : absent
dist/ : absent
.git/ : absent
```
Résultat archive : PASS.
L'absence de `.git` empêche de comparer l'objet du tag `v0.3.14`; aucune équivalence cryptographique au tag n'est revendiquée.
## 3. Preuve opérateur stable fournie
Le journal opérateur joint à la demande contient notamment l'exécution stable `0.3.14` de :
```text
cargo clean
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
cargo test --workspace --all-targets --all-features
cargo tree -p ksp-worker-raw-transaction-ingest-lib --edges normal
cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features
cargo tree --duplicates
```
Les sorties fournies montrent notamment :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (340 table(s), 886 file(s))
Worker unit tests: 152 passed / 0 failed
Worker cross-layer completeness: 12 passed / 0 failed
Worker dependency boundary: 21 passed / 0 failed
Worker hardening: 38 passed / 0 failed
Worker public API: 22 passed / 0 failed
Worker release completeness: 15 passed / 0 failed
```
Le journal continue avec le gate workspace stable et ses tests. Cette preuve qualifie l'entrée `0.3.14`; elle n'est pas réutilisée comme prétendue exécution post-bump `0.3.15-pre.1`.
## 4. Audits locaux de la base avant modification
Exécuté localement :
```bash
python3 scripts/audit_rust_workspace_rules.py
```
Résultat :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
```
Exécuté localement :
```bash
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
```
Résultat :
```text
Markdown table audit: clean (340 table(s), 886 file(s))
```
`cargo`/`rustfmt` ne sont pas présents dans l'environnement d'assemblage courant. Aucune commande Cargo locale n'est déclarée PASS.
## 5. Audit des règles
Documents relus :
```text
RULES.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/rules/RULES_GENERAL.md
docs/rules/RULES_KSP.md
docs/rules/RULES_RUST.md
docs/rules/RULES_DEPENDENCIES.md
docs/rules/RULES_DOCUMENTATION.md
docs/rules/FILE_CONTRACTS.md
docs/rules/VERSION_WORKFLOW.md
docs/rules/PROMPT_STRUCTURE.md
```
Scan des définitions normatives :
```text
489 définitions
489 IDs uniques
0 doublon
```
Les deltas publiés antérieurs ne sont pas réécrits. Le gate `pre.001` modifie uniquement `Cargo.toml` et ajoute les trois livrables exigés.
## 6. Handoff stable et Worker audités
Les documents `0.3.14`, README/USAGE Worker et les sources/tests Worker ont été audités.
API publique pertinente confirmée :
```text
RawTransactionIngestRuntimeResources
RawTransactionIngestYellowstoneSource
RawTransactionIngestStandardLogsSource
RawTransactionIngestStandardBlockSource
RawTransactionIngestHeliusTransactionSource
RawTransactionIngestHttpBlockPollingSource
RawTransactionIngestWorker::start_with_runtime_resources
RawTransactionIngestHandle
RawTransactionIngestSnapshotSource
```
Frontières confirmées :
```text
Worker -X-> Config
Worker -X-> Job Backfill
Worker -X-> ksp-store-postgres-lib
Worker -> ksp-store-lib
Worker -> ksp-onchain-transport-lib
```
Plusieurs Workers peuvent recevoir le même `Arc<Store>` ; leurs lifecycle/gaps/TargetCoverage restent indépendants.
## 7. Requirements exacts des cinq familles Worker
| Route V1 | Network | Required capability | Optional capability | Config evidence | Worker resource | Composable aujourdhui ? | Missing contract | Live-testable ? |
|-------------------------------|------------------|----------------------------------------------------------------|-------------------------------------------------|-----------------------|-----------------------------------------------|---------------------------------------------------------|--------------------------------------------------|-----------------------------------------------|
| `yellowstone-hydrated` | réseau du profil | Yellowstone gRPC Subscribe + HTTP `getTransaction` même réseau | scan HTTP repair si rôle compatible | gRPC + HTTP role | `RawTransactionIngestYellowstoneSource` | oui sur profil complet et secrets résolus | aucun contrat essentiel | provider-gated selon profil |
| `standard-logs-hydrated` | réseau du profil | WS Solana standard `logsSubscribe` + HTTP `getTransaction` | scan HTTP repair si rôle compatible | WS + HTTP role | `RawTransactionIngestStandardLogsSource` | non prouvable strictement avant capability WS explicite | Transport + Config + enforcement Worker minimaux | oui, notamment Devnet keyless après extension |
| `standard-block-direct` | réseau du profil | WS Solana standard `blockSubscribe` explicitement déclaré | aucune hydration obligatoire | WS capability Block | `RawTransactionIngestStandardBlockSource` | non prouvable aujourdhui | Transport + Config + enforcement Worker minimaux | seulement endpoint prouvé compatible |
| `helius-transaction-hydrated` | réseau du profil | WS Helius `transactionSubscribe` + HTTP `getTransaction` | scan HTTP repair si rôle compatible | Helius WS + HTTP role | `RawTransactionIngestHeliusTransactionSource` | non dans les profils committed actuels | Config data/composite + capability WS explicite | provider-gated Helius |
| `http-block-polling` | réseau du profil | HTTP `getSlot` + `getBlocksWithLimit` + `getBlock` | `getTransaction` pour known-reference hydration | HTTP role | `RawTransactionIngestHttpBlockPollingSource` | oui lorsque le rôle résolu annonce les trois méthodes | aucun contrat essentiel | oui sur endpoint public compatible |
Qualification importante : `Composable aujourd'hui ?` signifie « prouvable à partir de la Config stable telle qu'elle est structurée », pas « le provider distant répond actuellement ».
## 8. Audit Config
`ResolvedTransportConfig` fournit des settings typed HTTP/WS/gRPC et `ResolvedStoreConfig` fournit les settings Store sans exiger une lecture JSON frontend.
HTTP : rôles et `request_kinds` sont déjà projetables côté Rust.
WS : le protocol kind est projetable, mais `WsEndpointSettings` ne porte pas de liste de `WsSubscriptionKind`. C'est le gap déterminant de `pre.001`.
Profils committed vs exemple :
| Profil/config | Réseau | Surfaces | Secret requis | Committed ? | Observation |
|-------------------------|------------------------------|---------------------------------------|-----------------------|----------------------|-------------------------------------------|
| `devnet_public` | devnet | HTTP + WS Solana standard | non | oui | pas de capability WS fine aujourdhui |
| `orbitflare_devnet` | devnet | HTTP + WS standard + Yellowstone gRPC | token gRPC secret | conditionnel | profil complet seulement si secret résolu |
| `mainnet_public` | mainnet | HTTP + WS Solana standard | non | oui | pas de capability WS fine aujourdhui |
| `mainnet_backfill_pool` | mainnet | plusieurs HTTP + WS standard | selon endpoint/config | oui si profil résolu | priorités/rôles restent Transport-owned |
| `publicnode_mainnet` | mainnet | HTTP + WS standard + Yellowstone gRPC | x-token secret | conditionnel | gRPC provider-gated |
| `publicnode_testnet` | testnet | HTTP + WS standard + Yellowstone gRPC | x-token secret | conditionnel | gRPC provider-gated |
| Helius exemple | mainnet/devnet selon exemple | WS `helius_laserstream` | API key secret | non committed | exemple != profil actif |
Aucun profil Helius WS n'est committed dans `config/std.transport.json`; sa présence dans un exemple ne constitue pas une availability V1.
## 9. Audit Store
Chemin validé :
```text
ResolvedStoreConfig -> StoreSettings -> ksp-store-lib::Store::open
```
Aucun besoin de nouvelle API Store n'est identifié pour inventaire, Start/Stop ou partage du Store entre Workers du même réseau.
## 10. Audit gabarit Desk
Les cinq Desk KSP existantes ont été utilisées comme références de structure et non comme code à copier pendant `pre.001`.
Socle confirmé :
```text
splash KSP commun
fonts/style KSP
backend Tauri Rust propriétaire des ressources
frontend sans accès direct réseau/Store/secrets
@fltsci/tauri-plugin-tracing
@fortawesome/fontawesome-free
@tauri-apps/api
bootstrap
resize-observer-polyfill
simplebar
```
Aucun upgrade npm opportuniste n'est retenu.
## 11. External re-audit `pre.001`
Sources primaires/courantes consultées pour qualifier les capabilities :
```text
Solana JSON-RPC WebSocket blockSubscribe
Solana JSON-RPC WebSocket logsSubscribe
Yellowstone gRPC upstream Subscribe/proto/changelog
Helius WebSocket standard + transactionSubscribe + unsupported methods
PublicNode Solana RPC/WS/Yellowstone offre actuelle
OrbitFlare Yellowstone gRPC offre actuelle
```
Constats utilisés :
```text
blockSubscribe est unstable et dépend de l'activation côté validator/provider
logsSubscribe est standard
Helius distingue les méthodes Solana standard de son extension transactionSubscribe
Helius indique blockSubscribe non supporté
Yellowstone expose les filtres Subscribe et le replay/from_slot lower-layer
```
Aucune de ces informations Web n'est convertie directement en route sélectionnable : Config locale reste l'autorité de composabilité.
## 12. Gap classification
| Sujet | Classification | Owner | Décision |
|--------------------------------------------------|------------------------------|--------------------|----------------------------------------------------------------|
| Catalogue de cinq routes et IDs applicatifs | adaptation app seulement | Desk | catalogue borné, pas de nouvelle crate |
| Projection HTTP `request_kinds` / rôles / réseau | aucun gap | Config + Transport | déjà exploitable côté Rust |
| Projection gRPC Yellowstone / metadata sûre | aucun gap | Config + Transport | secrets restent Rust-only |
| Capability WS exacte par subscription | extension Transport minimale | Transport | ajouter une déclaration typed réutilisant `WsSubscriptionKind` |
| Mapping schema/config des capabilities WS | extension Config minimale | Config | Config reste propriétaire de la déclaration |
| Refus Worker si capability WS requise absente | extension Worker minimale | Worker | enforcement avant I/O, pas de logique provider dans Desk |
| Composite dédié Raw Ingest Desk | extension Config minimale | Config | profils app dédiés et cohérents Store/Transport |
| Store open / network / partage `Arc<Store>` | aucun gap | Store + app | `ksp-store-lib` suffit |
| Lifecycle / stop / snapshots Worker | aucun gap | Worker + app | handles publics existants |
| Backfill / historical repair | hors scope | Job Backfill | aucune orchestration automatique |
| Taille release | pas de split de release | plan | forecast étendu jusquà `pre.016` |
Résultat : `0.3.15` reste une release cohérente. Aucun split vers `0.3.16` n'est nécessaire avant implémentation, mais le forecast interne est élargi.
## 13. Décisions UX / architecture validées au gate
```text
catalogue de routes V1 app-owned
cinq route IDs bornés
réseau dérivé d'un composite/profil app cohérent Store+Transport
changement de profil interdit pendant Workers actifs
inventaire Config sans I/O réseau
Start revalide toute la Config
multiple endpoints satisfaisant une route : sélection Transport selon rôles/priorités
1 Worker par route
fault d'une route n'arrête pas les autres
Store partagé seulement si réseau strictement identique
fermeture app : stop/join de tous les Workers détenus
frontend sans endpoints/secrets/handles/source keys/payloads bruts
```
États UI retenus :
| État UI | Sémantique | Action principale |
|-------------|----------------------------------------------------------------|-------------------------------------|
| Unavailable | requirements incomplets ou incohérents | non |
| Configured | requirements Config complètes, aucune preuve runtime | oui |
| Starting | revalidation + reconstruction + ouverture Store + start Worker | non |
| Running | Worker actif, snapshots reçus | Stop |
| Stopping | stop demandé, attente terminale bornée | non |
| Stopped | Worker terminal propre, handle retiré | Start après nouvelle revalidation |
| Faulted | échec Start/runtime avec code sûr | Start après correction/revalidation |
## 14. IPC et tracing planifiés
| DTO candidat | Sens | Contenu autorisé | Exclusions |
|---------------------------------|---------------------|------------------------------------------------------------------------------|------------------------------------------|
| `RawIngestDeskOptionsDto` | backend -> frontend | profils logiques sûrs, réseaux, commitments supportés, génération inventaire | URL, secret, Store URI |
| `RawIngestRouteDto` | backend -> frontend | route_id, family, label, network, state, selectable, reason code | endpoint name/URL/token/source key |
| `RawIngestRouteStartRequestDto` | frontend -> backend | route_id, inventory_generation, commitment | endpoint/credential/client |
| `RawIngestRouteStopRequestDto` | frontend -> backend | route_id | Worker handle |
| `RawIngestRouteRuntimeDto` | backend -> frontend | route_id, lifecycle/health/activity, compteurs source-neutral | payload brut, erreur provider arbitraire |
| `CommandErrorDto` | backend -> frontend | code stable + contexte whiteliste | texte remote arbitraire |
| `FrontendLogPayloadDto` | frontend -> backend | target/level/action IDs bornés | valeurs config/route sensibles |
| Interaction | Trace autorisée | Interdit |
|--------------------------|---------------------------------------------|----------------------------------|
| Navigation/tab | control_id + action | aucun profil, endpoint ou secret |
| Sélection profil/réseau | action + résultat code + counts | pas de valeur de secret ni URL |
| Sélection route | route family/route_id sûr + booléen | pas de source key |
| Start/Stop | route_id sûr + lifecycle outcome code | pas de payload Worker |
| Refresh/resync snapshots | action + sequence/count | pas de transactions |
| IPC success/failure | command id + stable code + durée éventuelle | pas derreur remote brute |
Ces tables décrivent le contrat de sécurité à implémenter ; elles ne revendiquent aucune commande Tauri existante en `pre.001`.
## 15. Sizing / forecast
| Tranche | Objectif borné |
|-----------|------------------------------------------------------------------------------------------------------|
| `pre.001` | audit, route model, external re-audit, sizing, plan/validation |
| `pre.002` | Transport : capability WS typed par subscription + tests, sans app |
| `pre.003` | Config : schema/mapping capabilities WS + composite/profils Raw Ingest Desk |
| `pre.004` | Worker : enforcement des capabilities WS déclarées + canaris route constructors |
| `pre.005` | scaffold `ksp-app-raw-transaction-ingest-desk`, gabarit KSP, DTO/route IDs/states, sans Start Worker |
| `pre.006` | Config -> inventaire de routes composables/non composables + raisons sûres |
| `pre.007` | reconstruction/revalidation Start des ressources Transport pour les cinq routes, sans launch Worker |
| `pre.008` | Store lifecycle + Start/Stop mono-route réel |
| `pre.009` | multi-route : un Worker par route, même Store, isolation des faults |
| `pre.010` | snapshots/events/monitoring lifecycle-health-activity-backpressure-reconnect-replay-gaps-repair |
| `pre.011` | frontend fonctionnel complet + tracing TypeScript sûr |
| `pre.012` | races, shutdown app, sécurité IPC, hardening hostile/stale inventory |
| `pre.013` | cross-layer completeness + canaris système sans expansion de frontières |
| `pre.014` | gate technique/live accessible + frontend/Tauri + build final de validation technique |
| `pre.015` | réconciliation documentaire finale : plan/validation/README/USAGE |
| `pre.016` | préparation publication minimale : prompt suivant + CHANGELOG + ROADMAP |
| `rel.001` | mécanique stable uniquement, aucun rattrapage fonctionnel |
Le forecast initial du prompt n'est pas recopié : trois tranches lower-layer précèdent volontairement le scaffold UI.
## 16. Modifications `pre.001`
Ajouts :
```text
docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md
docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md
deltas/0.3.15/pre.001.md
```
Modification :
```text
Cargo.toml
header 593 -> 594
workspace.package.version 0.3.14 -> 0.3.15-pre.1
```
Aucun fichier de production Rust, Config, frontend ou Tauri n'est modifié par le gate.
## 17. Validations post-modification
Exécuté localement après le bump et lajout des trois livrables :
```bash
python3 scripts/audit_rust_workspace_rules.py
```
Résultat :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
```
Exécuté localement :
```bash
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
```
Résultat :
```text
Markdown table audit: clean (354 table(s), 889 file(s))
```
Contrôles complémentaires :
```text
rule definitions : 489
unique rule IDs : 489
duplicates : 0
stable -> worktree : 3 additions / 1 modification / 0 deletion
modified stable file : Cargo.toml seulement
```
Non exécuté localement :
```text
cargo fmt --all -- --check : NON EXÉCUTÉ — cargo absent du sandbox
cargo check --workspace : NON EXÉCUTÉ — cargo absent du sandbox
cargo clippy --workspace --all-targets --all-features -- -D warnings : NON EXÉCUTÉ — cargo absent du sandbox
cargo test : NON EXÉCUTÉ — cargo absent du sandbox
```
Aucun de ces gates Cargo nest déclaré PASS. Ils restent dans le gate opérateur après application du delta.