v0.2.8-pre.001-fix.001

This commit is contained in:
2026-08-23 12:46:17 +02:00
parent f0865d5137
commit df95f2f558
3 changed files with 880 additions and 457 deletions

View File

@@ -0,0 +1,269 @@
<!-- file: deltas/0.2.8/pre.001-fix.001.md -->
<!-- version: 1 -->
# Delta `0.2.8-pre.001-fix.001` — séparation des façades WebSocket et forecast visible
## 1. Base requise
Ce correctif s'applique exclusivement après :
```text
0.2.8-pre.001
workspace.package.version = 0.2.8-pre.1
```
Il corrige le **plan et la matrice de validation** de `pre.001` avant toute implémentation de `pre.002`.
Le correctif est documentaire uniquement. Conformément à `VER-ID-008` :
```text
livraison = 0.2.8-pre.001-fix.001
workspace.package.version = 0.2.8-pre.1 # inchangé
commit attendu = v0.2.8-pre.001-fix.001
```
## 2. Motif du fix
Le plan initial faisait porter à un `WsSession` public commun toute la surface WebSocket, puis utilisait une capability matrix pour rejeter avant I/O les méthodes standard non supportées par Helius.
Après revue du code réel `v0.2.7`, cette forme est jugée trop permissive au niveau API : les neuf wrappers standard sont directement implémentés sur `WsSession`. Un endpoint Helius aurait donc pu être représenté par un type exposant publiquement `block_subscribe`, `slots_updates_subscribe` et `vote_subscribe`, même si ces appels étaient ensuite rejetés.
Décision corrigée :
```text
séparer les façades publiques par protocole
partager intégralement le moteur physique/lifecycle
rendre les méthodes provider non supportées absentes de la façade Helius
conserver une validation interne defense-in-depth
```
## 3. Architecture corrigée
Cible :
```text
WsSession
moteur physique partagé
actor/socket/reconnect/queues
┌────────────┴────────────┐
▼ ▼
SolanaStandardWsSession HeliusLaserStreamWsSession
9 familles 6 standard communes
+ transaction
+ heartbeat policy
```
### Surface standard
```text
Account
Block
Logs
Program
Root
Signature
Slot
SlotsUpdates
Vote
```
### Surface Helius
```text
Account
Logs
Program
Root
Signature
Slot
HeliusTransaction
```
Absents de la façade Helius :
```text
Block
SlotsUpdates
Vote
```
Les DTOs standard réellement identiques restent partagés. Les DTOs Helius sont créés uniquement pour les contrats provider-specific (`transactionSubscribe`, `tokenAccounts`, notification transaction, etc.).
`WsSession` reste compatible avec la surface standard publiée en `0.2.7`. La façade Helius ne doit fournir aucun escape hatch public (`inner`/`into_inner`) qui permettrait de récupérer un handle générique et de contourner sa surface.
## 4. Capability matrix — rôle corrigé
La capability matrix n'est plus la première barrière publique. Elle devient une protection interne :
```text
API/façade correcte
-> méthodes impossibles absentes
-> validation descriptor/constructor avant I/O
-> actor commun
```
Matrice interne conservée :
```text
SolanaStandard:
Account Block Logs Program Root Signature Slot SlotsUpdates Vote -> allowed
HeliusTransaction -> rejected
HeliusLaserStream:
Account Logs Program Root Signature Slot HeliusTransaction -> allowed
Block SlotsUpdates Vote -> rejected
```
## 5. Gate Cargo désormais fermé
Les commandes manquantes de `pre.001` ont été fournies par l'opérateur :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
```
Résolution observée :
```text
futures-util 0.3.34
tokio 1.53.1
tokio-tungstenite 0.30.0
reqwest 0.13.4
new Helius SDK aucun
```
Doublons ciblés :
```text
syn 2.0.119 / 3.0.3
webpki-roots 0.26.11 / 1.0.9
```
Ils sont transitifs dans le graphe actuel et ne bloquent pas le gate.
**Verdict : gate `pre.001` positif après ce fix documentaire.**
## 6. Forecast souple recalibré
Le forecast revient à `pre.001 -> pre.011` parce que la séparation de façade mérite une tranche propre et que les six wrappers standard supportés par Helius doivent être validés séparément de la mécanique de connexion commune.
```text
pre.001 audit/sizing/matrice/dependencies
pre.001-fix.001 architecture de façades + gate Cargo + forecast visible
pre.002 socle protocolaire : protocol kind + façades + connexion physique partagée
pre.003 6 familles standard Helius + absence typée Block/SlotsUpdates/Vote
pre.004 Config V2 helius_laserstream + secret strategy
pre.005 transactionSubscribe/unsubscribe request/filter/options/tokenAccounts
pre.006 transactionNotification + reconnect/resubscribe/unsubscribe races
pre.007 heartbeat/idle lifecycle
pre.008 adversarial provider/security/backpressure
pre.009 compliance + standard WS 18/18 + HTTP 52/14 + Config/API canaries
pre.010 live smoke opt-in si sûr + README/USAGE + dependency audit
pre.011 workspace final + fermeture docs/matrix/indexes + prompt 0.2.9
rel.001 stable
```
Chaque tranche vise nominalement 1520 minutes. Le plan contient désormais un tableau immédiatement visible avec objectif, preuves, budget et critères de split pour chaque tranche.
`pre.011` n'est pas une deadline ; `pre.012+` ou des fixes sont ajoutés si nécessaire.
## 7. Fichiers ajoutés
```text
deltas/0.2.8/pre.001-fix.001.md
```
## 8. Fichiers modifiés
```text
docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md
```
## 9. Fichiers volontairement inchangés
```text
Cargo.toml
ROADMAP.md
CHANGELOG.md
.env.example
config/**
crates/**
docs/000-README.md
docs/plans/000-README.md
docs/validation/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
deltas/0.2.8/pre.001.md
```
Le delta `pre.001` publié reste immutable ; ce fix ne le réécrit pas.
## 10. Validations et preuves
### Réellement fournies par l'opérateur avant ce fix
```text
baseline v0.2.7 : fmt/audit/check/clippy/test workspace = OK
cargo tree transport = exécuté
cargo tree transport --duplicates = exécuté
```
### Réellement exécutées dans l'environnement de préparation du fix
```text
inspection du code public WsSession/WsSubscriptionKind/WsSessionSnapshot = OK
lecture VERSION_WORKFLOW.md pour VER-ID-008 = OK
contrôle overlay documentaire = OK
```
L'audit Rust workspace est réexécuté sur le workspace reconstitué après application de l'overlay lorsque le script est disponible.
### Non exécutées pour ce fix documentaire
```text
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
```
Motif : aucun code/build/runtime/config n'est modifié par ce correctif et l'environnement de préparation ne fournit pas Cargo.
## 11. Décisions prises
```text
façades publiques séparées par protocole
moteur WsSession actor unique partagé
SolanaStandardWsSession = 9 familles standard
HeliusLaserStreamWsSession = 6 familles standard + transaction
Block/SlotsUpdates/Vote absents de la façade Helius
capability matrix conservée defense-in-depth
DTOs communs réutilisés si wire identique
DTOs Helius dédiés seulement aux divergences
pas d'escape hatch Helius vers raw WsSession
forecast visible et recalibré jusqu'à pre.011
Cargo pre.1 inchangé car fix documentaire
```
## 12. Questions ouvertes laissées à `pre.002+`
```text
forme interne minimale pour partager la connexion physique sans dupliquer l'actor
forme exacte des constructeurs des deux façades
extension minimale de WsSubscriptionKind/snapshot pour HeliusTransaction
forme typed des différents transactionDetails insuffisamment documentés
wire éventuel futur de enhanced/filtered accountSubscribe
```
Ces questions ne remettent pas en cause la frontière décidée : **surface publique séparée, moteur physique partagé**.
## 13. Prochaine tranche
```text
0.2.8-pre.002
```
Mission : matérialiser uniquement le socle protocolaire et les façades/constructeurs autour du moteur `WsSession` existant. Ne pas commencer `transactionSubscribe` ni Config Helius dans cette tranche.

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Validation `0.2.8` — Helius LaserStream WebSocket
> **Statut : matrice ouverte par `0.2.8-pre.001`.** Les lignes normatives/sizing sont fermées ; les preuves runtime restent à matérialiser dans les prereleases suivantes. Le gate initial reste conditionné aux graphes Cargo opérateur absents du sandbox de préparation.
> **Statut : gate `0.2.8-pre.001` positif ; architecture corrigée par `0.2.8-pre.001-fix.001`.** Les graphes Cargo opérateur sont reçus et non bloquants. La validation runtime à venir doit prouver deux façades protocolaires distinctes partageant un seul moteur `WsSession`, et non un `WsSession` Helius générique exposant des méthodes provider non supportées.
## 1. Références
@@ -11,6 +11,8 @@
prompt prompts/013-V0_2_8_START_PROMPT.md
plan docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
base stable v0.2.7 / deltas/0.2.7/rel.001.md
pre.001 deltas/0.2.8/pre.001.md
fix architecture deltas/0.2.8/pre.001-fix.001.md
validation standard WS docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
HTTP compliance docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
@@ -18,31 +20,102 @@ KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AU
Audit Helius initial : **2026-08-23**.
## 2. Matrice provider normative initiale
## 2. Gate `pre.001` et dependency graph
| Capability | Standard KSP | Helius doc actuelle | Décision `0.2.8` | Preuve finale attendue |
|-------------------------------------|----------------:|-------------------------------------------------------|-----------------------------|-------------------------------------------|
| `accountSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `logsSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `programSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `rootSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `signatureSubscribe` pair | oui | supporté | réutiliser standard | one-shot conservé |
| `slotSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `blockSubscribe` pair | oui, unstable | non supporté Helius | rejet avant I/O | capability canary |
| `slotsUpdatesSubscribe` pair | oui, unstable | **docs divergentes ; index exhaustif = non supporté** | rejet avant I/O | canary + divergence documentée |
| `voteSubscribe` pair | oui, unstable | non supporté Helius | rejet avant I/O | capability canary |
| `transactionSubscribe` | non standard | extension Helius | ajouter typed | request/ack/notification fixtures |
| `transactionUnsubscribe` | non standard | explicitement documenté dans référence transaction | ajouter via handle | exact method + late message race |
| `tokenAccounts` | non standard | `none/balanceChanged/all` | ajouter typed | enum + serialization + invalid impossible |
| `notifyOn` account | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absence public DTO |
| `notifyOn` program | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absence public DTO |
| « enhanced accountSubscribe » extra | non standard | mentionné mais wire exact actuel non publié | report explicite | réaudit final |
| proactive heartbeat | absent standard | 10 min idle, ping recommandé | Helius-only actor heartbeat | deterministic timer tests |
| replay historique | absent standard | WebSocket sans contrat KSP de replay | interdit | docs/canary no promise |
Baseline opérateur acquise :
## 3. Contrat `transactionSubscribe` à couvrir
```text
cargo fmt --all OK
python3 scripts/audit_rust_workspace_rules.py clean
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test --workspace OK
```
### Filter
Graphes requis reçus :
```text
cargo tree -p ksp-onchain-transport-lib OK / inspecté
cargo tree -p ksp-onchain-transport-lib --duplicates OK / inspecté
```
Versions résolues observées :
```text
futures-util 0.3.34
tokio 1.53.1
tokio-tungstenite 0.30.0
reqwest 0.13.4
```
Doublons ciblés visibles :
```text
syn 2.0.119 / 3.0.3
webpki-roots 0.26.11 / 1.0.9
```
Verdict : doublons transitifs, aucune nouvelle dépendance Helius, aucune anomalie bloquante du gate.
## 3. Matrice provider normative
| Capability | Standard KSP | Helius doc actuelle | Décision `0.2.8` | Surface Helius attendue | Preuve finale attendue |
|------------------------------|----------------:|---------------------------------------------------|--------------------------|-------------------------|---------------------------------------|
| `accountSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `logsSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `programSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `rootSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression |
| `signatureSubscribe` pair | oui | supporté | réutiliser standard | présente | one-shot conservé |
| `slotSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression |
| `blockSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O |
| `slotsUpdatesSubscribe` pair | oui, unstable | docs divergentes ; index exhaustif = non supporté | ne pas exposer Helius | **absente** | API absence + divergence documentée |
| `voteSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O |
| `transactionSubscribe` | non standard | extension Helius | ajouter typed | présente | request/ack/notification fixtures |
| `transactionUnsubscribe` | non standard | documenté dans référence transaction | ajouter via handle | présente | exact method + late-message race |
| `tokenAccounts` | non standard | `none/balanceChanged/all` | ajouter typed | présente dans filter | enum + serialization |
| `notifyOn` account | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public |
| `notifyOn` program | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public |
| enhanced account extra | non standard | mentionné, wire exact non publié | report explicite | absente | réaudit final |
| proactive heartbeat | absent standard | 10 min idle, ping recommandé | Helius-only actor policy | interne | deterministic timer tests |
| replay historique | absent standard | pas de contrat WS KSP | interdit | absent | docs/canary no promise |
## 4. Matrice des façades protocolaires
### 4.1 Surface attendue
| Famille | `SolanaStandardWsSession` | `HeliusLaserStreamWsSession` | DTO/wire |
|--------------------|:-------------------------:|:----------------------------:|--------------------|
| Account | oui | oui | partagé standard |
| Block | oui | **non** | standard seulement |
| Logs | oui | oui | partagé standard |
| Program | oui | oui | partagé standard |
| Root | oui | oui | partagé standard |
| Signature | oui | oui | partagé standard |
| Slot | oui | oui | partagé standard |
| SlotsUpdates | oui | **non** | standard seulement |
| Vote | oui | **non** | standard seulement |
| Helius Transaction | **non** | oui | provider-specific |
### 4.2 Invariants architecture
| Critère | Décision | Preuve cible | État |
|-------------------------------------|-----------------------------------------------|---------------------------------|--------|
| actor physique | un seul `WsSession` actor partagé | source/runtime canary | décidé |
| façade standard | `SolanaStandardWsSession` | public API canary | décidé |
| façade Helius | `HeliusLaserStreamWsSession` | public API canary | décidé |
| escape hatch Helius | aucun `inner()`/`into_inner()` public | API/source canary | décidé |
| generic Helius `WsSession::connect` | ne doit pas permettre de contourner la façade | invalid protocol pre-I/O canary | décidé |
| Helius unsupported | absent de la façade | compile-fail/API absence canary | décidé |
| standard Helius commun | délégation vers le même wire/actor | exact fixture | décidé |
| DTO duplication | seulement si wire/sémantique divergent | public/source audit | décidé |
| Config direction | Config -> Transport uniquement | ownership tests | décidé |
| heartbeat | Helius-only, actor commun | deterministic timers | décidé |
| secret | query URL derrière `WsEndpointUrl` | redaction canaries | décidé |
| new Rust dependency | aucune | manifest/tree audit | décidé |
## 5. `transactionSubscribe` à couvrir
### 5.1 Filter
| Champ | Type | Limite/état | Statut |
|-------------------|--------------------|-------------------------------------|-------------|
@@ -54,7 +127,7 @@ Audit Helius initial : **2026-08-23**.
| `accountRequired` | string[] | <= 50 000 | audit fermé |
| `tokenAccounts` | enum string | `none`, `balanceChanged`, `all` | audit fermé |
### Options
### 5.2 Options
| Champ | Valeurs | Règle | Statut |
|----------------------------------|-------------------------------|-----------------------------------|-------------|
@@ -64,38 +137,36 @@ Audit Helius initial : **2026-08-23**.
| `showRewards` | bool | optionnel | audit fermé |
| `maxSupportedTransactionVersion` | integer | requis pour accounts/full | audit fermé |
### Notification
### 5.3 Notification
```text
method = transactionNotification
full documented result = transaction + signature + slot + transactionIndex
```
Le wire exact de tous les modes n'est pas suffisamment détaillé par la source officielle initiale. La validation finale exige :
- aucune forme inventée ;
- types précis pour les formes prouvées ;
- fallback borné/opaque pour une forme officielle non encore explicitée si nécessaire ;
- aucune projection brute dans logs/snapshots.
## 4. Matrice architecture
| Critère | Décision pre.001 | Preuve cible | État |
|-------------------------|--------------------------------------------|-------------------------------------------|----------------------|
| actor unique | réutiliser `WsSession` | aucun second client dans sources/manifest | décidé |
| protocol descriptor | `HeliusLaserStream` / `helius_laserstream` | public API + Config canary | décidé |
| provider metadata | `helius` reste metadata | snapshot sûr | décidé |
| Helius transaction kind | nouvelle variante provider explicite | registry triplet exact | décidé |
| capability before I/O | oui | local peer reçoit 0 request interdite | décidé |
| standard DTO pollution | interdite | public API/source canary | décidé |
| Config direction | Config -> Transport uniquement | ownership tests | décidé |
| heartbeat | actor Helius-only, 60s cible | deterministic timers | décidé |
| secret | URL query derrière `WsEndpointUrl` | redaction canaries | décidé |
| new Rust dependency | aucune | manifest/tree audit | décidé, tree pending |
## 5. Validation lifecycle/provider à construire
Validation finale :
```text
aucune forme inventée
types précis pour les formes prouvées
fallback borné si une forme officielle reste insuffisamment explicitée
aucun payload brut dans logs/snapshots
```
## 6. Validation lifecycle/provider à construire
```text
[ ] un seul actor/socket implementation path
[ ] SolanaStandardWsSession public et constructible
[ ] HeliusLaserStreamWsSession public et constructible
[ ] WsSession historique standard reste compatible
[ ] Helius facade n'expose pas blockSubscribe
[ ] Helius facade n'expose pas slotsUpdatesSubscribe
[ ] Helius facade n'expose pas voteSubscribe
[ ] SolanaStandard facade n'expose pas transactionSubscribe
[ ] Helius facade n'expose aucun escape hatch vers le handle générique
[ ] protocol mismatch rejeté avant I/O
[ ] 6 familles standard Helius utilisent le wire standard exact
[ ] transaction subscribe/ack exact
[ ] transaction unsubscribe/result exact
[ ] transaction notification dispatch exact
@@ -114,7 +185,7 @@ Le wire exact de tous les modes n'est pas suffisamment détaillé par la source
[ ] payload/filters/api-key absents de Debug/snapshots sûrs
```
## 6. Non-régressions obligatoires
## 7. Non-régressions obligatoires
```text
[ ] standard WebSocket 18/18 toujours comptabilisé pour SolanaStandard
@@ -128,7 +199,7 @@ Le wire exact de tous les modes n'est pas suffisamment détaillé par la source
[ ] no Transport -> Config/Wallet/Store/Program/tracing direct
```
## 7. Security/redaction
## 8. Security/redaction
```text
[ ] api-key absente de Debug WsEndpointUrl
@@ -139,59 +210,38 @@ Le wire exact de tous les modes n'est pas suffisamment détaillé par la source
[ ] raw transaction payload absent des logs/snapshots
[ ] large filter addresses non loggées
[ ] provider error payload arbitraire non copié dans context
```
## 8. Dependencies
Audit web du 2026-08-23 :
```text
futures-util 0.3.34
tokio 1.53.1
tokio-tungstenite 0.30.0
reqwest 0.13.4
new dependency aucune prévue
```
Preuve locale `pre.001` :
```text
python3 scripts/audit_rust_workspace_rules.py = clean
cargo tree = impossible dans sandbox, cargo absent
```
Gate opérateur requis :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
[ ] façade Helius ne permet pas de contourner les capabilities par exposition du inner
```
## 9. Smoke live
Statut initial : **non exécuté**.
Contrat cible : opt-in, Config résout l'api-key, Transport ne lit pas l'environnement. Aucun secret n'est versionné ou affiché. Un échec au plan/credential provider doit rester distinguable d'une panne du moteur.
Contrat cible : opt-in, Config résout l'api-key, Transport ne lit pas l'environnement. Aucun secret n'est versionné ou affiché. Un échec lié au plan/credential provider doit rester distinguable d'une panne du moteur.
## 10. Forecast courant
Le forecast détaillé et normatif est visible dans la section 3 du plan. Résumé :
```text
pre.001 audit/sizing
pre.002 protocol + capability model
pre.003 Config V2 + secrets
pre.004 transaction request/unsubscribe
pre.005 transaction notification + lifecycle
pre.006 heartbeat
pre.007 adversarial/security/backpressure
pre.008 compliance/non-regression
pre.009 live smoke/docs/dependency graph
pre.010 final workspace/prompt 0.2.9
pre.001-fix.001 façades séparées + gate Cargo fermé
pre.002 socle protocolaire/façades/connect partagé
pre.003 6 wrappers Helius communs + absence 3 unsupported
pre.004 Config V2 + secrets
pre.005 transaction request/unsubscribe
pre.006 transaction notification + lifecycle
pre.007 heartbeat
pre.008 adversarial/security/backpressure
pre.009 compliance/non-regression
pre.010 live smoke/docs/dependency graph
pre.011 final workspace/prompt 0.2.9
rel.001 stable
```
Le forecast est révisable ; seul le respect des gates autorise la publication.
Le forecast reste souple ; le numéro final n'est jamais un critère de clôture.
## 11. Gate initial
## 11. Gate initial après fix
```text
[x] base stable inspectée
@@ -203,14 +253,17 @@ Le forecast est révisable ; seul le respect des gates autorise la publication.
[x] tokenAccounts inventorié
[x] notifyOn classé deprecated/no-op
[x] divergence slotsUpdates enregistrée et arbitrée explicitement
[x] protocol/capability architecture décidée
[x] architecture corrigée : surfaces protocolaires séparées
[x] moteur WsSession/actor unique préservé
[x] stratégie de compatibilité WsSession 0.2.7 définie
[x] heartbeat ownership décidé
[x] Config shape décidée
[x] credential strategy décidée
[x] aucune nouvelle dépendance justifiée
[x] forecast recalibré
[ ] cargo tree direct exécuté par opérateur
[ ] cargo tree duplicates exécuté par opérateur
[x] forecast recalibré et rendu visible dans le plan
[x] cargo tree direct exécuté par opérateur
[x] cargo tree duplicates exécuté par opérateur
[x] doublons ciblés analysés comme transitifs/non bloquants
```
Verdict : **gate normatif/architectural prêt ; gate `pre.001` entièrement positif après réception des deux graphes Cargo sans anomalie bloquante.**
Verdict : **gate `0.2.8-pre.001` positif. `pre.002` peut ouvrir le socle protocolaire/façades sans commencer prématurément `transactionSubscribe`.**