1254 lines
35 KiB
Markdown
1254 lines
35 KiB
Markdown
<!-- file: prompts/023-V0_3_4_START_PROMPT.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Prompt de démarrage `0.3.4` — Store/PostgreSQL `RawAccountState` + complétude RAW
|
|
|
|
## 1. Identité de la release et base exacte requise
|
|
|
|
La release à ouvrir est :
|
|
|
|
```text
|
|
0.3.4 — Store/PostgreSQL RawAccountState + complétude/conformance RAW
|
|
```
|
|
|
|
La base autoritaire attendue est exclusivement la release stable :
|
|
|
|
```text
|
|
v0.3.3
|
|
workspace.package.version = 0.3.3
|
|
```
|
|
|
|
L'archive/repository `v0.3.3` fournie par l'opérateur prévaut sur toute mémoire, snippet, ancien artefact ou hypothèse de cette session.
|
|
|
|
La première tranche est :
|
|
|
|
```text
|
|
0.3.4-pre.001
|
|
```
|
|
|
|
Elle reste obligatoirement une tranche de **lecture + audit + brainstorming + threat model + design physique + sizing + planification**. Ne pas créer V002, les tables account ni les repositories SQL lourds avant la sortie cohérente de ce gate.
|
|
|
|
---
|
|
|
|
## 2. Mission et résultat attendu
|
|
|
|
`0.3.4` termine la couche RAW physique PostgreSQL ouverte par les trois releases précédentes :
|
|
|
|
```text
|
|
0.3.1 contrats backend-agnostic ksp-store-api
|
|
0.3.2 façade/runtime + backend PostgreSQL foundation
|
|
0.3.3 vertical slice RawTransaction complète
|
|
0.3.4 vertical slice RawAccountState + conformance RAW cross-family finale
|
|
```
|
|
|
|
La release étend le couple existant :
|
|
|
|
```text
|
|
ksp-store-lib
|
|
ksp-store-postgres-lib
|
|
```
|
|
|
|
avec les quatre capabilities account déjà stables dans `ksp-store-api` :
|
|
|
|
```text
|
|
RawAccountStateRead
|
|
RawAccountStateWrite
|
|
RawAccountObservationRead
|
|
RawAccountObservationWrite
|
|
```
|
|
|
|
Le résultat attendu à la clôture est que :
|
|
|
|
```text
|
|
PostgresBackend implémente les quatre capabilities RawAccount*
|
|
Store implémente/dispatch les quatre capabilities RawAccount*
|
|
les six capabilities RawTransaction acquises en 0.3.3 restent intactes
|
|
PostgresBackend et Store satisfont donc les dix capabilities RAW de ksp-store-api
|
|
RawAccountState est persisté sans perte de bytes ni narrowing entier
|
|
RawAccountState + observation initiale sont atomiques
|
|
une référence account déjà présente avec contenu identique est idempotente
|
|
une même référence avec contenu divergent retourne ERROR_CODE_RAW_CONFLICT
|
|
plusieurs états distincts d'un même pubkey dans un même slot restent représentables lorsque state_hash diffère
|
|
une observation supplémentaire est idempotente et ne crée jamais implicitement son state
|
|
get/list respectent RawAccountStateQuery et un ordre total déterministe
|
|
le cursor account est opaque, borné et impossible à rejouer comme cursor transaction ou contre une autre query
|
|
les optional Yellowstone metadata restent observation-only
|
|
V000/V001 restent immuables et la nouvelle persistence est additive
|
|
aucun index owner/provider/time n'est ajouté sans query réellement exposée
|
|
aucun SQL/type PostgreSQL ne fuit par ksp-store-lib
|
|
le tout est prouvé sur PostgreSQL réel avec coexistence RawTransaction + RawAccountState
|
|
```
|
|
|
|
Cette release ferme la **complétude RAW Store/PostgreSQL**, mais elle n'ouvre ni STRUCTURAL, ni Interface events, ni jobs/workers/backfill.
|
|
|
|
La release suivante reste :
|
|
|
|
```text
|
|
0.3.5 — ksp-interface-lib : modèles passifs/events réellement partagés par les premiers consumers d'acquisition
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Sources de vérité internes obligatoires — ordre de lecture
|
|
|
|
### 3.1 Règles globales
|
|
|
|
Lire d'abord :
|
|
|
|
```text
|
|
RULES.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
|
|
```
|
|
|
|
Relire particulièrement les règles applicables aux frontières :
|
|
|
|
```text
|
|
KSP-API-*
|
|
KSP-CONFIG-*
|
|
KSP-STORE-*
|
|
KSP-NOTIFY-*
|
|
KSP-PROC-*
|
|
KSP-REL-*
|
|
|
|
DEP-KSP-*
|
|
DEP-CARGO-*
|
|
DEP-LOG-*
|
|
DEP-STORE-*
|
|
DEP-WORKER-*
|
|
DEP-JOB-*
|
|
```
|
|
|
|
Rappels structurants :
|
|
|
|
```text
|
|
ksp-store-lib -> ksp-store-api
|
|
ksp-store-lib[postgres] -> ksp-store-postgres-lib
|
|
ksp-store-postgres-lib -> ksp-store-api
|
|
ksp-store-postgres-lib -X-> ksp-store-lib
|
|
Config -> Store autorisé
|
|
Store/backend -X-> Config
|
|
Transport -X-> Store
|
|
Program/Materializer -X-> Store
|
|
consumer ordinaire -> ksp-store-lib
|
|
consumer ordinaire -X-> ksp-store-postgres-lib
|
|
```
|
|
|
|
Un fix strictement documentaire ne modifie pas `workspace.package.version`. Une prerelease non-fix, y compris une tranche de publication, synchronise en revanche la version Cargo conformément à `VER-ID-009`.
|
|
|
|
### 3.2 Architecture durable
|
|
|
|
Lire ensuite :
|
|
|
|
```text
|
|
docs/architecture/000-README.md
|
|
docs/architecture/001-PROJECT_OBJECTIVES.md
|
|
docs/architecture/002-LAYERS_AND_DEPENDENCIES.md
|
|
docs/architecture/003-COMPONENT_CONTRACTS.md
|
|
docs/architecture/004-COMPONENT_INVENTORY.md
|
|
docs/architecture/005-DEPENDENCY_GRAPH.md
|
|
docs/architecture/007-EXECUTION_AND_POLICY.md
|
|
docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md
|
|
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
|
|
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md
|
|
```
|
|
|
|
Préserver notamment :
|
|
|
|
```text
|
|
RAW -> STRUCTURAL -> DECODED -> DOMAIN
|
|
Store persiste et sert ; il ne possède pas la policy de travail
|
|
pagination/cursorisation Store != batch-size/priorité/backlog worker/job
|
|
1 Store instance = 1 RawNetworkId + 1 backend physique
|
|
pas de multiplexage automatique de réseaux/bases dans Store
|
|
Config possède targets/URI/.env/secrets
|
|
backend PostgreSQL possède driver/pool/TLS/SQL/migrations
|
|
aucun type backend physique ne traverse la façade commune
|
|
```
|
|
|
|
### 3.3 Contrats RAW stables `0.3.1`
|
|
|
|
Lire intégralement :
|
|
|
|
```text
|
|
docs/plans/022-V0_3_1_STORE_RAW_PLAN.md
|
|
docs/validation/018-V0_3_1_STORE_RAW.md
|
|
crates/ksp-store-api/Cargo.toml
|
|
crates/ksp-store-api/src/**
|
|
crates/ksp-store-api/tests/**
|
|
```
|
|
|
|
Relire particulièrement :
|
|
|
|
```text
|
|
RawAccountStateReference
|
|
RawAccountState
|
|
RawAccountObservation
|
|
RawAccountStateQuery
|
|
RawPage / RawPageRequest / RawPageCursor / RawPageLimit
|
|
RawSlotRange / RawSortDirection
|
|
RawAcquisitionWriteOutcome
|
|
RawEntityWriteOutcome
|
|
RawObservationWriteOutcome
|
|
RawAcquisitionProvenance
|
|
RawObservationKey
|
|
RawContentHash
|
|
RawTransactionSignature
|
|
MAX_RAW_ACCOUNT_DATA_BYTES
|
|
les quatre capabilities RawAccount*
|
|
les six capabilities RawTransaction*
|
|
```
|
|
|
|
Ne pas redessiner `ksp-store-api` pour simplifier PostgreSQL. Une modification de l'API n'est recevable que si `pre.001` démontre un gap **backend-agnostic réel, bloquant et cross-backend**.
|
|
|
|
### 3.4 Fondation runtime/backend `0.3.2`
|
|
|
|
Lire :
|
|
|
|
```text
|
|
docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md
|
|
docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md
|
|
|
|
crates/ksp-store-lib/Cargo.toml
|
|
crates/ksp-store-lib/src/**
|
|
crates/ksp-store-lib/tests/**
|
|
|
|
crates/ksp-store-postgres-lib/Cargo.toml
|
|
crates/ksp-store-postgres-lib/src/**
|
|
crates/ksp-store-postgres-lib/tests/**
|
|
|
|
crates/ksp-config-lib/README.md
|
|
crates/ksp-config-lib/USAGE.md
|
|
config/std.store.json
|
|
config/schemas/std.store.schema.json
|
|
config/examples/std.store.example.json
|
|
```
|
|
|
|
### 3.5 Vertical slice `RawTransaction` stable `0.3.3`
|
|
|
|
Lire ensuite intégralement :
|
|
|
|
```text
|
|
docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md
|
|
docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md
|
|
|
|
crates/ksp-store-lib/README.md
|
|
crates/ksp-store-lib/USAGE.md
|
|
crates/ksp-store-postgres-lib/README.md
|
|
crates/ksp-store-postgres-lib/USAGE.md
|
|
|
|
crates/ksp-store-lib/src/**
|
|
crates/ksp-store-lib/tests/**
|
|
crates/ksp-store-postgres-lib/src/**
|
|
crates/ksp-store-postgres-lib/unit_tests/**
|
|
crates/ksp-store-postgres-lib/tests/**
|
|
crates/ksp-store-postgres-lib/migrations/**
|
|
```
|
|
|
|
Les patterns acquis de `0.3.3` sont des **précédents à réutiliser lorsque la sémantique account est réellement équivalente**, pas une invitation à copier chaque détail transaction.
|
|
|
|
Préserver notamment :
|
|
|
|
```text
|
|
V000/V001 checksummés et immuables
|
|
migration logique découpée en ressources typées backend-private
|
|
schema introspection Compatible/Missing/Incompatible
|
|
network binding via ksp_store_identity
|
|
u64 exact en NUMERIC(20,0) lorsque nécessaire
|
|
BYTEA fixed-width validé pour signatures/hashes/keys
|
|
transactions SQL atomiques
|
|
INSERT ... ON CONFLICT DO NOTHING puis comparaison exacte sous lock
|
|
keyset pagination sans OFFSET
|
|
cursor opaque lié à la query
|
|
PostgresBackendError = kind + phase statique/sûre
|
|
façade Store sans SQL/type physique
|
|
```
|
|
|
|
Lire enfin :
|
|
|
|
```text
|
|
CHANGELOG.md
|
|
ROADMAP.md
|
|
```
|
|
|
|
Créer en `pre.001` :
|
|
|
|
```text
|
|
docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md
|
|
docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Audit historique kbot3 obligatoire et ciblé
|
|
|
|
L'archive historique requise est :
|
|
|
|
```text
|
|
khadhroony-bot3_v0.5.3-pre.005-fix010.zip
|
|
```
|
|
|
|
Elle doit être disponible au `pre.001` parce que `0.3.4` ouvre la seconde famille métier PostgreSQL et doit comparer l'ancienne persistence account/observation avant de figer V002.
|
|
|
|
Réauditer uniquement les surfaces historiques pertinentes :
|
|
|
|
```text
|
|
ks-store/Cargo.toml
|
|
ks-store/README.md
|
|
ks-store/USAGE.md
|
|
|
|
ks-store/src/contracts/dto/raw.rs
|
|
ks-store/src/contracts/entity/raw.rs
|
|
ks-store/src/contracts/repository.rs
|
|
ks-store/src/contracts/dto/account_state.rs
|
|
ks-store/src/contracts/dto/core.rs
|
|
ks-store/src/contracts/entity/core.rs
|
|
|
|
ks-store/src/postgres/query/account_state_queries.rs
|
|
ks-store/src/postgres/repository/account_state_repository.rs
|
|
|
|
ks-store/migrations/postgres/schema/tables/create_table_if_not_exists_k_sol_obs_account_observations.sql
|
|
ks-store/migrations/postgres/schema/tables/create_table_if_not_exists_k_sol_core_account_states.sql
|
|
ks-store/migrations/postgres/schema/constraints/*account_observations*
|
|
ks-store/migrations/postgres/schema/constraints/*account_states*
|
|
ks-store/migrations/postgres/schema/indexes/*account_observations*
|
|
ks-store/migrations/postgres/schema/indexes/*account_states*
|
|
|
|
docs/guides/POSTGRES_STORAGE.md
|
|
docs/plans/V0_5_3_KS_STORE_NORMALIZATION_PLAN.md
|
|
```
|
|
|
|
Classer explicitement chaque idée sous :
|
|
|
|
```text
|
|
REPRENDRE
|
|
REDESSINER
|
|
REPORTER
|
|
REJETER
|
|
```
|
|
|
|
Points de comparaison obligatoires :
|
|
|
|
```text
|
|
identité account physique
|
|
pubkey/slot/hash
|
|
data bytes vs base64/text
|
|
lamports/rent_epoch exacts
|
|
owner/executable
|
|
observation identity/provenance
|
|
write_version Yellowstone
|
|
transaction_signature Yellowstone
|
|
is_startup Yellowstone
|
|
atomicité state + observation
|
|
idempotence observation
|
|
ordre/list/indexes
|
|
schema constraints
|
|
processing/normalization coupling
|
|
error mapping
|
|
```
|
|
|
|
Attention particulière : l'ancien `k_sol_core_account_states` appartient à une ancienne logique **CORE/normalization**, alors que le `RawAccountState` KSP actuel est un modèle **D1 RAW complet**. Ne pas traiter l'ancienne table CORE comme schéma de référence de V002.
|
|
|
|
Ne pas reprendre automatiquement :
|
|
|
|
```text
|
|
SQLx
|
|
ancien monolithe Store
|
|
processing ledger/stage dans la persistence RAW
|
|
MAX_ACCOUNT_STATE_SELECTION_ROWS ou autre batch-size worker/job
|
|
base64 comme représentation physique obligatoire des bytes RAW
|
|
BIGINT signé pour u64
|
|
ON CONFLICT DO UPDATE silencieux
|
|
status/error_message de processing dans les observations RAW
|
|
indexes owner/provider/method/time sans query KSP correspondante
|
|
maintenance destructive publique
|
|
IDs BIGSERIAL comme identité publique
|
|
```
|
|
|
|
Si l'archive historique n'est pas disponible :
|
|
|
|
```text
|
|
ne pas inventer son contenu depuis la mémoire
|
|
ne pas déclarer l'audit héritage terminé
|
|
ne pas figer V002/indexes account définitifs
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Sources externes à réauditer lorsque nécessaire
|
|
|
|
`0.3.4` n'est pas une release de mise à jour de dépendances.
|
|
|
|
Avant tout changement de version/feature, vérifier la version stable réellement courante et la documentation primaire des dépendances déjà utilisées :
|
|
|
|
```text
|
|
tokio-postgres
|
|
deadpool-postgres
|
|
tokio-postgres-rustls
|
|
rustls
|
|
sha2
|
|
PostgreSQL
|
|
```
|
|
|
|
Réauditer les sources PostgreSQL/tokio-postgres seulement lorsque le design l'exige, notamment pour :
|
|
|
|
```text
|
|
NUMERIC(20,0) et conversion exacte u64
|
|
BYTEA / length constraints
|
|
transactions et row locking
|
|
INSERT ... ON CONFLICT
|
|
FK/UNIQUE/CHECK
|
|
keyset pagination composite
|
|
NULL et optional metadata
|
|
catalog introspection / pg_get_constraintdef
|
|
cancellation/rollback
|
|
statement/parameter size pour account data jusqu'à la borne KSP
|
|
```
|
|
|
|
Ne pas ajouter ORM, query builder, codec wire ou SDK externe par habitude.
|
|
|
|
`RawAccountState::data()` fournit déjà des bytes canoniques. Aucun `bincode` n'est autorisé et aucun codec wire n'est requis pour cette persistence.
|
|
|
|
---
|
|
|
|
## 6. État validé `0.3.3` à préserver
|
|
|
|
### 6.1 `ksp-store-api`
|
|
|
|
La base stable possède **10 capabilities RAW** :
|
|
|
|
```text
|
|
6 RawTransaction*
|
|
4 RawAccount*
|
|
```
|
|
|
|
Les quatre capabilities account existent déjà et sont object-safe ; `0.3.4` doit les implémenter, pas les réinventer.
|
|
|
|
### 6.2 Façade `ksp-store-lib`
|
|
|
|
La base stable possède notamment :
|
|
|
|
```text
|
|
feature default = postgres
|
|
Store::open / runtime_snapshot / health / close
|
|
1 Store = 1 RawNetworkId + 1 backend
|
|
six capabilities RawTransaction dispatchées
|
|
validation réseau pré-I/O
|
|
mapping d'erreurs backend vers codes Store/API stables
|
|
compilation --no-default-features
|
|
aucun type PostgreSQL public
|
|
```
|
|
|
|
### 6.3 Backend `ksp-store-postgres-lib`
|
|
|
|
La base stable possède notamment :
|
|
|
|
```text
|
|
tokio-postgres + Deadpool + Rustls
|
|
moteur migration privé
|
|
V000 bootstrap
|
|
V001 RawTransaction
|
|
ksp_store_identity mono-network
|
|
schema resource compatibility + safe additive repair
|
|
PostgresBackendError kind + phase sûre
|
|
RawTransaction read/write/observation/retention complets
|
|
cursor transaction V1 opaque
|
|
live PostgreSQL 17 vert
|
|
```
|
|
|
|
Checksums immuables acquis :
|
|
|
|
```text
|
|
V000 d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450
|
|
V001 31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51
|
|
```
|
|
|
|
`0.3.4` ne modifie jamais les bytes de V000/V001 pour ajouter les comptes. Toute nouvelle structure physique est additive, normalement sous une nouvelle migration logique **V002** si le gate `pre.001` confirme ce design.
|
|
|
|
---
|
|
|
|
## 7. Contrat `RawAccountState` à respecter exactement
|
|
|
|
### 7.1 Référence canonique
|
|
|
|
L'identité backend-agnostic est :
|
|
|
|
```text
|
|
RawAccountStateReference
|
|
network
|
|
pubkey
|
|
slot
|
|
state_hash
|
|
```
|
|
|
|
Le commentaire API est structurant : plusieurs écritures d'un même compte peuvent exister dans le **même slot** lorsque les transports communs n'exposent pas `write_version`. Par conséquent :
|
|
|
|
```text
|
|
même pubkey + même slot + state_hash différent
|
|
!= conflit automatique
|
|
```
|
|
|
|
Ce sont potentiellement deux états canoniques distincts.
|
|
|
|
En revanche :
|
|
|
|
```text
|
|
même RawAccountStateReference + contenu complet divergent
|
|
=> ERROR_CODE_RAW_CONFLICT
|
|
```
|
|
|
|
Le hash ne dispense jamais de comparer exactement les champs canoniques en cas de collision.
|
|
|
|
### 7.2 Contenu canonique
|
|
|
|
`RawAccountState` contient exactement :
|
|
|
|
```text
|
|
reference
|
|
lamports: u64
|
|
owner: Pubkey
|
|
executable: bool
|
|
rent_epoch: u64
|
|
data: complete bytes
|
|
```
|
|
|
|
Les bytes doivent rester complets, non `jsonParsed`, non sliced et non convertis en base64 comme contrat physique obligatoire.
|
|
|
|
Borne KSP :
|
|
|
|
```text
|
|
MAX_RAW_ACCOUNT_DATA_BYTES = 16 MiB
|
|
```
|
|
|
|
Cette borne est une admission Store, pas une affirmation de limite protocolaire Solana.
|
|
|
|
### 7.3 Observation
|
|
|
|
`RawAccountObservation` contient :
|
|
|
|
```text
|
|
observation_key
|
|
account reference
|
|
provenance
|
|
is_startup: Option<bool>
|
|
transaction_signature: Option<RawTransactionSignature>
|
|
write_version: Option<u64>
|
|
```
|
|
|
|
Les trois champs optionnels sont **observation metadata**. Ils ne modifient jamais l'identité canonique account.
|
|
|
|
Ne pas inventer de valeur lorsque HTTP/WS ne l'expose pas.
|
|
|
|
### 7.4 Query
|
|
|
|
`RawAccountStateQuery` expose :
|
|
|
|
```text
|
|
network
|
|
optional pubkey
|
|
inclusive slot range
|
|
direction
|
|
page/cursor
|
|
```
|
|
|
|
Ne pas ajouter un index ou une query `owner`, provider, commitment, timestamp ou write_version si aucun contrat public ne le demande réellement.
|
|
|
|
---
|
|
|
|
## 8. Décisions déjà acquises et questions réellement ouvertes
|
|
|
|
### 8.1 Acquis
|
|
|
|
```text
|
|
PostgreSQL est le backend de référence
|
|
V000/V001 sont immuables
|
|
schema additions passent par le moteur de migrations existant
|
|
Store reste mono-network
|
|
u64 ne doit jamais être narrow vers BIGINT signé
|
|
pubkey/hash/observation key/signature ont des tailles exactes connues
|
|
canonical + observation initiale doivent être atomiques
|
|
idempotence identical / conflit divergent sont obligatoires
|
|
pagination Store reste policy-free
|
|
backend/facade ne lisent pas l'environnement
|
|
aucune erreur SQL/server brute ne traverse l'API
|
|
```
|
|
|
|
### 8.2 À décider en `pre.001`
|
|
|
|
Décider explicitement :
|
|
|
|
```text
|
|
forme et nom exacts de V002
|
|
ressources physiques exactes account state / observation
|
|
clé primaire/unique minimale
|
|
ordre total de RawAccountStateQuery
|
|
format/version du cursor account
|
|
liaison anti-replay cross-family transaction <-> account
|
|
indexes strictement nécessaires aux queries publiques
|
|
représentation PostgreSQL exacte de pubkey/hash/data/u64/optional u64
|
|
FK observation -> canonical account state
|
|
algorithme de collision canonical
|
|
algorithme d'idempotence observation
|
|
comportement concurrent identical/divergent
|
|
mapping d'erreurs account
|
|
stratégie live cross-family
|
|
```
|
|
|
|
Ne pas décider arbitrairement une rétention account : **aucune capability `RawAccountRetention*` n'existe dans `ksp-store-api`**.
|
|
|
|
Ne pas réutiliser `RawTransactionRetention*` pour les accounts.
|
|
|
|
---
|
|
|
|
## 9. Design physique attendu — contraintes de conception, pas schéma imposé
|
|
|
|
`pre.001` doit proposer puis figer un schéma minimal capable de représenter sans perte :
|
|
|
|
```text
|
|
RawAccountState
|
|
RawAccountObservation
|
|
```
|
|
|
|
Le design doit au minimum étudier :
|
|
|
|
### 9.1 Canonical account state
|
|
|
|
Candidats de représentation à auditer :
|
|
|
|
```text
|
|
pubkey BYTEA exact 32 bytes
|
|
slot NUMERIC(20,0)
|
|
state_hash BYTEA exact 32 bytes
|
|
lamports NUMERIC(20,0)
|
|
owner BYTEA exact 32 bytes
|
|
executable BOOLEAN
|
|
rent_epoch NUMERIC(20,0)
|
|
data BYTEA
|
|
```
|
|
|
|
Ce ne sont pas des noms de colonnes imposés ; le gate doit en revanche justifier toute représentation différente.
|
|
|
|
### 9.2 Observation
|
|
|
|
Candidats à auditer :
|
|
|
|
```text
|
|
observation_key BYTEA exact 32 bytes
|
|
account reference FK/colonnes exactes vers canonical
|
|
provenance mêmes codes/timestamps sûrs que RawTransactionObservation
|
|
is_startup BOOLEAN NULL
|
|
transaction_signature BYTEA exact 64 bytes NULL
|
|
write_version NUMERIC(20,0) NULL
|
|
```
|
|
|
|
### 9.3 Uniqueness et idempotence
|
|
|
|
Le design doit préserver :
|
|
|
|
```text
|
|
RawAccountStateReference unique
|
|
RawObservationKey unique globalement dans la famille account au minimum
|
|
observation référence exactement un canonical existant
|
|
pas de silent overwrite
|
|
```
|
|
|
|
Auditer si l'unicité `RawObservationKey` doit rester séparée par famille physique ou si un invariant cross-family est nécessaire. Ne pas changer `ksp-store-api` sans raison backend-agnostic.
|
|
|
|
### 9.4 Indexes
|
|
|
|
Partir des queries réelles :
|
|
|
|
```text
|
|
get by full reference
|
|
list optional pubkey + slot range + direction + cursor
|
|
get observation by observation_key
|
|
```
|
|
|
|
Le nombre d'indexes doit rester minimal et justifié par ces surfaces.
|
|
|
|
Les indexes kbot3 suivants ne sont **pas** automatiquement justifiés :
|
|
|
|
```text
|
|
owner
|
|
provider/method
|
|
received_at
|
|
status
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Atomicité, idempotence et concurrence
|
|
|
|
### 10.1 Acquisition state + observation
|
|
|
|
`persist_raw_account_acquisition(state, observation)` est une opération logique atomique :
|
|
|
|
```text
|
|
canonical state durable + observation durable
|
|
ou
|
|
aucun des deux
|
|
```
|
|
|
|
Valider avant I/O :
|
|
|
|
```text
|
|
network du state == network du backend
|
|
observation.account == state.reference
|
|
```
|
|
|
|
### 10.2 Collision canonical
|
|
|
|
La stratégie doit reprendre le principe validé en transaction lorsque compatible :
|
|
|
|
```text
|
|
INSERT ... ON CONFLICT DO NOTHING RETURNING
|
|
si insert absent -> lock/read canonical existant
|
|
comparaison exacte de tous les champs
|
|
identique -> AlreadyPresent
|
|
divergent -> Conflict
|
|
```
|
|
|
|
Le `state_hash` n'est pas une preuve suffisante d'égalité des bytes et champs en cas de collision.
|
|
|
|
### 10.3 Observation
|
|
|
|
Pour une observation supplémentaire :
|
|
|
|
```text
|
|
canonical absent -> ReferenceNotFound
|
|
observation key nouvelle -> Inserted
|
|
observation key existante + contenu complet identique -> AlreadyPresent
|
|
observation key existante + contenu divergent -> Conflict
|
|
```
|
|
|
|
Ne pas créer le canonical par effet de bord.
|
|
|
|
### 10.4 Concurrence
|
|
|
|
Prouver au minimum :
|
|
|
|
```text
|
|
deux acquisitions identiques concurrentes
|
|
même référence + contenu divergent concurrent
|
|
collision observation key entre deux acquisitions
|
|
annulation après insert canonical mais avant observation
|
|
observation supplémentaire concurrente
|
|
```
|
|
|
|
Les outcomes exacts doivent être déterministes ou, lorsque deux winners sont possibles, l'ensemble d'outcomes attendu doit être explicitement borné.
|
|
|
|
---
|
|
|
|
## 11. Pagination et cursor account
|
|
|
|
Le list account doit définir un ordre **total**, stable et compatible avec :
|
|
|
|
```text
|
|
optional pubkey filter
|
|
slot range
|
|
Ascending
|
|
Descending
|
|
continuation sans duplicate/skip
|
|
```
|
|
|
|
Le cursor reste backend-private et transporté uniquement via `RawPageCursor`.
|
|
|
|
Il doit être lié au minimum à :
|
|
|
|
```text
|
|
family = account
|
|
network
|
|
pubkey filter présent/absent + valeur
|
|
slot range
|
|
direction
|
|
last total-order key
|
|
cursor format/version
|
|
```
|
|
|
|
Un cursor transaction ne doit jamais être accepté comme cursor account, et inversement.
|
|
|
|
Ne pas utiliser :
|
|
|
|
```text
|
|
OFFSET
|
|
cursor JSON public
|
|
codec wire de ksp-interface-lib
|
|
bincode
|
|
batch-size worker caché
|
|
```
|
|
|
|
La limite demandée par `RawPageLimit` n'est pas une policy de worker. Seule une vraie borne physique PostgreSQL peut être refusée explicitement.
|
|
|
|
---
|
|
|
|
## 12. Complétude/conformance RAW cross-family
|
|
|
|
La release ne se limite pas à « ajouter deux tables ». Elle doit fermer la surface PostgreSQL RAW complète.
|
|
|
|
À la fin :
|
|
|
|
```text
|
|
PostgresBackend implémente exactement les 10 capabilities ksp-store-api
|
|
Store implémente exactement les mêmes 10 capabilities
|
|
RawTransaction reste non régressé
|
|
RawAccountState est complet
|
|
feature postgres default reste correcte
|
|
--no-default-features reste compilable/testable
|
|
aucun backend physique ne fuite
|
|
error mapping couvre toutes les classes nécessaires aux deux familles
|
|
migrations V000/V001/V002 sont cohérentes et vérifiables
|
|
schema compatibility/hardening couvre toutes les ressources gérées
|
|
```
|
|
|
|
Auditer les canaris de `pre.009/pre.010` de `0.3.3` : certains interdisent volontairement `RawAccount*` et devront être **mis à jour au moment exact où le scope devient légitime**, jamais supprimés globalement sans remplacement.
|
|
|
|
---
|
|
|
|
## 13. Threat model obligatoire
|
|
|
|
Couvrir au minimum :
|
|
|
|
```text
|
|
wrong-network input avant I/O
|
|
wrong-network database URI
|
|
pubkey/hash/observation key/signature malformés dans DB
|
|
u64 overflow/narrowing slot/lamports/rent_epoch/write_version
|
|
account data > MAX_RAW_ACCOUNT_DATA_BYTES
|
|
row data corrompue
|
|
observation orphan
|
|
canonical orphan après rollback
|
|
même pubkey+slot avec hashes distincts légitimes
|
|
même full reference avec contenu divergent
|
|
identical concurrent insert
|
|
divergent concurrent insert
|
|
observation-key collision
|
|
cursor hostile
|
|
cursor replay avec autre network
|
|
cursor replay avec autre pubkey filter/range/direction
|
|
cursor transaction rejoué sur account
|
|
pagination duplicate/skip sous ordre ambigu
|
|
optional Yellowstone metadata NULL/non-NULL mal mappées
|
|
SQL/server error leak
|
|
pool cancellation pendant transaction
|
|
V002 checksum/history mismatch
|
|
schema resource missing/incompatible
|
|
V000/V001 mutation accidentelle
|
|
index excessif/non justifié
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Première mission `pre.001`
|
|
|
|
### 14.1 Lecture et inventaire
|
|
|
|
Avant toute modification fonctionnelle :
|
|
|
|
1. vérifier que la base est bien `v0.3.3` stable ;
|
|
2. lire toutes les sources internes listées ci-dessus ;
|
|
3. inventorier V000/V001 et recalculer leurs checksums ;
|
|
4. inventorier les 10 capabilities et confirmer que 6/10 sont déjà implémentées physiquement ;
|
|
5. inventorier tous les canaris qui interdisent encore `RawAccount*` ;
|
|
6. inspecter `RawAccountState`, `RawAccountObservation` et `RawAccountStateQuery` champ par champ ;
|
|
7. auditer l'archive kbot3 ciblée ;
|
|
8. vérifier les dépendances actuelles seulement si le design en dépend.
|
|
|
|
### 14.2 Matrice des quatre capabilities
|
|
|
|
Produire une matrice explicite :
|
|
|
|
```text
|
|
capability
|
|
input
|
|
output
|
|
network guard
|
|
SQL/transaction requis
|
|
idempotence
|
|
conflit
|
|
absence/reference behavior
|
|
pagination/cursor éventuel
|
|
error mapping
|
|
live proof
|
|
```
|
|
|
|
### 14.3 Matrice modèle -> physique
|
|
|
|
Pour chaque champ account :
|
|
|
|
```text
|
|
champ API
|
|
type Rust
|
|
cardinalité/optionality
|
|
représentation PostgreSQL
|
|
borne/constraint
|
|
mapping read
|
|
mapping write
|
|
risque de narrowing/perte
|
|
```
|
|
|
|
### 14.4 Audit historique
|
|
|
|
Classer l'héritage kbot3 sous :
|
|
|
|
```text
|
|
REPRENDRE
|
|
REDESSINER
|
|
REPORTER
|
|
REJETER
|
|
```
|
|
|
|
Documenter explicitement pourquoi l'ancien `CoreAccountState` n'est pas le nouveau `RawAccountState`.
|
|
|
|
### 14.5 Design V002
|
|
|
|
Proposer :
|
|
|
|
```text
|
|
migration logical version/name
|
|
resource tree tables/constraints/indexes
|
|
identité canonical
|
|
observation FK/unicity
|
|
u64 representation
|
|
byte fixed-width checks
|
|
account data representation
|
|
indexes minimaux
|
|
schema compatibility contract
|
|
```
|
|
|
|
Ne pas écrire les ressources SQL avant validation cohérente du design.
|
|
|
|
### 14.6 Cursor/order
|
|
|
|
Décider l'ordre total account et un format cursor backend-private avec anti-replay cross-family.
|
|
|
|
### 14.7 Concurrence
|
|
|
|
Écrire les algorithmes d'acquisition/observation et leurs états de course avant le code SQL.
|
|
|
|
### 14.8 Threat model
|
|
|
|
Produire la matrice décrite en section 13.
|
|
|
|
### 14.9 Sizing
|
|
|
|
Chaque tranche prévue au-delà d'environ **15 à 20 minutes de travail effectif** doit être scindée.
|
|
|
|
Si `RawAccountState + conformance RAW` n'est plus clôturable dans cette session, redécouper avant V002 lourd. Ne jamais aspirer `0.3.5` dans `0.3.4`.
|
|
|
|
### 14.10 Documents de gate
|
|
|
|
Créer :
|
|
|
|
```text
|
|
docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md
|
|
docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md
|
|
```
|
|
|
|
### 14.11 Critères de sortie de `pre.001`
|
|
|
|
`pre.001` est terminé seulement si :
|
|
|
|
```text
|
|
base v0.3.3 vérifiée
|
|
V000/V001 immuables vérifiés
|
|
quatre capabilities account auditées
|
|
10-capability cross-family inventory établi
|
|
kbot3 account audit classé
|
|
Core historique != RawAccount actuel explicitement documenté
|
|
V002 proposé
|
|
mapping exact de tous les champs décidé
|
|
u64/bytes/optionality décidés
|
|
identity/unicity/FK décidés
|
|
atomicité/idempotence/conflit décidés
|
|
ordre total/cursor anti-replay décidé
|
|
indexes minimaux justifiés par query
|
|
error taxonomy décidée
|
|
threat model complet
|
|
stratégie live cross-family définie
|
|
plan 025 créé
|
|
validation 021 créée
|
|
prévision souple recalibrée
|
|
aucune persistence account lourde créée prématurément
|
|
```
|
|
|
|
---
|
|
|
|
## 15. Prévision souple initiale des prereleases
|
|
|
|
Cette prévision peut être scindée/recalibrée par `pre.001`.
|
|
|
|
### `pre.001` — Audit contrats, kbot3, V002, cursor, concurrence et sizing
|
|
|
|
Lectures, inventaire 10 capabilities, audit account historique, design physique, threat model, plan/validation.
|
|
|
|
### `pre.002` — V002 + schéma/indexes account
|
|
|
|
Ajouter uniquement les ressources physiques account réellement nécessaires via le moteur de migrations existant. V000/V001 restent byte-identiques. Tests registry/checksum/schema compatibility.
|
|
|
|
### `pre.003` — Mapping physique + lectures account
|
|
|
|
Mappings rows/API privés, `get_raw_account_state`, `get_raw_account_observation`, hostile rows, wrong-network pré-I/O.
|
|
|
|
### `pre.004` — Persistence account atomique + observations
|
|
|
|
`persist_raw_account_acquisition` et `record_raw_account_observation`, idempotence/conflit, exact compare, rollback et concurrence unitaire/intégration sans live externe.
|
|
|
|
### `pre.005` — List/query + cursor account
|
|
|
|
`RawAccountStateQuery`, ordre total, optional pubkey, ranges, directions, cursor opaque/versionné et anti-replay cross-family.
|
|
|
|
### `pre.006` — Façade + conformance des quatre capabilities account
|
|
|
|
Implémenter/dispatcher les quatre traits sur `PostgresBackend` et `Store`, network guard, error mapping, feature mismatch. Verrouiller la surface totale à 10 capabilities.
|
|
|
|
### `pre.007` — PostgreSQL integration réelle `RawAccountState`
|
|
|
|
Gate opt-in sur database dédiée : V000+V001+V002, state+observation atomic, idempotence, conflit, observations, concurrence, pagination, cancellation/rollback et petite preuve de coexistence transaction/account.
|
|
|
|
### `pre.008` — Hardening/completeness RAW cross-family
|
|
|
|
Exact modules/exports/capabilities, hostile rows/cursors, no-secret/no-SQL-leak, migration resource completeness, canaris transaction non régressés, aucun scope STRUCTURAL/Interface/job.
|
|
|
|
### `pre.009` — Gate technique/live final
|
|
|
|
Workspace complet, `--no-default-features`, `cargo test --workspace`, graphes/features/duplicates, replay des preuves PostgreSQL nécessaires et vérification finale des migrations V000/V001/V002.
|
|
|
|
### `pre.010` — Réconciliation documentaire finale
|
|
|
|
README/USAGE Store/backend, plan `025`, validation `021`, indexes docs et autres références durables réellement impactées. `USAGE.md` reste un guide d'utilisation durable avec exemples ; aucune preuve de gate/chronologie de prerelease n'y est ajoutée. Ne pas toucher `CHANGELOG.md`, `ROADMAP.md` ni au prompt suivant.
|
|
|
|
### `pre.011` — Préparation de publication minimale
|
|
|
|
Uniquement :
|
|
|
|
```text
|
|
Cargo.toml
|
|
CHANGELOG.md
|
|
ROADMAP.md
|
|
prompts/024-V0_3_5_START_PROMPT.md
|
|
deltas/0.3.4/pre.011.md
|
|
```
|
|
|
|
### `rel.001` — Publication stable
|
|
|
|
Version finale + delta uniquement.
|
|
|
|
---
|
|
|
|
## 16. Versionnement, deltas, commits et tags
|
|
|
|
Respecter `docs/rules/VERSION_WORKFLOW.md`.
|
|
|
|
Rappels :
|
|
|
|
```text
|
|
workspace.package.version prerelease : 0.3.4-pre.N
|
|
livraison : 0.3.4-pre.NNN
|
|
fix code/runtime/config : Cargo 0.3.4-pre.N.fix.M
|
|
fix strictement documentaire : Cargo inchangé
|
|
prerelease non-fix documentaire/publication : Cargo synchronisé
|
|
chaque delta commité
|
|
tag stable final : v0.3.4
|
|
```
|
|
|
|
Chaque delta contient au minimum :
|
|
|
|
```text
|
|
base requise
|
|
objectif
|
|
fichiers ajoutés
|
|
fichiers modifiés
|
|
fichiers supprimés
|
|
validations exécutées
|
|
validations non exécutées
|
|
décisions
|
|
questions ouvertes
|
|
```
|
|
|
|
Une commande non exécutée n'est jamais déclarée PASS.
|
|
|
|
---
|
|
|
|
## 17. Procédure d'application et validation opérateur
|
|
|
|
Après chaque overlay :
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.4
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
```
|
|
|
|
Tests ciblés typiques :
|
|
|
|
```bash
|
|
cargo test -p ksp-store-api
|
|
cargo test -p ksp-store-lib
|
|
cargo test -p ksp-store-postgres-lib
|
|
cargo test -p ksp-config-lib
|
|
cargo check -p ksp-store-lib --no-default-features
|
|
```
|
|
|
|
Lorsque la façade/account conformance change :
|
|
|
|
```bash
|
|
cargo test -p ksp-store-lib --no-default-features
|
|
```
|
|
|
|
Lorsque le graphe/features change ou au gate final :
|
|
|
|
```bash
|
|
cargo tree -p ksp-store-lib --edges normal
|
|
cargo tree -p ksp-store-lib -e features
|
|
cargo tree -p ksp-store-postgres-lib --edges normal
|
|
cargo tree --duplicates
|
|
```
|
|
|
|
Le gate technique final inclut :
|
|
|
|
```bash
|
|
cargo test --workspace
|
|
```
|
|
|
|
Ne pas refaire des builds Tauri sans changement de resources/config/packaging desktop démontré.
|
|
|
|
---
|
|
|
|
## 18. Validation PostgreSQL réelle spécifique
|
|
|
|
La release doit disposer d'une preuve account opt-in sur une database PostgreSQL dédiée.
|
|
|
|
Le test doit refuser de démarrer si le jeu d'objets KSP qu'il pourrait détruire existe déjà. Il ne doit jamais afficher l'URI.
|
|
|
|
Couvrir au minimum :
|
|
|
|
```text
|
|
PostgreSQL >= 15
|
|
bootstrap V000 + V001 + V002
|
|
health Ready
|
|
wrong network rejeté
|
|
persist state + observation
|
|
read state exact, bytes inclus
|
|
read observation exacte
|
|
re-persist identique -> AlreadyPresent
|
|
même full reference + contenu divergent -> Conflict
|
|
même pubkey + même slot + state_hash différent -> deux states distincts admis
|
|
observation supplémentaire
|
|
observation idempotente
|
|
observation-key collision divergente
|
|
optional is_startup/transaction_signature/write_version round-trip
|
|
concurrence identical/divergent
|
|
list avec/sans pubkey filter
|
|
Ascending/Descending
|
|
slot range
|
|
plusieurs pages
|
|
cursor hostile/cross-query rejeté
|
|
cursor transaction -> account rejeté
|
|
annulation/rollback sans canonical orphelin
|
|
petit canari RawTransaction après V002
|
|
close borné
|
|
cleanup uniquement des tables KSP dont l'absence initiale a été prouvée
|
|
```
|
|
|
|
Le test ne doit pas :
|
|
|
|
```text
|
|
lire l'environnement depuis Store/backend
|
|
afficher URI/credentials
|
|
DROP database/schema non créé par lui
|
|
exiger endpoint Solana HTTP/WS/gRPC
|
|
introduire worker/job/processing ledger
|
|
```
|
|
|
|
---
|
|
|
|
## 19. Critères de clôture de `0.3.4`
|
|
|
|
La release stable est prête seulement si :
|
|
|
|
```text
|
|
V000/V001 restent byte-identiques
|
|
V002 account est versionnée/checksummée et additive
|
|
schema physique représente RawAccountState sans perte/narrowing
|
|
PostgresBackend satisfait les 4 capabilities RawAccount
|
|
Store satisfait/dispatch les 4 capabilities RawAccount
|
|
PostgresBackend + Store satisfont les 10 capabilities RAW
|
|
RawTransaction reste intégralement vert
|
|
wrong-network est rejeté avant I/O
|
|
state+observation est atomique
|
|
identical est idempotent
|
|
divergent même full reference -> ERROR_CODE_RAW_CONFLICT
|
|
states distincts même pubkey+slot avec hash différent restent possibles
|
|
observations supplémentaires sont idempotentes
|
|
optional Yellowstone metadata round-trip exactement
|
|
get state/observation fonctionnent
|
|
list account est total/déterministe/cursorisé
|
|
cursor account est lié à sa family/query
|
|
aucun batch/backlog/policy n'est introduit
|
|
aucun index sans query réelle n'est ajouté
|
|
aucun SQL/type physique ne fuit
|
|
aucun secret/data/SQL distant ne fuite dans erreurs/logs
|
|
ksp-store-api reste backend-agnostic
|
|
aucune rétention account inventée
|
|
PostgreSQL live account/cross-family est vert
|
|
workspace/Clippy/tests/graphes sont verts
|
|
README/USAGE/plan/validation sont réconciliés selon leur rôle documentaire
|
|
prompt 0.3.5 est prêt
|
|
```
|
|
|
|
---
|
|
|
|
## 20. Hors périmètre explicite
|
|
|
|
Ne pas ouvrir dans `0.3.4` :
|
|
|
|
```text
|
|
nouvelles familles RAW
|
|
RawAccount retention/tombstone non contracté
|
|
STRUCTURAL persistence
|
|
Program decode/materialization
|
|
ksp-interface-lib events de 0.3.5
|
|
ksp-job-api/backfill de 0.3.6
|
|
application backfill/inspection de 0.3.7
|
|
worker RAW live
|
|
notification bus dédié
|
|
nouveau backend SQL/NoSQL
|
|
Store Desk
|
|
wire codec
|
|
policy de batch/priorité/retry
|
|
```
|
|
|
|
---
|
|
|
|
## 21. Release suivante et instruction d'ouverture
|
|
|
|
La release suivante envisagée est :
|
|
|
|
```text
|
|
0.3.5 — Interface events/acquisitions partagés si consumer réel
|
|
```
|
|
|
|
### Instruction d'ouverture
|
|
|
|
À réception de la base stable `v0.3.3` **et de l'archive kbot3 requise** :
|
|
|
|
1. vérifier la base exacte et recalculer V000/V001 ;
|
|
2. lire règles, architecture, plans/validations `0.3.1` à `0.3.3` ;
|
|
3. inventorier les 10 capabilities et confirmer que seules les quatre `RawAccount*` restent sans implémentation physique ;
|
|
4. auditer `RawAccountState`, `RawAccountObservation` et `RawAccountStateQuery` champ par champ ;
|
|
5. réauditer kbot3 uniquement sur account observation/state/indexes et séparer RAW actuel de l'ancien CORE ;
|
|
6. figer V002, identity/unicity/FK, u64/bytes, atomicité, cursor/order, error mapping et indexes ;
|
|
7. produire threat model, sizing, plan `025` et validation `021` ;
|
|
8. **ne pas écrire V002 ni le repository account lourd avant validation cohérente de `pre.001`** ;
|
|
9. **ne pas ouvrir STRUCTURAL, Interface events, jobs/workers/backfill ou application dans `0.3.4`**.
|