v0.3.14-pre.015
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
|
||||
<!-- version: 40 -->
|
||||
<!-- version: 41 -->
|
||||
|
||||
# Inventaire initial des composants KSP
|
||||
|
||||
@@ -46,7 +46,7 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse
|
||||
| Store Desk | `ksp-app-store-desk` | app | Implémenté | `0.3.8` | inspection RAW read-only Transaction/Account/Observation via façade Store |
|
||||
| RAW transaction common | `ksp-raw-transaction-lib` | lib | Implémenté | `0.3.10` | canonicalisation/wire RAW Transaction v1 source-neutral partagé entre producteurs |
|
||||
| Worker lifecycle | `ksp-worker-api` | API | Implémenté | `0.3.9` | lifecycle/health/progression génériques des services continus |
|
||||
| RAW transaction worker | `ksp-worker-raw-transaction-ingest-lib` | worker/lib | Implémenté | `0.3.11`–`0.3.13` | fondation + 5 familles live, convergence multi-source, fairness, health et shutdown bornés |
|
||||
| RAW transaction worker | `ksp-worker-raw-transaction-ingest-lib` | worker/lib | Implémenté | `0.3.11`–`0.3.14` | 5 familles live + gaps/coverage/repair run-local, fairness, health et shutdown bornés |
|
||||
| RAW ingest Desk | `ksp-app-raw-transaction-ingest-desk` | app | Retenu | `0.3.15` | choix/supervision d’une ou plusieurs sources/méthodes sans réimplémenter le worker |
|
||||
| STRUCTURAL job | nom à fixer | job/lib | Retenu | couche STRUCTURAL | normalisation Solana générique RAW -> STRUCTURAL bornée/rejouable |
|
||||
| STRUCTURAL worker | nom à fixer | worker/lib | Retenu | fin couche STRUCTURAL | backlog RAW -> STRUCTURAL continu |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/005-DEPENDENCY_GRAPH.md -->
|
||||
<!-- version: 29 -->
|
||||
<!-- version: 30 -->
|
||||
|
||||
# Graphe de dépendances KSP
|
||||
|
||||
@@ -433,9 +433,9 @@ ksp-worker-control-lib # composant retenu, non matérialis
|
||||
-> ksp-core-lib
|
||||
```
|
||||
|
||||
`ksp-worker-api` est ouvert en `0.3.9` comme contrat générique de services continus et ne connaît ni Solana, ni Transport, ni Store, ni Tauri. `ksp-worker-raw-transaction-ingest-lib` est son premier consumer concret : sa fondation `0.3.11` possède admission/persistence/snapshots/shutdown ; `0.3.12` ouvre la première verticale Yellowstone + hydration HTTP ; `0.3.13` matérialise la composition live multi-source. Config et le backend physique restent hors du Worker.
|
||||
`ksp-worker-api` est ouvert en `0.3.9` comme contrat générique de services continus et ne connaît ni Solana, ni Transport, ni Store, ni Tauri. `ksp-worker-raw-transaction-ingest-lib` est son premier consumer concret : sa fondation `0.3.11` possède admission/persistence/snapshots/shutdown ; `0.3.12` ouvre la première verticale Yellowstone + hydration HTTP ; `0.3.13` matérialise la composition live multi-source ; `0.3.14` ferme la continuité run-local par gaps bornés, preuves de coverage, repair conservatif, health gap-aware et shutdown/fairness durcis. Config et le backend physique restent hors du Worker.
|
||||
|
||||
La verticale actuelle n'est ni « un worker WebSocket » ni un moteur historique : `RawTransactionIngestRuntimeResources` contient de `1` à `32` sources logiques validées d'un même réseau parmi cinq familles — Yellowstone, Standard WS `logsSubscribe`, Standard WS `blockSubscribe`, Helius `transactionSubscribe` et HTTP live block polling. Yellowstone, Standard Logs et Helius convergent vers une registry globale d'hydration HTTP `getTransaction`; Standard Block et HTTP Block Polling qualifient directement le wire Base64 Legacy/V0/V1 vers Common RAW. Toutes les acquisitions rejoignent la même admission/persistence, la convergence canonique `(network, signature)` et des observations distinctes par provenance. Reconnect, `from_slot` et `SubscribeReplayInfo` restent propriétaires de Transport ; le Worker observe leur projection sûre, conserve une processing frontier run-local, applique des bornes/fairness globales et fault sur un gap de rétention prouvé sans appeler le Job Backfill.
|
||||
La verticale actuelle n'est ni « un worker WebSocket » ni un moteur historique : `RawTransactionIngestRuntimeResources` contient de `1` à `32` sources logiques validées d'un même réseau parmi cinq familles — Yellowstone, Standard WS `logsSubscribe`, Standard WS `blockSubscribe`, Helius `transactionSubscribe` et HTTP live block polling. Yellowstone, Standard Logs et Helius convergent vers une registry globale d'hydration HTTP `getTransaction`; Standard Block et HTTP Block Polling qualifient directement le wire Base64 Legacy/V0/V1 vers Common RAW. Toutes les acquisitions rejoignent la même admission/persistence, la convergence canonique `(network, signature)` et des observations distinctes par provenance. Reconnect, `from_slot`, replay natif et retries réseau restent propriétaires de Transport. Le Worker observe leurs preuves sûres, maintient processing/continuity frontiers distinctes, réconcilie uniquement des gaps du run courant avec coverage explicite et mécanismes bornés, et n'appelle jamais le Job Backfill. Une source perdue ne peut rester absente que si sa perte passée est réconciliée et si les sources restantes prouvent encore tout le `TargetCoverage` futur.
|
||||
|
||||
RAW worker puis STRUCTURAL worker sont introduits à la fin de leur couche respective, lorsque persistence/backlog sont disponibles. Le traitement RAW -> STRUCTURAL borné est porté par un STRUCTURAL job distinct du service continu. Les workers DECODED/DOMAIN sont introduits avec les groupes Program concernés plutôt que tous anticipés en bloc.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md -->
|
||||
<!-- version: 19 -->
|
||||
<!-- version: 20 -->
|
||||
|
||||
# Acquisition, workers, jobs et pipelines spécialisés
|
||||
|
||||
@@ -131,9 +131,9 @@ normalisation RawTransaction commune
|
||||
ksp-store-lib
|
||||
```
|
||||
|
||||
Le modèle général autorise des stratégies alternatives, complémentaires ou redondantes, mais la verticale productive actuelle est volontairement plus étroite : **une** source Yellowstone + **une** voie HTTP d'hydration. Ce choix n'inscrit pas le provider ou le protocole dans l'identité RAW et ne ferme pas l'architecture future multi-source.
|
||||
La verticale productive accepte désormais de `1` à `32` sources logiques d'un même réseau parmi cinq familles : Yellowstone, Standard WS `logsSubscribe`, Standard WS `blockSubscribe`, Helius `transactionSubscribe` et HTTP live block polling. Ces sources peuvent être complémentaires ou redondantes, mais aucune équivalence n'est supposée par le seul provider/protocole : la convergence canonique reste `(network, signature)` et la coverage utilise des scopes structuraux explicites.
|
||||
|
||||
Le reconnect/replay du stream est une capacité Transport. Le Worker conserve une processing frontier run-local sur le travail réellement observé, projette `Active/Reconnecting/Closing/Closed/Failed` et des compteurs reconnect/replay/gap, mais ne possède ni checkpoint durable ni campagne de gap repair. Un gap de rétention prouvé par Transport devient un fault `source_failed` ; une récupération historique éventuelle reste une responsabilité séparée du Job Backfill.
|
||||
Le reconnect/replay du stream est une capacité Transport. Le Worker conserve une processing frontier run-local sur le travail réellement observé et une continuity frontier séparée, projette des gaps bornés et leurs méthodes de réparation, mais ne possède aucun checkpoint durable ni campagne historique. Un gap du run courant peut être réconcilié par replay Transport, coverage redondante prouvée, scan HTTP borné, block fetch ou hydration d'une référence connue. Une perte de source ne devient non terminale que si sa plage passée est entièrement réconciliée et si les sources restantes couvrent encore tout le `TargetCoverage` futur. Toute lacune non bornable/non couverte reste terminale ; aucune récupération n'appelle le Job Backfill.
|
||||
|
||||
#### Résultat de l'audit `0.3.9`
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md -->
|
||||
<!-- version: 14 -->
|
||||
<!-- version: 15 -->
|
||||
|
||||
# Acquisition et alimentation `RawTransaction`
|
||||
|
||||
@@ -187,7 +187,7 @@ Yellowstone BlockMeta / Slot
|
||||
-> continuité run-local uniquement
|
||||
```
|
||||
|
||||
La composition est caller-owned : le Worker ne lit pas Config et ne reçoit pas de secret. `RawTransactionIngestRuntimeResources` accepte de `1` à `32` sources logiques d'un même réseau, refuse les identités source dupliquées et supervise toutes les sources simultanément. Une faute source reste terminale pour le Worker faute d'équivalence de coverage prouvée.
|
||||
La composition est caller-owned : le Worker ne lit pas Config et ne reçoit pas de secret. `RawTransactionIngestRuntimeResources` accepte de `1` à `32` sources logiques d'un même réseau, refuse les identités source dupliquées et supervise toutes les sources simultanément. Une faute source n'autorise la continuation des siblings que lorsque sa plage de perte est sûre, que la coverage passée est réconciliée et que les sources restantes couvrent encore tout le `TargetCoverage` futur. Aucune équivalence n'est déduite du provider ou du protocole.
|
||||
|
||||
Il ne lance pas de campagne historique arbitraire.
|
||||
|
||||
@@ -204,17 +204,20 @@ Store durable = persistence des acquisitions admises
|
||||
blockchain completeness = non prouvée par les métriques ci-dessus
|
||||
```
|
||||
|
||||
Une tentative de replay ne prouve ni succès ni continuité parfaite. Si Transport prouve qu'un slot demandé est antérieur à `first_available`, son compteur de continuity gap augmente ; le Worker projette ce gap puis termine avec un fault `source_failed`.
|
||||
Une tentative de replay ne prouve ni succès ni continuité parfaite. Si Transport prouve qu'un slot demandé est antérieur à `first_available`, son compteur de continuity gap augmente ; le Worker ouvre ou enrichit alors un gap run-local sans considérer la reconnexion comme une réparation.
|
||||
|
||||
Il n'existe pas de délégation automatique vers Backfill :
|
||||
La réconciliation reste bornée au run :
|
||||
|
||||
```text
|
||||
gap de rétention prouvé
|
||||
-> Worker fault/stop
|
||||
-> aucun lancement de campagne historique
|
||||
gap de continuité borné
|
||||
-> replay Transport si preuve exploitable
|
||||
-> coverage redondante structurale si prouvée
|
||||
-> scan HTTP borné / getBlock / getTransaction selon capability
|
||||
-> même Common RAW / admission / Store
|
||||
-> Repaired ou Unresolved explicite
|
||||
```
|
||||
|
||||
Inversement, une demande telle que « récupère les transactions du programme X depuis le slot Y » reste une campagne `ksp-job-backfill-lib`.
|
||||
Il n'existe toujours aucune délégation automatique vers Backfill. Une demande telle que « récupère les transactions du programme X depuis le slot Y » reste une campagne `ksp-job-backfill-lib`, tandis qu'un gap non bornable ou non réconciliable du run courant fait fault le Worker.
|
||||
|
||||
### 3.4 Absence de relation Job ↔ Worker
|
||||
|
||||
@@ -734,7 +737,7 @@ RAW v1 complet -> hydration HTTP avant persistence
|
||||
|
||||
Cette qualification cross-source a préparé le contrat sans créer d'edge Common RAW -> Transport. L'extension Worker live utilise désormais cette décision conservative : Yellowstone produit des signaux structurés dans le Worker concret, puis HTTP `getTransaction` fournit le matériau RAW complet avant canonicalisation. Common RAW reste entièrement Transport-neutral.
|
||||
|
||||
## 14. État du Worker live après `0.3.13`
|
||||
## 14. État du Worker live après `0.3.14`
|
||||
|
||||
### 14.0 Verticale matérialisée
|
||||
|
||||
@@ -756,11 +759,14 @@ convergence canonique par (network, signature) + disagreement explicite
|
||||
persistence atomique via ksp-store-lib en mode Normal + observations supplémentaires idempotentes
|
||||
quotas pending/in-flight par source et bornes globales exactes
|
||||
fairness minimale / anti-starvation sous duplicate storm
|
||||
processing frontier run-local multi-source conservative
|
||||
processing frontier et continuity frontier run-local distinctes
|
||||
ledger de gaps inclusifs bornés + TargetCoverage conservative
|
||||
replay Transport / coverage redondante / scan HTTP / block fetch / hydration comme preuves distinctes
|
||||
observabilité publique source-neutral des gaps, raisons, états, dernière méthode et compteurs checked
|
||||
projection source-neutral Active/Reconnecting/Closing/Closed/Failed + gauges source_total/active/reconnecting/failed
|
||||
observation des compteurs reconnect/replay/gap Transport
|
||||
health conservative Healthy/Degraded/Unhealthy
|
||||
fault sur gap de rétention prouvé
|
||||
health Healthy/Degraded/Unhealthy fondée sur gaps, frontiers et coverage présente/future
|
||||
fairness nominal/repair sur les mêmes admission/hydration/persistence
|
||||
source loss non terminale uniquement après réconciliation complète et coverage future prouvée
|
||||
shutdown deadline + abort/join sans tâche orpheline ni late persistence
|
||||
```
|
||||
|
||||
@@ -790,7 +796,8 @@ acquérir à partir du démarrage
|
||||
normaliser et persister RawTransaction + observations
|
||||
publier snapshots/notifications concrètes Worker
|
||||
laisser reconnect/from_slot/replay au Transport
|
||||
fault proprement lorsqu'un gap de rétention est prouvé
|
||||
réconcilier uniquement les gaps bornés du run courant avec des preuves de coverage explicites
|
||||
fault proprement lorsqu'une lacune reste non bornable, non couverte ou unresolved
|
||||
```
|
||||
|
||||
Il ne doit pas :
|
||||
@@ -805,7 +812,7 @@ hardcoder un provider unique
|
||||
|
||||
### 14.2 Sources Worker V1 matérialisées et reports
|
||||
|
||||
Matérialisé dans `0.3.13` :
|
||||
Matérialisé dans `0.3.13` puis durci dans `0.3.14` :
|
||||
|
||||
```text
|
||||
Yellowstone transactions / blocks / status + HTTP hydration
|
||||
@@ -815,14 +822,18 @@ Helius transactionSubscribe Full + HTTP hydration
|
||||
HTTP live block polling getSlot/getBlocksWithLimit/getBlock observed
|
||||
HTTP hydration partagée et coalescée cross-source
|
||||
replay Yellowstone conservé propriétaire de Transport pour continuité du run
|
||||
gaps run-local bornés et continuity frontier distincte de la processing frontier
|
||||
coverage exacte/superset conservative avec epochs prouvés
|
||||
repair borné réutilisant Transport/Common RAW/admission/Store existants
|
||||
source-loss continuation uniquement sous TargetCoverage prouvée
|
||||
snapshots gap/repair source-neutral et health gap-aware
|
||||
```
|
||||
|
||||
Reste hors de cette verticale et nécessite une tranche dédiée :
|
||||
|
||||
```text
|
||||
sources EARLY / pre-execution
|
||||
coverage-equivalence ou failover non-terminal entre sources
|
||||
repair historique multi-source
|
||||
campagne historique multi-source ou caller-paramétrable
|
||||
Worker multi-source -> Store live E2E avec environnement complet provisionné
|
||||
```
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
|
||||
<!-- version: 99 -->
|
||||
<!-- version: 100 -->
|
||||
|
||||
# Séquence des releases fonctionnelles KSP
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/035-V0_3_14_MULTI_SOURCE_GAP_REPAIR_HARDENING_PLAN.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Plan v0.3.14 — gap repair / hardening multi-source du Worker RawTransaction
|
||||
|
||||
@@ -1058,3 +1058,41 @@ cargo check --workspace
|
||||
Le toolchain Cargo n'est pas disponible dans l'environnement d'assemblage actuel. Les commandes Cargo post-bump restent donc `NON EXÉCUTÉ LOCAL` jusqu'au gate opérateur.
|
||||
|
||||
Les audits Python locaux et l'intégrité du delta sont exécutés avant livraison.
|
||||
|
||||
## 27. Réconciliation d'implémentation `pre.015`
|
||||
|
||||
Le forecast `pre.001 -> pre.014` a été exécuté sans rescinder la release. L'état réellement obtenu est :
|
||||
|
||||
```text
|
||||
pre.001 audit / sizing / threat model
|
||||
pre.002 contrats gap/range/TargetCoverage
|
||||
pre.003 observabilité de continuité WebSocket
|
||||
pre.004 preuves replay Yellowstone attempt/delivery/coverage
|
||||
pre.005 coverage redondante exacte/superset conservative
|
||||
pre.006 discovery HTTP bornée
|
||||
pre.007 known-reference hydration/missing obligation
|
||||
pre.008 réconciliation + décision source-loss
|
||||
pre.009 health gap-aware / future coverage
|
||||
pre.010 fairness nominal/repair et partage des ressources
|
||||
pre.011 snapshots publics gap/repair source-neutral
|
||||
pre.012 races/shutdown/drain hardening
|
||||
pre.013 completeness/security cross-layer
|
||||
pre.014 gate technique workspace + smokes keyless
|
||||
pre.015 réconciliation documentaire
|
||||
```
|
||||
|
||||
Les bornes finales restent celles fixées dès les contrats `0.3.14` :
|
||||
|
||||
```text
|
||||
MAX_OPEN_REPAIR_GAPS = 64
|
||||
MAX_REPAIR_RANGE_SLOTS = 4096
|
||||
MAX_REPAIR_DISCOVERY_WINDOW_SLOTS = 512
|
||||
MAX_REPAIR_BLOCK_FETCH_IN_FLIGHT = 4
|
||||
MAX_REPAIR_ACTIVE_GAPS = 1
|
||||
```
|
||||
|
||||
La release n'a introduit ni EARLY, ni nouveau provider SDK, ni edge Worker -> Job Backfill, ni backend Store direct, ni retry réseau parallèle dans le Worker. Les cinq familles live `0.3.13` restent les seules familles productives ; `0.3.14` durcit leur continuité dans le run actif.
|
||||
|
||||
Le gate opérateur `pre.014` du 12 septembre 2026 ferme le critère technique déterministe : fmt/audits/check/Clippy sont verts, `cargo test --workspace --all-targets --all-features` totalise `1931` tests passés, `0` échec et `15` ignored, les trois commandes `cargo tree` prévues sont exécutées, et les deux smokes keyless HTTP/WS Devnet passent chacun `1/1`. Les smokes provider/resource-gated restent explicitement non revendiqués sans provisionnement.
|
||||
|
||||
`pre.015` ne change aucun comportement ; il aligne les README/USAGE et architectures sur cet état réellement livré. `CHANGELOG.md`, `ROADMAP.md` et le prompt de la version suivante restent réservés à `pre.016`.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/031-V0_3_14_MULTI_SOURCE_GAP_REPAIR_HARDENING.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Validation v0.3.14 — gap repair / hardening multi-source RawTransaction
|
||||
|
||||
@@ -715,3 +715,84 @@ Markdown table audit : clean (340 tables / 882 files)
|
||||
Le toolchain Cargo/Rustfmt n'est pas disponible dans l'environnement d'assemblage. Aucun PASS Cargo post-bump n'est donc revendiqué localement.
|
||||
|
||||
Le gate Cargo complet et les smokes live de `pre.014` restent `À EXÉCUTER` par l'opérateur avant `pre.015`.
|
||||
|
||||
## 26. Gate opérateur final de `pre.014`
|
||||
|
||||
Gate exécuté le **12 septembre 2026 à 21:07 +02:00** sur `workspace.package.version = 0.3.14-pre.14` :
|
||||
|
||||
```text
|
||||
cargo fmt --all : PASS
|
||||
cargo fmt --all -- --check : PASS
|
||||
General Rust rule audit : clean
|
||||
Rust export completeness audit : 0 candidate(s)
|
||||
KSP workspace Rust rule audit : clean
|
||||
Markdown table audit : clean (340 tables / 882 files)
|
||||
cargo check --workspace : PASS
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS
|
||||
cargo test --workspace --all-targets --all-features : PASS
|
||||
workspace tests : 1931 passed / 0 failed / 15 ignored
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib --edges normal : exécuté
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features : exécuté
|
||||
cargo tree --duplicates : exécuté
|
||||
```
|
||||
|
||||
L'arbre normal confirme que le Worker conserve les dépendances directes documentées :
|
||||
|
||||
```text
|
||||
ksp-core-lib
|
||||
ksp-logging-lib
|
||||
ksp-onchain-transport-lib
|
||||
ksp-raw-transaction-lib
|
||||
ksp-store-lib
|
||||
ksp-worker-api
|
||||
sha2
|
||||
tokio
|
||||
```
|
||||
|
||||
La commande `cargo tree --duplicates` est un inventaire des duplications transitives du workspace, pas une exigence de zéro duplication ; son exécution n'a révélé aucune nouvelle dépendance directe introduite par `0.3.14`.
|
||||
|
||||
### 26.1 Smokes keyless réellement exécutés
|
||||
|
||||
HTTP Devnet :
|
||||
|
||||
```text
|
||||
cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture
|
||||
1 passed / 0 failed
|
||||
```
|
||||
|
||||
WebSocket Devnet :
|
||||
|
||||
```text
|
||||
cargo test -p ksp-onchain-transport-lib --test websocket_devnet_smoke -- --ignored --nocapture
|
||||
1 passed / 0 failed
|
||||
```
|
||||
|
||||
Ces deux smokes prouvent les canaris Transport keyless accessibles. Ils ne constituent pas un smoke Worker -> Store end-to-end.
|
||||
|
||||
### 26.2 Non-claims finaux
|
||||
|
||||
Restent explicitement `NON EXÉCUTÉ` faute de provisionnement opérateur dans ce gate :
|
||||
|
||||
```text
|
||||
OrbitFlare Yellowstone Devnet live/replay
|
||||
PublicNode Yellowstone Mainnet/Testnet live/replay
|
||||
Helius transactionSubscribe live
|
||||
PostgreSQL live Store
|
||||
Worker gap repair -> Store live end-to-end
|
||||
```
|
||||
|
||||
Les tests ignored correspondants présents dans le workspace ne sont pas requalifiés en PASS.
|
||||
|
||||
## 27. Réconciliation documentaire `pre.015`
|
||||
|
||||
`pre.015` ne modifie aucun Rust, test, dépendance, feature, Config, schema ou comportement runtime. Elle réconcilie seulement les documents durables avec les preuves `0.3.14` effectivement livrées :
|
||||
|
||||
```text
|
||||
README/USAGE Worker : source-loss conditionnel, gaps/repair, health et snapshots publics
|
||||
architecture : composant/graph/Worker-vs-Job/RawTransaction acquisition
|
||||
functional release sequence : rôle réel de 0.3.14
|
||||
plan 035 : forecast exécuté et invariants finaux
|
||||
validation 031 : gate workspace + smokes keyless réellement exécutés
|
||||
```
|
||||
|
||||
`CHANGELOG.md`, `ROADMAP.md` et le prompt `0.3.15` restent volontairement inchangés jusqu'à `pre.016`.
|
||||
|
||||
Reference in New Issue
Block a user