Files
khadhroony-solana-project/prompts/023-V0_3_4_START_PROMPT.md
2026-08-30 18:03:06 +02:00

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`**.